This sample is offered in Python 3, but the code itself is Python 2-compatible. Instructions on running it under 2.x will leverage the resources of the Cloud API Python sample which provides a more complete experiencce as it has all configuration available to support 2.x deployments. The app is tested against Python 2.7, 3.8, and 3.9; see Testing below for more information.
NOTES:
- For local or Cloud Run deployments, there are little/no updates to go from Python 2 to 3.
- Neither Cloud Functions nor Cloud Run with Cloud Buildpacks support Python 2.
| File | Description |
|---|---|
main.py |
main application file |
settings.py |
settings file with API key (copy & modify settings-tmpl.py template) |
templates/index.html |
application HTML template |
requirements.txt |
3rd-party package requirements file |
app.yaml |
App Engine configuration file (only for App Engine deployments) |
.gcloudignore |
files to exclude deploying to the cloud (administrative) |
noxfile.py |
unit tests nox tool setup file |
test_mapsgeo.py |
unit tests (pytest) |
Procfile |
"Entrypoint" directive Procfile to start app (only for Cloud Run deployments using Cloud Buildpacks) |
README.md |
this file (administrative) |
Below are the required settings and instructions for all documented deployments. The "TL:DR;" section at the top of each configuration summarizes the key files (see above) while the table beneath spells out the details. No administrative files are listed. Create your own settings.py file with the API your created in the Cloud console and take precautions to protect it, as outlined in the Google Maps API key documentation.
Local Flask server (Python 2 or 3)
TL;DR: application files (main.py, templates/, requirements.txt)
- Run
pip install -U pip -r requirements.txtto install/update packages locally (orpip2for Python 2 orpip3for Python 3 explicitly) - Run
python main.pyto run on local Flask server (python2orpython3to be explicit)
TL;DR: app files plus app.yaml
- Run
gcloud app deploy
TL;DR: app2.yaml (instead of app.yaml), app files plus appengine_config.py, and lib, and other modifications
- Copy the Cloud API Python 2
appengine_config.pyfile - Uncomment/enable
requests-toolbeltinrequirements.txt - Run
pip install -t lib -r requirements.txtto populatelibfolder (orpip2) - Edit
lib/googlemaps/client.pyby addingimport requests_toolbelt.adapters.appengine; requests_toolbelt.adapters.appengine.monkeypatch()belowimport requests(as documented here) - Run
gcloud app deploy app2.yaml
TL;DR: app files
- Run
gcloud functions deploy mapsgeo --runtime python39 --trigger-http --allow-unauthenticatedto deploy to Cloud Functions (or Python 3.7 or 3.8)
- Cloud Functions does not support Python 2.
- The Cloud Function name (here
mapsgeo) must match the function's name inmain.pyelse you need to use--entry-point.
TL;DR: app files plus Procfile
- Run
gcloud run deploy mapsgeo --allow-unauthenticated --platform managedto deploy to Cloud Run; optionally add--source . --region REGIONfor non-interactive deploy
- There is no support for Python 2 with Cloud Buildpacks (2.x developers must use Docker [see below])
NOTE: This sample uses the Flask development server by default for prototyping; for production, bundle and deploy a production server like
gunicorn:
- Uncomment
gunicornfromrequirements.txt(commented out for App Engine & Cloud Functions)- Uncomment
ENTRYPOINTentry forgunicorninDockerfilereplacing default entry- Re-use the same deploy command above
TL;DR: app files plus Dockerfile (nearly identical to Python 2 deployment)
- Copy the Cloud API Python
Dockerfilefile - Edit
Dockerfileand switch theFROMentry to thepython:3-slimbase image - Run
gcloud run deploy mapsgeo --allow-unauthenticated --platform managedto deploy to Cloud Run; optionally add--source . --region REGIONfor non-interactive deploy
- The
gunicornsidebar above also applies here.
TL;DR: app files plus Dockerfile
- Copy the Cloud API Python
Dockerfilefile - Run
gcloud run deploy mapsgeo --allow-unauthenticated --platform managedto deploy to Cloud Run; optionally add--source . --region REGIONfor non-interactive deploy
- The
gunicornsidebar above also applies here.
These are relevant links only to the app in this folder (for all others, see the README one level up:
- Google Maps client library for Python
- Google Maps API key documentation
- Python 3 App Engine quickstart
- Python 3 App Engine (standard environment) runtime
- Python 2 App Engine (standard environment) runtime
- Python Cloud Functions quickstart
- Python Cloud Run quickstart
- Differences between Python 2 & 3 App Engine (standard environment) runtimes
- Python 2 to 3 App Engine (standard environment) migration guide
- App Engine (standard environment) to Cloud Run codelab tutorial (Docker)
- App Engine (standard environment) to Cloud Run codelab tutorial (Cloud Buildpacks)
Testing is driven by nox which uses pytest for testing and flake8 for linting, installing both in virtual environments along with application dependencies, flask and googlemaps and finally, blinker, a signaling framework integrated into Flask. To run the lint and unit tests (testing GET and POST requests), install nox (with the expected pip install -U nox) and run it from the command line in the application folder and ensuring noxfile.py is present.
$ nox
nox > Running session tests-2.7
nox > Creating virtual environment (virtualenv) using python2.7 in .nox/tests-2-7
nox > python -m pip install pytest blinker flask googlemaps
nox > pytest
=============================================== test session starts ================================================
platform darwin -- Python 2.7.16, pytest-4.6.11, py-1.11.0, pluggy-0.13.1
rootdir: /tmp/noncloud/python/maps
collected 4 items
test_mapsgeo.py .... [100%]
============================================= 4 passed in 2.69 seconds =============================================
nox > Session tests-2.7 was successful.
nox > Running session tests-3.8
nox > Creating virtual environment (virtualenv) using python3.8 in .nox/tests-3-8
nox > python -m pip install pytest blinker flask googlemaps
nox > pytest
=============================================== test session starts ================================================
platform darwin -- Python 3.8.2, pytest-7.0.1, pluggy-1.0.0
rootdir: /tmp/noncloud/python/maps
collected 4 items
test_mapsgeo.py .... [100%]
================================================ 4 passed in 1.26s =================================================
nox > Session tests-3.8 was successful.
nox > Running session tests-3.9
nox > Creating virtual environment (virtualenv) using python3.9 in .nox/tests-3-9
nox > python -m pip install pytest blinker flask googlemaps
nox > pytest
=============================================== test session starts ================================================
platform darwin -- Python 3.9.9, pytest-7.0.1, pluggy-1.0.0
rootdir: /tmp/noncloud/python/maps
collected 4 items
test_mapsgeo.py .... [100%]
================================================ 4 passed in 1.05s =================================================
nox > Session tests-3.9 was successful.
nox > Running session lint-2.7
nox > Creating virtual environment (virtualenv) using python2.7 in .nox/lint-2-7
nox > python -m pip install flake8
nox > flake8 --show-source --builtin=gettext --max-complexity=20 --exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py --ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202 --max-line-length=88 .
nox > Session lint-2.7 was successful.
nox > Running session lint-3.8
nox > Creating virtual environment (virtualenv) using python3.8 in .nox/lint-3-8
nox > python -m pip install flake8
nox > flake8 --show-source --builtin=gettext --max-complexity=20 --exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py --ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202 --max-line-length=88 .
nox > Session lint-3.8 was successful.
nox > Running session lint-3.9
nox > Creating virtual environment (virtualenv) using python3.9 in .nox/lint-3-9
nox > python -m pip install flake8
nox > flake8 --show-source --builtin=gettext --max-complexity=20 --exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py --ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202 --max-line-length=88 .
nox > Session lint-3.9 was successful.
nox > Ran multiple sessions:
nox > * tests-2.7: success
nox > * tests-3.8: success
nox > * tests-3.9: success
nox > * lint-2.7: success
nox > * lint-3.8: success
nox > * lint-3.9: success