Home  >  Article  >  Backend Development  >  How to Download a File after POSTing Data Using FastAPI?

How to Download a File after POSTing Data Using FastAPI?

Barbara Streisand
Barbara StreisandOriginal
2024-10-31 20:25:17995browse

How to Download a File after POSTing Data Using FastAPI?

How to Download a File after POSTing Data using FastAPI?

When working with FastAPI and file handling, one common task is to enable users to download a file after submitting data through a POST request. This can be achieved by utilizing the FileResponse class and ensuring the proper configuration of headers and content type.

In the code provided below, we'll demonstrate how to set up a POST endpoint that processes data and returns an audio file (MP3) for download. We'll use the Form data type to capture user input and generate the audio file.

Option 1: Using a Separate Download Endpoint

In this approach, we'll create a separate endpoint for handling file downloads.

<code class="python">from fastapi import FastAPI, Request, Form, File, UploadFile
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.templating import Jinja2Templates
from gtts import gTTS

app = FastAPI()
templates = Jinja2Templates(directory="templates")


def text_to_speech(language: str, text: str) -> str:
    tts = gTTS(text=text, lang=language, slow=False)
    filepath = "temp/welcome.mp3"
    tts.save(filepath)
    return f"Text to speech conversion successful to {filepath}"


@app.get("/")
def home(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})


@app.post("/text2speech")
def text2speech(request: Request, message: str = Form(...), language: str = Form(...)):
    if message and language:
        output = text_to_speech(language, message)
    path = "temp/welcome.mp3"
    filename = os.path.basename(path)
    headers = {"Content-Disposition": f"attachment; filename={filename}"}
    return FileResponse(path, headers=headers, media_type="audio/mp3")</code>

The GET endpoint serves as the main page, while the POST endpoint handles user input and generates the audio file. The FileResponse takes care of setting the appropriate headers for file download.

In your template, you can add a link to trigger the file download:

<code class="html"><!DOCTYPE html>
<html>
  <head>
    <title>Download File</title>
  </head>
  <body>
    <a href="{{ url_for('text2speech') }}">Download File</a>
  </body>
</html></code>

Option 2: In-Endpoint File Download

Alternatively, you can handle file download within the same endpoint that processes the data:

<code class="python">from fastapi import FastAPI, Request, Form

app = FastAPI()


def text_to_speech(language: str, text: str) -> str:
    tts = gTTS(text=text, lang=language, slow=False)
    filepath = "temp/welcome.mp3"
    tts.save(filepath)
    return f"Text to speech conversion successful to {filepath}"


@app.post("/text2speech")
def text2speech(request: Request, message: str = Form(...), language: str = Form(...)):
    output = text_to_speech(language, message)
    return {"filepath": filepath}</code>

In your template, you can use JavaScript to trigger the file download using the filepath returned from the endpoint:

<code class="html"><script>
  const filepath = "{{ filepath }}";
  window.location.href = filepath;
</script></code>

Handling Large Files

For files exceeding memory limits, you can use StreamingResponse:

<code class="python">from fastapi.responses import StreamingResponse

@app.post("/text2speech")
def text2speech(request: Request, message: str = Form(...), language: str = Form(...)):
    ...
    def iterfile():
        with open(filepath, "rb") as f:
            yield from f

    headers = {"Content-Disposition": f"attachment; filename={filename}"}
    return StreamingResponse(iterfile(), headers=headers, media_type="audio/mp3")</code>

Deleting Files After Download

To prevent disk space accumulation, it's good practice to delete files after they have been downloaded. Using BackgroundTasks, you can schedule the file deletion as a background task:

<code class="python">from fastapi import BackgroundTasks

@app.post("/text2speech")
def text2speech(request: Request, background_tasks: BackgroundTasks, ...):
    ...
    background_tasks.add_task(os.remove, path=filepath)
    return FileResponse(filepath, headers=headers, media_type="audio/mp3")</code>

The above is the detailed content of How to Download a File after POSTing Data Using FastAPI?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn