To run this example need to install these modules.
pip install fastapi pip install uvicorn pip install python-multipart
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.
0 comments:
Post a Comment