microdot — framework HTTP mínimo#

Microdot é um framework HTTP pequeno, inspirado no Flask, para o MicroPython. Ele roda sobre o asyncio, lida com múltiplos clientes simultâneos sem usar threads e expõe uma API familiar baseada em decoradores de rota. Uma aplicação mínima se parece com:

from microdot import Microdot

app = Microdot()

@app.route('/')
async def index(request):
    return 'Hello, world!'

app.run(host='0.0.0.0', port=80)

class Microdot#

class microdot.Microdot#

Uma instância de aplicação HTTP. Uma instância é construída próximo ao topo do script e decorada com os manipuladores de rota; chamar run() ou aguardar start_server() inicia o atendimento das requisições.

Registro de rotas

route(url_pattern: str, methods: list | None = None) Callable#

Decorador que registra um manipulador para url_pattern sob os métodos HTTP listados (padrão ['GET']). Retorna o decorador que, quando aplicado a uma função, a registra como manipulador e retorna a função inalterada.

url_pattern

Um padrão de caminho. Suporta segmentos estáticos (/users) e segmentos dinâmicos delimitados por < / >. Segmentos dinâmicos aceitam um prefixo de tipo opcional separado por :<int:id>, <path:rest>, <re:[0-9a-f]+:hex>. O tipo padrão é string.

methods

Lista de nomes de métodos HTTP. Se omitida, apenas GET é correspondido.

O manipulador é chamado primeiro com o objeto de requisição e, em seguida, com quaisquer segmentos dinâmicos capturados como argumentos nomeados. O valor de retorno do manipulador torna-se a resposta HTTP: um Response, uma string, uma tupla (body, status_code[, headers]) ou um dict / list (enviado como JSON).

get(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['GET']) – registra a função decorada como um manipulador GET para url_pattern. Retorna o decorador.

post(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['POST']) – registra a função decorada como um manipulador POST para url_pattern. Retorna o decorador.

put(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['PUT']) – registra a função decorada como um manipulador PUT para url_pattern. Retorna o decorador.

patch(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['PATCH']) – registra a função decorada como um manipulador PATCH para url_pattern. Retorna o decorador.

delete(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['DELETE']) – registra a função decorada como um manipulador DELETE para url_pattern. Retorna o decorador.

Hooks de ciclo de vida

before_request(f: Callable) Callable#

Decorador que registra f para ser executada antes de cada requisição. f recebe o objeto de requisição; seu valor de retorno normalmente é ignorado. Para interromper a requisição antecipadamente, retorne um Response (ou um valor que se converta em um) – o restante do pipeline é então ignorado e essa resposta é enviada. Retorna f inalterada.

after_request(f: Callable) Callable#

Decorador que registra f para ser executada após cada requisição bem-sucedida. f recebe (request, response) e deve retornar o objeto de resposta (possivelmente modificado). Retorna f inalterada.

after_error_request(f: Callable) Callable#

Decorador que registra f para ser executada após o Microdot gerar uma resposta de erro (404, 500, exceção levantada, etc.). f recebe (request, response) e deve retornar o objeto de resposta (possivelmente modificado). Retorna f inalterada.

errorhandler(status_code_or_exception_class) Callable#

Decorador que registra um manipulador personalizado para um código de status HTTP ou uma classe de exceção do Python. Para códigos de status, o manipulador recebe apenas a requisição; para classes de exceção, (request, exception). Retorna o decorador.

Montagem e aborto

mount(subapp: Microdot, url_prefix: str = '', local: bool = False) None#

Anexa as rotas de outra instância de Microdot sob url_prefix. Quando local é False (padrão), os manipuladores before / after / error da sub-aplicação também são anexados à aplicação pai. Quando True, esses manipuladores são executados apenas para as rotas da sub-aplicação. Retorna None.

static abort(status_code: int, reason: str | None = None) None#

Levante HTTPException para abortar a requisição atual com o código de status fornecido. Nunca retorna normalmente – o framework captura a exceção e a transforma na resposta de erro correspondente. Conveniente dentro dos corpos de rota:

from microdot import abort

@app.get('/users/<int:id>')
def get_user(request, id):
    user = lookup(id)
    if user is None:
        abort(404)
    return user.to_dict()

Executando o servidor

run(host: str = '0.0.0.0', port: int = 5000, debug: bool = False, ssl=None) None#

Bloqueia a thread chamadora, executa asyncio.run() em start_server(). Retorna None somente depois que shutdown() tiver sido chamado e o laço de escuta encerrar. A forma mais simples de iniciar uma aplicação autônoma:

app.run(host='0.0.0.0', port=80)
async start_server(host: str = '0.0.0.0', port: int = 5000, debug: bool = False, ssl=None, start_serving: bool = True) None#

Inicia o servidor como uma corrotina. Use isto ao integrar com um laço de eventos asyncio existente junto a outras tarefas. A corrotina não retorna até que shutdown() seja chamado:

async def main():
    await asyncio.gather(
        app.start_server(port=80),
        capture_loop(),
    )
host

Interface de rede na qual escutar. '0.0.0.0' (padrão) significa todas as interfaces; '127.0.0.1' significa apenas loopback.

port

Porta TCP na qual escutar. Padrão 5000 – escolha 80 para HTTP simples, 443 para HTTPS.

debug

Se True, registra cada requisição e despeja os tracebacks na saída padrão.

ssl

Um ssl.SSLContext para envolver as conexões recebidas em TLS. None (padrão) significa HTTP simples.

start_serving

Relevante apenas no CPython; ignorado no MicroPython.

shutdown() None#

Solicita um desligamento gracioso do servidor. É seguro chamar a partir de um manipulador de rota – a requisição atual é concluída antes de o laço encerrar. Retorna imediatamente; o desligamento de fato ocorre assim que a requisição em andamento termina.

Atributos

url_map: list#

Lista das rotas registradas como tuplas (methods, URLPattern, handler, url_prefix, subapp).

before_request_handlers: list#

Lista de chamáveis registrados com before_request(), na ordem de registro. Cada um é executado com o objeto de requisição antes do manipulador de rota. Modificar a lista diretamente funciona, mas raramente é necessário – prefira o decorador.

after_request_handlers: list#

Lista de chamáveis registrados com after_request(), na ordem de registro. Cada um é executado com (request, response) após uma requisição bem-sucedida e deve retornar a resposta (possivelmente modificada).

after_error_request_handlers: list#

Lista de chamáveis registrados com after_error_request(), na ordem de registro. Cada um é executado com (request, response) após a geração de uma resposta de erro (pelo framework ou por um manipulador de erro da aplicação) e deve retornar a resposta.

error_handlers: dict#

Mapeamento de chaves de erro para chamáveis manipuladores, populado por errorhandler(). As chaves são códigos de status HTTP (int) ou classes de exceção do Python; os valores são os manipuladores registrados. Manipuladores de código de status recebem (request); manipuladores de classe de exceção recebem (request, exception).

debug: bool#

True enquanto o servidor estiver rodando com debug=True.

class Request#

class microdot.Request#

Uma requisição HTTP recebida. As instâncias são passadas aos manipuladores de rota como o primeiro argumento posicional. As aplicações não constroem Request diretamente.

Atributos de classe

max_content_length: int#

Rejeita requisições cujo Content-Length excede esta quantidade de bytes com uma resposta 413. Padrão 16 KB.

max_body_length: int#

Maior corpo que é armazenado em buffer na memória e exposto via body. Corpos maiores (até max_content_length) permanecem no socket e devem ser lidos através de stream. Padrão 16 KB.

max_readline: int#

Comprimento máximo de uma única linha de requisição / linha de cabeçalho em bytes. Padrão 2 KB.

Atributos de instância

app: Microdot#

A instância de Microdot que está tratando a requisição.

client_addr: tuple#

O endereço do cliente como (host, port).

method: str#

String do método HTTP ('GET', 'POST', …).

scheme: str#

'http' ou 'https'.

url: str#

O caminho completo da URL da requisição e a query string (tudo após o host).

path: str#

Apenas a parte do caminho.

query_string: str | None#

A query string bruta, ou None.

args: MultiDict#

A query string analisada como um MultiDict.

headers: NoCaseDict#

Os cabeçalhos da requisição como um NoCaseDict (busca sem distinção entre maiúsculas e minúsculas).

cookies: dict#

O cabeçalho Cookie analisado como um dict.

content_length: int#

O valor inteiro de Content-Length, ou 0 se ausente.

content_type: str | None#

O valor do cabeçalho Content-Type, ou None.

g: object#

Um contêiner de formato livre por requisição (um objeto vazio). Atribua atributos a ele para passar valores entre hooks e manipuladores (request.g.user = ...).

route: Callable#

A função manipuladora que correspondeu a esta requisição.

url_prefix: str#

O prefixo sob o qual a rota foi montada, ou ''.

subapp: Microdot | None#

A instância da sub-aplicação montada, ou None.

Acesso ao corpo

body: bytes#

O corpo completo da requisição como bytes. Vazio quando o corpo está sendo transmitido em stream (veja stream).

stream: object#

Um objeto de stream assíncrono que expõe read() sobre o corpo. Use isto para corpos maiores que max_body_length.

json: dict | list | str | int | float | bool | None#

O corpo analisado como JSON (um dict, list, str, int, float ou bool – o que quer que o payload codifique), ou None se o Content-Type não for application/json.

form: MultiDict | None#

Campos de formulário codificados em URL como um MultiDict, ou None. Para multipart/form-data, decore a rota com microdot.multipart.with_form_data().

files: dict | None#

Arquivos enviados como {name: FileUpload}, populado por microdot.multipart.with_form_data(). None até que esse decorador seja executado.

after_request(f: Callable) Callable#

Registra um hook after-request local à requisição – executado após os manipuladores after-request de nível de aplicação, apenas em caso de sucesso. f recebe (request, response) e deve retornar o objeto de resposta (possivelmente modificado). Retorna f inalterada.

class Response#

class microdot.Response(body=b'', status_code: int = 200, headers: dict | None = None, reason: str | None = None)#

Uma resposta HTTP. A maioria dos manipuladores retorna valores que o Microdot converte automaticamente em um Response; construa um diretamente quando precisar de cabeçalhos personalizados ou de um código de status específico.

body

Corpo da resposta. str é codificado em UTF-8; dict / list é codificado em JSON e o Content-Type é definido de acordo; bytes é enviado como está; um objeto semelhante a arquivo ou um gerador assíncrono é transmitido em stream.

status_code

Status HTTP numérico. Padrão 200.

headers

Dict de cabeçalhos da resposta (sem distinção entre maiúsculas e minúsculas).

reason

Frase de motivo personalizada. O padrão é "OK" para 200 e "N/A" caso contrário.

Atributos de classe

default_content_type: str#

Content-Type usado quando nenhum é definido explicitamente. Padrão 'text/plain'.

default_send_file_max_age: int | None#

Valor de Cache-Control: max-age para send_file() quando max_age não é fornecido. None (padrão) significa nenhum cabeçalho Cache-Control.

send_file_buffer_size: int#

Tamanho do bloco para o streaming de send_file(). Padrão 1024.

already_handled: None#

Sentinela retornado por manipuladores que já escreveram a resposta diretamente (usado por upgrades de WebSocket). Sempre None; o que importa é a identidade.

types_map: dict#

Mapa de extensão para tipo mime usado por send_file() para inferência do tipo de conteúdo. Mapeia css, gif, html, jpg, js, json, png, txt, svg.

Métodos

Adiciona um cabeçalho Set-Cookie. expires pode ser uma string pré-formatada ou um objeto semelhante a datetime com timetuple(). Retorna None; o cabeçalho é anexado a esta resposta no local.

Define um Set-Cookie que expira o cookie indicado imediatamente. kwargs aceita as mesmas opções que set_cookie() (path, domain, secure, http_only, partitioned); expires e max_age são ignorados. Retorna None; o cabeçalho é anexado a esta resposta no local.

classmethod redirect(location: str, status_code: int = 302) Response#

Retorna uma resposta de redirecionamento:

@app.get('/old')
def old(request):
    return Response.redirect('/new')
classmethod send_file(filename: str, status_code: int = 200, content_type: str | None = None, stream=None, max_age: int | None = None, compressed: bool | str = False, file_extension: str = '') Response#

Transmite um arquivo do sistema de arquivos como o corpo da resposta. content_type é inferido a partir da extensão via types_map se não for fornecido. compressed=True define Content-Encoding: gzip (o arquivo já deve estar comprimido).

Aviso

filename é aberto diretamente. Nunca passe um caminho fornecido pelo usuário sem sanitização – fazer isso permite a divulgação arbitrária de arquivos.

Exceções#

exception microdot.HTTPException#

Levantada por abort() para interromper antecipadamente uma requisição com um código de status específico. O Microdot captura isso e a transforma na resposta de erro correspondente.

status_code: int#

Código de status HTTP numérico a retornar – o valor passado para abort().

reason: str#

Frase de motivo a incluir na resposta de erro. Se não for fornecida a abort(), o padrão é "<status_code> error" (por exemplo, "404 error").

class URLPattern#

class microdot.URLPattern(url_pattern: str)#

A forma compilada do padrão de URL de uma rota. Construída automaticamente por Microdot.route(); as aplicações raramente instanciam uma diretamente.

classmethod register_type(type_name: str, pattern: str = '[^/]+', parser: Callable | None = None) None#

Registra um novo tipo de segmento dinâmico para uso em padrões de rota. Retorna None; o tipo é adicionado ao registro de tipos de nível de classe. Por exemplo, para adicionar um tipo <uuid:...>

URLPattern.register_type('uuid', '[0-9a-f-]{36}')

parser é um chamável opcional que converte a string capturada antes que ela chegue ao manipulador.

match(path: str) dict | None#

Corresponde path ao padrão e retorna um dict dos grupos capturados, ou None se não houver correspondência.

Classes auxiliares#

class microdot.MultiDict(initial_dict: dict | None = None)#

Uma subclasse de dict que armazena múltiplos valores por chave. Usada para query strings e corpos de formulário codificados em URL, onde a mesma chave pode aparecer mais de uma vez (?tag=a&tag=b).

get(key, default=None, type: Callable | None = None)#

Retorna o primeiro valor para key, opcionalmente convertido com type (um chamável). Retorna default se a chave estiver ausente ou a conversão falhar; caso contrário, retorna o valor (opcionalmente convertido).

getlist(key, type: Callable | None = None) list#

Retorna todos os valores para key como uma lista, opcionalmente com cada valor convertido por type. Retorna uma lista vazia se key não estiver presente.

class microdot.NoCaseDict#

Uma subclasse de dict com chaves de string sem distinção entre maiúsculas e minúsculas. Usada para Request.headers e Response.headers.

Funções de nível de módulo#

microdot.abort(status_code: int, reason: str | None = None) None#

Atalho para Microdot.abort(). Nunca retorna normalmente – levanta HTTPException. Importável como from microdot import abort.

microdot.redirect(location: str, status_code: int = 302) Response#

Atalho para Response.redirect(). Importável como from microdot import redirect.

microdot.send_file(filename: str, **kwargs) Response#

Atalho para Response.send_file().

microdot.urlencode(s: str) str#

Codifica em percent-encoding um componente de URL. Substitui os caracteres que têm significado reservado em uma URL (/, ?, &, =, #, espaço, …) por seus escapes hexadecimais %xx, de modo que o resultado possa ser usado com segurança dentro de um segmento de caminho ou de um valor de query. Retorna a str codificada.

microdot.urldecode(s: str) str#

Decodifica de percent-encoding um componente de URL – o inverso de urlencode(). Os escapes %xx são substituídos pelo byte que codificam, e + é convertido em espaço (a convenção histórica de query string). Retorna a str decodificada.

Submódulos#