Esta página descreve como instalar e usar serviços agrupados antigos com o tempo de execução do Python 3 para o ambiente padrão. A sua app tem de aceder aos serviços incluídos através do SDK dos serviços do App Engine para Python 3.
Antes de começar
- Consulte a lista de APIs de serviços agrupados antigos que pode chamar no tempo de execução do Python.
- Antes de iniciar um projeto de migração para o Python 3, consulte a vista geral da migração de tempo de execução e as considerações de migração quando usar serviços agrupados antigos.
Instalar o SDK dos serviços do App Engine
Para instalar o SDK dos serviços do App Engine, siga estes passos:
Inclua o SDK na sua app adicionando a seguinte linha ao ficheiro
requirements.txt
:appengine-python-standard>=1.0.0
Pode encontrar o SDK no GitHub no repositório
appengine-python-standard
e no PyPI.Adicione o seguinte código ao seu script Python principal. Este código cria middleware WSGI que define as variáveis necessárias para ativar as chamadas da API.
Frasco
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 ficheiro
app.yaml
antes de implementar a app:app_engine_apis: true
Para implementar a sua app, use o comando
gcloud app deploy
.
Considerações sobre a migração
Deve ter em atenção as seguintes considerações se estiver a migrar para o tempo de execução do Python 3 e a sua app usar serviços agrupados antigos.
Testes
Para testar localmente a funcionalidade dos serviços agrupados antigos na sua app Python 3, use o servidor de desenvolvimento local.
Quando executar o comando dev_appserver.py
, tem de definir o argumento --runtime_python_path
para incluir um caminho para o intérprete do Python 3.
Por exemplo:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path=/usr/bin/python3
Também pode 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
Os serviços partilhados, incluindo o Memcache, o Cloud NDB e o deferred, usam o módulo pickle para serializar e partilhar objetos Python. Se o seu ambiente do App Engine usar o Python 2 e o Python 3, o que é comum durante uma migração, tem de garantir que os objetos serializados partilhados escritos por uma versão do Python podem ser reconstituídos pela outra. Pode encontrar orientações sobre a implementação da compatibilidade com o pickle entre versões no guia.
Por predefinição, o Python 3 usa protocolos de pickling que não são suportados no Python 2.
Isto pode causar falhas quando a sua app tenta reconstituir um objeto Python num ambiente Python 2 que foi escrito num ambiente Python 3.
Para evitar este problema, defina as seguintes variáveis de ambiente no ficheiro app.yaml
da sua app Python 3, conforme necessário:
- Para apps que usam a cache de memória, incluindo apps que usam o NDB, defina:
MEMCACHE_USE_CROSS_COMPATIBLE_PROTOCOL: 'True'
- Para apps que usam o NDB para se ligarem ao Datastore, defina:
NDB_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
- Para apps que usam o carregamento diferido, defina:
DEFERRED_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
No Python 2, os objetos string
contêm uma sequência de valores de bytes de 8 bits. No Python 3, os objetos string
contêm uma sequência de carateres Unicode. Por predefinição, o Python 3
pickle converte um Python 2 string
em Unicode interpretando o Python 3
string
como ASCII. Isto pode originar erros para valores fora do intervalo de carateres ASCII de 0 a 127. O Memcache suporta a substituição deste mapeamento predefinido.
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 num string
do Python 2. Isto evita erros de descodificação. No entanto, se o seu Python 2 string
contiver dados unicode reais fora do intervalo latin1
, como dados lidos de um ficheiro, o cPickle não mapeia os dados corretamente. Por conseguinte, é importante que atualize o seu código Python 2 para conter dados Unicode com objetos unicode
e não objetos string
, para objetos que usa com Pickle. O guia de compatibilidade inclui detalhes sobre as atualizações necessárias.
O método descrito anteriormente para atualizar o código Python 2 de modo a produzir serializações compatíveis com o Python 3 aborda serializações de curta duração, como as armazenadas no Memcache. Pode ter de atualizar ou reescrever as serializações do Python 2 de longa duração, como as armazenadas no Datastore como parte da sua migração. Por exemplo, a serialização escrita com
google.appengine.ext.ndb.model.PickleProperty
pode exigir uma atualização.
Consulte o guia de compatibilidade para saber mais sobre as limitações e os problemas menos comuns.
Frameworks Web
O webapp2
não está incluído nem é suportado no Python 3, pelo que qualquer aplicação tem de ser reescrita para usar qualquer framework compatível com WSGI (como o Flask).
Uma estratégia de migração recomendada é substituir primeiro a utilização de webapp2
na sua app Python 2.7 pelo Flask (ou uma framework Web alternativa, como Django, Pyramid, Bottle ou web.py), enquanto permanece no Python 2.7.
Em seguida, quando a app atualizada estiver estável, migre o código para o Python 3 e
implemente e teste com o App Engine para Python 3.
Para ver exemplos de como converter apps Python 2.7 que usam webapp2
para usar a framework Flask, pode consultar
estes recursos adicionais.
Usar controladores
Uma app Python 3 só pode ter um script associado. Por isso, se o seu
app.yaml
tiver vários processadores script
que mapeiam URLs para scripts diferentes,
tem de combinar esses scripts num só que processe o encaminhamento de URLs.
O exemplo seguinte mostra as diferenças do controlador no ficheiro app.yaml
para os respetivos tempos 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: python313
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
A sua app Python 3 tem de processar o encaminhamento de URLs (por exemplo, com decoradores Flask).
Se quiser usar vários processadores script
com padrões de URL diferentes ou
se quiser usar outros atributos nos seus processadores, cada processador tem de
especificar script: auto
.
Também pode substituir o comportamento de arranque predefinido
especificando um campo entrypoint
no seu ficheiro app.yaml
.
Consulte as descrições gerais do Blobstore, Deferred e Mail para obter mais informações sobre como usar processadores específicos.
Segurança de threads
As apps são consideradas seguras para threads. As chamadas API têm de ser feitas no pedido de processamento. Se usar uma API de serviços agrupados antiga quando a app está a ser iniciada, isto pode originar erros de segurança.
Para saber mais, consulte o artigo Erros de segurança ao usar serviços agrupados antigos para Python.
Usar a obtenção de URLs
Para usar a API URL Fetch para Python, tem de chamar explicitamente a biblioteca URL Fetch.
Se a sua app Python 3 usar a API URL Fetch, o cabeçalho do pedido X-Appengine-Inbound-Appid
é adicionado quando a sua app envia um pedido para outra app do
App Engine. Isto permite que a app de receção valide a identidade da
app de chamada. Para saber mais, consulte o artigo
Migrar pedidos de saída.
Exemplo (App Engine ndb
)
Segue-se uma app Python 2 básica que regista visitas a páginas através do App Engine ndb
para aceder ao Datastore. A respetiva app complementar é equivalente ao Python 3, em que a webapp2
utilização foi substituída pelo Flask e as alterações necessárias descritas acima para
aceder aos serviços incluídos no Python 3 foram implementadas.
Python 2 (webapp2
)
Python 3 (Flask)
Pode encontrar ambas as apps no repositório de código aberto para o conteúdo de migração do Python
App Engine (exemplos de código,
vídeos,
codelabs), especificamente nas pastas mod0
e mod1b
, respetivamente.