O Modelo WSGI e de Contexto do Flask
O Flask é famoso por parecer Python puro: from flask import request e request.args se comportam como uma importação comum e acesso a atributos, mesmo que a requisição real seja diferente a cada chamada.
Busque em todas as páginas da documentação
O Flask é famoso por parecer Python puro: from flask import request e request.args se comportam como uma importação comum e acesso a atributos, mesmo que a requisição real seja diferente a cada chamada.
Essa sensação é deliberada e se baseia em duas ideias que precedem quase todas as outras funcionalidades do Flask: Flask é uma aplicação WSGI fina e usa proxies contextuais locais para fazer com que o estado por requisição pareça um global em nível de módulo sem realmente ser um.
Quase tudo mais no Flask - blueprints, extensões, g, fábricas de aplicação - é uma consequência de manter essas duas ideias mínimas e deixar o ecossistema construir sobre elas.
Esta página é o modelo mental por trás desse minimalismo; Flask Basics cobre o roteamento e as requisições práticas que esta página explica por baixo, e Request Lifecycle & Context cobre os hooks práticos (before_request, teardown_request) que seguem diretamente disso.
request "vazar" entre requisições, g não persistir, ou current_app falhar fora de uma requisição, todos rastreiam de volta ao mal-entendido desses dois mecanismos, e não a um Flask imprevisível.g é seguro para usar como cache, ou explicando por que as views async do Flask não tornam o framework nativamente concorrente.WSGI (Web Server Gateway Interface) é um contrato simples de Python: uma aplicação web é um "callable" que recebe um dicionário environ e uma função start_response, e retorna um iterável de bytes de resposta.
O Flask não implementa este contrato por si só; ele é construído sobre Werkzeug, um toolkit WSGI que fornece o roteamento real (o mapa de URL), objetos de requisição/resposta, e o servidor de desenvolvimento, além do Jinja2 para templates.
A contribuição do próprio Flask sobre o Werkzeug é comparativamente pequena: o objeto de app Flask, o açúcar de roteamento baseado em decoradores (@app.route, @app.get), e o sistema de contexto descrito abaixo - que é consistente com a filosofia declarada do Flask de permanecer minimalista e deixar quase tudo mais (ORMs, autenticação, painéis de administração) para extensões.
A segunda ideia fundamental é o proxy contextual local. Quando você escreve from flask import request, você não está importando um objeto de requisição - você está importando um objeto proxy que, sempre que acessado, procura a requisição real para a thread ou tarefa que está atualmente em execução e encaminha o acesso a ela.
Essa busca é o que permite que request.args se comporte como um global comum do ponto de vista do código, enquanto na verdade resolve para dados subjacentes diferentes em cada requisição concorrente, de forma segura, sem que você precise passar request como parâmetro por todas as chamadas de função.
O Flask na verdade tem dois contextos, não um, e a distinção é uma fonte comum de confusão: o contexto da aplicação (que torna current_app e g disponíveis) e o contexto da requisição (que torna request e session disponíveis, e que automaticamente empurra um contexto de aplicação junto com ele).
Servidor WSGI chama app Flask(environ, start_response)
-> Flask empurra um contexto de app (se nenhum estiver ativo)
-> Flask empurra um contexto de requisição para esta requisição
-> Mapa de URL (Werkzeug) resolve o path do environ para uma função de view
-> função de view executa; request/g/current_app resolvem via proxies
-> objeto de resposta construído e retornado
-> teardown_request, então teardown_appcontext, executam
-> ambos os contextos são retirados; servidor WSGI envia bytes de respostag é um espaço de rascunho por requisição, limpo no início de cada contexto de requisição e desmontado em seu final - é fácil confundi-lo com um cache porque ele sobrevive a toda a requisição, mas não guarda nada entre requisições, muito menos entre processos worker.
Fora de uma requisição ativa - um comando CLI, um script de background, uma sessão de shell - current_app e url_for ainda precisam de um contexto de aplicação, que é por que o código invocado fora de uma requisição explicitamente empurra um com app.app_context(); esta é a origem do clássico erro "working outside of application context".
Blueprints registram um conjunto de rotas, manipuladores de erro e pastas estáticas/de templates que são mesclados no mapa de URL do app principal no momento de app.register_blueprint() - eles são uma ferramenta organizacional para dividir um app grande em arquivos, não um limite de isolamento como são sistemas de plugins com escopo separado; um blueprint compartilha a mesma configuração do app, as mesmas extensões, e a mesma pilha de contexto que todo o resto.
from flask import Flask, g, has_app_context
def get_db():
if "db" not in g:
g.db = {"connected": True} # criado uma vez por requisição, não uma vez por app
return g.dbO núcleo WSGI do Flask é síncrono por design: cada worker (uma thread, processo ou greenlet, dependendo da implantação) lida com uma requisição por vez do início ao fim, o que é uma grande parte do motivo pelo qual a implantação WSGI escala adicionando mais workers em vez de depender de concorrência cooperativa dentro de um único worker.
O Flask 3.x suporta funções de view async def, mas isso não transforma o Flask em um framework async nativo como os frameworks ASGI: uma view async é "ponteada" para o modelo de worker síncrono nos bastidores, então ela ainda ocupa um worker durante sua duração e não ganha benefício de concorrência a menos que a implantação em si use algo como workers gevent/eventlet ou um adaptador ASGI - contraste isso com Flask vs FastAPI vs Django, onde a alternativa async nativa é coberta diretamente.
Como os locais de contexto são escopados por thread (ou por tarefa, sob contextvars), nada em g ou um padrão mutável em nível de módulo é compartilhado entre processos worker WSGI separados - um erro comum de implantação é assumir que um cache em memória definido em uma requisição será visível de uma requisição atendida por um processo worker diferente, quando na verdade cada processo tem seu próprio interpretador e espaço de memória.
O ecossistema de extensões existe precisamente porque o núcleo do Flask permanece tão fino: Flask-SQLAlchemy, Flask-Login, Flask-Migrate e pacotes similares se conectam ao contexto do app/requisição e ao mecanismo de registro de blueprint em vez de exigir mudanças no Flask em si, o que permite que o conjunto de funcionalidades de um app Flask escale sem que o framework principal cresça.
| Abordagem | Força | Fraqueza | Melhor Ajuste |
|---|---|---|---|
| Núcleo WSGI fino do Flask + extensões | Pequena área de superfície, fácil de raciocinar, vasto ecossistema de extensões | Sem concorrência async nativa; "baterias não incluídas" (auth, ORM, admin) | Serviços pequenos a médios onde a equipe monta exatamente o que precisa |
| Pilha MTV "batteries-included" do Django | ORM, admin, auth, forms todos integrados e embutidos | Pegada mais pesada; mais convenção de framework para aprender de antemão | Apps focados em conteúdo ou CRUD que se beneficiam de uma stack opinativa |
| Modelo nativo ASGI do FastAPI | I/O async nativo, validação e docs automáticos | Sem admin/templating/ORM embutidos; curva de aprendizado mais íngreme para Python tipado | Serviços com foco em API onde concorrência async e validação de schema são mais importantes |
request é um objeto global compartilhado entre todas as requisições." É um proxy contextual local: o código sempre escreve request, mas cada thread/tarefa o resolve para sua própria requisição atual, isolada de qualquer outra requisição concorrente.async def do Flask 3 tornam o Flask um framework async." Elas se conectam ao mesmo modelo de worker síncrono WSGI - a view ainda ocupa um worker durante sua duração, e nenhum ganho de concorrência é obtido sem uma configuração de servidor/worker diferente.g é um bom lugar para cachear dados entre requisições." Ele é limpo no início e no final de cada contexto de requisição; é apenas um espaço de rascunho para a requisição atual, nunca um cache entre requisições.app.app_context() explícito para usar current_app, url_for, ou outros recursos vinculados ao contexto da aplicação.O objeto de aplicação do Flask, através do Werkzeug, eventualmente conforma-se ao contrato de callable WSGI (environ, start_response), que lida com o roteamento real e a análise de requisição/resposta por baixo da API baseada em decoradores do Flask.
Não. O flask run embutido do Flask usa o servidor de desenvolvimento do Werkzeug para uso local; em produção, um servidor WSGI separado (Gunicorn, uWSGI, etc.) executa o objeto de app Flask como seu callable.
request é um objeto proxy contextual local. Acessar um atributo nele procura a requisição real para a thread ou tarefa que está executando no momento e encaminha para ela, em vez de se referir a um único objeto compartilhado.
current_app e g disponíveisrequest e session disponíveis, e automaticamente empurra um contexto de aplicação junto com elePorque código como current_app ou url_for precisa de um contexto de aplicação ativo, e fora de uma requisição HTTP real (em um comando CLI ou script autônomo) nada empurra um automaticamente - você precisa explicitamente de with app.app_context():.
Não - g é criado novo e desmontado no início e no final de cada contexto de requisição, então nada armazenado nele sobrevive para a próxima requisição.
Não. Um blueprint apenas agrupa rotas relacionadas, manipuladores de erro e pastas estáticas/de templates sob um namespace; ele é registrado no mesmo objeto de app e compartilha sua configuração, extensões e pilha de contexto com todo o resto.
Não por si só. Uma view async é conectada ao mesmo modelo de worker síncrono WSGI, então ela ainda ocupa um worker durante sua duração, a menos que a implantação use um tipo de worker diferente ou um adaptador ASGI.
Se o app for implantado com múltiplos processos worker WSGI, cada processo tem seu próprio espaço de memória; um valor armazenado no g de um worker ou em uma variável de nível de módulo é invisível para requisições atendidas por um processo worker diferente.
Porque o núcleo do framework deliberadamente permanece fino - apenas roteamento, contextos e manipulação de requisição/resposta - deixando integrações de ORM, autenticação, migrações e preocupações semelhantes para extensões que se conectam aos mesmos mecanismos de contexto e blueprint.
Uma função fábrica adia a criação do app, o que torna possível construir múltiplas instâncias com configurações diferentes (para testes, para ambientes distintos) em vez de se comprometer com um único objeto de app global no momento da importação.
Sim - session também é um proxy contextual local, escopado ao contexto da requisição, com o backend sendo a implementação de sessão de cookie assinado do Flask por padrão.
g na práticaVersões da Stack: Esta página foi escrita para Flask 3.1 em Python 3.14 (manutenção: 3.13), que depende de Werkzeug 3.
Revisado por Chris St. John·Última atualização: 15 de jul. de 2026