Docker Image

If you are just getting started with code generation for protobuf-based APIs, or if you do not have a robust Python environment already available, we recommend using our Docker image to build client libraries.

However, this tool offers first-class support for local execution using protoc: Local Installation. It is still reasonably easy, but initial setup will take a bit longer.

Note

If you are interested in contributing, using a local installation is recommended.

Installing

Docker

In order to use a Docker image, you must have Docker installed. Docker is a container management service, and is available on Linux, Mac, and Windows (although most of these instructions will be biased toward Linux and Mac).

Install Docker according to their installation instructions.

Note

This image requires Docker 17.05 or later.

Pull the Docker Image

Once Docker is installed, simply pull the Docker image for this tool:

$ docker pull gcr.io/gapic-images/gapic-generator-python:latest

Usage

To use this plugin, you will need an API which is specified using protocol buffers. Additionally, this plugin makes some assumptions at the margins according to Google API design conventions as described in AIPs, so following those conventions is recommended.

Example

If you want to experiment with an already-existing API, one example is available. (Reminder that this is still considered experimental, so apologies for this part being a bit strange.)

You need to clone the googleapis repository from GitHub:

$ git clone https://github.com/googleapis/googleapis.git

It is possible to generate libraries for most (possibly all) APIs described here. The API we use as an example is the Google Cloud Vision API, available in the google/cloud/vision/v1/ subdirectory. This will be used for the remainder of the examples on this page.

Compiling an API

Note

If you are running code generation repeatedly, executing the long docker run command may be cumbersome. While you should ensure you understand this section, a shortcut script is available to make iterative work easier.

Compile the API into a client library by invoking the Docker image.

It is worth noting that the image must interact with the host machine (your local machine) for two things: reading in the protos you wish to compile, and writing the output. This means that when you run the image, two mount points are required in order for anything useful to happen.

In particular, the input protos are expected to be mounted into /in/, and the desired output location is expected to be mounted into /out/. The output directory must also be writable.

Note

The /in/ and /out/ directories inside the image are hard-coded; they can not be altered where they appear in the command below.

Docker requires the output directory to pre-exist; create a directory where you want the generated code to go:

$ mkdir dest/

Perform the actual code generation step with docker run:

# This is assumed to be run from the `googleapis` project root.
$ docker run \
  --mount type=bind,source=$(pwd)/google/cloud/vision/v1/,destination=/in/google/cloud/vision/v1/,readonly \
  --mount type=bind,source=$(pwd)/dest/,destination=/out/ \
  --rm \
  --user $UID \
  gcr.io/gapic-images/gapic-generator-python

Warning

protoc is very picky about paths, and the exact construction here matters a lot. The source is google/cloud/vision/v1/, and then the destination is that full directory path after the /in/ root; therefore: /in/google/cloud/vision/v1/.

This matters because of how proto imports are resolved. The import statement imports a file, relative to a base directory or set of base directories, called the proto_path. This is assumed (and hard-coded) to /in/ in the Docker image, and so any directory structure present in the imports of the proto files must be preserved beneath this for compilation to succeed.

Generating Samples

In addition to generating client libraries, the generator can also create standalone executable code samples.

The user can specify individual sample config files or can pass paths to directories that contain sample configs. Directories are searched recursively, and any file that is not a sample config is ignored.

A full description of the sample config, generated manifest, and generated samples is outside the scope of this documentation. We will provide links to such documentation when it is ready.

Samples and manifests are always generated in a ‘samples’ subdir of the destination directory.

# Multiple sample paths or directories can be passed simultaneously by duplicating
# the 'samples' option.
# If no 'samples' option is passed, the generator does not generate a manifest.
$ docker run \
  --mount type=bind,source=$(pwd)/path/to/proto/dir,destination=/in/path/to/proto,readonly \
  --mount type=bind,source=$(pwd)/dest/,destination=/out/ \
  --rm \
  --user $UID \
  gcr.io/gapic-images/gapic-generator-python \
  --samples path/to/sample/config.yaml \
  --samples path/to/sample/dir/

Verifying the Library

Once you have compiled a client library, whether using a Docker image, local installation or bazel, it is time for the fun part: actually running it!

Create a virtual environment for the library:

$ virtualenv ~/.local/client-lib --python=`which python3.7`
$ source ~/.local/client-lib/bin/activate

Next, install the library:

$ cd dest/
$ pip install --editable .

Now it is time to play with it! Here is a test script:

# This is the client library generated by this plugin.
from google.cloud import vision

# Instantiate the client.
#
# If you need to manually specify credentials, do so here.
# More info: https://cloud.google.com/docs/authentication/getting-started
#
# If you wish, you can send `transport='grpc'` or `transport='http'`
# to change which underlying transport layer is being used.
ia = vision.ImageAnnotatorClient()

# Send the request to the server and get the response.
response = ia.batch_annotate_images({
    'requests': [{
        'features': [{
            'type': vision.Feature.Type.LABEL_DETECTION,
        }],
        'image': {'source': {
            'image_uri': 'https://images.pexels.com/photos/67636'
                         '/rose-blue-flower-rose-blooms-67636.jpeg',
        }},
    }],
})
print(response)