content-understanding/docs/api.md

355 lines
5.7 KiB
Markdown

# REST API
The package includes a FastAPI service for HTTP-based content analysis.
## Running the Service
```bash
# Production
uvicorn lilith_content_understanding.api:app --host 0.0.0.0 --port 8002
# Development with auto-reload
uvicorn lilith_content_understanding.api:app --reload --port 8002
# With workers
uvicorn lilith_content_understanding.api:app --workers 4 --port 8002
```
## API Documentation
Once running, visit:
- **Swagger UI**: http://localhost:8002/docs
- **ReDoc**: http://localhost:8002/redoc
- **OpenAPI JSON**: http://localhost:8002/openapi.json
---
## Endpoints
### Health Check
```http
GET /health
```
Response:
```json
{
"status": "healthy",
"version": "0.1.0",
"detectors": {
"nsfw": true,
"body_parts": false
},
"analyzers": {
"depth": true,
"color": true,
"composition": true,
"scene": true
}
}
```
---
### NSFW Detection
```http
POST /detect/nsfw
Content-Type: multipart/form-data
file: <image file>
threshold: 0.7 (optional)
```
Response:
```json
{
"is_nsfw": false,
"confidence": 0.95,
"category": "safe",
"all_scores": {
"nsfw": 0.05,
"safe": 0.95
}
}
```
---
### Body Part Detection
```http
POST /detect/body-parts
Content-Type: multipart/form-data
file: <image file>
threshold: 0.4 (optional)
```
Response:
```json
{
"has_nudity": true,
"has_male_genitalia": false,
"has_female_genitalia": false,
"has_breasts": true,
"has_buttocks": false,
"gender_presentation": "female",
"gender_confidence": 0.85,
"body_parts": ["BREASTS", "FACE_FEMALE"],
"detections": [
{
"label": "FEMALE_BREAST_EXPOSED",
"confidence": 0.92,
"bbox": [0.3, 0.4, 0.7, 0.8],
"category": "BREASTS"
}
]
}
```
---
### Depth Analysis
```http
POST /analyze/depth
Content-Type: multipart/form-data
file: <image file>
include_map: false (optional, include base64 depth map)
model: "depth-anything-v2-small" (optional)
```
Response:
```json
{
"width": 512,
"height": 512,
"min_depth": 0.0,
"max_depth": 1.0,
"depth_map_base64": null
}
```
Get depth as image:
```http
GET /analyze/depth/image
Content-Type: multipart/form-data
file: <image file>
colormap: "magma" (optional)
```
Returns: `image/png`
---
### Color Analysis
```http
POST /analyze/colors
Content-Type: multipart/form-data
file: <image file>
num_colors: 5 (optional, 2-10)
```
Response:
```json
{
"colors": [
{
"rgb": [45, 52, 89],
"hex": "#2d3459",
"hsl": [230.5, 32.8, 26.3],
"percentage": 35.2,
"name": "blue"
}
],
"hex_colors": ["#2d3459", "#f5a623", ...],
"harmony_type": "complementary",
"mood": "cool",
"average_saturation": 45.2,
"average_lightness": 52.1
}
```
Get color swatch as image:
```http
GET /analyze/colors/swatch
Content-Type: multipart/form-data
file: <image file>
num_colors: 5 (optional)
width: 500 (optional)
height: 100 (optional)
```
Returns: `image/png`
---
### Composition Analysis
```http
POST /analyze/composition
Content-Type: multipart/form-data
file: <image file>
```
Response:
```json
{
"rule_of_thirds_score": 0.72,
"symmetry_score": 0.45,
"balance_score": 0.68,
"balance_type": "asymmetric",
"negative_space_ratio": 0.35,
"complexity_score": 0.52,
"focal_points": [
{
"x": 0.33,
"y": 0.33,
"strength": 0.85,
"quadrant": 1,
"on_thirds_intersection": true
}
],
"suggestions": [
"Consider adding more negative space for breathing room"
]
}
```
---
### Scene Classification
```http
POST /analyze/scene
Content-Type: multipart/form-data
file: <image file>
```
Response:
```json
{
"scene_type": "landscape",
"scene_confidence": 0.87,
"environment": "outdoor",
"time_of_day": "sunset",
"weather": "sunny",
"tags": ["landscape", "outdoor", "nature", "mountain"],
"suggested_styles": ["golden hour", "hdr", "dramatic"]
}
```
---
### Full Analysis
Perform all analyses in one request:
```http
POST /analyze/full
Content-Type: multipart/form-data
file: <image file>
include_nsfw: true (optional)
include_body_parts: false (optional)
include_depth: true (optional)
include_colors: true (optional)
include_composition: true (optional)
include_scene: true (optional)
```
Response includes all enabled analyses:
```json
{
"nsfw": { ... },
"body_parts": null,
"depth": { ... },
"colors": { ... },
"composition": { ... },
"scene": { ... }
}
```
---
## Python Client Example
```python
import httpx
# Upload image and get NSFW result
with open("image.jpg", "rb") as f:
response = httpx.post(
"http://localhost:8002/detect/nsfw",
files={"file": f},
params={"threshold": 0.7}
)
result = response.json()
print(f"NSFW: {result['is_nsfw']}")
# Full analysis
with open("image.jpg", "rb") as f:
response = httpx.post(
"http://localhost:8002/analyze/full",
files={"file": f},
params={
"include_body_parts": False,
"include_depth": True
}
)
result = response.json()
print(f"Scene: {result['scene']['scene_type']}")
```
---
## Error Responses
### 400 Bad Request
Invalid image file:
```json
{
"detail": "Invalid image: cannot identify image file"
}
```
### 501 Not Implemented
Missing optional dependency:
```json
{
"detail": "Body part detection requires nudenet. Install with: pip install lilith-content-understanding[nudenet]"
}
```
---
## CORS Configuration
```python
from lilith_content_understanding.api import create_app
app = create_app(
cors_origins=["http://localhost:3000", "https://myapp.com"]
)
```
---
## Custom Configuration
```python
from lilith_content_understanding.api import create_app
app = create_app(
title="My Content API",
version="1.0.0",
cors_origins=["*"],
)
```