image-upload
A lightweight FastAPI package for saving uploaded files and generating absolute URLs for stored images using Pydantic.
Features
- Simple file upload handling
- Automatically stores files inside an
uploads/directory - Returns the saved file path
- Easily generate absolute URLs with Pydantic
- Asynchronous file saving using
aiofiles - File size and MIME type validation
Requirements
- Python 3.12+
- FastAPI
- Pydantic v2
- aiofiles
Installation
Install from PyPI:
pip install image-upload
Supported File Types
By default the package accepts:
- JPEG (
image/jpeg) - PNG (
image/png) - GIF (
image/gif) - PDF (
application/pdf) - Plain Text (
text/plain)
Maximum upload size is 50 MB.
Saving an Uploaded File
Import get_path and pass an UploadFile.
from image_upload import get_path
data.picture = await get_path(data.picture)
or
data["picture"] = await get_path(data.pop("picture"))
The function returns the relative storage path.
Example output:
uploads/0c6d8a69-9c84-47d4-81f6-d15d11fcbf88.png
FastAPI Example
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from image_upload import get_path
router = APIRouter()
@router.post("/")
async def create(
data: UserCreate = Depends(UserCreate.as_form),
db: AsyncSession = Depends(get_db),
):
data.picture = await get_path(data.picture)
return await user(db, data.model_dump())
Save Inside a Custom Folder
You can optionally provide a folder name.
path = await get_path(file, folder="users")
Building Absolute URLs
AbsoluteUrl automatically prepends the application's base URL using the Pydantic validation context.
from pydantic import BaseModel
from image_upload import AbsoluteUrl
class UserOut(BaseModel):
name: str
picture: AbsoluteUrl
When validating:
user = UserOut.model_validate(
data,
context={
"base_url": "https://example.com/"
}
)
Note: Can also use "base_url": request.base_url
from fastapi import Request
@router.get("/")
async def get_user(
request: Request,
db: AsyncSession = Depends(get_db),
) -> UserOut:
users = await list_user(
db
)
return UserOut.model_validate(
users,
context={"base_url": request.base_url},
)
Result:
{
"name": "John",
"picture": "https://example.com/uploads/avatar.png"
}
API
get_path(file, folder=None)
Stores the uploaded file and returns its storage path.
Parameters
| Parameter | Type | Description |
|---|---|---|
| file | UploadFile | Uploaded file |
| folder | str | None |
Returns
str
Example:
path = await get_path(upload_file)
Security
The package performs basic validation:
- Allowed MIME type validation
- Maximum file size validation (50 MB)
- UUID-based file names to avoid collisions
- Asynchronous streaming to reduce memory usage
Dependencies
- FastAPI
- Pydantic v2
- aiofiles
License
MIT License
Release files for image-upload 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| image_upload-0.1.0.tar.gz | 4.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| image_upload-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:9.6 kB
Release files / image_upload-0.1.0.tar.gz
| Download URL | image_upload-0.1.0.tar.gz |
|---|---|
| Size | 4.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8f55dfdac6751a4a90bd75ebb31cf375b437cb18576cce9664c4d6241d460df5
|
|
BLAKE2b-256 checksum How to use checksums |
19f38ec25cc0a519bd013defec8330865227e6887864cfcc66f35dd62708753a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / image_upload-0.1.0-py3-none-any.whl
| Download URL | image_upload-0.1.0-py3-none-any.whl |
|---|---|
| Size | 5.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4dcff132fa34f8caa42cb5831bcbf3c7703ddc0908f73e805d3104c0d695f409
|
|
BLAKE2b-256 checksum How to use checksums |
4f361c921b48ae7fcf8971da2064eebcd9645347ab32b49b922e05c6d74da6db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|