Search code examples
pythonfastapistarlette

FastAPI: How to download bytes through the API


Is there a way to download a file through FastAPI? The files we want are located in an Azure Datalake and retrieving them from the lake is not an issue, the problem occurs when we try to get the bytes we get from the datalake down to a local machine.

We have tried using different modules in FastAPI such as starlette.responses.FileResponse and fastapi.Response with no luck.

In Flask this is not an issue and can be done in the following manner:

from io import BytesIO
from flask import Flask
from werkzeug import FileWrapper

flask_app = Flask(__name__)

@flask_app.route('/downloadfile/<file_name>', methods=['GET'])
def get_the_file(file_name: str):
    the_file = FileWrapper(BytesIO(download_file_from_directory(file_name)))
    if the_file:
        return Response(the_file, mimetype=file_name, direct_passthrough=True)

When running this with a valid file name the file automatically downloads. Is there equivalent way to this in FastAPI?

Solved

After some more troubleshooting I found a way to do this.

from fastapi import APIRouter, Response

router = APIRouter()

@router.get('/downloadfile/{file_name}', tags=['getSkynetDL'])
async def get_the_file(file_name: str):
    # the_file object is raw bytes
    the_file = download_file_from_directory(file_name)
    if the_file:
        return Response(the_file)

So after a lot of troubleshooting and hours of looking through documentation, this was all it took, simply returning the bytes as Response(the_file).


Solution

  • After some more troubleshooting I found a way to do this.

    from fastapi import APIRouter, Response
    
    router = APIRouter()
    
    @router.get('/downloadfile/{file_name}', tags=['getSkynetDL'])
    async def get_the_file(file_name: str):
        # the_file object is raw bytes
        the_file = download_file_from_directory(file_name)
        if the_file:
            return Response(the_file)
    

    So after a lot of troubleshooting and hours of looking through documentation, this was all it took, simply returning the bytes as Response(the_file) with no extra parameters and no extra formatting for the raw bytes object.