O tempo de execução do Python

O tempo de execução do Python é a pilha de software responsável por instalar o código e as dependências da sua aplicação e, em seguida, executar essa aplicação no ambiente flexível.

Versões do Python

O Python 3.13 usa buildpacks. Para ver a lista completa das versões do Python suportadas e a respetiva versão do Ubuntu, consulte a Programação de suporte de tempo de execução.

Para usar uma versão do Python suportada, tem de:

  • Inclua as definições runtime_config e operating_system no ficheiro app.yaml para especificar um sistema operativo.

  • Instale a versão gcloud420.0.0 ou posterior da CLI. Pode atualizar as ferramentas de CLI executando o comando gcloud components update. Para ver a versão instalada, execute o comando gcloud version.

  • Opcionalmente, pode especificar uma versão do tempo de execução incluindo a definição runtime_version no ficheiro app.yaml. Por predefinição, é usada a versão mais recente do Python se a definição runtime_version não for especificada.

Exemplos

  • Para especificar o Python 3.13 no Ubuntu 22:

    runtime: python
    env: flex
    entrypoint: gunicorn -b :$PORT main:app
    
    runtime_config:
        operating_system: "ubuntu22"
        runtime_version: "3.13"
    
  • Para especificar a versão do Python mais recente suportada no Ubuntu 22:

      runtime: python
      env: flex
      entrypoint: gunicorn -b :$PORT main:app
    
      runtime_config:
          operating_system: "ubuntu22"
    

Consulte a app.yaml página de referência para mais informações.

Versões de tempo de execução anteriores

Para o Python versão 3.7 e anterior, especifica uma versão através das definições runtime_config e python_version no ficheiro app.yaml da sua aplicação.

Exemplo

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
    python_version: 3.7

Para as versões 3.7 e anteriores do Python, o intérprete predefinido é o Python 2.7.12 se runtime_config ou python_version forem omitidos. Por exemplo, pode usar a duração de execução predefinida especificando runtime: python no ficheiro app.yaml:

runtime: python
env: flex

Consulte a app.yaml página de referência para mais informações.

Os intérpretes implementados para cada definição de versão são apresentados na tabela seguinte:

python_version definição Intérprete implementado ID do ambiente de execução app.yaml exemplo
2 (predefinição) 2.7.12 python2 runtime_config:
python_version: 2
3.4 3.4.8 python34 runtime_config:
python_version: 3.4
3.5 3.5.9 python35 runtime_config:
python_version: 3.5
3 ou 3.6 3.6.10 python36 runtime_config:
python_version: 3
3.7 3.7.9 python37 runtime_config:
python_version: 3.7

Suporte para outros tempos de execução do Python

Se precisar de usar uma versão do Python que não seja suportada, pode criar um tempo de execução personalizado e selecionar uma imagem base válida com a versão do Python de que precisa.

Para imagens base fornecidas pela Google ou imagens base do Docker Python, consulte o artigo Criar tempos de execução personalizados.

Para investigar mais a fundo a contentorização de apps do App Engine para o Cloud Run, consulte o guia de migração.

Dependências

O tempo de execução procura um ficheiro requirements.txt no diretório de origem da sua aplicação e usa pip para instalar todas as dependências antes de iniciar a aplicação. Para mais informações sobre a declaração e a gestão de pacotes, consulte Usar bibliotecas Python.

Se a sua app exigir dependências privadas, tem de usar um tempo de execução personalizado baseado no tempo de execução do Python para instalar os pacotes adequados.

Arranque da aplicação

O tempo de execução inicia a sua aplicação através do entrypoint definido no ficheiro app.yaml. O ponto de entrada deve iniciar um processo que responda a pedidos HTTP na porta definida pela variável de ambiente PORT.

A maioria das aplicações Web usa um servidor WSGI, como o Gunicorn, o uWSGI ou o Waitress.

Antes de poder usar um destes servidores, tem de os adicionar como uma dependência no requirements.txt da sua aplicação. Se usar o gunicorn para a sua aplicação Flask, certifique-se de que a versão do Python da sua aplicação é compatível com o gunicorn.

O tempo de execução garante que todas as dependências são instaladas antes de o ponto de entrada ser chamado.

Flask==2.0.2
gunicorn==20.1.0

Um exemplo de ponto de entrada que usa o gunicorn para uma aplicação Flask:

entrypoint: gunicorn -b :$PORT main:app

Um ponto de entrada de exemplo que usa o gunicorn para uma aplicação Django:

entrypoint: gunicorn -b :$PORT mydjangoapp:wsgi

O Gunicorn é o servidor WSGI recomendado, mas é perfeitamente possível usar qualquer outro servidor WSGI. Por exemplo, segue-se um ponto de entrada que usa o uWSGI com o Flask:

entrypoint: uwsgi --http :$PORT --wsgi-file main.py --callable app

Para aplicações que podem processar pedidos sem um servidor WSGI, basta executar um script Python:

entrypoint: python main.py

Os exemplos de pontos de entrada básicos apresentados acima destinam-se a ser pontos de partida e podem funcionar para as suas aplicações Web. No entanto, a maioria das aplicações tem de configurar ainda mais o servidor WSGI. Em vez de especificar todas as definições no ponto de entrada, crie um ficheiro gunicorn.conf.py no diretório raiz do projeto, onde se encontra o ficheiro app.yaml, e especifique-o no ponto de entrada:

entrypoint: gunicorn -c gunicorn.conf.py -b :$PORT main:app

Pode ler acerca de todos os valores de configuração do Gunicorn na respetiva documentação.

Trabalhadores

O Gunicorn usa trabalhadores para processar pedidos. Por predefinição, o Gunicorn usa trabalhadores de sincronização. Esta classe de worker é compatível com todas as aplicações Web, mas cada worker só pode processar um pedido de cada vez. Por predefinição, o gunicorn usa apenas um destes trabalhadores. Isto pode fazer com que as suas instâncias sejam subutilizadas e aumentar a latência nas aplicações sob carga elevada.

Recomendamos que defina o número de trabalhadores para 2 a 4 vezes o número de núcleos do CPU da sua instância, mais um. Pode especificar isto em gunicorn.conf.py como:

import multiprocessing

workers = multiprocessing.cpu_count() * 2 + 1

Além disso, algumas aplicações Web que estão principalmente limitadas por E/S podem observar uma melhoria no desempenho através da utilização de uma classe de worker diferente. Se a sua classe de trabalho exigir dependências adicionais, como gevent ou tornado, essas dependências têm de ser declaradas no requirements.txt da sua aplicação.

HTTPS e proxies de encaminhamento

O App Engine termina a ligação HTTPS no balanceador de carga e encaminha o pedido para a sua aplicação. A maioria das aplicações não precisa de saber se o pedido foi enviado através de HTTPS ou não, mas as aplicações que precisam destas informações devem configurar o Gunicorn para confiar no proxy do App Engine no respetivo gunicorn.conf.py:

forwarded_allow_ips = '*'
secure_scheme_headers = {'X-FORWARDED-PROTO': 'https'}

O Gunicorn vai agora garantir que o wsgi.url_scheme para 'https', que a maioria das frameworks Web usa como indicação de que o pedido é seguro. Se o seu servidor WSGI ou framework não suportar esta funcionalidade, basta verificar o valor do cabeçalho X-Forwarded-Proto manualmente.

Algumas aplicações também precisam de determinar o endereço IP do utilizador. Esta opção está disponível no cabeçalho X-Forwarded-For.

Tenha em atenção que a definição secure_scheme_headers em gunicorn.conf.py deve estar em maiúsculas, como X-FORWARDED-PROTO, mas os cabeçalhos que o seu código pode ler estão em letras misturadas, como X-Forwarded-Proto.

Prolongar o tempo de funcionamento

O tempo de execução do Python do ambiente flexível pode ser usado para criar um tempo de execução personalizado. Consulte o artigo Personalizar o Python para mais informações.

Variáveis de ambiente

As seguintes variáveis de ambiente são definidas pelo ambiente de tempo de execução:

Variável de ambiente Descrição
GAE_INSTANCE O nome da instância atual.
GAE_MEMORY_MB A quantidade de memória disponível para o processo da aplicação.
GAE_SERVICE O nome do serviço especificado no ficheiro app.yaml da sua aplicação ou, se não for especificado nenhum nome do serviço, é definido como default.
GAE_VERSION A etiqueta da versão da aplicação atual.
GOOGLE_CLOUD_PROJECT O ID do projeto associado à sua aplicação, que é visível na Google Cloud consola
PORT A porta que vai receber pedidos HTTP.

Pode definir variáveis de ambiente adicionais no ficheiro app.yaml.

Servidor de metadados

Cada instância da sua aplicação pode usar o servidor de metadados do Compute Engine para consultar informações sobre a instância, incluindo o respetivo nome do anfitrião, endereço IP externo, ID da instância, metadados personalizados e informações da conta de serviço. O App Engine não lhe permite definir metadados personalizados para cada instância, mas pode definir metadados personalizados ao nível do projeto e lê-los a partir das suas instâncias do App Engine e Compute Engine.

Esta função de exemplo usa o servidor de metadados para obter o endereço IP externo da instância:

METADATA_NETWORK_INTERFACE_URL = (
    "http://metadata/computeMetadata/v1/instance/network-interfaces/0/"
    "access-configs/0/external-ip"
)


def get_external_ip():
    """Gets the instance's external IP address from the Compute Engine metadata
    server.

    If the metadata server is unavailable, it assumes that the application is running locally.

    Returns:
        The instance's external IP address, or the string 'localhost' if the IP address
        is not available.
    """
    try:
        r = requests.get(
            METADATA_NETWORK_INTERFACE_URL,
            headers={"Metadata-Flavor": "Google"},
            timeout=2,
        )
        return r.text
    except requests.RequestException:
        logging.info("Metadata server could not be reached, assuming local.")
        return "localhost"