💥 Jan 2024 update |
---|
Python 2.7 apps can no longer be deployed on App Engine. Either upgrade to 3.8+ or migrate your app to Cloud Run or other platform that still supports Python 2. More information is available in the "What you need to know" deprecation post. |
While the majority of this app's deployments are in Python 3, there are still users upgrading from Python 2, so our Python 2 code is meant to help with migration & planning. Admittedly, there may seem to be a bit of "cheating" due to the duplicity of Python 2 and 3, especially since the application is compatible across both language versions without modification or use of compatibility libraries. However there are significant differences between Python 2 and 3 deployment requirements irregardless of language differences. Additional 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.
- There is also an equivalent Node.js version of this app.
Deployment | Python 2 | Python 3 |
---|---|---|
Local/hosted Flask | codelab | same as Python 2 |
App Engine | codelab | codelab |
Cloud Functions | N/A | codelab |
Cloud Run (Docker) | codelab | codelab |
Cloud Run (Buildpacks) | N/A | codelab |
^ — not recommended as of Jan 2024 as developers can no longer deploy Python 2 apps to App Engine (see sidebar above)
These are the files provided in this repo and the deployments they're applicable to:
NOTES:
- —
requirements.txt
is used for local and App Engine (2.x) package installations and not required in deployments themselves unlike all othersmain.py
andtemplates/index.html
comprise the entire application and are always requirednoxfile.py
andtest_translate.py
are for testing only; see Testing section below- All
.*ignore
and.git*
files/folders are administrative and not listed in table above or deployments below- Files applicable only to a specific language version are annotated above
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.
NOTE: Serverless deployments (as configured here) use default service accounts which provide a broad set of permissions to assist you in getting a working prototype. When preparing to launch to production, the Google Cloud team recommends the best practice of "least privileges," and instead use user-managed service accounts with the minimal set of permissions allowing your app to function properly.
TL;DR: application files (main.py
& requirements.txt
)
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
unused (delete or leave as-is) |
appengine_config.py |
unused (delete) |
requirements.txt |
use as-is to install packages locally (see below) but unused thereafter |
lib |
unused (delete or leave as-is if it exists) |
Dockerfile |
unused (delete or leave as-is) |
Procfile |
unused (delete or leave as-is) |
Instructions:
- Run
pip install -U pip -r requirements.txt
to install/update packages locally (orpip2
) - Run
gcloud auth application-default login
to set your credentials - Run
python main.py
to run on local Flask server (orpython2
)
TL;DR: app files (identical to Python 2 deployment)
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
unused (delete or leave as-is) |
appengine_config.py |
unused (delete) |
requirements.txt |
use as-is to install packages locally (see below) but unused thereafter |
lib |
unused (delete or leave as-is if it exists) |
Dockerfile |
unused (delete or leave as-is) |
Procfile |
unused (delete or leave as-is) |
Instructions:
- Run
pip install -U pip -r requirements.txt
to install/update packages locally (orpip3
) - Run
gcloud auth application-default login
to set your credentials - Run
python main.py
to run on local Flask server (orpython3
)
NOTE: apps can no longer be deployed to Python 2 GAE; this section is left for historical purposes.
TL;DR: app files plus app.yaml
, appengine_config.py
, and lib
File | Description |
---|---|
main.py |
|
app.yaml |
#runtime:python312 commented out) |
appengine_config.py |
|
requirements.txt |
|
lib |
|
Dockerfile |
|
Procfile |
Instructions:
Runpip install -t lib -r requirements.txt
to populatelib
folder (orpip2
)Rungcloud app deploy
to deploy to Python 2 App EngineYou'll be prompted for the REGION if deploying to App Engine the first time.App Engine apps are tied to one region, so it can't be changed once it's set, meaning you won't be prompted thereafter.
TL;DR: app files plus app.yaml
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
uncomment runtime:python312 (or Python 3.8-3.12); delete all other lines |
appengine_config.py |
unused (delete) |
requirements.txt |
use as-is from repo |
lib |
delete (or rename) this folder if it exists (not used with Python 3 App Engine) |
Dockerfile |
unused (delete or leave as-is) |
Procfile |
unused (delete or leave as-is) |
Instructions:
- Edit
app.yaml
(see above) - (optional) Delete
app.yaml
,lib
andappengine_config.py
(unused) - Run
gcloud app deploy
to deploy to Python 3 App Engine- You'll be prompted for the REGION if deploying to App Engine the first time.
- App Engine apps are tied to one region, so it can't be changed once it's set, meaning you won't be prompted thereafter.
TL;DR: app files
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
unused (delete or leave as-is; only for App Engine) |
appengine_config.py |
unused (delete) |
requirements.txt |
use as-is from repo |
lib |
delete (or rename) this folder if it exists (not used with Cloud Functions) |
Dockerfile |
unused (delete or leave as-is) |
Procfile |
unused (delete or leave as-is) |
Instructions:
- (optional) Delete
app.yaml
,lib
andappengine_config.py
(unused) - Run
gcloud functions deploy translate --runtime python312 --trigger-http --allow-unauthenticated
to deploy to Cloud Functions (or Python 3.8-3.12)- That command creates & deploys a new HTTP-triggered Cloud Function (name must match what's in
main.py
) - You'll be prompted for the REGION if deploying a Cloud Function the first time.
- Cloud Functions can be deployed to different regions within a project, but once the region has been set for a function, it cannot be changed.
- That command creates & deploys a new HTTP-triggered Cloud Function (name must match what's in
- There is no support for Python 2 with Cloud Functions
TL;DR: app files plus Dockerfile
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
unused (delete or leave as-is; only for App Engine) |
appengine_config.py |
unused (delete) |
requirements.txt |
grpcio<1.40.0 applies to this deployment |
lib |
delete (or rename) this folder if it exists (not used with Cloud Run) |
Dockerfile |
use as-is from repo (ensure #FROM python:3-slim commented out) |
Procfile |
unused (delete or leave as-is) |
Instructions:
- (optional) Delete
app.yaml
,lib
andappengine_config.py
(unused) - Run
gcloud run deploy translate --allow-unauthenticated --platform managed
to deploy to Cloud Run- The above command wraps
docker build
anddocker push
, deploying the image to Cloud Artifact Registry (must be enabled), and finallydocker run
to deploy the service, all in one convenient command. - You'll be prompted to provide a REGION unless you also add
--region REGION
on the cmd-line - You'll be prompted to provide a SOURCE folder unless you also add
--source FOLDER
, e.g.,--source .
on the cmd-line - Supplying both
--region
and--source
options provide a fully non-interactive deploy (unless you don't have a repository, in which case you'll be prompted to create one)
- The above command wraps
- You can also use this shortcut to deploy to Cloud Run:
- By default, App Engine & Cloud Functions launch production servers; with Cloud Run, the Flask development server is used for prototyping. For production, bundle and deploy a production server like
gunicorn
:- Uncomment
gunicorn
fromrequirements.txt
(commented out for App Engine & Cloud Functions) - Uncomment the
ENTRYPOINT
entry forgunicorn
replacing the default entry inDockerfile
- Re-use the same deploy command
- Uncomment
TL;DR: app files plus Dockerfile
(nearly identical to Python 2 deployment)
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
unused (delete or leave as-is; only for App Engine) |
appengine_config.py |
unused (delete) |
requirements.txt |
use as-is from repo |
lib |
delete (or rename) this folder if it exists (not used with Cloud Run) |
Dockerfile |
replace FROM python:2-slim with FROM python:3-slim (commented out) but keep all other lines |
Procfile |
unused (delete or leave as-is) |
Instructions:
- (optional) Delete
app.yaml
,lib
andappengine_config.py
(unused) - Edit
Dockerfile
(see above) - Run
gcloud run deploy translate --allow-unauthenticated --platform managed
to deploy to Cloud Run- The above command wraps
docker build
anddocker push
, deploying the image to Cloud Artifact Registry (must be enabled), and finallydocker run
to deploy the service, all in one convenient command. - You'll be prompted to provide a REGION unless you also add
--region REGION
on the cmd-line - You'll be prompted to provide a SOURCE folder unless you also add
--source FOLDER
, e.g.,--source .
on the cmd-line - Supplying both
--region
and--source
options provide a fully non-interactive deploy (unless you don't have a repository, in which case you'll be prompted to create one)
- The above command wraps
- The shortcut "button" above can be customized for Python 3 if you make the
Dockerfile
update above and commit it to your fork/clone. - By default, App Engine & Cloud Functions launch production servers; with Cloud Run, the Flask development server is used for prototyping. For production, bundle and deploy a production server like
gunicorn
:- Uncomment
gunicorn
fromrequirements.txt
(commented out for App Engine & Cloud Functions) - Uncomment the
ENTRYPOINT
entry forgunicorn
replacing the default entry inDockerfile
- Re-use the same deploy command
- Uncomment
TL;DR: app files plus Procfile
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
unused (delete or leave as-is; only for App Engine) |
appengine_config.py |
unused (delete) |
requirements.txt |
use as-is from repo |
lib |
delete (or rename) this folder if it exists (not used with Cloud Run) |
Dockerfile |
delete (or rename) this file (required) |
Procfile |
use as-is from repo |
Instructions:
- (optional) Delete
app.yaml
,lib
andappengine_config.py
(unused) - Delete
Dockerfile
(or rename it)- There is no support for Python 2 with Cloud Buildpacks (2.x developers must use Docker)
- Run
gcloud run deploy translate --allow-unauthenticated --platform managed
to deploy to Cloud Run- The above command wraps
docker build
anddocker push
, deploying the image to Cloud Artifact Registry (must be enabled), and finallydocker run
to deploy the service, all in one convenient command. - You'll be prompted to provide a REGION unless you also add
--region REGION
on the cmd-line - You'll be prompted to provide a SOURCE folder unless you also add
--source FOLDER
, e.g.,--source .
on the cmd-line - Supplying both
--region
and--source
options provide a fully non-interactive deploy (unless you don't have a repository, in which case you'll be prompted to create one)
- The above command wraps
- By default, App Engine & Cloud Functions launch production servers; with Cloud Run, the Flask development server is used for prototyping. For production, bundle and deploy a production server like
gunicorn
:- Uncomment
gunicorn
fromrequirements.txt
(commented out for App Engine & Cloud Functions) - Uncomment the
web:
entry forgunicorn
replacing the default entry inProcfile
- Re-use the same deploy command
- Uncomment
These are relevant links only to the app in this folder (for all others, see the README one level up:
- 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)
- Flask
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 google-cloud-translate
, 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 google-cloud-translate
nox > pytest
============================================ test session starts =============================================
platform darwin -- Python 2.7.16, pytest-4.6.11, py-1.10.0, pluggy-0.13.1
rootdir: /private/tmp/cloud-nebulous-serverless-python
collected 2 items
test_translate.py .. [100%]
============================================== warnings summary ==============================================
.nox/tests-2-7/lib/python2.7/site-packages/google/cloud/translate_v3/__init__.py:32
/private/tmp/cloud-nebulous-serverless-python/.nox/tests-2-7/lib/python2.7/site-packages/google/cloud/translate_v3/__init__.py:32: DeprecationWarning: A future version of this library will drop support for Python 2.7. More details about Python 2 support for Google Cloud Client Libraries can be found at https://cloud.google.com/python/docs/python2-sunset/
warnings.warn(message, DeprecationWarning)
-- Docs: https://docs.pytest.org/en/latest/warnings.html
==================================== 2 passed, 1 warnings in 1.02 seconds ====================================
nox > Session tests-2.7 was successful.
nox > Running session tests-3.6
nox > Creating virtual environment (virtualenv) using python3.6 in .nox/tests-3-6
nox > python -m pip install pytest blinker flask google-cloud-translate
nox > pytest
============================================ test session starts =============================================
platform darwin -- Python 3.6.8, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /private/tmp/cloud-nebulous-serverless-python
collected 2 items
test_translate.py .. [100%]
============================================= 2 passed in 1.22s ==============================================
nox > Session tests-3.6 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 google-cloud-translate
nox > pytest
============================================ test session starts =============================================
platform darwin -- Python 3.9.1, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /private/tmp/cloud-nebulous-serverless-python
collected 2 items
test_translate.py .. [100%]
============================================= 2 passed in 1.04s ==============================================
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.6
nox > Creating virtual environment (virtualenv) using python3.6 in .nox/lint-3-6
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.6 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.6: success
nox > * tests-3.9: success
nox > * lint-2.7: success
nox > * lint-3.6: success
nox > * lint-3.9: success