Skip to content

Commit d6da454

Browse files
Add FastAPI deployment tutorial for MONAI models (#2050)
This tutorial demonstrates how to deploy MONAI model bundles as production-ready REST APIs using FastAPI. Features: - Complete FastAPI application with inference endpoints - MONAI model bundle integration (spleen_ct_segmentation) - Singleton pattern for efficient model loading - Async/await for optimal performance - Pydantic validation for type safety - Auto-generated API documentation (Swagger/ReDoc) - Docker deployment with multi-stage builds - Comprehensive unit tests - Example client code and HTTP requests - Production-ready error handling and logging Structure: - app/: FastAPI application code - tests/: Unit test suite - docker/: Containerization configs - examples/: Usage examples - README.md: Complete tutorial documentation Addresses #2048 Fixes # . ### Description A few sentences describing the changes proposed in this pull request. ### Checks <!--- Put an `x` in all the boxes that apply, and remove the not applicable items --> - [ ] Avoid including large-size files in the PR. - [ ] Clean up long text outputs from code cells in the notebook. - [ ] For security purposes, please check the contents and remove any sensitive info such as user names and private key. - [ ] Ensure (1) hyperlinks and markdown anchors are working (2) use relative paths for tutorial repo files (3) put figure and graphs in the `./figure` folder - [ ] Notebook runs automatically `./runner.sh -t <path to .ipynb file>` --------- Signed-off-by: Mohamed Salah <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 97f1075 commit d6da454

File tree

13 files changed

+1271
-0
lines changed

13 files changed

+1271
-0
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
# MONAI + FastAPI Inference Deployment Tutorial
2+
3+
This tutorial demonstrates how to deploy MONAI model bundles as production-ready REST APIs using FastAPI.
4+
5+
## πŸ“š Overview
6+
7+
Learn how to:
8+
- Load and serve MONAI model bundles
9+
- Create FastAPI endpoints for medical image inference
10+
- Handle medical image uploads (NIfTI format)
11+
- Deploy with Docker for production
12+
- Test and monitor your deployed model
13+
14+
## 🎯 What You'll Build
15+
16+
A complete REST API service that:
17+
- βœ… Loads a pre-trained MONAI model (spleen CT segmentation)
18+
- βœ… Accepts medical image uploads via HTTP
19+
- βœ… Returns inference results in JSON format
20+
- βœ… Includes auto-generated API documentation
21+
- βœ… Runs in Docker containers for easy deployment
22+
23+
## πŸ“‹ Prerequisites
24+
25+
- Python 3.9+ installed
26+
- Docker installed (for containerization)
27+
- Basic knowledge of Python and REST APIs
28+
- Familiarity with medical imaging (helpful but not required)
29+
30+
## πŸš€ Quick Start
31+
32+
### 1. Install Dependencies
33+
34+
```bash
35+
pip install -r requirements.txt
36+
```
37+
38+
### 2. Run the API Locally
39+
40+
```bash
41+
# From the fastapi_inference directory
42+
python -m uvicorn app.main:app --reload
43+
```
44+
45+
The API will be available at `http://localhost:8000`
46+
47+
### 3. Test the API
48+
49+
**Health Check:**
50+
```bash
51+
curl http://localhost:8000/health
52+
```
53+
54+
**View API Documentation:**
55+
Open `http://localhost:8000/docs` in your browser
56+
57+
**Make a Prediction:**
58+
```bash
59+
curl -X POST http://localhost:8000/predict \
60+
-F "file=@path/to/your/image.nii.gz"
61+
```
62+
63+
## πŸ“ Project Structure
64+
65+
```
66+
fastapi_inference/
67+
β”œβ”€β”€ README.md # This file
68+
β”œβ”€β”€ requirements.txt # Python dependencies
69+
β”œβ”€β”€ app/ # FastAPI application
70+
β”‚ β”œβ”€β”€ __init__.py
71+
β”‚ β”œβ”€β”€ main.py # FastAPI app and routes
72+
β”‚ β”œβ”€β”€ model_loader.py # MONAI model loading (singleton)
73+
β”‚ β”œβ”€β”€ inference.py # Inference logic
74+
β”‚ └── schemas.py # Pydantic models for validation
75+
β”œβ”€β”€ tests/ # Unit tests
76+
β”‚ β”œβ”€β”€ __init__.py
77+
β”‚ └── test_api.py # API endpoint tests
78+
β”œβ”€β”€ docker/ # Docker configuration
79+
β”‚ β”œβ”€β”€ Dockerfile # Container definition
80+
β”‚ └── docker-compose.yml # Orchestration
81+
β”œβ”€β”€ notebooks/ # Interactive tutorials
82+
β”‚ └── fastapi_tutorial.ipynb # Step-by-step walkthrough
83+
└── examples/ # Usage examples
84+
β”œβ”€β”€ client.py # Python client example
85+
└── sample_requests.http # HTTP request examples
86+
```
87+
88+
## πŸ”§ API Endpoints
89+
90+
### `GET /`
91+
Returns API information
92+
93+
### `GET /health`
94+
Health check endpoint
95+
- Returns service status
96+
- Indicates if model is loaded
97+
- Shows computation device (CPU/GPU)
98+
99+
**Example Response:**
100+
```json
101+
{
102+
"status": "healthy",
103+
"model_loaded": true,
104+
"device": "cuda"
105+
}
106+
```
107+
108+
### `POST /predict`
109+
Run inference on uploaded medical image
110+
111+
**Request:**
112+
- Method: POST
113+
- Content-Type: multipart/form-data
114+
- Body: file (NIfTI format: .nii or .nii.gz)
115+
116+
**Response:**
117+
```json
118+
{
119+
"success": true,
120+
"prediction": {
121+
"shape": [1, 2, 96, 96, 96],
122+
"min_value": 0.0,
123+
"max_value": 1.0,
124+
"unique_labels": [0, 1],
125+
"num_labels": 2
126+
},
127+
"segmentation_shape": [1, 2, 96, 96, 96],
128+
"metadata": {
129+
"image_shape": [1, 1, 96, 96, 96],
130+
"processing_time": 2.345,
131+
"device": "cuda"
132+
},
133+
"message": "Inference completed successfully in 2.345s"
134+
}
135+
```
136+
137+
### `GET /docs`
138+
Interactive API documentation (Swagger UI)
139+
140+
### `GET /redoc`
141+
Alternative API documentation (ReDoc)
142+
143+
## 🐳 Docker Deployment
144+
145+
### Build and Run with Docker
146+
147+
```bash
148+
# Build the image
149+
docker build -t monai-fastapi -f docker/Dockerfile .
150+
151+
# Run the container
152+
docker run -p 8000:8000 monai-fastapi
153+
```
154+
155+
### Or use Docker Compose
156+
157+
```bash
158+
# Start the service
159+
docker-compose -f docker/docker-compose.yml up -d
160+
161+
# View logs
162+
docker-compose -f docker/docker-compose.yml logs -f
163+
164+
# Stop the service
165+
docker-compose -f docker/docker-compose.yml down
166+
```
167+
168+
## πŸ“ Usage Examples
169+
170+
### Python Client
171+
172+
```python
173+
from examples.client import MONAIClient
174+
175+
# Initialize client
176+
client = MONAIClient(base_url="http://localhost:8000")
177+
178+
# Check health
179+
health = client.health_check()
180+
print(health)
181+
182+
# Make prediction
183+
result = client.predict("path/to/image.nii.gz")
184+
print(result)
185+
```
186+
187+
### Command Line
188+
189+
```bash
190+
# Check health
191+
python examples/client.py --health
192+
193+
# Run prediction
194+
python examples/client.py --image path/to/image.nii.gz
195+
```
196+
197+
### cURL Examples
198+
199+
```bash
200+
# Health check
201+
curl http://localhost:8000/health
202+
203+
# Prediction
204+
curl -X POST http://localhost:8000/predict \
205+
-F "file=@tests/sample_image.nii.gz"
206+
```
207+
208+
## πŸ§ͺ Running Tests
209+
210+
```bash
211+
# Install test dependencies
212+
pip install pytest pytest-asyncio httpx
213+
214+
# Run all tests
215+
pytest tests/
216+
217+
# Run with coverage
218+
pytest tests/ --cov=app --cov-report=html
219+
```
220+
221+
## πŸ” Model Information
222+
223+
**Default Model:** spleen_ct_segmentation
224+
225+
This tutorial uses MONAI's spleen CT segmentation bundle, which:
226+
- Segments spleen from CT scans
227+
- Pre-trained on Medical Segmentation Decathlon dataset
228+
- Fast inference (~2-3 seconds on GPU)
229+
- Good starting point for learning deployment
230+
231+
**To use a different model:**
232+
Edit `app/main.py` and change the model name in the `lifespan` function:
233+
```python
234+
model_loader.load_model(
235+
model_name="your_model_name", # Change this
236+
bundle_dir="./models"
237+
)
238+
```
239+
240+
## βš™οΈ Configuration
241+
242+
### Environment Variables
243+
244+
Create a `.env` file for configuration:
245+
246+
```env
247+
# Server configuration
248+
HOST=0.0.0.0
249+
PORT=8000
250+
LOG_LEVEL=info
251+
252+
# Model configuration
253+
MODEL_NAME=spleen_ct_segmentation
254+
MODEL_DIR=./models
255+
256+
# Performance
257+
WORKERS=1
258+
```
259+
260+
### GPU Support
261+
262+
The application automatically detects and uses GPU if available:
263+
- **With GPU:** Faster inference, handles larger images
264+
- **Without GPU:** Runs on CPU (slower but works)
265+
266+
## 🚦 Production Considerations
267+
268+
### Security
269+
- Add authentication (JWT, API keys)
270+
- Validate file sizes and types
271+
- Use HTTPS in production
272+
- Set CORS origins explicitly
273+
274+
### Performance
275+
- Use multiple worker processes for scaling
276+
- Add caching for frequently used models
277+
- Implement request queuing for high load
278+
- Consider model quantization for speed
279+
280+
### Monitoring
281+
- Add logging and metrics
282+
- Track inference times
283+
- Monitor memory usage
284+
- Set up health check endpoints
285+
286+
### Example Production Command
287+
288+
```bash
289+
uvicorn app.main:app \
290+
--host 0.0.0.0 \
291+
--port 8000 \
292+
--workers 4 \
293+
--log-level info \
294+
--proxy-headers \
295+
--forwarded-allow-ips='*'
296+
```
297+
298+
## πŸ› Troubleshooting
299+
300+
### Model Download Fails
301+
```
302+
Error: Failed to download model bundle
303+
Solution: Check internet connection and MONAI bundle name
304+
```
305+
306+
### Out of Memory
307+
```
308+
Error: CUDA out of memory
309+
Solution: Reduce batch size or use CPU with smaller model
310+
```
311+
312+
### File Format Error
313+
```
314+
Error: Invalid file format
315+
Solution: Ensure file is NIfTI format (.nii or .nii.gz)
316+
```
317+
318+
### Port Already in Use
319+
```
320+
Error: Address already in use
321+
Solution: Change port or kill process using port 8000
322+
```
323+
324+
## πŸ“š Additional Resources
325+
326+
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
327+
- [MONAI Documentation](https://docs.monai.io/)
328+
- [MONAI Model Zoo](https://monai.io/model-zoo.html)
329+
- [MONAI Bundle Guide](https://docs.monai.io/en/stable/bundle_intro.html)
330+
- [Docker Documentation](https://docs.docker.com/)
331+
332+
## 🀝 Contributing
333+
334+
This tutorial is part of the MONAI tutorials collection. Contributions welcome!
335+
336+
## πŸ“„ License
337+
338+
Copyright 2025 MONAI Consortium
339+
Licensed under the Apache License, Version 2.0
340+
341+
## πŸ™‹ Support
342+
343+
For questions about this tutorial:
344+
- Open an issue on GitHub
345+
- Visit MONAI community forums
346+
- Check existing tutorials for similar examples
347+
348+
---
349+
350+
**Next Steps:**
351+
1. βœ… Run through the tutorial
352+
2. βœ… Experiment with different models
353+
3. βœ… Deploy to your infrastructure
354+
4. βœ… Build your own medical AI application!
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
FastAPI Inference Service for MONAI Models
3+
4+
This package provides a production-ready REST API for deploying MONAI model bundles.
5+
"""
6+
7+
__version__ = "1.0.0"

0 commit comments

Comments
Β (0)