Esta página aborda as medidas necessárias para atualizar a sua aplicação Python para o tempo de execução do Python 2.7. Depois de seguir este tutorial passo a passo, a sua aplicação pode tirar partido das muitas novas capacidades do tempo de execução do Python 2.7, incluindo multithreading, o motor de modelos Jinja2, o acesso e o carregamento de bytecode, e várias novas bibliotecas de terceiros incluídas.
Pré-requisitos e considerações
Para usar o Python 2.7, uma aplicação tem de cumprir os seguintes requisitos:
- Se a aplicação usar o Django, tem de usar a versão 1.2 ou posterior. Consulte a documentação do Django para ver detalhes da atualização.
- Se quiser usar pedidos simultâneos, a aplicação tem de usar controladores de scripts da interface de gateway do servidor Web (WSGI), conforme abordado no artigo Usar WSGI.
Além de cumprir estes pré-requisitos gerais, tem de usar versões específicas de algumas funcionalidades do App Engine e bibliotecas de terceiros. Certifique-se de que atualiza as versões que inclui e importa para a sua aplicação, e teste a aplicação extensivamente após a atualização. A lista seguinte identifica os principais problemas de compatibilidade e indica recursos adicionais para os resolver:
- Desempenho: o desempenho da aplicação pode mudar após a atualização para o Python 2.7. Se verificar um aumento da latência de resposta, pode aumentar a classe de instância do front-end e ativar os pedidos simultâneos. Os pedidos simultâneos permitem que a sua aplicação tenha um desempenho mais rápido com um custo de instância inferior em instâncias maiores. Para mais informações, consulte o artigo Processamento de pedidos em instâncias.
- Django: Tem de usar o Django 1.2 ou posterior com o Python 2.7. Para obter informações sobre a atualização, consulte as notas de lançamento do Django.
- PyCrypto:
Crypto.Util.randpool
foi descontinuado a favor deCrypto.Random
. Para mais informações, consulte o artigo O que fazer em relação ao RandomPool. webapp
: os modelos de apps Web estão descontinuados no Python 2.7. Em alternativa, pode usar diretamente modelos do Django, jinja2 ou um motor de modelos diferente à sua escolha.- WebOb: O Python 2.7 suporta a versão 1.1 do WebOb. Esta versão não é totalmente retrocompatível com a versão antiga (0.9). Se a aplicação usar o WebOb, tem de testá-lo extensivamente para detetar erros resultantes da atualização.
- zipimport: O Python 2.7 não suporta zipimport, mas o Python 2.7 pode importar nativamente de ficheiros .zip.
- simplejson: O Python 2.7 não suporta o simplejson, mas o Python 2.7 inclui o módulo json da biblioteca padrão equivalente e muito mais rápido.
Pedidos simultâneos e WSGI
A funcionalidade do Python 2.7 que mais afeta o design e o desempenho da sua aplicação é o respetivo suporte para aplicações com várias linhas de execução que podem processar pedidos simultâneos. A capacidade de processar pedidos simultâneos resulta numa utilização melhorada que pode melhorar significativamente o desempenho da sua aplicação, especialmente para aplicações que usam classes de instâncias mais elevadas que exploram vários núcleos da CPU.
Para ativar a multithreading, as aplicações têm de passar da abordagem baseada na Common Gateway Interface (CGI) dos runtimes Python anteriores para uma abordagem baseada na Web Server Gateway Interface (WSGI). Isto acontece porque os scripts CGI, que foram concebidos para processar pedidos em série, dependem de variáveis de ambiente para aceder aos fluxos de entrada e saída.
Embora o modelo WSGI para processar pedidos dê às aplicações um acesso mais direto aos fluxos de entrada e saída (permitindo pedidos concorrentes), o processamento de vários pedidos em paralelo pode causar condições de concorrência quando a lógica de um processador de pedidos se baseia ou interage com dados com um âmbito superior ao local, como o estado da aplicação. Por este motivo, é importante programar de forma defensiva para lidar com condições de corrida, de modo a garantir que a sua nova aplicação WSGI é segura para threads.
Consulte o artigo Tornar a sua aplicação segura para vários threads para ver mais detalhes.
Atualizar o ficheiro app.yaml
O Python 2.7 requer um elemento de configuração runtime
especial no cabeçalho de app.yaml
.
Tenha em atenção que o elemento threadsafe: [ true | false ]
é obrigatório para aplicações Python 2.7. Se true
, o App Engine envia pedidos em simultâneo; se false
, o App Engine envia-os em série. O seguinte cabeçalho app.yaml
permite pedidos simultâneos:
application: myapp version: 1 runtime: python27 api_version: 1 threadsafe: true ...
Usar WSGI
O tempo de execução do Python 2.7 permite-lhe, opcionalmente, executar diretamente uma aplicação de interface de gateway do servidor Web (WSGI), em vez de usar o adaptador run_wsgi_app
para executar o programa como um script CGI.
Para tal, substitua o controlador CGI (por exemplo, myapp.py
) em
app.yaml
por um nome de aplicação WSGI (por exemplo, myapp.app
).
... handlers: - url: /.* script: myapp.app ...
Também tem de mover o objeto da aplicação WSGI para o âmbito global:
import webapp2 class MainPage(webapp2.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.out.write('Hello, WebApp World!') app = webapp2.WSGIApplication([('/', MainPage)]) """ Old code: def main(): run_wsgi_app(app) if __name__ == '__main__': main() """
Ainda pode especificar controladores de scripts CGI em
app.yaml
; no entanto, os pedidos processados por scripts CGI são processados
em série e não em simultâneo. Além disso, não pode ter um ficheiro que misture scripts CGI e aplicações WSGI, e não pode definir threadsafe
como true
se definir quaisquer controladores CGI.app.yaml
Algumas convenções de runtimes Python anteriores, como a utilização de
main()
e a verificação de
__name__ == 'main'
,
estão agora descontinuadas. Estas medidas ajudaram a manter em cache os scripts CGI do passado, mas agora que está a executar aplicações WSGI diretamente, estes passos já não são necessários.
Usar o diretório raiz da app
No Python 2.5, os scripts CGI eram executados com o diretório de trabalho atual definido para o diretório que continha o script. Isto foi alterado no Python 2.7. Com o WSGI, o diretório de trabalho atual no início do tempo de vida do controlador de pedidos é o diretório raiz da aplicação.
Reveja o código da aplicação e certifique-se de que todos os controladores são escritos para esperar que o diretório de trabalho atual seja a raiz da aplicação.
Configurar bibliotecas
O tempo de execução do Python 2.7 inclui alguns módulos de terceiros. Algumas destas opções estão disponíveis por predefinição; outras só estão disponíveis se forem configuradas. Pode especificar a versão que quer usar.
libraries: - name: PIL version: "1.1.7" - name: webob version: "1.1.1"
Pode especificar que a aplicação deve usar a versão mais recente do módulo. Isto é útil se estiver a desenvolver uma aplicação que ainda não tem utilizadores: não precisa de acompanhar as novas versões. No entanto, se a sua aplicação estiver a ser usada ativamente, tenha cuidado: pode surpreender-se ao ver que a sua aplicação começa a usar uma nova versão da biblioteca não compatível com versões anteriores. Para usar a versão mais recente:
libraries: - name: PIL version: latest
Para ver uma lista das bibliotecas suportadas, consulte o artigo Bibliotecas de terceiros.
Tornar a sua aplicação segura para vários processos
O processamento de pedidos simultâneos é simples se cada controlador interagir apenas com variáveis no respetivo âmbito. No entanto, torna-se rapidamente complicado se um controlador modificar os recursos enquanto outro os está a ler. Garantir que a sua aplicação se comporta como esperado, mesmo que vários pedidos possam estar a manipular os mesmos dados e a interferir uns com os outros, é conhecido como tornar a sua aplicação "segura para threads".
A regra principal ao criar uma aplicação para ser segura para threads é limitar a utilização de recursos partilhados (como informações de estado ou variáveis globais) o mais frequentemente possível. No entanto, normalmente, não é possível excluir completamente a respetiva utilização, e é aqui que entram os mecanismos de sincronização, como os objetos de bloqueio.
No Python 2.7, tem acesso à biblioteca threading do Python, que lhe permite declarar um bloqueio num bloco de lógica que força a execução do código no interior em série em vez de em simultâneo. Considere o seguinte código:
class Configuration(ndb.Model): some_config_data = ndb.StringProperty() _config_cache = None _config_lock = threading.Lock() @classmethod def get_config(cls): with cls._config_lock: if not cls._config_cache: cls._config_cache = cls.get_by_id('config') return cls._config_cache
Este código mostra a criação de uma cache de algumas variáveis de configuração globais numa variável denominada _config_cache
. Aqui, a utilização de um objeto de bloqueio denominado _config_lock
garante que a verificação de um _config_cache
pré-existente se comporta de forma fiável. Caso contrário, esta variável pode desperdiçar tempo a fazer
várias viagens ao Datastore para definir a mesma variável várias
vezes com os mesmos dados, porque os pedidos concorrentes descobriram que _config_cache
estava vazio.
Não escolha usar bloqueios de ânimo leve. Um bloqueio força o bloqueio de todas as outras threads que executam este método. Isto pode ser uma restrição de desempenho.
Atualizar a sua aplicação para o webapp2
Nota: se não estiver a usar webapp
como processador de pedidos, pode ignorar esta secção.
A framework Web incluída no tempo de execução do Python 2.7 foi
atualizada de webapp
para webapp2. Entre outras
coisas, a versão webapp2
adiciona um encaminhamento de URI e um processamento de exceções melhorados, um
objeto de resposta com todas as funcionalidades e um mecanismo de
envio mais flexível.
Os modelos webapp
foram
descontinuados. Em alternativa, pode usar o Jinja2, o Django ou um sistema de modelos à sua escolha (desde que seja escrito em Python puro).
No App Engine, webapp2
foi associado a webapp
e webapp2
é retrocompatível. No entanto, após a atualização, continua a ter de
testar exaustivamente a sua aplicação e familiarizar-se com a
nova sintaxe e capacidades do webapp2
,
em vez de continuar a confiar na retrocompatibilidade.
A atualização está concluída!
Depois de carregar a aplicação, tem de a testar exaustivamente para garantir a compatibilidade com versões anteriores. Se estiver a ter problemas, consulte os fóruns.