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