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 |
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 or leave as-is; only for Python 2 App Engine) |
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 or leave as-is; only for Python 2 App Engine) |
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
)
TL;DR: app files plus app.yaml
, appengine_config.py
, and lib
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
use as-is from repo (ensure #runtime:python310 commented out) |
appengine_config.py |
use as-is from repo |
requirements.txt |
use as-is to install packages locally (see below) but unused thereafter |
lib |
create folder per instructions below |
Dockerfile |
unused (delete or leave as-is) |
Procfile |
unused (delete or leave as-is) |
Instructions:
- Run
pip install -t lib -r requirements.txt
to populatelib
folder (orpip2
) - Run
gcloud app deploy
to deploy to Python 2 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 plus app.yaml
File | Description |
---|---|
main.py |
use as-is from repo |
app.yaml |
uncomment runtime:python310 (or Python 3.7-3.9); delete all other lines |
appengine_config.py |
unused (delete or leave as-is; only for Python 2 App Engine) |
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 or leave as-is; only for Python 2 App Engine) |
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 python310 --trigger-http --allow-unauthenticated
to deploy to Cloud Functions (or Python 3.7-3.9)- 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 or leave as-is; only for Python 2 App Engine) |
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 or leave as-is; only for Python 2 App Engine) |
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 or leave as-is; only for Python 2 App Engine) |
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