feat: add card-renderer internal service (v1)

- New card-renderer FastAPI service (Python 3.11 + Pillow)
  - GET /health, GET /templates
  - POST /render (URL input)
  - POST /render/file (multipart upload)
  - POST /render/meta (dry-run layout metadata)
  - nova-artwork-v1 template: cover crop, gradient overlay, text, logo
  - SSRF-safe async image fetch with redirect validation
  - Smart center cover crop isolated for future YOLO focal-point support
  - Graceful font/logo fallback when assets are absent

- docker-compose.yml: add card-renderer service + healthcheck;
  extend gateway with CARD_RENDERER_URL and depends_on

- gateway/main.py: proxy endpoints under /cards/*
  - GET  /cards/templates
  - POST /cards/render
  - POST /cards/render/file
  - POST /cards/render/meta
  All protected by existing APIKeyMiddleware
This commit is contained in:
2026-03-31 10:39:29 +02:00
parent 613023de86
commit 58ee1b3bdd
12 changed files with 589 additions and 1 deletions

View File

@@ -12,6 +12,7 @@ services:
- BLIP_URL=http://blip:8000
- YOLO_URL=http://yolo:8000
- QDRANT_SVC_URL=http://qdrant-svc:8000
- CARD_RENDERER_URL=http://card-renderer:8000
- API_KEY=${API_KEY}
- VISION_TIMEOUT=300
- MAX_IMAGE_BYTES=52428800
@@ -24,6 +25,26 @@ services:
condition: service_healthy
qdrant-svc:
condition: service_healthy
card-renderer:
condition: service_healthy
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=5).read()"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
card-renderer:
build:
context: .
dockerfile: card-renderer/Dockerfile
environment:
- CARD_DEFAULT_FONT=/app/assets/fonts/Inter-Regular.ttf
- CARD_BOLD_FONT=/app/assets/fonts/Inter-Bold.ttf
- CARD_LOGO_PATH=/app/assets/logo.png
- CARD_MAX_IMAGE_BYTES=52428800
- CARD_DEFAULT_OUTPUT=webp
- CARD_DEFAULT_QUALITY=90
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=5).read()"]
interval: 30s