microdot — framework HTTP minimalista#

O Microdot é um pequeno framework HTTP para MicroPython inspirado no Flask. É executado sobre asyncio, gere múltiplos clientes concorrentes sem utilizar threads, e expõe uma API familiar baseada em decoradores de rotas. Uma aplicação mínima tem o seguinte aspeto:

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. Constrói-se uma instância perto do início do script e decora-se com handlers de rotas; chamar run() ou aguardar start_server() inicia o serviço.

Registo de rotas

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

Decorador que regista um handler para url_pattern sob os métodos HTTP indicados (predefinição ['GET']). Devolve o decorador que, quando aplicado a uma função, a regista como handler e devolve a função inalterada.

url_pattern

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

methods

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

O handler é chamado com o objeto de pedido em primeiro lugar, seguido de quaisquer segmentos dinâmicos capturados como argumentos de palavra-chave. O valor de retorno do handler torna-se a resposta HTTP: um Response, uma string, um tuplo (body, status_code[, headers]), ou um dict / lista (enviado como JSON).

get(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['GET']) – regista a função decorada como handler GET para url_pattern. Devolve o decorador.

post(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['POST']) – regista a função decorada como handler POST para url_pattern. Devolve o decorador.

put(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['PUT']) – regista a função decorada como handler PUT para url_pattern. Devolve o decorador.

patch(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['PATCH']) – regista a função decorada como handler PATCH para url_pattern. Devolve o decorador.

delete(url_pattern: str) Callable#

Alias de conveniência para route(url_pattern, methods=['DELETE']) – regista a função decorada como handler DELETE para url_pattern. Devolve o decorador.

Hooks de ciclo de vida

before_request(f: Callable) Callable#

Decorador que regista f para ser executada antes de cada pedido. f recebe o objeto de pedido; o seu valor de retorno é normalmente ignorado. Para curto-circuitar o pedido, retorne um Response (ou um valor que seja convertível para um) – o restante pipeline é então ignorado e essa resposta é enviada. Devolve f inalterada.

after_request(f: Callable) Callable#

Decorador que regista f para ser executada após cada pedido bem-sucedido. f recebe (request, response) e deve devolver o objeto de resposta (possivelmente modificado). Devolve f inalterada.

after_error_request(f: Callable) Callable#

Decorador que regista f para ser executada após o Microdot gerar uma resposta de erro (404, 500, exceção lançada, etc.). f recebe (request, response) e deve devolver o objeto de resposta (possivelmente modificado). Devolve f inalterada.

errorhandler(status_code_or_exception_class) Callable#

Decorador que regista um handler personalizado para um código de estado HTTP ou uma classe de exceção Python. Para códigos de estado, o handler recebe apenas o pedido; para classes de exceção, (request, exception). Devolve o decorador.

Montagem e abortar

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

Associa as rotas de outra instância Microdot sob url_prefix. Quando local é False (predefinição), os handlers before / after / error da sub-aplicação também são associados ao pai. Quando True, esses handlers são executados apenas para as rotas da sub-aplicação. Devolve None.

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

Lança HTTPException para abortar o pedido atual com o código de estado indicado. Nunca retorna normalmente – o framework captura a exceção e converte-a na resposta de erro correspondente. Conveniente no interior de 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()

Executar o servidor

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

Bloqueia a thread de chamada, executa asyncio.run() sobre start_server(). Devolve None apenas após shutdown() ter sido chamado e o ciclo de escuta terminar. A forma mais simples de lançar 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 ciclo de eventos asyncio existente juntamente com outras tarefas. A corrotina não retorna até shutdown() ser chamado:

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

Interface de rede a escutar. '0.0.0.0' (predefinição) significa todas as interfaces; '127.0.0.1' significa apenas loopback.

port

Porta TCP a escutar. Predefinição 5000 – use 80 para HTTP simples, 443 para HTTPS.

debug

Se True, regista cada pedido e imprime tracebacks para stdout.

ssl

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

start_serving

Relevante apenas no CPython; ignorado no MicroPython.

shutdown() None#

Solicita um encerramento gracioso do servidor. Seguro para chamar a partir de um handler de rota – o pedido atual é concluído antes do ciclo terminar. Retorna imediatamente; o encerramento efetivo ocorre assim que o pedido em curso terminar.

Atributos

url_map: list#

Lista de rotas registadas como tuplos (methods, URLPattern, handler, url_prefix, subapp).

before_request_handlers: list#

Lista de chamáveis registados com before_request(), por ordem de registo. Cada um é executado com o objeto de pedido antes do handler de rota. Alterar a lista diretamente é possível, mas raramente necessário – prefira o decorador.

after_request_handlers: list#

Lista de chamáveis registados com after_request(), por ordem de registo. Cada um é executado com (request, response) após um pedido bem-sucedido e deve devolver a resposta (possivelmente modificada).

after_error_request_handlers: list#

Lista de chamáveis registados com after_error_request(), por ordem de registo. Cada um é executado com (request, response) após ser gerada uma resposta de erro (pelo framework ou por um handler de erro da aplicação) e deve devolver a resposta.

error_handlers: dict#

Mapeamento de chaves de erro para chamáveis de handler, preenchido por errorhandler(). As chaves são códigos de estado HTTP (int) ou classes de exceção Python; os valores são os handlers registados. Os handlers de código de estado recebem (request); os handlers de classe de exceção recebem (request, exception).

debug: bool#

True enquanto o servidor está em execução com debug=True.

class Request#

class microdot.Request#

Um pedido HTTP recebido. As instâncias são passadas aos handlers de rota como primeiro argumento posicional. As aplicações não constroem Request diretamente.

Atributos de classe

max_content_length: int#

Rejeita pedidos cujo Content-Length exceda este número de bytes com uma resposta 413. Predefinição 16 KB.

max_body_length: int#

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

max_readline: int#

Comprimento máximo de uma linha de pedido / linha de cabeçalho em bytes. Predefinição 2 KB.

Atributos de instância

app: Microdot#

A instância Microdot que trata o pedido.

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 URL completo do pedido, incluindo caminho e query string (tudo após o host).

path: str#

Apenas a parte do caminho.

query_string: str | None#

A parte da query string em bruto, ou None.

args: MultiDict#

Query string analisada como MultiDict.

headers: NoCaseDict#

Cabeçalhos do pedido como NoCaseDict (pesquisa insensível a maiúsculas/minúsculas).

cookies: dict#

Cabeçalho Cookie analisado como 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 contentor de livre forma por pedido (um objeto simples). Atribua-lhe atributos para passar valores entre hooks e handlers (request.g.user = ...).

route: Callable#

A função de handler que correspondeu a este pedido.

url_prefix: str#

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 do pedido como bytes. Vazio quando o corpo está a ser transmitido em stream (ver 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 o payload codificar), ou None se o Content-Type não for application/json.

form: MultiDict | None#

Campos de formulário com codificação URL como MultiDict, ou None. Para multipart/form-data, decore a rota com microdot.multipart.with_form_data().

files: dict | None#

Ficheiros carregados como {name: FileUpload}, preenchido por microdot.multipart.with_form_data(). None até o decorador ser executado.

after_request(f: Callable) Callable#

Regista um hook after-request local ao pedido – executado após os handlers after-request ao nível da aplicação, apenas em caso de sucesso. f recebe (request, response) e deve devolver o objeto de resposta (possivelmente modificado). Devolve 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 handlers devolve valores que o Microdot converte automaticamente para Response; construa um diretamente quando precisar de cabeçalhos personalizados ou de um código de estado específico.

body

Corpo da resposta. str é codificado em UTF-8; dict / list é codificado como JSON e o Content-Type é definido em conformidade; bytes é enviado tal como está; um objeto do tipo ficheiro ou um gerador assíncrono transmite em stream.

status_code

Estado HTTP numérico. Predefinição 200.

headers

Dict de cabeçalhos de resposta (insensível a maiúsculas/minúsculas).

reason

Frase de razão personalizada. Predefinição "OK" para 200 e "N/A" caso contrário.

Atributos de classe

default_content_type: str#

Content-Type utilizado quando nenhum é definido explicitamente. Predefiniçã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 (predefinição) significa sem cabeçalho Cache-Control.

send_file_buffer_size: int#

Tamanho do bloco para streaming em send_file(). Predefinição 1024.

already_handled: None#

Sentinela devolvido por handlers que já escreveram a resposta diretamente (utilizado por upgrades WebSocket). Sempre None; é a identidade que importa.

types_map: dict#

Mapa de extensão para tipo MIME utilizado por send_file() para inferência de 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(). Devolve None; o cabeçalho é acrescentado 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. Devolve None; o cabeçalho é acrescentado a esta resposta no local.

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

Devolve 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 em stream um ficheiro do sistema de ficheiros como 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 ficheiro já deve estar comprimido).

Aviso

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

Exceções#

exception microdot.HTTPException#

Lançada por abort() para curto-circuitar um pedido com um código de estado específico. O Microdot captura esta exceção e converte-a na resposta de erro correspondente.

status_code: int#

Código de estado HTTP numérico a devolver – o valor passado a abort().

reason: str#

Frase de razão a incluir na resposta de erro. Se não for fornecida a abort(), tem como predefiniçã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ído automaticamente por Microdot.route(); as aplicações raramente instanciam um diretamente.

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

Regista um novo tipo de segmento dinâmico para utilização em padrões de rota. Devolve None; o tipo é adicionado ao registo de tipos ao nível da 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 de esta chegar ao handler.

match(path: str) dict | None#

Faz a correspondência de path com o padrão e devolve um dict de 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. Utilizada para query strings e corpos de formulário com codificação URL onde a mesma chave pode aparecer mais do que uma vez (?tag=a&tag=b).

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

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

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

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

class microdot.NoCaseDict#

Uma subclasse de dict com chaves de string insensíveis a maiúsculas/minúsculas. Utilizada para Request.headers e Response.headers.

Funções ao nível do módulo#

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

Atalho para Microdot.abort(). Nunca retorna normalmente – lança 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 percentagem um componente de URL. Substitui caracteres com significado reservado num URL (/, ?, &, =, #, espaço, …) pelos seus escapes hexadecimais %xx, para que o resultado possa ser colocado com segurança dentro de um segmento de caminho ou valor de query. Devolve a str codificada.

microdot.urldecode(s: str) str#

Descodifica em percentagem 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 das query strings). Devolve a str descodificada.

Submódulos#