Nesta página, descrevemos como instalar e usar os serviços em pacote legados com o ambiente de execução do Python 3 no ambiente padrão. O aplicativo precisa acessar os serviços incluídos pelo SDK de serviços do App Engine para Python 3.
Antes de começar
- Consulte a lista de APIs legadas de serviços em pacote que podem ser chamadas no ambiente de execução do Python.
- Antes de iniciar um projeto de migração para o Python 3, consulte a visão geral da migração do ambiente de execução e as considerações sobre migração ao usar os serviços em pacote legados.
Como instalar o SDK de serviços do App Engine
Para instalar o SDK de serviços do App Engine, siga estas etapas:
Inclua o SDK ao app adicionando a seguinte linha ao arquivo
requirements.txt
:appengine-python-standard>=1.0.0
É possível encontrar o SDK no GitHub no repositório
appengine-python-standard
e em PyPI.Adicione o seguinte código ao script Python principal: Este código cria um middleware WSGI que define as variáveis necessárias para ativar as chamadas de API.
Flask
from flask import Flask from google.appengine.api import wrap_wsgi_app app = Flask(__name__) app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
Django
from DJANGO_PROJECT_NAME.wsgi import application from google.appengine.api import wrap_wsgi_app app = wrap_wsgi_app(application)
Pirâmide
from pyramid.config import Configurator from google.appengine.api import wrap_wsgi_app config = Configurator() # make configuration settings app = config.make_wsgi_app() app = wrap_wsgi_app(app)
WSGI
import google.appengine.api def app(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield b'Hello world!\n' app = google.appengine.api.wrap_wsgi_app(app)
Adicione a seguinte linha ao arquivo
app.yaml
antes de implantar o aplicativo:app_engine_apis: true
Para implantar o aplicativo, use o comando
gcloud app deploy
.
Considerações sobre a migração
Esteja ciente das seguintes considerações se você estiver migrando para o ambiente de execução do Python 3 e seu aplicativo usar pacotes de serviços legados.
Teste
Para testar localmente a funcionalidade de serviços em pacote legados no
app em Python 3, use o servidor de desenvolvimento local.
Ao executar o comando dev_appserver.py
, defina o argumento
--runtime_python_path
para incluir um caminho para o interpretador do Python 3.
Por exemplo:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path=/usr/bin/python3
Também é possível definir o argumento como uma lista separada por vírgulas de pares [RUNTIME_ID]=[PYTHON_INTERPRETER_PATH]
. Por exemplo:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path="python27=/user/bin/python2.7,python3=/usr/bin/python3"
Compatibilidade com o Pickle
Serviços compartilhados, incluindo Memcache, Cloud NDB e deferred, usam o módulo pickle para serializar e compartilhar objetos do Python. Se o ambiente do App Engine usa o Python 2 e o Python 3, o que é comum durante uma migração, garanta que os objetos serializados compartilhados gravados por uma versão do Python possam ser reconstituídos pela outra. Você pode encontrar orientações sobre como implementar a compatibilidade com o Pickle em várias versões no guia.
Por padrão, o Python 3 usa protocolos de conservação que não são compatíveis com o Python 2.
Isso pode causar falhas quando o aplicativo tenta reconstituir um objeto Python
em um ambiente Python 2 gravado em um ambiente Python 3.
Para evitar esse problema, defina as seguintes
variáveis de ambiente
no arquivo app.yaml
do seu aplicativo Python 3 conforme necessário:
- Para apps que usam o Memcache, incluindo apps que usam o NDB, defina:
MEMCACHE_USE_CROSS_COMPATIBLE_PROTOCOL: 'True'
- Para aplicativos que usam o NoSQL para se conectar ao Datastore, defina:
NDB_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
- Para apps que usam deferred, defina:
DEFERRED_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
No Python 2, os objetos string
contêm uma sequência de valores de byte de 8 bits. No Python 3, os objetos string
contêm uma sequência de caracteres Unicode. Por padrão, o pickle do Python 3 traduz um string
do Python 2 em unicode interpretando o string
do Python 3 como ASCII. Isso pode levar a erros para valores fora do intervalo de caracteres ASCII de 0 a 127. O Memcache é compatível com a substituição desse mapeamento padrão.
from google.appengine.api import memcache
import six.moves.cPickle as pickle
def _unpickle_factory(file):
return pickle.Unpickler(file, encoding='latin1')
memcache.setup_client(memcache.Client(unpickler=_unpickle_factory))
A codificação latin1
define um mapeamento para cada um dos 256 valores possíveis de
cada byte em uma string
do Python 2. Isso evita erros de decodificação No entanto, se a string
do Python 2 contiver dados unicode reais fora do intervalo latin1
, como os dados lidos em um arquivo, o cPickle não os mapeará corretamente. Portanto, é importante atualizar o código Python 2 para manter
dados unicode com objetos unicode
, e não com objetos string
, para os objetos
escolhidos. O guia de compatibilidade inclui detalhes sobre as atualizações necessárias.
O método descrito anteriormente para atualizar o código do Python 2 para produzir serializações compatíveis com o Python 3 trata de serializações de curta duração, como as armazenadas no Memcache. Talvez seja necessário atualizar ou reescrever serializações de longa duração do Python 2, como as armazenadas no Datastore como parte da migração. Por exemplo, a serialização escrita com
google.appengine.ext.ndb.model.PickleProperty
pode exigir um upgrade.
Consulte o guia de compatibilidade para saber mais sobre limitações e problemas menos comuns.
Frameworks da Web
webapp2
não é incluído ou compatível no Python 3,. Portanto, os aplicativos precisam
ser reescritos para usar qualquer framework compatível com WSGI (como
Flask).
Uma estratégia de migração recomendada é primeiro substituir o uso do webapp2
no
app em Python 2.7 pelo Flask (ou um framework da Web alternativo, como
Django,
Pyramid,
Bottle ou
web.py) enquanto permanecerem em Python 2.7.
Em seguida, quando o app atualizado estiver estável, migre o código para o Python 3 e
implante e teste usando o App Engine para Python 3.
Para exemplos de como converter apps Python 2.7 que usam webapp2
para usar o framework Flask, consulte
estes recursos adicionais.
Como usar gerenciadores
Um app em Python 3 pode ter apenas um script associado a ele. Portanto, se o
app.yaml
tiver vários gerenciadores script
que mapeiam URLs para scripts diferentes,
será necessário combinar esses scripts em um que processe o roteamento de URL.
O exemplo a seguir mostra as diferenças de gerenciador no arquivo app.yaml
para os respectivos ambientes de execução.
Python 2
runtime: python27 api_version: 1 threadsafe: true handlers: - url: / script: home.app - url: /index\.html script: home.app - url: /stylesheets static_dir: stylesheets - url: /(.*\.(gif|png|jpg))$ static_files: static/\1 upload: static/.*\.(gif|png|jpg)$ - url: /admin/.* script: admin.app login: admin - url: /.* script: not_found.app
Python 3
runtime: python312
app_engine_apis: true
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /(.*\.(gif|png|jpg))$
static_files: static/\1
upload: static/.*\.(gif|png|jpg)$
- url: /admin/.*
script: auto
login: admin
O aplicativo Python 3 precisa gerenciar o roteamento de URL (por exemplo, com decoradores Flask).
Se você quiser usar vários gerenciadores script
com padrões de URL diferentes ou
se quiser usar outros atributos nos gerenciadores, cada gerenciador precisará
especificar script: auto
.
Você também pode substituir o comportamento de inicialização padrão
especificando um campo entrypoint
no arquivo app.yaml
.
Consulte as visões gerais de repositório de blobs, Deferred e de Mail para mais informações sobre como usar gerenciadores específicos.
Concorrência segura
Presume-se que os apps são seguros para threads. As chamadas de API precisam ser feitas no thread de solicitação. Se você usa uma API de serviços incluídos legada quando o app está sendo iniciado, isso pode causar erros de segurança.
Para saber mais, consulte Erros de segurança ao usar serviços incluídos legados para Python.
Como usar a busca de URL
Para usar a busca de URL para Python, você precisa chamar explicitamente a biblioteca de busca de URL.
Se o aplicativo Python 3 usar a API URL Fetch, o cabeçalho de solicitação
X-Appengine-Inbound-Appid
será adicionado quando o aplicativo enviar uma solicitação para outro
aplicativo do App Engine. Isso permitirá que o aplicativo receptor verifique a identidade do aplicativo
de chamada. Para saber mais, consulte
Como migrar solicitações de saída.
Exemplo (App Engine ndb
)
Veja abaixo um aplicativo básico do Python 2 que registra visitas à página usando o ndb
do App Engine para
acessar o Datastore. O complemento dele é um app equivalente do Python 3 em que o uso
do webapp2
foi substituído pelo Flask, e as alterações necessárias descritas acima para
acessar serviços incluídos no Python 3 foram implementadas.
Python 2 (webapp2
)
Python 3 (Flask)
Os dois apps podem ser encontrados no repositório de código
aberto do conteúdo de
migração do App Engine para Python (exemplos de código,
vídeos,
codelabs), especificamente nas pastas mod0
e mod1b
, respectivamente.