ML-backed API that predicts an artwork’s style from an input image (27 WikiArt-style categories). It also includes an optional Postgres-backed “gallery” endpoint for serving example artworks by style.
This repo is a compact example of:
- Serving a PyTorch model behind a production-friendly FastAPI service (lazy model loading, simple input validation, Dockerized deployment).
- Basic backend hygiene (health endpoint, env-driven config, non-leaky error handling).
- A small data pipeline (
seed_wikiart.py) to populate a Postgres table from a public dataset, storing images in Cloudinary for fast delivery.
- API: Python 3.11, FastAPI, Uvicorn
- ML inference: PyTorch, torchvision (EfficientNet-B3), Pillow
- Data: Postgres (
psycopg2) - Optional seeding: HuggingFace
datasets,tqdm, Cloudinary
| Method | Path | Description |
|---|---|---|
| GET | /health |
Liveness check |
| GET | /styles |
Returns the supported style labels |
| POST | /predict-style |
Upload an image and get top-k style predictions |
| GET | /gallery |
Returns artworks matching a style (requires Postgres) |
- Body:
multipart/form-datawith fieldfile(image/jpeg,image/png, orimage/webp) - Query params:
top_k(default5) - Response: the best prediction plus the top-k list with probabilities
Example:
curl -F "file=@/path/to/image.jpg" "http://localhost:10000/predict-style?top_k=5"Returns random artworks for a given style.
- Query params:
style(required) — style/category name (e.g.,Impressionism)limit(default24, min1, max60)exclude_id(optional) — omit a specific artwork id
- Requires:
DATABASE_URL
This endpoint expects a table:
artworks(id, title, artist, style, image_url)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtAt startup the API ensures models/efficientnet_b3_best.pt exists:
- Recommended: set
MODEL_URLto a downloadable.ptfile (the server downloads it on first run). - Or: place the weights file at
models/efficientnet_b3_best.pt.
uvicorn app:app --reload --host 0.0.0.0 --port 10000curl http://localhost:10000/health
curl http://localhost:10000/stylesdocker build -t art-style-api .
docker run -p 10000:10000 -e MODEL_URL="https://..." art-style-apiseed_wikiart.py can populate the artworks table used by /gallery by:
- pulling images from the HuggingFace WikiArt dataset, then
- uploading them to Cloudinary, and
- upserting metadata into Postgres.
This script uses extra dependencies that aren’t in requirements.txt:
pip install datasets tqdm cloudinaryRequired env vars:
DATABASE_URLCLOUDINARY_CLOUD_NAMECLOUDINARY_API_KEYCLOUDINARY_API_SECRET
Optional env vars:
PER_STYLE(default300)CLOUDINARY_FOLDER(defaultwikiart)WIKIART_SPLIT(defaulttrain)STYLE_WHITELIST_FILE(optional path toidx_to_style.json, a JSON list, or a newline-separated list of styles)
Run:
python seed_wikiart.pyapp.py: FastAPI routes (/predict-style,/gallery, etc.)model.py: model loading + preprocessing + prediction helpersidx_to_style.json: class label mapseed_wikiart.py: dataset → Cloudinary + Postgres seeding pipelineDockerfile: container build for deployment
- CORS is currently wide-open for easier demo; production should restrict
allow_origins. /galleryuses a new DB connection per request; a connection pool would be the next step for higher throughput.- If exposing publicly: add auth, rate limiting, and request size limits.