microdot — framework HTTP minimaliste

Microdot est un petit framework HTTP inspiré de Flask pour MicroPython. Il s’appuie sur asyncio, gère plusieurs clients simultanés sans threads et expose une API de décorateurs de routes familière. Une application minimale ressemble à ceci

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

Une instance d’application HTTP. Une instance est construite près du début du script et décorée avec des gestionnaires de routes ; l’appel de run() ou l’attente de start_server() lance le service.

Enregistrement de routes

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

Décorateur qui enregistre un gestionnaire pour url_pattern sous les méthodes HTTP indiquées (par défaut ['GET']). Renvoie le décorateur qui, lorsqu’il est appliqué à une fonction, l’enregistre comme gestionnaire et renvoie la fonction inchangée.

url_pattern

Un motif de chemin. Prend en charge les segments statiques (/users) et les segments dynamiques encadrés par < / >. Les segments dynamiques acceptent un préfixe de type optionnel séparé par :<int:id>, <path:rest>, <re:[0-9a-f]+:hex>. Le type par défaut est string.

methods

Liste de noms de méthodes HTTP. Si elle est omise, seul GET est reconnu.

Le gestionnaire est appelé d’abord avec l’objet de requête, puis avec les éventuels segments dynamiques capturés en tant qu’arguments nommés. La valeur de retour du gestionnaire devient la réponse HTTP : une Response, une chaîne, un tuple (body, status_code[, headers]) ou un dict / liste (envoyé en JSON).

get(url_pattern: str) Callable

Alias pratique pour route(url_pattern, methods=['GET']) – enregistre la fonction décorée comme gestionnaire GET pour url_pattern. Renvoie le décorateur.

post(url_pattern: str) Callable

Alias pratique pour route(url_pattern, methods=['POST']) – enregistre la fonction décorée comme gestionnaire POST pour url_pattern. Renvoie le décorateur.

put(url_pattern: str) Callable

Alias pratique pour route(url_pattern, methods=['PUT']) – enregistre la fonction décorée comme gestionnaire PUT pour url_pattern. Renvoie le décorateur.

patch(url_pattern: str) Callable

Alias pratique pour route(url_pattern, methods=['PATCH']) – enregistre la fonction décorée comme gestionnaire PATCH pour url_pattern. Renvoie le décorateur.

delete(url_pattern: str) Callable

Alias pratique pour route(url_pattern, methods=['DELETE']) – enregistre la fonction décorée comme gestionnaire DELETE pour url_pattern. Renvoie le décorateur.

Crochets de cycle de vie

before_request(f: Callable) Callable

Décorateur qui enregistre f pour qu’elle s’exécute avant chaque requête. f prend l’objet de requête ; sa valeur de retour est normalement ignorée. Pour court-circuiter la requête, renvoyez une Response (ou une valeur qui se convertit en une) – le reste du pipeline est alors ignoré et cette réponse est envoyée. Renvoie f inchangée.

after_request(f: Callable) Callable

Décorateur qui enregistre f pour qu’elle s’exécute après chaque requête réussie. f prend (request, response) et doit renvoyer l’objet de réponse (éventuellement modifié). Renvoie f inchangée.

after_error_request(f: Callable) Callable

Décorateur qui enregistre f pour qu’elle s’exécute après que Microdot a généré une réponse d’erreur (404, 500, exception levée, etc.). f prend (request, response) et doit renvoyer l’objet de réponse (éventuellement modifié). Renvoie f inchangée.

errorhandler(status_code_or_exception_class) Callable

Décorateur qui enregistre un gestionnaire personnalisé pour un code de statut HTTP ou une classe d’exception Python. Pour les codes de statut, le gestionnaire ne prend que la requête ; pour les classes d’exception, (request, exception). Renvoie le décorateur.

Montage et interruption

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

Attache les routes d’une autre instance Microdot sous url_prefix. Lorsque local vaut False (par défaut), les gestionnaires before / after / error de la sous-application sont également attachés au parent. Lorsqu’il vaut True, ces gestionnaires ne s’exécutent que pour les routes de la sous-application. Renvoie None.

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

Levez HTTPException pour interrompre la requête en cours avec le code de statut donné. Ne renvoie jamais normalement – le framework intercepte l’exception et la transforme en la réponse d’erreur correspondante. Pratique à l’intérieur du corps des routes

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()

Exécution du serveur

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

Bloque le thread appelant et exécute asyncio.run() sur start_server(). Ne renvoie None qu’après l’appel de shutdown() et la sortie de la boucle d’écoute. La manière la plus simple de lancer une application autonome

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

Démarre le serveur sous forme de coroutine. À utiliser lors de l’intégration à une boucle d’événements asyncio existante aux côtés d’autres tâches. La coroutine ne se termine pas tant que shutdown() n’est pas appelée

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

Interface réseau sur laquelle écouter. '0.0.0.0' (par défaut) signifie toutes les interfaces ; '127.0.0.1' signifie uniquement le bouclage.

port

Port TCP sur lequel écouter. Par défaut 5000 – choisissez 80 pour du HTTP simple, 443 pour du HTTPS.

debug

Si True, journalise chaque requête et affiche les traces de la pile sur la sortie standard.

ssl

Un ssl.SSLContext pour encapsuler les connexions entrantes dans du TLS. None (par défaut) signifie du HTTP simple.

start_serving

Pertinent uniquement sous CPython ; ignoré sous MicroPython.

shutdown() None

Demande un arrêt gracieux du serveur. Peut être appelée sans danger depuis un gestionnaire de route – la requête en cours se termine avant la sortie de la boucle. Renvoie immédiatement ; l’arrêt effectif a lieu une fois la requête en cours terminée.

Attributs

url_map: list

Liste des routes enregistrées sous forme de tuples (methods, URLPattern, handler, url_prefix, subapp).

before_request_handlers: list

Liste des appelables enregistrés avec before_request(), dans l’ordre d’enregistrement. Chacun s’exécute avec l’objet de requête avant le gestionnaire de route. Modifier la liste directement fonctionne mais est rarement nécessaire – préférez le décorateur.

after_request_handlers: list

Liste des appelables enregistrés avec after_request(), dans l’ordre d’enregistrement. Chacun s’exécute avec (request, response) après une requête réussie et doit renvoyer la réponse (éventuellement modifiée).

after_error_request_handlers: list

Liste des appelables enregistrés avec after_error_request(), dans l’ordre d’enregistrement. Chacun s’exécute avec (request, response) après la génération d’une réponse d’erreur (par le framework ou par un gestionnaire d’erreur de l’application) et doit renvoyer la réponse.

error_handlers: dict

Correspondance entre des clés d’erreur et des appelables gestionnaires, peuplée par errorhandler(). Les clés sont soit des codes de statut HTTP (int), soit des classes d’exception Python ; les valeurs sont les gestionnaires enregistrés. Les gestionnaires de codes de statut prennent (request) ; les gestionnaires de classes d’exception prennent (request, exception).

debug: bool

True tant que le serveur s’exécute avec debug=True.

class Request

class microdot.Request

Une requête HTTP entrante. Les instances sont transmises aux gestionnaires de routes comme premier argument positionnel. Les applications ne construisent pas directement de Request.

Attributs de classe

max_content_length: int

Rejette avec une réponse 413 les requêtes dont le Content-Length dépasse ce nombre d’octets. Par défaut 16 Ko.

max_body_length: int

Plus grand corps mis en mémoire tampon et exposé via body. Les corps plus volumineux (jusqu’à max_content_length) restent sur la socket et doivent être lus via stream. Par défaut 16 Ko.

max_readline: int

Longueur maximale d’une seule ligne de requête / ligne d’en-tête en octets. Par défaut 2 Ko.

Attributs d’instance

app: Microdot

L’instance Microdot qui traite la requête.

client_addr: tuple

L’adresse du client sous la forme (host, port).

method: str

Chaîne de méthode HTTP ('GET', 'POST', …).

scheme: str

'http' ou 'https'.

url: str

Le chemin d’URL complet de la requête et la chaîne de requête (tout ce qui suit l’hôte).

path: str

Uniquement la partie chemin.

query_string: str | None

La partie brute de la chaîne de requête, ou None.

args: MultiDict

La chaîne de requête analysée sous forme de MultiDict.

headers: NoCaseDict

Les en-têtes de la requête sous forme de NoCaseDict (recherche insensible à la casse).

cookies: dict

L’en-tête Cookie analysé sous forme de dict.

content_length: int

La valeur entière de Content-Length, ou 0 si absente.

content_type: str | None

La valeur de l’en-tête Content-Type, ou None.

g: object

Un conteneur libre propre à chaque requête (un objet nu). Assignez-lui des attributs pour transmettre des valeurs entre les crochets et les gestionnaires (request.g.user = ...).

route: Callable

La fonction gestionnaire qui a correspondu à cette requête.

url_prefix: str

Préfixe sous lequel la route a été montée, ou ''.

subapp: Microdot | None

L’instance de sous-application montée, ou None.

Accès au corps

body: bytes

Le corps complet de la requête sous forme de bytes. Vide lorsque le corps est diffusé en flux (voir stream).

stream: object

Un objet de flux asynchrone exposant read() sur le corps. À utiliser pour les corps plus volumineux que max_body_length.

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

Le corps analysé comme JSON (un dict, une list, une str, un int, un float ou un bool – selon ce qu’encode la charge utile), ou None si le Content-Type n’est pas application/json.

form: MultiDict | None

Les champs de formulaire encodés en URL sous forme de MultiDict, ou None. Pour multipart/form-data, décorez la route avec microdot.multipart.with_form_data().

files: dict | None

Les fichiers téléversés sous forme de {name: FileUpload}, peuplés par microdot.multipart.with_form_data(). None jusqu’à l’exécution de ce décorateur.

after_request(f: Callable) Callable

Enregistre un crochet after-request local à la requête – s’exécute après les gestionnaires after-request de niveau application, uniquement en cas de succès. f prend (request, response) et doit renvoyer l’objet de réponse (éventuellement modifié). Renvoie f inchangée.

class Response

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

Une réponse HTTP. La plupart des gestionnaires renvoient des valeurs que Microdot convertit automatiquement en Response ; construisez-en une directement lorsque vous avez besoin d’en-têtes personnalisés ou d’un code de statut spécifique.

body

Corps de la réponse. Une str est encodée en UTF-8 ; un dict / une list est encodé en JSON et le Content-Type est défini en conséquence ; les bytes sont envoyés tels quels ; un objet de type fichier ou un générateur asynchrone est diffusé en flux.

status_code

Statut HTTP numérique. Par défaut 200.

headers

Dict d’en-têtes de réponse (insensible à la casse).

reason

Phrase de motif personnalisée. Par défaut "OK" pour 200 et "N/A" sinon.

Attributs de classe

default_content_type: str

Content-Type utilisé lorsqu’aucun n’est défini explicitement. Par défaut 'text/plain'.

default_send_file_max_age: int | None

Valeur Cache-Control: max-age pour send_file() lorsque max_age n’est pas fourni. None (par défaut) signifie aucun en-tête Cache-Control.

send_file_buffer_size: int

Taille de bloc pour la diffusion en flux de send_file(). Par défaut 1024.

already_handled: None

Sentinelle renvoyée par les gestionnaires qui ont déjà écrit la réponse directement (utilisée par les mises à niveau WebSocket). Toujours None ; c’est l’identité qui importe.

types_map: dict

Table de correspondance extension-vers-type-mime utilisée par send_file() pour l’inférence du type de contenu. Couvre css, gif, html, jpg, js, json, png, txt, svg.

Méthodes

Ajoute un en-tête Set-Cookie. expires peut être une chaîne préformatée ou un objet de type datetime doté de timetuple(). Renvoie None ; l’en-tête est ajouté à cette réponse sur place.

Définit un Set-Cookie qui fait expirer immédiatement le cookie donné. kwargs accepte les mêmes options que set_cookie() (path, domain, secure, http_only, partitioned) ; expires et max_age sont ignorés. Renvoie None ; l’en-tête est ajouté à cette réponse sur place.

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

Renvoie une réponse de redirection

@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

Diffuse en flux un fichier du système de fichiers comme corps de la réponse. content_type est déduit de l’extension via types_map s’il n’est pas fourni. compressed=True définit Content-Encoding: gzip (le fichier doit déjà être compressé).

Avertissement

filename est ouvert directement. Ne transmettez jamais un chemin fourni par l’utilisateur non assaini – cela permettrait la divulgation arbitraire de fichiers.

Exceptions

exception microdot.HTTPException

Levée par abort() pour court-circuiter une requête avec un code de statut spécifique. Microdot l’intercepte et la transforme en la réponse d’erreur correspondante.

status_code: int

Code de statut HTTP numérique à renvoyer – la valeur transmise à abort().

reason: str

Phrase de motif à inclure dans la réponse d’erreur. Si elle n’est pas fournie à abort(), vaut par défaut "<status_code> error" (par ex. "404 error").

class URLPattern

class microdot.URLPattern(url_pattern: str)

La forme compilée du motif d’URL d’une route. Construite automatiquement par Microdot.route() ; les applications en instancient rarement une directement.

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

Enregistre un nouveau type de segment dynamique à utiliser dans les motifs de route. Renvoie None ; le type est ajouté au registre de types au niveau de la classe. Par exemple, pour ajouter un type <uuid:...>

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

parser est un appelable optionnel qui convertit la chaîne capturée avant qu’elle n’atteigne le gestionnaire.

match(path: str) dict | None

Confronte path au motif et renvoie un dict des groupes capturés, ou None en l’absence de correspondance.

Classes utilitaires

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

Une sous-classe de dict qui stocke plusieurs valeurs par clé. Utilisée pour les chaînes de requête et les corps de formulaire encodés en URL où la même clé peut apparaître plusieurs fois (?tag=a&tag=b).

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

Renvoie la première valeur pour key, éventuellement convertie avec type (un appelable). Renvoie default si la clé est absente ou si la conversion échoue ; sinon renvoie la valeur (éventuellement convertie).

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

Renvoie toutes les valeurs pour key sous forme de liste, éventuellement chaque valeur étant convertie par type. Renvoie une liste vide si key est absente.

class microdot.NoCaseDict

Une sous-classe de dict avec des clés de chaîne insensibles à la casse. Utilisée pour Request.headers et Response.headers.

Fonctions au niveau du module

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

Raccourci pour Microdot.abort(). Ne renvoie jamais normalement – lève HTTPException. Importable via from microdot import abort.

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

Raccourci pour Response.redirect(). Importable via from microdot import redirect.

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

Raccourci pour Response.send_file().

microdot.urlencode(s: str) str

Encode en pourcentage un composant d’URL. Remplace les caractères ayant une signification réservée dans une URL (/, ?, &, =, #, espace, …) par leurs échappements hexadécimaux %xx afin que le résultat puisse figurer sans danger dans un segment de chemin ou une valeur de requête. Renvoie la str encodée.

microdot.urldecode(s: str) str

Décode en pourcentage un composant d’URL – l’inverse de urlencode(). Les échappements %xx sont remplacés par l’octet qu’ils encodent, et + est converti en espace (la convention historique des chaînes de requête). Renvoie la str décodée.

Sous-modules