Hey Pythonistas, we can deploy Python functions!
Wikipedia is my source of truth to list an author’s bibliography, filmography…Unfortunately, not everything is available in digital form. For instance, I’d like to list books actually available as ebooks. This is a very simple task, a microservice in fact: GCP’s Cloud Functions looks perfect for this. Let’s check it out starting from scratch, in a couple of minutes.
A few questions
What is Cloud Functions?
Cloud Functions is a managed service for serverless functions. The acronym describing such a service is FaaS (Function as a Service).
What’s a managed service?
It’s a service I don’t have to manage. I just use it.
What’s a serverless function?
Like a function in a program, a serverless (or cloud) function is an independent unit that can be naturally isolated in an app architecture.
How does it work?
The function is event driven: code will be called upon triggers such as an HTTP request, a file uploaded to a cloud storage, a message published…
What are the benefits of a serverless function?
- The code itself can be directly deployed in an isolated cloud function.
- The function resources scale automatically when the traffic evolves (the infra handles this for me).
- The function is highly available (a benefit of using a managed service).
- I only pay for what I use: if the function is not used, the cost is zero.
Why do I love serverless as a developer?
- I can focus on code.
- I have a clearer, yet robust and performant, architecture.
- I can sleep on both ears. If there’s a service outage at 2am, reliability engineers will handle the issue.
How do I get started?
I just need a GCP account. Also, GCP offers a generous free tier:
- First-time users get a $300 free credit to use over 12 months.
- Additionally, on a monthly basis, Cloud Functions is free for the first 2 million invocations (and below other high volume thresholds).
So, unless I deploy a successful function invoked millions of times every month, this won’t cost anything. Did I say I love serverless?
What is my toolbox?
There are 3 ways I can work with Cloud Functions (or GCP in general):
- From the graphical user interface (GUI): I can deploy cloud functions straight from the browser, without installing any tool. This is perfect to monitor or just discover the service, but also for a quick prototyping or debugging.
- From the command line interface (CLI): in a proper development workflow, I will typically script everything and use
gcloud(GCP’s main command line utility).
- From the application programming interface (API): all GCP services are API based, allowing for fully industrialized developments. When I use the GUI or the CLI, I actually initiate web requests to the REST API undercover.
What’s my battle plan?
I’ll deploy a simple HTTP-triggered cloud function, first from the GUI, then from the CLI. But let’s prepare the code first.
Show me the code!
Flask is the underlying framework used to handle incoming HTTP requests. A typical “hello world” cloud function is as simple as this:
This gives, without parameters:
or, with a parameter:
Defining the HTTP entry point
I want to print out the list of available ebooks by a given author, in a given language. Based on the hello world sample above, I can define this simple Python function:
Getting the data from Google Books API
Requests is “an elegant and simple HTTP library for Python, built for human beings” (docs.python-requests.org) and indeed it is. This allows querying an API (such as the Google Books API) very easily:
Printing the result in plain text
Flask naturally handles HTML templates but, for the sake of simplicity, let’s define this basic function to return a plain text result:
Deploying a cloud function from the GUI
GCP offers a web console, a GUI that works from any browser, without any prior installation. The web console is perfect for testing a feature (which is my case right now), quickly building a proof of concept, and of course monitoring my services.
Opening the web console
Creating a new project
Monitoring my project from the dashboard
Using the “getting started” shortcut
Creating my cloud function
Checking the function
Deleting the project
Deploying a cloud function from the CLI
GCP offers Cloud Shell, a command line interface. This also works from any browser, without any prior installation. The magic behind it is that it automatically handles an SSH connection to a small VM where everything I need is pre-installed. The command line utility is
gcloud. Let’s get a chrono (⌛) of each step…
Opening Cloud Shell (⌛15”)
Creating a new project (+11” → ⌛26”)
PROJECT_NAME="Get Ebooks PyGCF"gcloud projects create $PROJECT_ID \
--set-as-defaultCreate in progress for [https://cloudresourcemanager.googleapis.com/v1/projects/...].
Waiting for [operations/cp...] to finish...done.
Updated property [core/project] to [PROJECT_ID].
Note: Project IDs are unique across GCP. I used “get-ebooks-pygcf” but you should define your own.
Linking the project to my billing account (+5” → ⌛31”)
BILLING_ACCOUNT=$(gcloud beta billing accounts list \
--format 'value(name)')gcloud beta billing projects link $PROJECT_ID \
--billing-account $BILLING_ACCOUNTbillingAccountName: billingAccounts/XXXXXX-YYYYYY-ZZZZZZ
Enabling the Cloud Functions API (+11” → ⌛42”)
gcloud services enable cloudfunctions.googleapis.comOperation "operations/acf..." finished successfully.
Getting the code (+3” → ⌛45”)
git clone https://github.com/PicardParis/cloud-snippets.gitCloning into 'cloud-snippets'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 0), reused 8 (delta 0), pack-reused 0
Unpacking objects: 100% (8/8), done.cd cloud-snippets/python/gcf-get-ebooks/
Deploying the function (+1’42” → ⌛2’27”)
GCF_REGION="europe-west1"gcloud functions deploy $GCF_NAME \
--entry-point $GCF_ENTRY \
--region $GCF_REGION \
--runtime python37 \
--trigger-httpDeploying function (may take a while - up to 2 minutes)...done.
Note: The first deployment is longer (sets up the environment). If I update main.py and redeploy, the update takes ~25 seconds.
Calling the function (+1” → ⌛2’28”)
"saint exupery" ebooks (lang=fr)
# | Pages | Title
1 | 528 | Écrits de guerre (1939-1944)
2 | 384 | Carnets
3 | 240 | Lettres à sa mère
5 | 180 | Les plus belles pensées d'Antoine de Saint-Exupéry
6 | 48 | Saint-Exupéry - / Le Royaume des étoiles
7 | 36 | Le Petit Prince raconté aux enfants
"jrr tolkien" ebooks (lang=de)
# | Pages | Title
1 | 1,568 | Der Herr der Ringe / Sonderausgabe
2 | 964 | Das Buch der verschollenen Geschichten / 1. & 2. Teil
3 | 720 | Nachrichten aus Mittelerde
4 | 608 | Der Herr der Ringe - Die Gefährten / Neuüberarbeitung
5 | 560 | Die Legende von Sigurd und Gudrún
6 | 558 | Das Silmarillion
7 | 444 | Der Herr der Ringe - Die Rückkehr des Königs /
Deleting the project (+5” → ⌛2’33”)
gcloud projects delete $PROJECT_ID
- f( ☁️, 🐍 ) = 🌈🌤️🐍🐍🐍…
- The function can be called from:
- The code snippet is available from this repo:
- Deploying a simple cloud function from scratch takes less than 3 minutes.
- Updating an existing cloud function takes less than 30 seconds.
Deploying a Python serverless app in minutes (stay tuned)…