Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
8.2 KiB
Envoyer des fichiers
Vous pouvez définir des fichiers à téléverser par le client en utilisant File.
/// info
Pour recevoir des fichiers téléversés, installez d'abord python-multipart.
Assurez-vous de créer un environnement virtuel, de l'activer, puis d'installer le paquet, par exemple :
$ pip install python-multipart
C'est parce que les fichiers téléversés sont envoyés en « données de formulaire ».
///
Importer File
Importez File et UploadFile depuis fastapi :
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
Définir des paramètres File
Créez des paramètres de fichier de la même manière que pour Body ou Form :
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
/// info
File est une classe qui hérite directement de Form.
Mais souvenez-vous que lorsque vous importez Query, Path, File et d'autres depuis fastapi, ce sont en réalité des fonctions qui renvoient des classes spéciales.
///
/// tip | Astuce
Pour déclarer des fichiers dans le corps de la requête, vous devez utiliser File, sinon les paramètres seraient interprétés comme des paramètres de requête ou des paramètres de corps (JSON).
///
Les fichiers seront téléversés en « données de formulaire ».
Si vous déclarez le type de votre paramètre de fonction de chemin d'accès comme bytes, FastAPI lira le fichier pour vous et vous recevrez le contenu sous forme de bytes.
Gardez à l'esprit que cela signifie que tout le contenu sera stocké en mémoire. Cela fonctionnera bien pour de petits fichiers.
Mais dans plusieurs cas, vous pourriez bénéficier de l'utilisation d'UploadFile.
Paramètres de fichier avec UploadFile
Définissez un paramètre de fichier de type UploadFile :
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
Utiliser UploadFile présente plusieurs avantages par rapport à bytes :
- Vous n'avez pas besoin d'utiliser
File()comme valeur par défaut du paramètre. - Il utilise un fichier « spooled » :
- Un fichier stocké en mémoire jusqu'à une taille maximale, puis, au-delà de cette limite, stocké sur le disque.
- Cela fonctionne donc bien pour des fichiers volumineux comme des images, des vidéos, de gros binaires, etc., sans consommer toute la mémoire.
- Vous pouvez obtenir des métadonnées à partir du fichier téléversé.
- Il offre une interface
asyncde type file-like. - Il expose un véritable objet Python
SpooledTemporaryFileque vous pouvez passer directement à d'autres bibliothèques qui attendent un objet « file-like ».
UploadFile
UploadFile a les attributs suivants :
filename: unestrcontenant le nom de fichier original téléversé (par ex.myimage.jpg).content_type: unestravec le type de contenu (type MIME / type média) (par ex.image/jpeg).file: unSpooledTemporaryFile(un objet file-like). C'est l'objet fichier Python réel que vous pouvez passer directement à d'autres fonctions ou bibliothèques qui attendent un objet « file-like ».
UploadFile a les méthodes async suivantes. Elles appellent toutes les méthodes correspondantes du fichier sous-jacent (en utilisant le SpooledTemporaryFile interne).
write(data): écritdata(stroubytes) dans le fichier.read(size): litsize(int) octets/caractères du fichier.seek(offset): se déplace à la position d'octetoffset(int) dans le fichier.- Par ex.,
await myfile.seek(0)irait au début du fichier. - C'est particulièrement utile si vous exécutez
await myfile.read()une fois puis devez relire le contenu.
- Par ex.,
close(): ferme le fichier.
Comme toutes ces méthodes sont async, vous devez les « await ».
Par exemple, à l'intérieur d'une fonction de chemin d'accès async, vous pouvez obtenir le contenu avec :
contents = await myfile.read()
Si vous êtes dans une fonction de chemin d'accès def normale, vous pouvez accéder directement à UploadFile.file, par exemple :
contents = myfile.file.read()
/// note | Détails techniques async
Lorsque vous utilisez les méthodes async, FastAPI exécute les méthodes de fichier dans un pool de threads et les attend.
///
/// note | Détails techniques Starlette
L'UploadFile de FastAPI hérite directement de l'UploadFile de Starlette, mais ajoute certaines parties nécessaires pour le rendre compatible avec Pydantic et les autres parties de FastAPI.
///
Qu'est-ce que les « données de formulaire »
La façon dont les formulaires HTML (<form></form>) envoient les données au serveur utilise normalement un encodage « spécial » pour ces données, différent de JSON.
FastAPI s'assure de lire ces données au bon endroit plutôt que depuis JSON.
/// note | Détails techniques
Les données des formulaires sont normalement encodées avec le « type de média » application/x-www-form-urlencoded lorsqu'elles n'incluent pas de fichiers.
Mais lorsque le formulaire inclut des fichiers, il est encodé en multipart/form-data. Si vous utilisez File, FastAPI saura qu'il doit récupérer les fichiers depuis la partie appropriée du corps.
Si vous souhaitez en savoir plus sur ces encodages et les champs de formulaire, consultez la MDN Web Docs pour POST.
///
/// warning | Alertes
Vous pouvez déclarer plusieurs paramètres File et Form dans un chemin d'accès, mais vous ne pouvez pas également déclarer des champs Body que vous vous attendez à recevoir en JSON, car la requête aura le corps encodé en multipart/form-data au lieu de application/json.
Ce n'est pas une limitation de FastAPI, cela fait partie du protocole HTTP.
///
Téléversement de fichier facultatif
Vous pouvez rendre un fichier facultatif en utilisant des annotations de type standard et en définissant une valeur par défaut à None :
{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
UploadFile avec des métadonnées supplémentaires
Vous pouvez aussi utiliser File() avec UploadFile, par exemple pour définir des métadonnées supplémentaires :
{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
Téléverser plusieurs fichiers
Il est possible de téléverser plusieurs fichiers en même temps.
Ils seraient associés au même « champ de formulaire » envoyé en « données de formulaire ».
Pour cela, déclarez une list de bytes ou d'UploadFile :
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
Vous recevrez, comme déclaré, une list de bytes ou d'UploadFile.
/// note | Détails techniques
Vous pourriez aussi utiliser from starlette.responses import HTMLResponse.
FastAPI fournit les mêmes starlette.responses sous fastapi.responses simplement pour votre convenance en tant que développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.
///
Téléversements multiples avec métadonnées supplémentaires
Et de la même manière que précédemment, vous pouvez utiliser File() pour définir des paramètres supplémentaires, même pour UploadFile :
{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
Récapitulatif
Utilisez File, bytes et UploadFile pour déclarer des fichiers à téléverser dans la requête, envoyés en « données de formulaire ».