1# Using the Cloud Client Libraries for Python 2 3This document demonstrates how to use the Cloud Client Libraries for Python for Compute Engine. 4It describes how to authorize requests and how to create, list, and delete instances. 5This exercise discusses how to use the `google-api-python-client` library to access Compute Engine 6resources. You can run this sample from your local machine or on a VM instance, provided that 7you have authorized the sample correctly. 8 9For a full list of available client libraries, including other Google client libraries and 10third-party open source libraries, see the [client libraries page](https://cloud.google.com/compute/docs/api/libraries). 11 12To view the full code example with all of the necessary imports, see the [create_instance.py file](create_instance.py). 13 14## Objectives 15 16 * Perform OAuth 2.0 authorization using the `oauth2client` library 17 * Create, list and delete instances using the `google-api-python-client` library 18 19## Costs 20 21This tutorial uses billable components of Google Cloud including Compute Engine. 22 23## Before you begin 24 251. In the Google Cloud Console, on the project selector page, select or create a Google Cloud project. 26 [Go to project selector](https://console.cloud.google.com/projectselector2/home/dashboard). 271. Make sure that billing is enabled for your cloud project. 28 [Learn how to confirm that billing is enabled for your project.](https://cloud.google.com/billing/docs/how-to/modify-project) 291. [Install Google Cloud SDK and `gcloud`](https://cloud.google.com/sdk) 301. After the SDK is installed, run `gcloud auth application-default login`. 311. Install the [google-api-python-client](http://github.com/googleapis/google-api-python-client) library. Typically, you can run: 32 33 ```bash 34 pip install --upgrade google-api-python-client 35 ``` 36 371. Enable the Cloud Storage API. 38 ```bash 39 gcloud services enable storage.googleapis.com 40 ``` 411. [Create a Cloud Storage bucket](https://cloud.google.com/storage/docs/creating-buckets) and note the bucket name for later. 42 43## Authorizing requests 44 45This sample uses OAuth 2.0 authorization. There are many ways to authorize requests using OAuth 2.0, 46but for the example use [application default credentials](https://developers.google.com/accounts/docs/application-default-credentials). This lets you reuse the credentials from 47the `gcloud` tool if you are running the sample on a local workstation or reuse credentials from a 48service account if you are running the sample from within Compute Engine or App Engine. You should 49have installed and authorized the `gcloud` tool in the "Before you begin" section. 50 51Application default credentials are provided in Google API Client Libraries automatically. 52You just have to build and initialize the API: 53 54```python 55import googleapiclient 56compute = googleapiclient.discovery.build('compute', 'v1') 57``` 58 59See the `main()` method in the [create_instance.py](create_instance.py) script, to see how an API 60client is built and used. 61 62## Listing instances 63 64Using `google-api-python-client`, you can list instances by using the `compute.instances().list()` method. 65You need to provide the project ID and the zone for which you want to list instances. For example: 66 67```python 68def list_instances(compute, project, zone): 69 result = compute.instances().list(project=project, zone=zone).execute() 70 return result['items'] if 'items' in result else None 71``` 72 73## Adding an instance 74 75To add an instance, use the `compute.instances().insert()` method and specify the properties of the new 76instance. These properties are specified in the request body; for details about each property see 77the [API reference for `instances.insert`](https://cloud.google.com/compute/docs/reference/latest/instances/insert). 78 79At a minimum, your request must provide values for the following properties when you create a new 80instance: 81 82* Instance name 83* Root persistent disk 84* Machine type 85* Zone 86* Network Interfaces 87 88This sample starts an instance with the following properties in a zone of your choice: 89 90* Machine type: e2-standard-2 91* Root persistent disk: a new persistent disk based on the latest Debian 8 image 92* The Compute Engine default service account with the following scopes: 93 * https://www.googleapis.com/auth/devstorage.read_write, so the instance can read and write files in Cloud Storage 94 * https://www.googleapis.com/auth/logging.write, so the instances logs can upload to Cloud Logging 95* Metadata to specify commands that the instance should execute upon startup 96 97You can see an example of instance creation in the `create_instance` method in [create_instance.py](create_instance.py) file. 98 99### Root persistent disks 100 101All instances must boot from a [root persistent disk](https://cloud.google.com/compute/docs/disks/create-root-persistent-disks). 102The root persistent disk contains all of the necessary files required for starting an instance. 103When you create a root persistent disk you must select a public image or a custom image to apply to 104the disk. In the example above, a new root persistent disk is created based on Debian 8 at the same 105time as the instance. However, it is also possible to create a disk beforehand and attach it to the 106instance. 107 108To create an instance using your own custom OS image, you need to provide a different URL than 109the one included in the example. For more information about starting an instance with your own 110images, see [Creating an instance from a custom image](https://cloud.google.com/compute/docs/instances/create-start-instance#creating_an_instance_from_a_custom_image). 111 112 113 114### Instance metadata 115 116When you create your instance, you might want to include instance metadata such as a [startup script](https://cloud.google.com/compute/docs/startupscript), 117configuration variables, and SSH keys. In the example above, you used the `metadata` field in your 118request body to specify a startup script for the instance and some configuration variables as 119key/values pairs. The [startup-script.sh](startup-script.sh) shows how to read these variables and use them 120to apply text to an image and upload it to [Cloud Storage](https://cloud.google.com/storage). 121 122## Deleting an Instance 123 124To delete an instance, you need to call the `compute.instances().delete()` method and provide the name, 125zone, and project ID of the instance to delete. When the `autoDelete` parameter is set to `true` for the 126boot disk it is also deleted with the instance. This setting is off by default but is 127useful when your use case calls for disks and instances to be deleted together. 128 129```python 130def delete_instance(compute, project, zone, name): 131 return compute.instances().delete( 132 project=project, 133 zone=zone, 134 instance=name).execute() 135``` 136 137## Running the sample 138 139You can run the full sample by downloading the code and running it on the command line. Make sure 140to download the `create_instance.py` file and the `startup-script.sh` file. To run the sample: 141 142```bash 143python create_instance.py --name [INSTANCE_NAME] --zone [ZONE] [PROJECT_ID] [CLOUD_STORAGE_BUCKET] 144``` 145 146where: 147 148* `[INSTANCE_NAME]` is the name of the instance to create. 149* `[ZONE]` is the desired zone for this request. 150* `[PROJECT_ID]` is our project ID. 151* `[CLOUD_STORAGE_BUCKET]` is the name of the bucket you initially set up but without the `gs://` prefix. 152 153For example: 154 155```bash 156python python-example.py --name example-instance --zone us-central1-a example-project my-gcs-bucket 157``` 158 159## Waiting for operations to complete 160 161Requests to the Compute Engine API that modify resources such as instances immediately return a 162response acknowledging your request. The acknowledgement lets you check the status of the requested 163operation. Operations can take a few minutes to complete, so it's often easier to wait for the 164operation to complete before continuing. This helper method waits until the operation completes 165before returning: 166 167```python 168def wait_for_operation(compute, project, zone, operation): 169 print('Waiting for operation to finish...') 170 while True: 171 result = compute.zoneOperations().get( 172 project=project, 173 zone=zone, 174 operation=operation).execute() 175 176 if result['status'] == 'DONE': 177 print("done.") 178 if 'error' in result: 179 raise Exception(result['error']) 180 return result 181 182 time.sleep(1) 183``` 184 185When you query per-zone operations, use the `compute.zoneOperations.get()` method. When you query global 186operations, use the `compute.globalOperations.get()` method. For more information, see zone resources. 187 188## Cleaning up 189 190To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, 191either delete the project that contains the resources, or keep the project and delete the 192individual resources. 193 194### Delete your Cloud Storage bucket 195 196To delete a Cloud Storage bucket: 1971. In the Cloud Console, go to the Cloud Storage [Browser page](https://console.cloud.google.com/storage/browser). 1981. Click the checkbox for the bucket that you want to delete. 1991. To delete the bucket, click `Delete`, and then follow the instructions. 200