microdot — framework HTTP minimalista#
Microdot es un framework HTTP pequeño, inspirado en Flask, para MicroPython. Se ejecuta sobre asyncio, gestiona múltiples clientes concurrentes sin hilos y expone una API familiar de decoradores de rutas. Una aplicación mínima tiene este aspecto:
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#
Una instancia de aplicación HTTP. Se construye una instancia cerca del comienzo del script y se decora con manejadores de rutas; al llamar a
run()o esperar astart_server()comienza el servicio.Registro de rutas
- route(url_pattern: str, methods: list | None = None) Callable#
Decorador que registra un manejador para url_pattern bajo los métodos HTTP indicados (por defecto
['GET']). Devuelve el decorador que, al aplicarse a una función, la registra como manejador y devuelve la función sin cambios.- url_pattern
Un patrón de ruta. Admite segmentos estáticos (
/users) y segmentos dinámicos delimitados por</>. Los segmentos dinámicos aceptan un prefijo de tipo opcional separado por:–<int:id>,<path:rest>,<re:[0-9a-f]+:hex>. El tipo por defecto esstring.- methods
Lista de nombres de métodos HTTP. Si se omite, solo se compara
GET.
El manejador se llama primero con el objeto de la solicitud y luego con los segmentos dinámicos capturados como argumentos de palabra clave. El valor de retorno del manejador se convierte en la respuesta HTTP: una
Response, una cadena, una tupla(body, status_code[, headers]), o un dict / list (enviado como JSON).
- get(url_pattern: str) Callable#
Alias de conveniencia para
route(url_pattern, methods=['GET'])– registra la función decorada como un manejadorGETpara url_pattern. Devuelve el decorador.
- post(url_pattern: str) Callable#
Alias de conveniencia para
route(url_pattern, methods=['POST'])– registra la función decorada como un manejadorPOSTpara url_pattern. Devuelve el decorador.
- put(url_pattern: str) Callable#
Alias de conveniencia para
route(url_pattern, methods=['PUT'])– registra la función decorada como un manejadorPUTpara url_pattern. Devuelve el decorador.
- patch(url_pattern: str) Callable#
Alias de conveniencia para
route(url_pattern, methods=['PATCH'])– registra la función decorada como un manejadorPATCHpara url_pattern. Devuelve el decorador.
- delete(url_pattern: str) Callable#
Alias de conveniencia para
route(url_pattern, methods=['DELETE'])– registra la función decorada como un manejadorDELETEpara url_pattern. Devuelve el decorador.
Hooks del ciclo de vida
- before_request(f: Callable) Callable#
Decorador que registra f para ejecutarse antes de cada solicitud. f toma el objeto de la solicitud; su valor de retorno normalmente se ignora. Para cortocircuitar la solicitud, devuelve una
Response(o un valor que se convierta en una) – el resto del pipeline se omite entonces y se envía esa respuesta. Devuelve f sin cambios.
- after_request(f: Callable) Callable#
Decorador que registra f para ejecutarse después de cada solicitud exitosa. f toma
(request, response)y debe devolver el objeto de respuesta (posiblemente modificado). Devuelve f sin cambios.
- after_error_request(f: Callable) Callable#
Decorador que registra f para ejecutarse después de que Microdot genere una respuesta de error (404, 500, excepción lanzada, etc.). f toma
(request, response)y debe devolver el objeto de respuesta (posiblemente modificado). Devuelve f sin cambios.
- errorhandler(status_code_or_exception_class) Callable#
Decorador que registra un manejador personalizado para un código de estado HTTP o una clase de excepción de Python. Para los códigos de estado, el manejador toma solo la solicitud; para las clases de excepción,
(request, exception). Devuelve el decorador.
Montaje y aborto
- mount(subapp: Microdot, url_prefix: str = '', local: bool = False) None#
Adjunta las rutas de otra instancia
Microdotbajo url_prefix. Cuando local esFalse(por defecto), los manejadores before / after / error de la subaplicación también se adjuntan al padre. Cuando esTrue, esos manejadores se ejecutan solo para las rutas de la subaplicación. DevuelveNone.
- static abort(status_code: int, reason: str | None = None) None#
Lanza
HTTPExceptionpara abortar la solicitud actual con el código de estado dado. Nunca retorna de forma normal – el framework captura la excepción y la convierte en la respuesta de error correspondiente. Cómodo dentro de los cuerpos de las rutas: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()
Ejecución del servidor
- run(host: str = '0.0.0.0', port: int = 5000, debug: bool = False, ssl=None) None#
Bloquea el hilo que llama, ejecuta
asyncio.run()sobrestart_server(). DevuelveNonesolo después de que se haya llamado ashutdown()y el bucle de escucha salga. La forma más sencilla de lanzar una aplicación independiente: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 el servidor como una corrutina. Usa esto al integrarlo con un bucle de eventos
asyncioexistente junto con otras tareas. La corrutina no retorna hasta que se llama ashutdown():async def main(): await asyncio.gather( app.start_server(port=80), capture_loop(), )
- host
Interfaz de red en la que escuchar.
'0.0.0.0'(por defecto) significa todas las interfaces;'127.0.0.1'significa solo loopback.- port
Puerto TCP en el que escuchar. Por defecto
5000– elige80para HTTP simple,443para HTTPS.- debug
Si es
True, registra cada solicitud y vuelca los trazados de pila a stdout.- ssl
Un
ssl.SSLContextpara envolver las conexiones entrantes en TLS.None(por defecto) significa HTTP simple.- start_serving
Solo relevante en CPython; se ignora en MicroPython.
- shutdown() None#
Solicita un apagado ordenado del servidor. Es seguro llamarlo desde un manejador de ruta – la solicitud actual se completa antes de que el bucle salga. Retorna de inmediato; el apagado real ocurre una vez que termina la solicitud en curso.
Atributos
- url_map: list#
Lista de rutas registradas como tuplas
(methods, URLPattern, handler, url_prefix, subapp).
- before_request_handlers: list#
Lista de invocables registrados con
before_request(), en orden de registro. Cada uno se ejecuta con el objeto de la solicitud antes del manejador de ruta. Mutar la lista directamente funciona pero rara vez es necesario – es preferible el decorador.
- after_request_handlers: list#
Lista de invocables registrados con
after_request(), en orden de registro. Cada uno se ejecuta con(request, response)después de una solicitud exitosa y debe devolver la respuesta (posiblemente modificada).
- after_error_request_handlers: list#
Lista de invocables registrados con
after_error_request(), en orden de registro. Cada uno se ejecuta con(request, response)después de que se genera una respuesta de error (por el framework o por un manejador de errores de la aplicación) y debe devolver la respuesta.
- error_handlers: dict#
Mapeo de claves de error a invocables manejadores, poblado por
errorhandler(). Las claves son códigos de estado HTTP (int) o clases de excepción de Python; los valores son los manejadores registrados. Los manejadores de códigos de estado toman(request); los manejadores de clases de excepción toman(request, exception).
class Request#
- class microdot.Request#
Una solicitud HTTP entrante. Las instancias se pasan a los manejadores de ruta como primer argumento posicional. Las aplicaciones no construyen
Requestdirectamente.Atributos de clase
- max_content_length: int#
Rechaza con una respuesta 413 las solicitudes cuyo
Content-Lengthsupere esta cantidad de bytes. Por defecto 16 KB.
- max_body_length: int#
El cuerpo más grande que se almacena en memoria y se expone a través de
body. Los cuerpos más grandes (hastamax_content_length) permanecen en el socket y deben leerse a través destream. Por defecto 16 KB.
- max_readline: int#
Longitud máxima de una sola línea de solicitud / línea de cabecera en bytes. Por defecto 2 KB.
Atributos de instancia
- url: str#
La ruta y cadena de consulta completas de la URL de la solicitud (todo lo que va después del host).
- headers: NoCaseDict#
Cabeceras de la solicitud como un
NoCaseDict(búsqueda sin distinción de mayúsculas/minúsculas).
- g: object#
Un contenedor de formato libre por solicitud (un objeto vacío). Asigna atributos a él para pasar valores entre los hooks y los manejadores (
request.g.user = ...).
- route: Callable#
La función manejadora que coincidió con esta solicitud.
Acceso al cuerpo
- body: bytes#
El cuerpo completo de la solicitud como
bytes. Vacío cuando el cuerpo se está transmitiendo en streaming (verstream).
- stream: object#
Un objeto de stream asíncrono que expone
read()sobre el cuerpo. Úsalo para cuerpos más grandes quemax_body_length.
- json: dict | list | str | int | float | bool | None#
El cuerpo analizado como JSON (un
dict,list,str,int,floatobool– lo que codifique la carga útil), oNonesi elContent-Typeno esapplication/json.
- form: MultiDict | None#
Campos de formulario codificados en URL como un
MultiDict, oNone. Paramultipart/form-data, decora la ruta conmicrodot.multipart.with_form_data().
- files: dict | None#
Archivos subidos como
{name: FileUpload}, poblado pormicrodot.multipart.with_form_data(). EsNonehasta que se ejecuta ese decorador.
- after_request(f: Callable) Callable#
Registra un hook after-request local a la solicitud – se ejecuta después de los manejadores after-request a nivel de aplicación, solo en caso de éxito. f toma
(request, response)y debe devolver el objeto de respuesta (posiblemente modificado). Devuelve f sin cambios.
class Response#
- class microdot.Response(body=b'', status_code: int = 200, headers: dict | None = None, reason: str | None = None)#
Una respuesta HTTP. La mayoría de los manejadores devuelven valores que Microdot convierte automáticamente en una
Response; constrúyela directamente cuando necesites cabeceras personalizadas o un código de estado específico.- body
Cuerpo de la respuesta.
strse codifica en UTF-8;dict/listse codifica como JSON y elContent-Typese establece en consecuencia;bytesse envía tal cual; un objeto tipo archivo o un generador asíncrono se transmiten en streaming.- status_code
Estado HTTP numérico. Por defecto 200.
- headers
Dict de cabeceras de respuesta (sin distinción de mayúsculas/minúsculas).
- reason
Frase de motivo personalizada. Por defecto es
"OK"para 200 y"N/A"en caso contrario.
Atributos de clase
- default_content_type: str#
Content-Type usado cuando no se establece ninguno explícitamente. Por defecto
'text/plain'.
- default_send_file_max_age: int | None#
Valor de
Cache-Control: max-ageparasend_file()cuando no se proporcionamax_age.None(por defecto) significa sin cabecera Cache-Control.
- send_file_buffer_size: int#
Tamaño de fragmento para el streaming de
send_file(). Por defecto 1024.
- already_handled: None#
Centinela devuelto por los manejadores que ya han escrito la respuesta directamente (usado por las actualizaciones a WebSocket). Siempre
None; lo que importa es la identidad.
- types_map: dict#
Mapa de extensión a tipo MIME usado por
send_file()para inferir el tipo de contenido. Mapeacss,gif,html,jpg,js,json,png,txt,svg.
Métodos
- set_cookie(cookie: str, value: str, path: str | None = None, domain: str | None = None, expires=None, max_age: int | None = None, secure: bool = False, http_only: bool = False, partitioned: bool = False) None#
Añade una cabecera
Set-Cookie. expires puede ser una cadena ya formateada o un objeto similar adatetimecontimetuple(). DevuelveNone; la cabecera se añade a esta respuesta en el sitio.
- delete_cookie(cookie: str, **kwargs) None#
Establece un
Set-Cookieque expira inmediatamente la cookie dada.kwargsacepta las mismas opciones queset_cookie()(path,domain,secure,http_only,partitioned);expiresymax_agese ignoran. DevuelveNone; la cabecera se añade a esta respuesta en el sitio.
- classmethod redirect(location: str, status_code: int = 302) Response#
Devuelve una respuesta de redirección:
@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 en streaming un archivo del sistema de archivos como cuerpo de la respuesta.
content_typese infiere de la extensión a través detypes_mapsi no se proporciona.compressed=TrueestableceContent-Encoding: gzip(el archivo ya debe estar comprimido).Advertencia
filename se abre directamente. Nunca pases una ruta proporcionada por el usuario sin sanear – hacerlo permite la divulgación arbitraria de archivos.
Excepciones#
class URLPattern#
- class microdot.URLPattern(url_pattern: str)#
La forma compilada del patrón de URL de una ruta. Construida automáticamente por
Microdot.route(); las aplicaciones rara vez instancian una directamente.- classmethod register_type(type_name: str, pattern: str = '[^/]+', parser: Callable | None = None) None#
Registra un nuevo tipo de segmento dinámico para usar en los patrones de ruta. Devuelve
None; el tipo se añade al registro de tipos a nivel de clase. Por ejemplo, para añadir un tipo<uuid:...>:URLPattern.register_type('uuid', '[0-9a-f-]{36}')parser es un invocable opcional que convierte la cadena capturada antes de que llegue al manejador.
Clases auxiliares#
- class microdot.MultiDict(initial_dict: dict | None = None)#
Una subclase de dict que almacena múltiples valores por clave. Se usa para las cadenas de consulta y los cuerpos de formulario codificados en URL donde la misma clave puede aparecer más de una vez (
?tag=a&tag=b).
- class microdot.NoCaseDict#
Una subclase de dict con claves de cadena sin distinción de mayúsculas/minúsculas. Se usa para
Request.headersyResponse.headers.
Funciones a nivel de módulo#
- microdot.abort(status_code: int, reason: str | None = None) None#
Atajo para
Microdot.abort(). Nunca retorna de forma normal – lanzaHTTPException. Importable comofrom microdot import abort.
- microdot.redirect(location: str, status_code: int = 302) Response#
Atajo para
Response.redirect(). Importable comofrom microdot import redirect.
- microdot.send_file(filename: str, **kwargs) Response#
Atajo para
Response.send_file().
- microdot.urlencode(s: str) str#
Codifica en porcentaje un componente de URL. Reemplaza los caracteres que tienen un significado reservado en una URL (
/,?,&,=,#, espacio, …) con sus escapes hexadecimales%xxpara que el resultado pueda situarse de forma segura dentro de un segmento de ruta o un valor de consulta. Devuelve elstrcodificado.
- microdot.urldecode(s: str) str#
Decodifica en porcentaje un componente de URL – el inverso de
urlencode(). Los escapes%xxse reemplazan por el byte que codifican, y+se convierte en un espacio (la convención histórica de las cadenas de consulta). Devuelve elstrdecodificado.
Submódulos#
microdot.auth— Autenticación HTTPmicrodot.cors— Intercambio de recursos de origen cruzadomicrodot.csrf— Protección CSRFmicrodot.login— flujo de inicio de sesión de usuariomicrodot.multipart— análisis de multipart/form-datamicrodot.session— sesiones de cookies firmadasmicrodot.sse— Server-Sent Eventsmicrodot.websocket— compatibilidad con WebSocket