Como migrar para o ambiente de execução do Python 3

O Python 2.7 chegou ao fim do suporte em 31 de janeiro de 2024. Os aplicativos Python 2.7 atuais continuarão a ser executados e a receber tráfego. No entanto, o App Engine pode bloquear a reimplantação de aplicativos que usam ambientes de execução após o término da data de suporte. Recomendamos que você migre para a versão compatível mais recente do Python seguindo as diretrizes nesta página.

A migração para o ambiente de execução do Python 3 permite usar recursos de linguagem atualizados e criar apps mais portáteis, com código idiomático. O ambiente de execução do Python 3 usa a versão mais recente do interpretador de código aberto do Python, fornecido pela Python Software Foundation. Os aplicativos criados no ambiente de execução do Python 3 podem usar o ecossistema avançado de pacotes e frameworks do Python no aplicativo, incluindo aqueles que usam código C, declarando as dependências em um arquivo requirements.txt.

Visão geral do processo de migração do ambiente de execução

Recomendamos a seguinte abordagem incremental para a migração, na qual você mantém um aplicativo funcional e testável durante todo o processo:

  1. Fazer upgrade do app para que seja compatível com o Python 3.

    Várias soluções estão disponíveis para ajudar nesse upgrade. Por exemplo, use Six, Python-Future, ou Python-Modernize.

    Para mais informações sobre essa etapa do processo de migração, consulte Portabilidade do código do Python 2 para o Python 3 no site da documentação do Python Software Foundation.

  2. Escolha uma destas estratégias para qualquer serviço em pacote do App Engine usado pelo seu aplicativo:

    1. Migre os serviços incluídos do App Engine no aplicativo Python 2 para serviços do Google Cloud, serviços de terceiros ou outras substituições recomendadas.

    2. Continue usando serviços em pacote legados nos seus aplicativos em Python 3. Essa abordagem oferece flexibilidade para migrar para serviços desagrupados posteriormente no ciclo de migração.

    Teste seu app após migrar cada serviço.

  3. Prepare os arquivos de configuração do App Engine para o ambiente de execução do Python 3. Várias alterações importantes afetam as definições de configuração em app.yaml, incluindo, entre outros:

    • Agora, os apps são considerados threadsafe. Se o aplicativo não for seguro para linha de execução, defina max_concurrent_requests no app.yaml como 1. Essa configuração pode fazer com que mais instâncias sejam criadas do que o necessário para um app threadsafe e gerar custos desnecessários.
    • O arquivo app.yaml não encaminha mais solicitações para os scripts. Em vez disso, é necessário usar um framework da Web com roteamento no aplicativo e atualizar ou remover todos os gerenciadores script em app.yaml. Para ver um exemplo de como fazer isso com o framework Flask, consulte o exemplo de código do guia de migração do App Engine no GitHub.

      Para saber mais sobre como alterar esse e outros arquivos de configuração, consulte a seção Arquivos de configuração.

  4. Nos ambientes de execução de segunda geração, os registros de apps não estão mais aninhados nos registros de solicitação. Outras etapas são necessárias para exibir a visualização aninhada de registros de solicitação e de aplicativos na Análise de registros. Para mais informações, consulte Migrar para o Cloud Logging.

  5. Teste e implante seu aplicativo atualizado em um ambiente do Python 3.

    Após a aprovação de todos os testes, implante o aplicativo atualizado no App Engine, mas impeça que o tráfego seja roteado automaticamente para a nova versão. Use a divisão de tráfego para migrar lentamente o tráfego do aplicativo no ambiente de execução do Python 2 para o aplicativo no ambiente de execução do Python 3. Se você tiver problemas, encaminhe todo o tráfego para uma versão estável até que o problema seja corrigido.

Para exemplos de como converter apps em Python 2 em Python 3, consulte estes recursos adicionais.

Principais diferenças entre os ambientes de execução do Python 2 e do Python 3

A maioria das alterações que você precisa fazer durante a migração vem das seguintes diferenças entre os ambientes de execução do Python 2 e do Python 3:

Diferenças de uso da memória

Os ambientes de execução de segunda geração têm um valor de referência maior do uso de memória em comparação com os da primeira geração. Isso ocorre devido a vários fatores, como versões diferentes da imagem de base e diferenças na forma como as duas gerações calculam o uso de memória.

Os ambientes de execução de segunda geração calculam o uso de memória da instância como a soma do que um processo do aplicativo usa e o número de arquivos de aplicativos armazenados em cache dinamicamente na memória. Para evitar que aplicativos com uso intensivo de memória tenham encerramentos de instâncias por excederem os limites de memória, faça upgrade para uma classe de instância maior com mais memória.

Diferenças de uso da CPU

Os ambientes de execução de segunda geração podem ter um valor de referência mais alto de uso da CPU durante a inicialização a frio da instância. Dependendo da configuração de escalonamento de um aplicativo, isso pode ter efeitos colaterais não intencionais, como uma contagem de instâncias maior do que o previsto se um aplicativo estiver configurado para escalonar com base na utilização da CPU. Para evitar esse problema, revise e teste as configurações de escalonamento do aplicativo para garantir que o número de instâncias seja aceitável.

Diferenças de cabeçalhos de solicitação

Os ambientes de execução de primeira geração permitem que os cabeçalhos das solicitações com sublinhados (por exemplo, X-Test-Foo_bar) sejam encaminhados para o aplicativo. Os ambientes de execução de segunda geração introduzem o Nginx na arquitetura do host. Como resultado dessa mudança, os ambientes de execução de segunda geração são configurados para remover automaticamente cabeçalhos com sublinhados (_). Para evitar problemas no aplicativo, evite usar sublinhados nos cabeçalhos das solicitações.

Diferenças de worker do Gunicorn

Para ambientes de execução do Python 3 e versões mais recentes, o número de workers do Gunicorn tem impacto direto no uso da memória. O aumento no uso da memória é diretamente proporcional ao aumento na contagem de workers. Para reduzir o consumo de memória, reduza o número de workers do Gunicorn. Consulte as Práticas recomendadas do ponto de entrada para instruções sobre como configurar a contagem de workers do Gunicorn.

Problemas de compatibilidade entre o Python 2 e o Python 3

Quando o Python 3 foi lançado pela primeira vez em 2008, várias alterações incompatíveis com versões anteriores foram introduzidas na linguagem. Algumas alterações exigem apenas pequenas atualizações no seu código, como a alteração da declaração print para uma função print(). Outras alterações podem exigir atualizações significativas no código, como atualizar a maneira como você lida com dados binários, texto e strings.

Muitas bibliotecas de código aberto conhecidas, incluindo as bibliotecas padrão do Python, também foram alteradas quando foram movidas do Python 2 para o Python 3.

Serviços em pacote do App Engine no ambiente de execução do Python 3

Para reduzir o esforço e a complexidade da migração, o ambiente padrão do App Engine permite acessar muitos serviços e APIs em pacote legados no ambiente de execução do Python 3, como o Memcache. O aplicativo Python 3 pode chamar as APIs de serviços em pacote por meio de bibliotecas idiomáticas da linguagem e acessar a mesma funcionalidade que no ambiente de execução do Python 2.

Você também tem a opção de usar produtos do Google Cloud que oferecem funcionalidades semelhantes aos serviços incluídos legados. Recomendamos migrar para os produtos desagrupados do Google Cloud e aproveitar as melhorias contínuas e os novos recursos.

Para os serviços incluídos que não estão disponíveis como produtos separados no Google Cloud, como processamento de imagens, pesquisa e mensagens, use nossos provedores terceirizados sugeridos ou outras soluções alternativas.

Arquivos de configuração

Antes de executar o aplicativo no ambiente de execução do Python 3 do ambiente padrão do App Engine, talvez seja necessário alterar alguns dos arquivos de configuração usados pelo App Engine:

Estrutura da Web necessária para encaminhar solicitações de conteúdo dinâmico

No ambiente de execução do Python 2, é possível criar gerenciadores de URL no arquivo app.yaml para especificar qual aplicativo será executado quando um URL específico ou um padrão de URL for solicitado.

No ambiente de execução do Python 3, seu aplicativo precisa usar um framework da Web, como Flask ou Django, para encaminhar solicitações de conteúdo dinâmico em vez de usar gerenciadores de URL em app.yaml. Para conteúdo estático, é possível continuar a criar gerenciadores de URL no arquivo app.yaml do aplicativo.

Apps apenas com conteúdo estático

Ao hospedar um webapp estático no App Engine, você especifica gerenciadores no seu arquivo app.yaml para mapear URLs para seus arquivos estáticos.

No Python 2, se uma solicitação não corresponder a nenhum dos gerenciadores especificados no arquivo app.yaml, o App Engine retornará um código de erro 404.

No Python 3, se uma solicitação não corresponder a nenhum dos gerenciadores, o App Engine procurará um arquivo main.py e retornará um erro 5xx se um arquivo main.py não for encontrado. Como os aplicativos do App Engine apenas com conteúdo estático não exigem um arquivo main.py, a maioria dos usuários vê esse erro, além de ver erros de inicialização da instância nos registros do aplicativo.

Para manter o mesmo comportamento de retornar um erro 404 quando nenhum dos gerenciadores estáticos corresponder, e para evitar erros nos registros, é possível fazer o seguinte:

  • Adicione um gerenciador estático "pega-tudo" que aponte para um diretório vazio no arquivo app.yaml
  • Adicione um app dinâmico simples ao arquivo main.py para retornar um erro 404

Exemplos de como usar uma das opções:

app.yaml

Crie um diretório vazio no diretório raiz do app, como empty/. Na seção app.yaml do gerenciador de arquivos, crie um novo gerenciador no final para capturar todos os outros padrões de URL e especifique o diretório empty nos elementos static_files eupload:

  handlers:
  - url:
    .
    .
    .
  - url: /(.*)$
    static_files: empty/\1
    upload: empty/.*$

main.py

Crie um arquivo main.py e adicione o seguinte código para retornar um erro 404:

  def app(env, start_response):
    start_response('404 Not Found', [('Content-Type','text/html')])
    return [b"Not Found"]

Teste

Recomendamos que você use uma abordagem de teste que seja idiomática para Python em vez de depender de dev_appserver. Por exemplo, você pode usar venv para criar um ambiente Python 3 local isolado. Qualquer biblioteca de testes padrão do Python pode ser usada para escrever sua unidade, integração e testes de sistema. Também é possível configurar versões de desenvolvimento de seus serviços ou usar os emuladores locais disponíveis para muitos produtos do Google Cloud.

Opcionalmente, é possível usar a versão de pré-lançamento do dev_appserver, que é compatível com o Python 3. Para saber mais sobre esse recurso de teste, consulte Como usar o servidor de desenvolvimento local.

Implantação

As implantações via appcfg.py não são compatíveis com o Python 3. Em vez disso, use a ferramenta de linha de comando gcloud para implantar seu aplicativo.

Logging

A geração de registros no ambiente de execução do Python 3 segue o padrão de geração de registros no Cloud Logging. No ambiente de execução do Python 3, os registros de aplicativos não são mais incluídos com os registros de solicitação, mas são separados em registros diferentes. Para saber mais sobre como ler e gravar registros no ambiente de execução do Python 3, consulte o guia de geração de registros.

Recursos adicionais de migração

Para mais informações sobre como migrar seus aplicativos do App Engine para serviços autônomos do Cloud ou para o ambiente de execução do Python 3, consulte estes recursos do App Engine: