Home > Software engineering >  Upload files from (Fast)API to Azure Blob Storage
Upload files from (Fast)API to Azure Blob Storage

Time:06-21

I'm trying to create a function that let me select a file from input on the frontend, then pass the file to the backend FastAPI, and eventually upload the file to Azure Blob storage. My Frontend code is below:

//front end
async function handleSubmit(){
    
    const formdata = new FormData();
    formdata.append(
      "file",
      file[0],
    )

    const headers={'Content-Type': file[0].type}

    await axios.post("/uploadfile",formdata,headers)
    .then(function (response) {
      console.log(response)
          });
  }

Backend FastAPI - two methods I tried

//Backend FastAPI
@app.post("/uploadfile") //currently using 
async def create_upload_file(file: UploadFile):
    name = file.filename
    type = file.content_type
    return uploadtoazure(file,name,type)

@app.post("/files") //another method I tried
async def create_file(file: bytes= File()):
    
    await uploadtoazure(file)

And the uploadtoazure() function

//Backend uploadtoazure() function
async def uploadtoazure(f,n,t):
    connect_str = ""//removed from sample code
   
    blob_service_client = BlobServiceClient.from_connection_string(connect_str)
    container_name = "notes"

    file = f.read()
    local_file_name = n
    cnt_settings = ContentSettings(content_type=t)

    blob_client = blob_service_client.get_blob_client(container=container_name, blob=local_file_name)
    
    blob_client.upload_blob(file,cnt_settings)

The error kept coming at me and when I tried another method another new error prevents me from moving forward.

Some problem I'm aware:

  • blob_client.upload_blob() only accept some types of files, in which the file type I passed in from API isn't one of it.
  • I used the sample code in https://fastapi.tiangolo.com/tutorial/request-files/In which I am not quite sure of the characteristic of the class UploadFile and File().
  • When I use the method which the file passed to API is file: bytes= File(), the file type seems able to upload to the blob storage, however it does not have a content type or suffix, hence I think finding a way to pass in the content_type of the file could be another solution, but it was harder than I thought.

I hope there's enough information, I desperately need someone to clear my confusion. Thank you very much.

CodePudding user response:

You were pretty close, but there are some improvements. For example, you are using synchronous and asynchronous code together. This leads to confusing issues, such as not awaiting f.read() while that is an async method. Also, you don't have to pass content type to the azure storage blob client, just leave that to Azure.

I would recommend to use the async version of the azure-storage-blob package.

I re-wrote it a little. The below will run as-is and is a full working example.

from fastapi import FastAPI, HTTPException, UploadFile
from azure.storage.blob.aio import BlobServiceClient

app = FastAPI()

@app.post("/uploadfile")
async def create_upload_file(file: UploadFile):
    name = file.filename
    type = file.content_type
    return await uploadtoazure(file,name,type)


async def uploadtoazure(file: UploadFile,file_name: str,file_type:str):
    connect_str = "HERE_YUOUR_CONNECTION_STRING"
    blob_service_client = BlobServiceClient.from_connection_string(connect_str)
    container_name = "stackoverflow"
    async with blob_service_client:
            container_client = blob_service_client.get_container_client(container_name)
            try:
                blob_client = container_client.get_blob_client(file_name)
                f = await file.read()
                await blob_client.upload_blob(f)
            except Exception as e:
                print(e)
                return HTTPException(401, "Something went terribly wrong..")
    
    return "{'did_it_work':'yeah it did!'}"


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000, )    

Hope this clarifies some bits!

  • Related