Maison >développement back-end >Tutoriel Python >Comment télécharger efficacement des fichiers volumineux (≥3 Go) vers un backend FastAPI ?

Comment télécharger efficacement des fichiers volumineux (≥3 Go) vers un backend FastAPI ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-04 15:22:11573parcourir

How to Effectively Upload Large Files (≥3GB) to a FastAPI Backend?

Comment télécharger un fichier volumineux (≥3 Go) vers le backend FastAPI ?

FastAPI peut traiter des fichiers dépassant 1 Mo en récupérant des parties du fichier à la fois auprès du corps de la demande. Cette approche élimine le besoin de charger l'intégralité du fichier en mémoire, ce qui est recommandé lors du traitement de fichiers volumineux.

Demande côté client :

m = MultipartEncoder(fields = {"upload_file":open(file_name,'rb')})
prefix = "http://xxx:5000"
url = "{}/v1/uploadfiles".format(prefix)
try:
    req = requests.post(
    url,
    data=m,
    verify=False,
            )

Réponse côté serveur :

HTTP 422 {"detail":[{"loc":["body","upload_file"],"msg":"field required","type":"value_error.missing"}]}

Raison du Erreur :

L'erreur se produit car la requête côté client omet l'en-tête Content-Type. FastAPI s'attend à ce que le client envoie des requêtes multipart/form-data lors du téléchargement de fichiers. Sans l'en-tête Content-Type, FastAPI ne peut pas analyser correctement le corps de la requête.

Solution 1 (recommandée) : utilisation des téléchargements de fichiers en streaming et des requêtes codées en bloc

Bibliothèque HTTPX prend en charge les téléchargements de fichiers en streaming par défaut, vous permettant d'envoyer des fichiers sans les charger entièrement dans mémoire.

Exemple :

import httpx
import time

url = 'http://127.0.0.1:8000/upload'
files = {'file': open('bigFile.zip', 'rb')}
headers = {'Filename': 'bigFile.zip'}
data = {'data': 'Hello World!'}

with httpx.Client() as client:
    start = time.time()
    r = client.post(url, data=data, files=files, headers=headers)
    end = time.time()
    print(f'Time elapsed: {end - start}s')
    print(r.status_code, r.json(), sep=' ')

Solution 2 : Utilisation de la bibliothèque streaming_form_data

Cette bibliothèque fournit un multipart/formulaire de streaming -analyseur de données pour Python, vous permettant d'analyser les requêtes multipart/form-data sans charger complètement l'intégralité du corps de la requête dans mémoire.

Exemple :

from streaming_form_data import StreamingFormDataParser
from streaming_form_data.targets import FileTarget, ValueTarget

app = FastAPI()
MAX_REQUEST_BODY_SIZE = 1024 * 1024 * 1024 * 4  # = 4GB
MAX_FILE_SIZE = 1024 * 1024 * 1024 * 3  # = 3GB

@app.post('/upload')
async def upload(request: Request):
    
    parser = StreamingFormDataParser(headers=request.headers)
    filename = request.headers.get('Filename')
    file_ = FileTarget('./' + filename)
    data = ValueTarget()
    parser.register('file', file_)
    parser.register('data', data)
    body_validator = MaxBodySizeValidator(MAX_REQUEST_BODY_SIZE)
    file_validator = MaxSizeValidator(MAX_FILE_SIZE)
    
    async for chunk in request.stream():
        body_validator(chunk)
        parser.data_received(chunk)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn