microdot.multipart — analyse multipart/form-data

Analyse les corps de requête Content-Type: multipart/form-data – l’encodage que les navigateurs utilisent pour les formulaires comportant des champs <input type="file">. Deux variantes d’API :

  • Un FormDataIter en flux qui produit les champs un à la fois – utile lorsque l’application doit traiter de très grands téléversements morceau par morceau sur un appareil à mémoire limitée.

  • Un décorateur with_form_data() qui met tout en tampon et remplit request.form / request.files – l’API pratique pour les téléversements de taille normale.

class FormDataIter

class microdot.multipart.FormDataIter(request)

Itérateur asynchrone sur les parties du corps multipart de request. Les valeurs produites sont des tuples (name, value) ; value est un str pour les champs ordinaires et un FileUpload pour les champs de fichier.

Utilisé directement lorsque la mémoire importe plus que l’ergonomie

from microdot.multipart import FormDataIter, FileUpload

@app.post('/upload')
async def upload(request):
    async for name, value in FormDataIter(request):
        if isinstance(value, FileUpload):
            await value.save('/sdcard/' + value.filename)
        else:
            print(name, '=', value)
    return 'ok'

Note

Lors de l’itération sur les champs de fichier, le fichier doit être consommé (via FileUpload.read() ou FileUpload.save()) avant l’itération async for suivante – le flux sous-jacent est invalidé lorsque l’itération avance.

buffer_size: int

Attribut de classe. Taille de fragment utilisée lors de la lecture depuis le flux de la requête. Par défaut 256 octets. Augmentez-la pour un débit plus élevé au prix de la RAM.

class FileUpload

class microdot.multipart.FileUpload(filename: str, content_type: str | None, read)

Un seul fichier téléversé. Les instances sont produites par FormDataIter et collectées dans request.files par with_form_data(). Les applications ne construisent normalement pas FileUpload directement.

filename: str

Le nom d’origine du fichier tel que le client l’a envoyé (non fiable – ne le passez pas à open() sans l’assainir).

content_type: str | None

Le type MIME issu de l’en-tête Content-Type de la partie, ou None s’il n’est pas fourni.

max_memory_size: int

Attribut de classe. Seuil (en octets) au-delà duquel copy() passe d’une mise en tampon en mémoire à un fichier temporaire. Par défaut 1024.

async read(n: int = -1)

Lit jusqu’à n octets depuis le flux de téléversement. -1 lit jusqu’à la fin.

async save(path_or_file)

Enregistre le téléversement dans path_or_file, qui peut être un chemin de système de fichiers ou un objet fichier déjà ouvert.

async copy(max_memory_size: int | None = None)

Met le téléversement en tampon (soit en RAM, soit dans un fichier temporaire, selon max_memory_size) afin que le reste du corps multipart puisse être analysé sans que le flux d’origine soit invalidé. Le décorateur with_form_data() l’appelle automatiquement.

async close()

Libère tout fichier temporaire créé par copy(). Appelé automatiquement à la fin de la requête si le téléversement a atteint request.files via with_form_data().

Décorateurs au niveau du module

microdot.multipart.with_form_data(f)

Décorateur qui analyse le corps multipart en amont et remplit request.form et request.files avant l’exécution du gestionnaire

from microdot import Microdot
from microdot.multipart import with_form_data

app = Microdot()

@app.post('/upload')
@with_form_data
async def upload(request):
    print('fields:', dict(request.form))
    for name, file in request.files.items():
        await file.save('/sdcard/' + sanitize(file.filename))
    return 'ok'

Les fichiers téléversés sont mis en tampon via FileUpload.copy(), de sorte que le gestionnaire peut parcourir librement request.files et request.form. Les fichiers temporaires sont nettoyés automatiquement à la fin de la requête.

Pour les téléversements de plus de quelques mégaoctets, préférez l’API en flux FormDataIter ; with_form_data() accumule l’intégralité de la requête en mémoire ou sur le système de fichiers avant l’exécution du gestionnaire.