Skip to content

Instantly share code, notes, and snippets.

@myselfhimself
Last active May 19, 2022 19:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save myselfhimself/51a56e273343b0b6ae17e1f696c7474f to your computer and use it in GitHub Desktop.
Save myselfhimself/51a56e273343b0b6ae17e1f696c7474f to your computer and use it in GitHub Desktop.
Emulating your Python Google Cloud function locally (Python 3)

Emulating your own Python Google Cloud Function (Python >=3.6)

Python Google Cloud Functions have been introduced publically in Q3-Q4 2018. Deploying them takes time (2-10 minutes with gcloud functions deploy. Actually, a Python cloud function equates to a Flask handler. Thus, you can test them cloud function first on your own computer. This spares you from long deployments, difficult step-by-step debugging and bad GCP weather.

Here is how:

  1. keep the traditional Python Cloud Function requirements.txt and main.py untouched.
  2. add emulator-requirements.txt (a super-set combining a flask module + the requirements.txt's contents)
  3. add emulator.py
  4. leave any Python virtual environment and make one out of emulator-requirements.txt
  • Example: mkvirtualenv my_function_emulator -p /usr/bin/python3.6; workon my_function emulator
  • then: pip install -r emulator-requirements.txt
  1. run python emulator.py within that new virtual environment
  2. keep the Flask server running, then test it by running sh local_curl_tests.sh
  3. kill your Flask server (Ctrl+C in the emulator.py window)
  4. deploy your Cloud Function using sh deploy.sh
  5. test it using sh remote_curl_tests.sh
  6. You are a super star!! Tap yourself on the shoulder : )
#!/bin/sh
gcloud beta functions deploy my_function --runtime python37 --trigger-http --region=europe-west1 --memory=128MB
#!/usr/bin/env python3
"""
Cloud function emulator for running main.py locally.
"""
# Per
# https://github.com/GoogleCloudPlatform/cloud-functions-emulator/issues/268#issuecomment-422919983
from flask import Flask, request
from main import my_function
APP = Flask(__name__)
def wrapper():
""" Runs the main app, without having it depend
on flask too much (Cloud Function)."""
return my_function(request)
wrapper.provide_automatic_options = False # type: ignore
wrapper.methods = ['GET', 'POST', 'PUT', 'DELETE'] # type: ignore
APP.add_url_rule('/', 'index', wrapper)
if __name__ == '__main__':
APP.run(debug=True, port=5000)
#!/bin/sh
echo "Testing cloud function LOCALLY EMULATED"
MY_FUNCTION_URL=http://localhost:5000
set -x
curl -s $MY_FUNCTION_URL -X POST -H "Content-Type: application/json" -d '{"breakfast_mode": "in_bed"}'
set +x
import os
from flask import Request, Response
def my_function(request: Request) -> Response:
"""Responds to any HTTP request.
Args:
request (flask.Request): HTTP request object.
Returns:
The response text or any set of values that can be turned into a
Response object using
`make_response <http://flask.pocoo.org/docs/0.12/api/#flask.Flask.make_response>`. # noqa: E501
"""
req = request.json
return Response(f"Your said that breakfast is: {req['breakfast_mode']", 200)
#!/bin/sh
echo "Testing cloud function DEPLOYED REMOTELY"
MY_FUNCTION_URL=`gcloud beta functions describe my_function --region=europe-west1 --format=config | grep url | awk '{ print $3 }'`
set -x
curl -s $MY_FUNCTION_URL -X POST -H "Content-Type: application/json" -d '{"breakfast_mode": "in_bed"}'
set +x
# Nothing
# Google cloud function provides Flask
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment