Media Service

File upload and download service with S3/MinIO storage backend and image processing

Media Service (Port 8011)

The media-service handles file uploads, storage (S3/MinIO/local), image processing, and media URL generation.

Database

Database: media_db

TablePurpose
media_assetsFile metadata records
upload_sessionsChunked upload session tracking

API Endpoints

MethodPathPurpose
POST/uploadUpload a file
GET/assetsList assets
GET/assets/{id}Get asset metadata
DELETE/assets/{id}Delete asset
GET/download/{id}Download file

Storage Backends

Supports multiple storage backends selected via configuration:

class StorageBackend(Enum):
    S3 = "s3"           # Amazon S3
    MINIO = "minio"     # MinIO (S3-compatible, local dev)
    LOCAL = "local"     # Local filesystem (development)

Upload Flow

Client ──► POST /upload (multipart)
  │
  ├──► media-service validates file type/size
  ├──► Stores in configured backend (S3/MinIO/local)
  ├──► Creates media_asset record in media_db
  └──► Returns asset ID and URL

# Response
{
  "id": "asset-uuid",
  "url": "http://files.mquad.local/uploads/abc123.jpg",
  "mime_type": "image/jpeg",
  "size_bytes": 1048576,
  "filename": "photo.jpg"
}

Image Processing

Images are automatically processed on upload:

  • Thumbnail generation (256x256)
  • Resize variants (sm: 640, md: 1280, lg: 2048)
  • Format conversion (WebP for modern browsers)
async def process_image(file_path: str, asset_id: str):
    variants = {
        "thumbnail": (256, 256),
        "small": (640, 0),     # 0 = maintain aspect ratio
        "medium": (1280, 0),
        "large": (2048, 0),
    }
    for name, (width, height) in variants.items():
        await resize_image(file_path, f"{asset_id}_{name}.webp", width, height)

Environment Configuration

S3_ENDPOINT_URL=http://minio:9000
S3_ACCESS_KEY=mquadadmin
S3_SECRET_KEY=mquadadmin123
S3_BUCKET_NAME=mquad-media
S3_PUBLIC_URL=http://files.${HOST_MAIN_DOMAIN}