Nesta página, descrevemos as medidas necessárias para fazer upgrade do aplicativo Python para o ambiente de execução do Python 2.7. Seguindo essas instruções, o aplicativo aproveitará muitos dos recursos novos do ambiente de execução do Python 2.7, incluindo multissegmentação, mecanismo de modelos Jinja2 (ambos em inglês), acesso e upload de bytecode e diversas novas bibliotecas terceirizadas.
Pré-requisitos e considerações
Para usar o Python 2.7, um aplicativo precisa atender aos seguintes requisitos:
- Para usar o Django, é preciso que a versão seja 1.2 ou posterior. Consulte a documentação do Django para detalhes de upgrade.
- Para usar solicitações simultâneas, o aplicativo precisa usar gerenciadores de scripts de interface de gateway do servidor da Web (WSGI na sigla em inglês), conforme abordado em Como usar a WSGI.
Além de atender a esses pré-requisitos gerais, é preciso usar versões específicas de alguns recursos do App Engine e de bibliotecas de terceiros. Certifique-se de atualizar as versões incluídas e importadas no aplicativo e de testar o aplicativo extensivamente após o upgrade. A lista abaixo identifica os principais problemas de compatibilidade e aponta para outros recursos a fim de resolvê-los:
- Desempenho: o desempenho do aplicativo está sujeito a alterações após o upgrade para o Python 2.7. Caso você tenha uma elevação na latência de resposta, aumente a classe de instância de front-end e ative as solicitações simultâneas. Essas solicitações permitem maior rapidez na execução do seu aplicativo com menor custo de instância em instâncias maiores. Para mais informações, consulte Gerenciamento de solicitações em instâncias.
- Django: é preciso usar o Django 1.2 ou posterior com o Python 2.7. Para informações sobre upgrade, consulte as Notas de lançamento do Django.
- PyCrypto:
Crypto.Util.randpool
foi trocado porCrypto.Random
. Para mais informações, consulte O que fazer com o RandomPool (em inglês). webapp
: os modelos de aplicativo da Web foram descontinuados no Python 2.7. Use diretamente os modelos do Django, jinja2, (ambos em inglês) ou um mecanismo de modelo diferente de sua escolha.- WebOb: o Python 2.7 é compatível com WebOb versão 1.1. Essa versão não é totalmente compatível com a versão anterior (0.9). Para que o aplicativo use o WebOb, será preciso testá-lo extensivamente para detectar erros resultantes do upgrade.
- zipimport: o Python 2.7 não é compatível. No entanto, ele faz importação de forma nativa a partir de arquivos .zip.
- simplejson: o Python 2.7 não é compatível, mas inclui o módulo json da biblioteca padrão, equivalente e muito mais rápido.
Solicitações simultâneas e WSGI
O recurso do Python 2.7 que mais afeta o design e o desempenho do aplicativo é a compatibilidade com aplicativos de multissegmentação que gerenciam solicitações simultâneas. A capacidade de gerenciar solicitações simultâneas resulta na melhoria da utilização e aprimoramento significativo do desempenho do aplicativo, especialmente para aplicativos que usam classes de instâncias mais elevadas que exploram diversos núcleos de CPU.
Para ativar a multissegmentação, os aplicativos precisam migrar da abordagem baseada na Common Gateway Interface (CGI) dos ambientes de execução anteriores no Python para uma abordagem baseada na interface de gateway do servidor da Web (WSGI). Isso ocorre porque os scripts CGI, projetados para gerenciar solicitações em série, dependem de variáveis de ambiente para acesso aos streams de entrada e saída.
Embora o modelo da WSGI para gerenciar solicitações dê aos aplicativos acesso mais direto aos streams de entrada e saída, permitindo solicitações simultâneas, gerenciar diversas solicitações em paralelo causa uma disputa quando a lógica de um gerenciador de solicitação depende de ou interage com dados maiores do que o escopo local, por exemplo, o estado do aplicativo. Por esse motivo, é importante codificar defensivamente para lidar com disputas e garantir que seu novo aplicativo WSGI seja thread-safe.
Para mais detalhes, veja Como tornar seu aplicativo thread-safe.
Como atualizar o app.yaml
O Python 2.7 requer um elemento especial de configuração runtime
no cabeçalho de app.yaml
.
O elemento threadsafe: [ true | false ]
é necessário para aplicativos Python 2.7. Se for true
, o App Engine enviará solicitações simultaneamente. Se for false
, o App Engine os enviará em série. O seguinte cabeçalho app.yaml
permite solicitações simultâneas:
application: myapp version: 1 runtime: python27 api_version: 1 threadsafe: true ...
Como usar a WSGI
O ambiente de execução do Python 2.7 permite executar diretamente um aplicativo da interface de gateway do servidor da Web (WSGI, na sigla em inglês), em vez de usar o adaptador run_wsgi_app
para executar o programa como um script CGI.
Para fazer isso, substitua o manipulador CGI (por exemplo, myapp.py
) em app.yaml
com um nome de aplicativo WSGI (por exemplo, myapp.app
).
... handlers: - url: /.* script: myapp.app ...
É preciso também mover o objeto do aplicativo WSGI para o escopo 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() """
Além disso, é possível especificar gerenciadores de scripts CGI no app.yaml
. No entanto, as solicitações gerenciadas por scripts CGI são processadas em série, não simultaneamente. Além disso, não é possível ter um arquivo app.yaml
que misture scripts CGI e aplicativos WSGI e não é possível definir threadsafe
como true
se você definir qualquer gerenciador CGI.
Algumas convenções de ambientes de execução anteriores do Python, como o uso de main()
e a verificação de __name__ == 'main'
, foram suspensas. Essas medidas ajudavam os scripts CGI anteriores a permanecer em cache, mas agora que os aplicativos WSGI estão sendo executados diretamente, essas etapas não são mais necessárias.
Como usar o diretório raiz do aplicativo
No Python 2.5, os scripts CGI eram executados com o diretório de trabalho atual configurado como o diretório que continha o script. Isso foi alterado no Python 2.7. Com a WSGI, o diretório de trabalho atual no início do tempo de vida do gerenciador da solicitação é o diretório raiz do aplicativo.
Revise seu código de aplicativo e verifique se todos os gerenciadores estão escritos para esperar que o diretório de trabalho atual seja a raiz do aplicativo.
Como configurar bibliotecas
O ambiente de execução do Python 2.7 inclui alguns módulos de terceiros. Alguns estão disponíveis por padrão. Outros estão disponíveis apenas quando configurados. Especifique qual versão você quer usar.
libraries: - name: PIL version: "1.1.7" - name: webob version: "1.1.1"
Especifique que o aplicativo use a versão mais recente do módulo. Isso é útil para desenvolver um aplicativo que ainda não tem usuários, Não é preciso rastrear novas versões. Caso o aplicativo esteja sendo usado ativamente, cuidado. Talvez você se surpreenda ao constatar que seu aplicativo começou a usar uma nova versão de biblioteca não compatível com versões anteriores. Para usar a versão mais recente:
libraries: - name: PIL version: latest
Para uma lista de bibliotecas suportadas, veja Bibliotecas de terceiros.
Como tornar seu aplicativo thread-safe
O gerenciamento de solicitações simultâneas é simples quando cada gerenciador interage apenas com variáveis dentro do respectivo escopo. No entanto, ele se torna complicado quando um gerenciador modifica recursos enquanto outro faz a leitura deles. Ao garantir o comportamento esperado do seu aplicativo, mesmo que diversas solicitações estejam manipulando os mesmos dados e interferindo umas nas outras - você torna seu aplicativo "thread-safe".
A regra principal ao projetar um aplicativo para se tornar thread-safe é limitar o uso de recursos compartilhados, como informações de estado ou variáveis globais, com a maior frequência possível. Entretanto, geralmente não é possível descartar completamente este uso, e é aí que entram mecanismos de sincronização, como objetos de bloqueio.
No Python 2.7, você tem acesso à biblioteca de threads do Python. Isso permite declarar um bloqueio em um bloco de lógica, fazendo com que o código seja executado em série em vez de simultaneamente. Pense no 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
Esse código mostra a criação de um cache de algumas variáveis de configuração globais em uma variável chamada _config_cache
. Aqui, o uso de um objeto de bloqueio chamado _config_lock
garante que a verificação de um _config_cache
preexistente se comporte de maneira confiável. Caso contrário, essa variável poderá perder tempo fazendo várias viagens ao Datastore para definir a mesma variável várias vezes com os mesmos dados, porque todas as solicitações concorrentes descobriram que _config_cache
estava vazio.
Pense bem ao utilizar bloqueios. Um bloqueio trava todos os outros threads que executam esse método. Isso se torna um gargalo no desempenho.
Como atualizar seu aplicativo para webapp2
Observação: se você não estiver usando webapp
como gerenciador de solicitações, ignore esta seção.
O framework da Web incluído no ambiente de execução do Python 2.7 foi atualizado de webapp
para webapp2. Dentre outras coisas, o webapp2
promove a melhoria do roteamento de URIs e gerenciamento de exceções, um objeto de resposta completo e um mecanismo de despacho mais flexível.
O uso de modelos webapp
foi suspenso. Substitua-os por Jinja2 (em inglês), Djangoou por um sistema de modelos de sua escolha, desde que ele esteja programado em Python puro.
No App Engine, webapp2
tem o alias webapp
, e webapp2
é compatível com versões anteriores. No entanto, após o upgrade, ainda será preciso testar completamente seu aplicativo e se familiarizar com a nova sintaxe e os recursos (em inglês) do webapp2
, em vez de continuar a depender da compatibilidade com versões anteriores.
E seu upgrade está completo!
Após fazer o upload do aplicativo, é preciso testá-lo extensivamente para garantir a compatibilidade com versões anteriores. Se você tiver problemas, confira os fóruns.