|
| 1 | +# Using the Cloud Client Libraries for Python |
| 2 | + |
| 3 | +This document demonstrates how to use the Cloud Client Libraries for Python for Compute Engine. |
| 4 | +It describes how to authorize requests and how to create, list, and delete instances. |
| 5 | +This exercise discusses how to use the `google-api-python-client` library to access Compute Engine |
| 6 | +resources. You can run this sample from your local machine or on a VM instance, provided that |
| 7 | +you have authorized the sample correctly. |
| 8 | + |
| 9 | +For a full list of available client libraries, including other Google client libraries and |
| 10 | +third-party open source libraries, see the [client libraries page](https://cloud.google.com/compute/docs/api/libraries). |
| 11 | + |
| 12 | +To 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 | + |
| 21 | +This tutorial uses billable components of Google Cloud including Compute Engine. |
| 22 | + |
| 23 | +## Before you begin |
| 24 | + |
| 25 | +1. 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). |
| 27 | +1. 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) |
| 29 | +1. [Install Google Cloud SDK and `gcloud`](https://cloud.google.com/sdk) |
| 30 | +1. After the SDK is installed, run `gcloud auth application-default login`. |
| 31 | +1. 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 | + |
| 37 | +1. Enable the Cloud Storage API. |
| 38 | + ```bash |
| 39 | + gcloud services enable storage.googleapis.com |
| 40 | + ``` |
| 41 | +1. [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 | + |
| 45 | +This sample uses OAuth 2.0 authorization. There are many ways to authorize requests using OAuth 2.0, |
| 46 | +but for the example use [application default credentials](https://developers.google.com/accounts/docs/application-default-credentials). This lets you reuse the credentials from |
| 47 | +the `gcloud` tool if you are running the sample on a local workstation or reuse credentials from a |
| 48 | +service account if you are running the sample from within Compute Engine or App Engine. You should |
| 49 | +have installed and authorized the `gcloud` tool in the "Before you begin" section. |
| 50 | + |
| 51 | +Application default credentials are provided in Google API Client Libraries automatically. |
| 52 | +You just have to build and initialize the API: |
| 53 | + |
| 54 | +```python |
| 55 | +import googleapiclient |
| 56 | +compute = googleapiclient.discovery.build('compute', 'v1') |
| 57 | +``` |
| 58 | + |
| 59 | +See the `main()` method in the [create_instance.py](create_instance.py) script, to see how an API |
| 60 | +client is built and used. |
| 61 | + |
| 62 | +## Listing instances |
| 63 | + |
| 64 | +Using `google-api-python-client`, you can list instances by using the `compute.instances().list()` method. |
| 65 | +You need to provide the project ID and the zone for which you want to list instances. For example: |
| 66 | + |
| 67 | +```python |
| 68 | +def 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 | + |
| 75 | +To add an instance, use the `compute.instances().insert()` method and specify the properties of the new |
| 76 | +instance. These properties are specified in the request body; for details about each property see |
| 77 | +the [API reference for `instances.insert`](https://cloud.google.com/compute/docs/reference/latest/instances/insert). |
| 78 | + |
| 79 | +At a minimum, your request must provide values for the following properties when you create a new |
| 80 | +instance: |
| 81 | + |
| 82 | +* Instance name |
| 83 | +* Root persistent disk |
| 84 | +* Machine type |
| 85 | +* Zone |
| 86 | +* Network Interfaces |
| 87 | + |
| 88 | +This 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 | + |
| 97 | +You 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 | + |
| 101 | +All instances must boot from a [root persistent disk](https://cloud.google.com/compute/docs/disks/create-root-persistent-disks). |
| 102 | +The root persistent disk contains all of the necessary files required for starting an instance. |
| 103 | +When you create a root persistent disk you must select a public image or a custom image to apply to |
| 104 | +the disk. In the example above, a new root persistent disk is created based on Debian 8 at the same |
| 105 | +time as the instance. However, it is also possible to create a disk beforehand and attach it to the |
| 106 | +instance. |
| 107 | + |
| 108 | +To create an instance using your own custom OS image, you need to provide a different URL than |
| 109 | +the one included in the example. For more information about starting an instance with your own |
| 110 | +images, 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 | + |
| 116 | +When you create your instance, you might want to include instance metadata such as a [startup script](https://cloud.google.com/compute/docs/startupscript), |
| 117 | +configuration variables, and SSH keys. In the example above, you used the `metadata` field in your |
| 118 | +request body to specify a startup script for the instance and some configuration variables as |
| 119 | +key/values pairs. The [startup-script.sh](startup-script.sh) shows how to read these variables and use them |
| 120 | +to apply text to an image and upload it to [Cloud Storage](https://cloud.google.com/storage). |
| 121 | + |
| 122 | +## Deleting an Instance |
| 123 | + |
| 124 | +To delete an instance, you need to call the `compute.instances().delete()` method and provide the name, |
| 125 | +zone, and project ID of the instance to delete. When the `autoDelete` parameter is set to `true` for the |
| 126 | +boot disk it is also deleted with the instance. This setting is off by default but is |
| 127 | +useful when your use case calls for disks and instances to be deleted together. |
| 128 | + |
| 129 | +```python |
| 130 | +def 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 | + |
| 139 | +You can run the full sample by downloading the code and running it on the command line. Make sure |
| 140 | +to download the `create_instance.py` file and the `startup-script.sh` file. To run the sample: |
| 141 | + |
| 142 | +```bash |
| 143 | +python create_instance.py --name [INSTANCE_NAME] --zone [ZONE] [PROJECT_ID] [CLOUD_STORAGE_BUCKET] |
| 144 | +``` |
| 145 | + |
| 146 | +where: |
| 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 | + |
| 153 | +For example: |
| 154 | + |
| 155 | +```bash |
| 156 | +python python-example.py --name example-instance --zone us-central1-a example-project my-gcs-bucket |
| 157 | +``` |
| 158 | + |
| 159 | +## Waiting for operations to complete |
| 160 | + |
| 161 | +Requests to the Compute Engine API that modify resources such as instances immediately return a |
| 162 | +response acknowledging your request. The acknowledgement lets you check the status of the requested |
| 163 | +operation. Operations can take a few minutes to complete, so it's often easier to wait for the |
| 164 | +operation to complete before continuing. This helper method waits until the operation completes |
| 165 | +before returning: |
| 166 | + |
| 167 | +```python |
| 168 | +def 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 | + |
| 185 | +When you query per-zone operations, use the `compute.zoneOperations.get()` method. When you query global |
| 186 | +operations, use the `compute.globalOperations.get()` method. For more information, see zone resources. |
| 187 | + |
| 188 | +## Cleaning up |
| 189 | + |
| 190 | +To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, |
| 191 | +either delete the project that contains the resources, or keep the project and delete the |
| 192 | +individual resources. |
| 193 | + |
| 194 | +### Delete your Cloud Storage bucket |
| 195 | + |
| 196 | +To delete a Cloud Storage bucket: |
| 197 | +1. In the Cloud Console, go to the Cloud Storage [Browser page](https://console.cloud.google.com/storage/browser). |
| 198 | +1. Click the checkbox for the bucket that you want to delete. |
| 199 | +1. To delete the bucket, click `Delete`, and then follow the instructions. |
0 commit comments