web-dev-qa-db-fra.com

Comment enregistrer le fichier de téléchargement dans FASTAPI

J'accepte le fichier via Post. Lorsque je l'enregistre localement, je peux lire le contenu à l'aide de fichier.Read (), mais le nom via File.Name incorrect (16) est affiché. Lorsque j'essaie de le trouver par ce nom, je reçois une erreur. Quel pourrait être le problème?

Mon code :

  @router.post(
    path="/po/{id_po}/upload",
    response_model=schema.ContentUploadedResponse,
)
async def upload_file(
        id_po: int,
        background_tasks: BackgroundTasks,
        uploaded_file: UploadFile = File(...)):
    """pass"""
    uploaded_file.file.rollover()
    uploaded_file.file.flush()
    #shutil.copy(uploaded_file.file.name, f'/home/fyzzy/Desktop/api/{uploaded_file.filename}')
    background_tasks.add_task(s3_upload, uploaded_file=fp)
    return schema.ContentUploadedResponse()
3
Fyzzys

Dans mon cas, je dois gérer d'énormes fichiers. Je dois donc éviter de les lire dans la mémoire. Ce que je veux, c'est de les sauvegarder sur le disque de manière asynchrone, dans des morceaux.

J'essaye avec cela et il semble faire le travail (chunk_size est choisi assez arbitrairement, des tests supplémentaires sont nécessaires pour trouver une taille optimale):

import os
import logging

from fastapi import FastAPI, BackgroundTasks, File, UploadFile

log = logging.getLogger(__name__)

app = FastAPI()

DESTINATION = "/"
CHUNK_SIZE = 2 ** 20  # 1MB


async def chunked_copy(src, dst):
    await src.seek(0)
    with open(dst, "wb") as buffer:
        while True:
            contents = await src.read(CHUNK_SIZE)
            if not contents:
                log.info(f"Src completely consumed\n")
                break
            log.info(f"Consumed {len(contents)} bytes from Src file\n")
            buffer.write(contents)


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
    fullpath = os.path.join(DESTINATION, file.filename)
    await chunked_copy(file, fullpath)
    return {"File saved to disk at": fullpath}

Cependant, je réalise rapidement que create_upload_file n'est pas invoqué tant que le fichier n'a pas été complètement reçu. Donc, si cet extrait de code est correct, il sera probablement bénéfique pour la performance, mais ne permettra rien de fournir des commentaires au client sur la progression du téléchargement et une copie de données complète sur le serveur. Il semble idiot de ne pas pouvoir accéder à un fichier temporaire d'origine pour le téléchargement de téléchargement d'origine et de le déplacer ailleurs, en évitant ainsi une copie.

0
benelgiac