question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] Is this the correct way to save an uploaded file ?

See original GitHub issue

Hello, i am trying to save an uploaded file to disk, the following code works correctly but i wonder if it is the correct way to do that.

def parse(file: UploadFile = File(...)):

    extension = os.path.splitext(file.filename)[1]
    _, path = tempfile.mkstemp(prefix='parser_', suffix=extension)

    with open(path, 'wb') as f:
        f.write(file.file.read())

Basically i need to get the path of the temp file. I also have tried with .rollover() but file.file.name does not return the path (only the file descriptor)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:21 (10 by maintainers)

github_iconTop GitHub Comments

40reactions
dmontagucommented, Oct 16, 2019

@classywhetten FastAPI has almost no custom logic related to UploadFile – most of it is coming from starlette. So if you want a “save” wrapper or a better example of usage, it probably makes sense to ask in the starlette repo.

@damianoporta This line:

_, path = tempfile.mkstemp(prefix='parser_', suffix=extension)

causes the file with location path to actually be opened by python, which is what @vitalik was referring to when he said you need to close the tempfile handle (which is the thing named _ in your code).


Here are some utility functions that the people in this thread might find useful (at least as a starting point):

import shutil
from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Callable

from fastapi import UploadFile


def save_upload_file(upload_file: UploadFile, destination: Path) -> None:
    try:
        with destination.open("wb") as buffer:
            shutil.copyfileobj(upload_file.file, buffer)
    finally:
        upload_file.file.close()


def save_upload_file_tmp(upload_file: UploadFile) -> Path:
    try:
        suffix = Path(upload_file.filename).suffix
        with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
            shutil.copyfileobj(upload_file.file, tmp)
            tmp_path = Path(tmp.name)
    finally:
        upload_file.file.close()
    return tmp_path


def handle_upload_file(
    upload_file: UploadFile, handler: Callable[[Path], None]
) -> None:
    tmp_path = save_upload_file_tmp(upload_file)
    try:
        handler(tmp_path)  # Do something with the saved temp file
    finally:
        tmp_path.unlink()  # Delete the temp file

(I haven’t tested the above functions, just adapted them from slightly more complex functions in my own code.)

Note: you’d want to use the above functions inside of def endpoints, not async def, since they make use of blocking APIs.

I don’t know whether it handles out-of-memory issues reasonably well or not, but that is not an issue in my application – maximum request size is capped elsewhere, and the volume of concurrent requests I’m currently handling is such that OOM isn’t really an issue.

34reactions
classywhettencommented, Oct 16, 2019

I’ve been digging through Flask’s documentation, and their file.save function is a wrapper around shutils.copyfileobj() in the standard library.

Here’s my working code:

@app.post("/files/upload")
def create_file(file: UploadFile = File(...)):
    global upload_folder
    file_object = file.file
    #create empty file to copy the file_object to
    upload_folder = open(os.path.join(upload_folder, file.filename), 'wb+')
    shutil.copyfileobj(file_object, upload_folder)
    upload_folder.close()
    return {"filename": file.filename}

I would much appreciate a wrapper around this be built into fastapi

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to save a file after upload | OutSystems
How to save a file after upload · 1) Create a new Web application i.e. Traditional web application · 2) Create a module...
Read more >
Add a “file upload” question to a Google Form - YouTube
Looking for an easy way to upload a file to a Google Form ? In this episode of The Suite Life, Laura Mae...
Read more >
How to save uploaded file in JSF - Stack Overflow
You should first prepare a folder on the local disk file system where the uploaded files should be stored. For example, /path/to/uploads (on ......
Read more >
Upload and save files and folders to OneDrive
Select the files you want to upload, and drag them to OneDrive in the File Explorer Navigation pane. Select File > Save a...
Read more >
File Upload Question - Qualtrics
Stop betting on what your employees and customers want and find out why they contact you, how they feel and what they will...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found