Serverless API around Google Cloud Vision with the Serverless Framework05 Sep 2016
The Serverless Framework hit v1.0 (beta) recently after about a year of development. The framework has matured quickly to help devs build scalable applications without having to maintain servers. It aims to ease deployment via:
- Easy-to-use CLI tool
- Customizable deployment via config files
- Simplifies/automates the annoying parts
- Extensible via plugins
Although the Serverless Framework does not yet support Google Cloud Functions, it is designed to support a variety of event-driven compute services, including AWS Lambda and (eventually) Google Cloud Functions. If you’re not familiar with serverless computing, I recommend you start with Martin Fowler’s overview.
So why would I use a framework rather than glue a bunch of bash scripts together? Simple. Serverless Framework takes care of AWS IAM Roles, making deployment much less annoying. Also, as we’ll see below, Serverless makes it easy to include Python dependencies along with your Lambda function.
I’ve been eager to build a serverless app. Combining that goal with wanting to make Google Cloud Vision a bit more convenient to work with, I built a serverless API wrapper around Google Cloud Vision using AWS API Gateway and AWS Lambda. I expected there to be some craziness when combining services from both Amazon and Google, but the Serverless Framework ensured there was none. I focused on AWS Lambda in this project but may play with Google’s offering after it matures a bit.
What Does the App Do?
For the impatient, check out the GitHub repository.
Briefly, I created a microservice via API Gateway that accepts an image URL and triggers a Lambda function, which ingests the image from a URL and sends the image to Google Cloud Vision for standard image recognition tasks (e.g., facial detection, OCR, etc.). A JSON response is returned, from which I was able to produce a new image with bounding boxes around the faces detected (my son and me).
Beyond facial detection, Google Cloud Vision supports the following image recognition tasks:
How to Get Started?
Above, we described what the project does. Now, let’s go through how to set up the project and deploy it in your own cloud environment.
Google Cloud Vision API
First, let’s go through a few details to set up the Google Cloud Vision API. In order to access the Cloud Vision API, you will need a Google Cloud Platform account. Fortunately, Google provides a free 60-day trial with $300 credit.
Next, you will need to create Google Application Credentials. You will need to
create a Service Account Key by following the instructions given
After creating a Service Account Key, I downloaded a JSON file with my
application credentials into
my app and renamed the
As I said above, we are mixing cloud providers, which might be weaksauce to some of you. Regardless, AWS doesn’t have a spiffy API for image recognition, but their cloud offerings are mature.
Next, you need to create a default AWS profile on your local box. To do this,
and then run the following at the command line:
Serverless Framework to Deploy the App on AWS
The above command makes the
serverless command available at the CLI along with
slss. If you simply type
serverless, the Serverless
Framework provides some intuitive docs.
If you haven’t already done so,
git clone the app with:
Here’s one of the best parts about Serverless Framework. We can install any
Python dependencies we need in our app to a local folder, and those dependencies
will be deployed along with our app. To see this, install the Python
dependencies in our
requirements.txt to the
NOTE: Homebrew + Mac OS users who encounter the
should see this SO post for a fix.
After installing the Python requirements to the
vendored folder, we are ready
to deploy our app to AWS. Type the following at the commandline to deploy the
This command does the following:
- Create IAM roles on AWS for Lambda and API Gateway (only done once)
- Zips Python code and uploads to S3
- Creates AWS Lambda function
- Creates API Gateway endpoint that triggers AWS Lambda function
Serverless takes a bit longer to run this command the first time because it has to create IAM roles. However, after you have deployed your app once and then made a change to the code, this command executes much quicker.
After the Serverless command returns successfully, it’ll provide a few useful pieces of information, including the API endpoint you’ll need to use your microservice:
provided by API Gateway is automatically generated by AWS and will differ in
Now we have a simple API to apply basic image recognition tasks. For instance,
curl command sends an image URL of my son and me to the API.
The response JSON includes a variety of metadata to describe the image and the faces detected:
This JSON response was used to draw the bounding boxes in the image above. For
implementation details, see the
examples folder within my repo.
By default, facial recognition is performed as we can see from the
lambda_handler function in
The API calls the
detect_image function with the image URL and
two optional arguments:
argument specifies how many entities (e.g., faces) we wish to find, whereas the
detect_type argument indicates the image recognition task we wish to
perform. As mentioned above, Google Cloud Vision supports multipe image
beyond facial detection. For instance, let’s apply OCR to my employer,
To do this, let’s run the following
The response JSON has a similar form as our facial detection example, but this
time a bounding box around the logo is given with a
Nice! OCR made simple.
The Serverless Framework simplified our microservice deployment via API Gateway and Lambda. There are some gotchas though that you should be aware of.
First, neither AWS nor Serverless Framework are fully aware of your folder
structure, so you’ll need to ensure Python is aware of where your dependencies
are located, as in this snippet from
Second, YAML indentation. Grrrrr. My API Gateway endpoints were not working for some time (no errors!) because I was missing two spaces in my YAML file. Two spaces!!! It was only after someone else encountered the same issue did I see what to do:
That’s it! Besides the couple of gotchas, the Serverless Framework makes it easy to deploy simple microservices.