A scalable backend application for detecting and segmenting food items in images, then calculating their area.
Built using FastAPI and YOLOv8. Designed to support asynchronous image processing and horizontal scaling via Docker.
- Backend: FastAPI (Python 3.10.11)
- Image Processing: YOLOv8 (via Ultralytics)
- Containerization: Docker & Docker Compose
- Client: Local Python script (
batch_upload_test.py, upload_search_test.py) to send requests
- Python 3.10+
- pip
- (Optional) Docker & Docker Compose
-
Clone this repository:
git clone https://github.com/your-username/your-repo.git cd your-repo -
(Optional) Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Run the FastAPI server:
fastapi dev backend/main.py
-
Make sure Docker is installed and running.
-
Run this from the root directory where
docker-compose.ymlis located.docker-compose up --build
-
The API will be available at:
http://localhost:8000/docs
Alternative option: you can make up for the limited resources by changing start_workers(4, app.state.job_queue, app.state.results, app.state.lock) from 4 to 1 or 2. While this may result in lower performance, it will ensure stability, Also you might need to adjust TIMEOUT_LIMIT in the test case
-
The client script (
client/batch_upload_test.py,client/upload_search_test.py) is not containerized — it runs locally from your host machine to send requests to the backend. -
You can send requests manually from your local environment:
cd client python upload_search_test.py
+-------------+
| Client | (Python script: upload_search_test.py)
+------+------+
|
HTTP POST /upload_images
|
v
+------+------+
| FastAPI | (REST API)
| Backend |
+------+------+
|
Enqueue job
and return batch_id
|
v
+--------+--------+
| JoinableQueue | ← receives image jobs (1 image per job)
+--------+--------+
|
v
+--------+--------+
| Background Worker| ← multiprocessing workers
| + YOLOv8 Model |
+--------+--------+
|
Segmentation + Area Calculation
|
Store result in memory
|
v
+--------+--------+
| Results Store | <- (results[batch_id][data][job_id] = job_result)
+--------+--------+
^
|
Client polls /result/{batch_id} <- (results[batch_id])
|
+------+------+
| Client |
+-------------+
- Backend returns a
batch_idimmediately when theupload_imagesendpoint is called by the client. - Clients poll
/result/{batch_id}to check result status. - No persistent storage or cloud services are used — in-memory queue only.
- Designed to run locally on a single machine for simplicity.
The following benchmarks compare execution time between local and Dockerized environments.
| Test Script | Local Run Time with ThreadPoolExecutor | Local Run Time with multiprocessing | Docker Run Time (1 container - ThreadPoolExecutor) |
|---|---|---|---|
upload_search_test.py |
18 seconds | 6 ~ 10 seconds | 30 seconds |
batch_upload_test.py |
159 seconds | 56 seconds | 283 seconds |
- OS: Windows 10 Education (64-bit)
- CPU: AMD Ryzen 7 5700G (8 cores / 16 threads, 3.8 GHz)
- RAM: 32 GB
- GPU: AMD Radeon RX 7600 XT (YOLO model loading and prediction were performed on CPU due to unsupported CUDA on AMD GPUs)
- YOLO Model:
yolov8n-seg.pt(Segmentation task, CPU inference)
| Tool | Version |
|---|---|
| Python | 3.10.11 |
| FastAPI | latest |
| Docker | 24+ recommended |
| YOLOv8 | via ultralytics |