StackStalk
  • Home
  • Java
    • Java Collection
    • Spring Boot Collection
  • Python
    • Python Collection
  • C++
    • C++ Collection
    • Progamming Problems
    • Algorithms
    • Data Structures
    • Design Patterns
  • General
    • Tips and Tricks

Sunday, February 5, 2023

Python FastAPI file upload and download

 February 05, 2023     Python     No comments   

In this article, we will look at an example of how to implement a file upload and download API in a Python FastAPI microservice. Example below provides a simple microservice built with FastAPI which supports API paths "/upload" and "/download" to handle the files.

To run this example need to install these modules.

pip install fastapi
pip install uvicorn
pip install python-multipart
Here uvicorn is an implementation of ASGI (Asynchronous Service Gateway Interface) specifications and provides a standard interface between async-capable Python web servers, frameworks and applications.

Application code is simple. We expose 2 APIs.

  • In the upload API, we create a writable file with .zip extension. Uploaded file contents are read in chunks and appended to the file.
  • In the download API, we access the file based on provided name and return as a FileRespone object.
from fastapi import FastAPI, Request
from fastapi import File, UploadFile
from fastapi.responses import FileResponse

import uvicorn
import os

description = """
Sample app to demonstrate file upload with FastAPI
"""
app = FastAPI(title="FileUploadApp",
              description=description,
              version="0.1")


@app.get("/download")
async def download(name: str):
    file_path = "/app/filecache/" + name + ".zip"
    if os.path.exists(file_path):
       return FileResponse(path=file_path, filename=file_path, media_type='application/zip')

    return {"message": "File not found"}


@app.post("/upload")
async def upload(name: str, file: UploadFile = File(...)):
    try:
        filename = "/app/filecache/" + name + ".zip"
        with open(filename, 'wb') as f:
            while contents := file.file.read(1024 * 1024):
                f.write(contents)
    except Exception as e:
        print(e)
        return {"message": "Error uploading the file"}
    finally:
        file.file.close()

    return {"message": f"Successfully uploaded {file.filename}"}

if __name__ == '__main__':
    uvicorn.run('app:app',
                host='0.0.0.0',
                port=8091,
                reload=True)

To run the application as a container we create a simple Dockerfile. Here we install the python modules and bring up the application on port 8091.

FROM python:3.9-slim-buster

WORKDIR /app

COPY requirements.txt /app/requirements.txt
RUN pip3 install -r /app/requirements.txt

COPY app.py /app
RUN mkdir -p /app/resources
RUN mkdir -p /app/filecache

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8091"]

Now build the docker image using this command.

docker build -t fileupload:1 -f Dockerfile .

We use a simple docker compose file to start the file upload service. Also note that we are mounting a host folder (/tmp/filecache) to the container so that the files are persisted across restarts of the container.

version: '2.1'

services:
  fileupload:
    image: fileupload:1
    ports:
      - "8091:8091"
    volumes:
      - /tmp/filecache:/app/filecache

Now start the service using the docker compose command.

docker-compose -f docker-compose.yml up

Best way to validate the service is to use the Swagger UI of the service using this URL. http://localhost:8091/docs/

Download the full source of this example here.

  • Share This:  
Newer Post Older Post Home

0 comments:

Post a Comment

Follow @StackStalk
Get new posts by email:
Powered by follow.it

Popular Posts

  • Avro Producer and Consumer with Python using Confluent Kafka
    In this article, we will understand Avro a popular data serialization format in streaming data applications and develop a simple Avro Produc...
  • Monitor Spring Boot App with Micrometer and Prometheus
    Modern distributed applications typically have multiple microservices working together. Ability to monitor and manage aspects like health, m...
  • Server-Sent Events with Spring WebFlux
    In this article we will review the concepts of server-sent events and work on an example using WebFlux. Before getting into this article it ...
  • Implement caching in a Spring Boot microservice using Redis
    In this article we will explore how to use Redis as a data cache for a Spring Boot microservice using PostgreSQL as the database. Idea is to...
  • Python FastAPI microservice with Okta and OPA
    Authentication (AuthN) and Authorization (AuthZ) is a common challenge when developing microservices. In this article, we will explore how t...
  • Spring Boot with Okta and OPA
    Authentication (AuthN) and Authorization (AuthZ) is a common challenge when developing microservices. In this article, we will explore how t...
  • Getting started with Kafka in Python
    This article will provide an overview of Kafka and how to get started with Kafka in Python with a simple example. What is Kafka? ...
  • Getting started in GraphQL with Spring Boot
    In this article we will explore basic concepts on GraphQL and look at how to develop a microservice in Spring Boot with GraphQL support. ...

Copyright © StackStalk