Quick Start¶
This guide walks you through building your first file upload endpoint with filestore.
1. Create a FastAPI App¶
app.py
from fastapi import Depends, FastAPI
from filestore import FileStore, LocalEngine, Store
app = FastAPI()
# Configure a storage dependency
storage = FileStore(
"file", # HTML form field name
required=True, # Reject requests with no files
engine=LocalEngine(
base_dir="uploads", # Directory to write files to
base_url="/media", # Public URL prefix
),
)
@app.post("/upload")
async def upload(store: Store = Depends(storage)) -> Store:
"""Accept a single file upload."""
return store # Store is a Pydantic model — FastAPI serializes it
2. Run It¶
3. Test It¶
What Happened?¶
- FastAPI parsed the multipart request and extracted the
filefield - filestore validated the upload (size, type, etc.)
- The file was written atomically to
uploads/document.pdf - If
document.pdfalready existed, it was automatically renamed todocument-1.pdf - A
Storemodel was returned with all the results
Adding Validation¶
Let's restrict uploads to images under 5 MB:
app.py
from filestore import FileStore, LocalEngine, StoreConfig
storage = FileStore(
"image",
required=True,
engine=LocalEngine(base_dir="uploads/images", base_url="/media/images"),
config=StoreConfig(
allowed_extensions=[".jpg", ".jpeg", ".png", ".webp"],
allowed_content_types=["image/jpeg", "image/png", "image/webp"],
max_file_size=5 * 1024 * 1024, # 5 MB
),
)
A plain dict works too — it is validated into a StoreConfig automatically:
Any file that doesn't match the constraints is rejected with a clear error message in store.errors.
Switching Backends¶
Every engine shares the same interface. To switch from local disk to S3, swap the engine:
# Before: local storage
from filestore import FileStore, LocalEngine
storage = FileStore("file", engine=LocalEngine(base_dir="uploads"))
# After: S3 storage
from filestore import FileStore, S3Engine
storage = FileStore("file", engine=S3Engine(bucket="my-bucket", region="us-east-1"))
Your endpoint code doesn't change at all.
Next Steps¶
- Storage Engines — Learn about all five engines in detail
- Presigned URLs — Let clients upload/download directly to cloud storage
- Validation — File size, extensions, content types, and custom filters
- Callbacks — Dynamic filenames, destinations, and metadata
- Multi-Field Uploads — Handle multiple upload fields per request