Overview
The Python runtime is the software stack responsible for installing your application code and its dependencies and running your application. The standard runtime is declared in app.yaml
as runtime: python
:
runtime: python
env: flex
Runtimes in the flexible environment are built using Docker. The Python runtime is based on Ubuntu 16.04. The source code for the Python runtime is publicly available on GitHub.
Interpreter
The default interpreter is
Python 2.7.9. You can specify
whether to use Python 2 or Python 3 in your application's
app.yaml
with the runtime_config
setting:
runtime: python
env: flex
runtime_config:
python_version: 3
The following interpreter versions are supported:
- Python 2.7.9 as specified by
2
. - Python 3.7.2 as specified by
3
.
Dependencies
The runtime looks for a requirements.txt
file in your application's source directory and uses pip
to install any dependencies before starting your application. For more information on declaring and managing packages, see Using Python Libraries
Using C libraries with Python
To enable the use of Python packages that require C extensions, the headers for the current Python version and the following Ubuntu packages are pre-installed on the system:
- build-essential
- ca-certificates
- curl
- gfortran
- git
- libatlas-dev
- libblas-dev
- libcurl4-openssl-dev
- libffi-dev
- libfreetype6-dev
- libjpeg-dev
- liblapack-dev
- libmemcached-dev
- libmysqlclient-dev
- libpng12-dev
- libpq-dev
- libquadmath0
- libsasl2-2
- libsasl2-dev
- libsasl2-modules
- libsqlite3-dev
- libssl-dev
- libxml2-dev
- libxslt1-dev
- libz-dev
- mercurial
- netbase
- pkg-config
- sasl2-bin
- swig
- wget
- zlib1g-dev
These packages allow the installation of most popular Python libraries. If your application requires additional operating-system level dependencies, you will need to use a custom runtime based on this runtime to install the appropriate packages.
Application startup
The runtime starts your application using the entrypoint
defined in app.yaml
. The entrypoint should start a process that
responds to HTTP requests on the port defined by the environment variable PORT
.
Most web applications use a WSGI server such as Gunicorn, uWSGI or Waitress.
Before you can use one of these servers, you must add them as a dependency in your application's requirements.txt
. The runtime ensures that all dependences are installed before your entrypoint is called.
Flask==0.10.1
gunicorn==19.3.0
An example entrypoint using gunicorn for a Flask application:
entrypoint: gunicorn -b :$PORT main:app
An example entrypoint using gunicorn for a Django application:
entrypoint: gunicorn -b :$PORT mydjangoapp:wsgi
Gunicorn is the recommended WSGI server, but it's completely possible to use any other WSGI server. For example, here is an entrypoint that uses uWSGI with Flask:
entrypoint: uwsgi --http :$PORT --wsgi-file main.py --callable app
For applications that can handle requests without a WSGI server, you can just execute a python script:
entrypoint: python main.py
Recommended Gunicorn configuration
The basic entrypoint examples shown above are intended to be starting points
and may work for your web applications. Most applications, however, will need to
further configure the WSGI server. Instead of specifying all of the settings on
the entrypoint, create a gunicorn.conf.py
file in your project root directory,
where your app.yaml
is located, and specify it in your entrypoint:
entrypoint: gunicorn -c gunicorn.conf.py -b :$PORT main:app
You can read about all of Gunicorn's configuration values in its documentation.
Workers
Gunicorn uses workers to handle requests. By default, Gunicorn uses sync workers. This worker class is compatible with all web applications, but each worker can only handle one request at a time. By default, gunicorn only uses one of these workers. This can often cause your instances to be underutilized and increase latency in applications under high load.
We recommend setting the number of workers to 2-4 times the number of CPU cores for your instance plus one. You can specify this in gunicorn.conf.py
as:
import multiprocessing
workers = multiprocessing.cpu_count() * 2 + 1
Additionally, some web applications that are mostly I/O bound can see a
performance improvement by using a different worker class.
If your worker class requires additional dependencies such as gevent or tornado, those dependencies will need to be declared in your application's requirements.txt
.
HTTPS and forwarding proxies
App Engine terminates the HTTPS connection at the load balancer and forwards the
request to your application. Most applications do not need to know if the
request was sent over HTTPS or not, but applications that do need this
information should configure Gunicorn to trust the App Engine proxy in their
gunicorn.conf.py
:
forwarded_allow_ips = '*'
secure_scheme_headers = {'X-FORWARDED-PROTO': 'https'}
Gunicorn will now ensure that the wsgi.url_scheme
to 'https'
, which most web
frameworks will use as indication of the request is secure. If your WSGI server
or framework doesn't support this, just check the value of the
X-Forwarded-Proto
header manually.
Some applications also need to ascertain the user's IP address. This is
available in the X-Forwarded-For
header.
Note that the secure_scheme_headers
setting in gunicorn.conf.py
should be
upper case, like X-FORWARDED-PROTO
, but the headers that your code can read
will be in mixed case, like X-Forwarded-Proto
.
Extending the runtime
The standard python runtime can be used to create a custom runtime. Custom runtimes are configured via Dockerfile
s. You can generate a Dockerfile
based on the standard Python runtime using gen-config
:
gcloud beta app gen-config --custom
You can then customize the Dockerfile
and .dockerignore
as desired. Finally, you will need to specify runtime: custom
instead of runtime: python
in app.yaml
. See Customizing the Python Runtime for more information.
Environment variables
The following environment variables are set by the runtime environment:
Environment Variable | Description |
---|---|
GAE_INSTANCE |
The name of the current instance. |
GAE_MEMORY_MB |
The amount of memory available to the application process. |
GAE_SERVICE |
The service name specified in your application's app.yaml
file, or if no service name is specified, it is set to default . |
GAE_VERSION |
The version label of the current application. |
GOOGLE_CLOUD_PROJECT |
The Project ID associated with your application, which is visible in the Google Cloud Console |
PORT |
The port that will receive HTTP requests. |
You can set additional environment variables with app.yaml
.
Metadata server
Each instance of your application can use the Compute Engine metadata server to query information about the instance, including its host name, external IP address, instance ID, custom metadata, and service account information. App Engine does not allow you to set custom metadata for each instance, but you can set project-wide custom metadata and read it from your App Engine and Compute Engine instances.
This example function uses the metadata server to get the external IP address of the instance: