A conveniência e versatilidade do Python significam que ele é usado para construir software em quase todas as fases da vida de TI. Um nicho importante são os serviços web, onde a velocidade de desenvolvimento do Python e metáforas flexíveis facilitam a colocação de websites em funcionamento rapidamente.
E, como você pode adivinhar, Python lhe dá muitas escolhas e latitude em frameworks web, tanto pequenos quanto grandes. Afinal de contas, nem todos os projetos web precisam ser em escala empresarial. A maioria deve ser apenas grande o suficiente para fazer o trabalho, e não maior. Este artigo pesquisa oito dos mais conhecidos frameworks Python que enfatizam simplicidade, entrega leve, e um foco apertado.
Bottle
Bottle poderia ser considerado uma espécie de mini-Flask, pois é ainda mais compacto e sucinto do que aquele outro “microframework”. Devido à sua pegada mínima, o Bottle é ideal para incluir em outros projetos ou para entregar rapidamente pequenos projetos como REST APIs. (O frasco é discutido abaixo.)
A base de código inteira para Bottle cabe em um único arquivo e não tem absolutamente nenhuma dependência externa. Mesmo assim, Bottle vem equipado com funcionalidade suficiente para construir tipos comuns de aplicações web sem depender de ajuda externa.
O sistema de roteamento em Bottle, que mapeia URLs para funções, tem quase exatamente a mesma sintaxe de Flask. Você também não está limitado a um conjunto de caminhos com fio rígido; você pode criá-los dinamicamente. Dados de solicitação e resposta, cookies, variáveis de consulta, dados de formulário de uma ação POST, cabeçalhos HTTP e upload de arquivos podem ser acessados e manipulados por meio de objetos em Bottle.
A capacidade de cada um foi implementada com boa atenção aos detalhes. Com uploads de arquivo, por exemplo, você não precisa renomear o arquivo se a convenção de nomenclatura entrar em conflito com o sistema de arquivos de destino (tais como cortes no nome no Windows). O Bottle pode fazer isso para você.
Bottle inclui o seu próprio motor de templates HTML simples. Mais uma vez, embora mínimo, o motor de templates tem todos os elementos essenciais. As variáveis incluídas em um template são renderizadas com HTML seguro por padrão; você tem que indicar quais variáveis são seguras para reproduzir literalmente. Se preferir trocar o motor de templates Bottle por outro diferente, como o Jinja2, o Bottle permite-lhe fazê-lo sem alarido. Eu prefiro o sistema de templates simples empacotado com Bottle; é rápido, sua sintaxe é despretensiosa, e permite que você misture código e texto de template sem dificuldade indevida.
Bottle suporta até mesmo múltiplos back ends de servidor. Ele vem com seu próprio miniserver embutido para testes rápidos, mas também suporta WSGI genérico, uma grande variedade de servidores HTTP compatíveis com WSGI, e CGI simples e antigo se necessário.
Bottle não precisa de tanta documentação como outros frameworks, mas os docs não são de forma alguma escumosos. Todas as coisas cruciais cabem em uma única (embora longa) página web. Além disso, você encontrará documentação completa para cada API, exemplos para implantação em várias infra-estruturas, uma explicação da linguagem de templates integrada e uma série de receitas comuns.
Como no Flask, você pode expandir a funcionalidade do Bottle manualmente ou através de plug-ins. Os plug-ins para frascos não são tão numerosos como os do Flask, mas existem peças úteis, como a integração com várias camadas de base de dados e a autenticação básica do usuário. Para suporte a async, Bottle pode usar um dos adaptadores de servidor existentes que corre de forma assíncrona, como aiohttp/uvloop, mas async/await
não é suportado nativamente.
Uma consequência do minimalismo do Bottle é que alguns itens simplesmente não estão lá. A validação do formulário, incluindo funcionalidades como a protecção CSRF (cross-site request forgery), não está incluída. Se você quiser construir uma aplicação web que suporte um alto grau de interação do usuário, você mesmo precisará adicionar esse suporte.
Outro problema com Bottle é que o desenvolvimento estagnou; o último ponto de lançamento, 0.12, chegou em 2013. Dito isto, o Bottle continua a ser mantido, e os seus lançamentos de desenvolvimento continuam utilizáveis para a produção. Os programadores pretendem entregar novas versões que derramam suporte às edições antigas do Python.
CherryPy
CherryPy existe de uma forma ou de outra há quase 20 anos, mas não perdeu o minimalismo e a elegância que o distinguia desde o início.
O objetivo por trás do CherryPy, além de conter apenas os bits necessários para servir páginas web, é sentir, na medida do possível, não como uma “estrutura web”, mas como qualquer outro tipo de aplicação Python. Sites como Hulu e Netflix têm usado CherryPy na produção porque o framework fornece uma base altamente discreta para construir. CherryPy usa threads agrupados sob o hood, o melhor para suportar adaptadores de servidor multithreaded.
CherryPy permite manter a sua aplicação web separada da lógica do núcleo. Para mapear as funções da sua aplicação para URLs ou rotas servidas pelo CherryPy, você cria uma classe onde os namespaces dos objetos mapeiam diretamente para os URLs que você deseja servir. Por exemplo, a raiz do site é fornecida por uma função chamada “índice”. Os parâmetros passados para essas funções são usados para lidar com variáveis fornecidas pelos métodos GET ou POST.
Os bits que o CherryPy inclui são destinados a funcionar como blocos de construção de baixo nível. Identificadores de sessão e manipulação de cookies estão incluídos, mas a manipulação de templates HTML não está. Como Bottle, CherryPy oferece uma maneira de mapear rotas para diretórios em disco para servir arquivos estáticos.
CherryPy muitas vezes irá diferir para uma biblioteca existente de terceiros para suportar uma característica, em vez de fornecê-la nativamente. Aplicações WebSocket, por exemplo, não são suportadas diretamente pelo CherryPy, mas através da biblioteca ws4py.
A documentação para o CherryPy inclui um útil tutorial para percorrer os vários aspectos do programa. Ele não o levará através de uma aplicação completa de ponta a ponta, ao contrário de alguns outros tutoriais do framework, mas ainda assim é útil. Os docs vêm com úteis notas sobre implantação em hosts virtuais, proxy reverso via Apache e Nginx, e muitos outros cenários.
Falcon
Se você está construindo APIs baseadas em REST e nada mais, o Falcon foi feito apenas para você. De forma enxuta e rápida, com quase nenhuma dependência além da biblioteca padrão, o Falcon fornece tudo o que você precisa para as APIs REST e nada mais. Falcon 2.0, lançado em 2019, elimina o suporte ao Python 2.x e requer pelo menos Python 3.5.
Uma grande parte do porquê do Falcon ganhar o rótulo “light and slender” tem pouco a ver com o número de linhas de código na estrutura. É porque o Falcon não impõe quase nenhuma estrutura própria em aplicações. Tudo o que uma aplicação Falcon tem que fazer é indicar quais funções mapeiam para quais pontos finais da API. Retornar JSON de um endpoint envolve pouco mais do que configurar uma rota e retornar os dados através da função json.dumps
da biblioteca padrão do Python. O suporte para async ainda não aterrissou no Falcon, mas está trabalhando para fazer isso acontecer no Falcon 3.0.
Falcon também emprega padrões sãos fora da caixa, então pouco ajuste é necessário para a configuração. Por exemplo, 404s são levantados por padrão para qualquer rota que não seja explicitamente declarada. Se você quiser retornar erros ao cliente, você pode levantar uma das várias exceções de estoque agrupadas com a estrutura (como HTTPBadRequest
) ou usar uma exceção genérica falcon.HTTPError
. Se você precisar de pré-processamento ou pós-processamento para uma rota, o Falcon fornece ganchos para esses também.
Falcon’s focus on APIs significa que há pouco aqui para construir aplicações web com interfaces de usuário HTML convencionais. Não espere muito no modo de funções de processamento de formulários e ferramentas de proteção CSRF, por exemplo. Dito isto, o Falcon fornece opções elegantes para ampliar sua funcionalidade, para que itens mais sofisticados possam ser construídos. Além do mecanismo de engate mencionado acima, você encontrará uma interface para criar middleware que pode ser usada para envolver todas as APIs do Falcon.
A documentação do Falcon é esbelta em comparação com outras estruturas, mas apenas porque há menos para cobrir. O guia do usuário inclui um passo-a-passo formal de todas as principais características, juntamente com uma seção de início rápido que permite que você veja exemplos de código com ou sem anotação.
FastAPI
FastAPI O nome do Falcon é uma boa soma do que ele faz. Ele é construído para criar endpoints de API rapidamente, e roda rápido também.
FastAPI faz uso do projeto Starlette para seu núcleo de rede de alta velocidade, mas você não precisa saber sobre os internos do Starlette para usar FastAPI. Você define os pontos finais da mesma maneira que um frasco ou uma garrafa de aplicação – use decoradores para indicar quais funções lidam com quais rotas – e depois retorne dicionários que são traduzidos automaticamente para JSON.
Você pode facilmente ignorar como as coisas são retornadas. Por exemplo, se você quiser retornar HTML/XML de alguns endpoints, você pode fazer isso simplesmente retornando um objeto personalizado Response
. Se você quiser adicionar middleware personalizado, você pode popup em qualquer coisa que siga o padrão ASGI.
FastAPI faz uso da sugestão do tipo Python para fornecer restrições sobre os tipos de dados que as rotas aceitam. Por exemplo, se você tiver uma rota com o tipo Optional
, FastAPI rejeitará quaisquer submissões, exceto inteiros. Você não precisa adicionar código de validação de dados aos seus endpoints; você pode apenas usar dicas de tipo e deixar FastAPI fazer o trabalho.
Naturalmente, algumas coisas são deixadas de fora. Não há um motor de template HTML nativo, por exemplo, mas não há falta de soluções de terceiros para preencher essa lacuna. O mesmo acontece com a conectividade de banco de dados, mas a documentação contém detalhes sobre como coaxar certos ORMs (por exemplo, Peewee) para trabalhar com os comportamentos async de FastAPI.
Flask
Muitas discussões sobre frameworks web Python começam com o Flask, e por uma boa razão. Flask é um framework bem estabelecido, bem entendido, fácil de usar e bastante estável. É quase impossível dar errado usando Flask para um projeto web leve ou uma API REST básica, mas você enfrentará um levantamento pesado se tentar construir algo maior.
O apelo central de Flask é sua baixa barreira à entrada. Um aplicativo básico “olá mundo” pode ser configurado em menos de 10 linhas de Python. Flask inclui um sistema de templates HTML amplamente utilizado, Jinja2, para facilitar a renderização de texto, mas Jinja2 pode ser trocado por qualquer número de outros motores de templates (como Bigode) ou você pode rolar o seu próprio.
Em nome da simplicidade, Flask omite niceties como uma camada de dados ou ORM, e não oferece provisões para os gostos de validação de formulários. No entanto, Flask pode ser expandido através de extensões, das quais existem dezenas, cobrindo muitos casos de uso comum, como caching, manipulação e validação de formulários e conectividade com banco de dados. Este design lean-by-default permite que você inicie a engenharia de uma aplicação Flask com o mínimo absoluto de funcionalidade, e depois layer in only the pieces you need when you need them.
Flask’s documentation is genial and easy to read. O documento quick-start faz um excelente trabalho para que você comece enquanto também explica o significado das escolhas padrão para uma aplicação Flask simples, e os documentos da API estão repletos de bons exemplos. Também excelente é a coleção de snippets Flash, que são exemplos rápidos e sujos de como realizar tarefas específicas, como retornar um objeto se ele existir ou um erro 404 se ele não existir.
Flask atingiu seu marco 1.0 em 2018, com Python 2.6 e Python 3.3 sendo as versões com suporte mínimo, e com muitos de seus comportamentos finalmente definidos em pedra. Flask não suporta explicitamente a sintaxe assimétrica do Python, mas uma variação compatível com API do Flask chamada Quart foi desviada para satisfazer essa demanda.
Pyramid
Pequeno e leve, Pyramid é bem adequado para tarefas como expor o código Python existente como uma API REST, ou fornecer o núcleo para um projeto web onde o desenvolvedor faz a maior parte do levantamento pesado.
“Pyramid permitirá que você se torne produtivo rapidamente, e crescerá com você”, diz a documentação. “Ele não vai segurá-lo quando sua aplicação for pequena, e não vai atrapalhar quando sua aplicação se tornar grande”
Uma boa maneira de descrever o minimalismo do Pyramid seria “livre de políticas”, um termo usado na seção da documentação que discute como o Pyramid se forma contra outros frameworks web. Basicamente, “livre de política” significa que qual banco de dados ou qual linguagem de templates você escolhe usar não é preocupação do Pyramid.
Muito pouco trabalho é necessário para construir uma aplicação básica do Pyramid. Como com Bottle and Flask, uma aplicação Pyramid pode consistir em um único arquivo Python, além dos arquivos para o framework em si. Uma simples API de uma rota não requer mais do que uma dúzia de linhas de código. A maior parte disso é boilerplate como from … import
declarações e configuração do servidor WSGI.
Por padrão, o Pyramid inclui vários itens que são comuns em aplicações web, mas eles são fornecidos como componentes a serem costurados juntos, e não como soluções completas. O suporte para sessões de usuários, por exemplo, vem até com proteção CSRF. Mas o suporte para contas de usuário, como logins ou gerenciamento de contas, não faz parte do acordo. Você mesmo terá que rolar ou adicionar através de um plug-in. O mesmo vale para o manuseio de formulários e conexões de banco de dados.
Pyramid oferece até mesmo uma maneira de criar modelos de projetos Pyramid anteriores para reutilizar trabalhos anteriores. Estes templates, chamados “scaffolds”, geram uma aplicação Pyramid com roteamento simples e alguns templates iniciais HTML/CSS. Os scaffolds empacotados incluem um projeto inicial de exemplo e um projeto que se conecta a bancos de dados através da popular biblioteca Python SQLAlchemy.
As finas ferramentas de teste e depuração da pirâmide fazem o truque. Agrupe a extensão debugtoolbar
em um aplicativo Pyramid e você terá um ícone clicável em cada página da web que gera detalhes sobre a execução do aplicativo, incluindo um traceback detalhado no caso de erros. Logging and unit testing are also present.
Pyramid’s documentation is excellent. Além de um rápido tour pelo básico e uma caminhada no estilo tutorial, você encontrará um conjunto de tutoriais com contribuições da comunidade e um livro de receitas comuns. Este último inclui técnicas de implementação para uma série de ambientes alvo, desde o Google App Engine ao Nginx.
Pyramid suporta tanto Python 2 como Python 3, mas não usa a sintaxe assíncrona do Python 3. Se você quer alavancar a async no Pyramid, veja o projeto aiopyramid, que inclui um andaime para uma aplicação “olá mundo” assimétrica.
Sanic
Desenhado para velocidade e simplicidade, Sanic trabalha com Python 3.6 ou superior e usa a sintaxe do Python async/await
(disponível a partir do Python 3.5) para permitir que você crie aplicações web eficientes.
As with Flask or Bottle, um “hello world” básico do Sanic roda cerca de 10 linhas de código, a maior parte dele importa e outros boilerplate. A principal diferença é que as rotas da aplicação devem ser declaradas como async def
funções, e você deve usar await
para invocar essas funções dentro do seu código assimétrico. Se você já escreveu aplicações assíncronas antes, você já tem a parte mais difícil debaixo do seu cinto.
Muitos dos mecanismos que a Sanic usa para lidar com conexões e respostas serão familiares. As solicitações e respostas são apenas objetos com propriedades de aparência familiar, como arquivos carregados, formulários, objetos JSON, cabeçalhos e assim por diante.
Aplicações com muitas rotas tornam-se desajeitadas de gerenciar. Sanic aborda isso com “plantas”, objetos que podem descrever grupos de rotas e permitir que você as gerencie através de uma interface de alto nível. Ao invés de escrever cada rota explicitamente, ou usar um excesso de rotas com variáveis, você pode escrever alguns planos para descrever genericamente como as rotas funcionam em sua aplicação (por exemplo, /object/object_id/action
). Blueprints podem ter middleware comum, que é útil se você quiser aplicar funcionalidade de gerenciamento a algumas rotas, mas não a outras.
Sanic também funciona com outros protocolos além de HTTP. WebSocket endpoints requerem apenas um decorador diferente e um pouco mais de lógica interna (por exemplo, aguardando e manipulando respostas). Protocolos de rede personalizados podem ser suportados pela subclassificação asyncio.protocol
.
Sanic deixa deliberadamente de fora funcionalidades como conectividade de banco de dados e templates HTML, enquanto mantém os recursos que seriam usados para conectar essas capacidades: middleware, configuração centralizada de aplicativos, e assim por diante.
Tornado
Tornado é outro framework minúsculo destinado a um caso de uso específico: aplicativos de rede assíncronos. O Tornado é bem adequado para criar serviços que abrem muitas conexões de rede e as mantêm vivas – ou seja, qualquer coisa envolvendo WebSockets ou sondagens longas. O Tornado 6.0 requer o Python 3.5 ou superior, e deixa de suportar Python 2 por completo.
Like Bottle ou Falcon, o Tornado omite funcionalidades estranhas ao seu propósito central. O Tornado tem um sistema de templates embutido para gerar HTML e outras saídas, e fornece mecanismos para internacionalização, manipulação de formulários, configuração de cookies, autenticação de usuários, e proteção CSRF. Mas deixa de fora recursos, como validação de formulários e um ORM, que são principalmente para aplicativos web voltados para o usuário.
Tornado se destaca por fornecer infra-estrutura para aplicativos que precisam de controle próximo sobre redes assíncronas. Por exemplo, Tornado fornece não só um servidor HTTP assíncrono integrado, mas também um cliente HTTP assíncrono. Assim, o Tornado é bem adequado para construir aplicativos, como um scraper web ou um bot, que consultam outros sites em paralelo e atuam sobre os dados retornados.
Se você quiser criar um aplicativo que utilize protocolos que não o HTTP, o Tornado tem você coberto. O Tornado fornece acesso a conexões TCP de baixo nível e sockets a utilitários como resolvedores DNS, bem como a serviços de autenticação de terceiros, e suporta interoperação com outros frameworks através do padrão WSGI. A documentação, que é pequena mas não esparsa, inclui amplos exemplos para realizar tudo isso.
Tornado tanto alavanca quanto complementa a funcionalidade nativa do Python para comportamentos assíncronos. Se você estiver usando o Python 3.5, o Tornado suporta as palavras-chave internas async
e await
, que prometem dar às aplicações um aumento de velocidade. Você também pode usar futuros ou callbacks para lidar com respostas a eventos.
Tornado fornece uma biblioteca de primitivas de sincronização – semáforos, bloqueios, e assim por diante – para coordenar eventos entre coroutinas assíncronas. Note que o Tornado normalmente roda com uma única rosca, portanto esses primitivos não são os mesmos que seus nomes de rosca. No entanto, se você quiser executar o Tornado em processos paralelos para alavancar vários soquetes e núcleos, há ferramentas disponíveis para isso.
A documentação do Tornado cobre cada conceito principal na estrutura e todas as principais APIs do modelo. Embora inclua uma aplicação de amostra (um web crawler), é principalmente para demonstrar o módulo de enfileiramento do Tornado.