Download Sidecar/knowledge/11_FASTAPI.md from smlflg/Sidecar-Workspace: direct link, hf CLI and curl.
- Browser
- Download file 9.61 kB
-
https://huggingface.co/smlflg/Sidecar-Workspace/resolve/main/Sidecar/knowledge/11_FASTAPI.md
- Command line
-
hf download hf://smlflg/Sidecar-Workspace/Sidecar/knowledge/11_FASTAPI.md
-
curl -L -o 11_FASTAPI.md https://huggingface.co/smlflg/Sidecar-Workspace/resolve/main/Sidecar/knowledge/11_FASTAPI.md
FastAPI β Referenz fuer das Keeper System
Was macht FastAPI hier?
FastAPI ist unser REST-API-Layer β die Schnittstelle zwischen der Aussenwelt und dem System. Ueber die API kann man:
- Produkte zur Ueberwachung hinzufuegen (Watches)
- Preise manuell pruefen
- Deals suchen (via Keepa oder Elasticsearch)
- Preis-Statistiken und -Historie abrufen
- System-Status und Token-Budget einsehen
Version: 2.0.0
Port: 8000
Datei: src/api/main.py
Swagger UI
FastAPI generiert automatisch eine interaktive API-Dokumentation:
URL: http://localhost:8000/docs
Dort kannst du jeden Endpoint direkt im Browser testen.
Startup (Lifespan)
@asynccontextmanager
async def lifespan(app: FastAPI):
# Beim Start:
await init_db() # PostgreSQL Tabellen erstellen
await es_service.connect() # Elasticsearch verbinden
yield # App laeuft
# Beim Shutdown:
await es_service.close()
Was passiert beim Start:
- Datenbank-Tabellen werden erstellt (falls nicht vorhanden)
- Elasticsearch-Verbindung wird hergestellt + Indices erstellt
- App ist bereit
CORS Middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5601", "http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Erlaubt Zugriffe von:
localhost:5601β Kibana Dashboardslocalhost:3000β Frontend (falls vorhanden)
Endpoint-Referenz
Health & Status
GET /health
System-Health-Check. Zeigt Token-Status und Watch-Anzahl.
curl http://localhost:8000/health
{
"status": "healthy",
"timestamp": "2026-02-20T12:00:00",
"tokens_available": 150,
"watches_count": 12
}
GET /api/v1/status
Detaillierter System-Status mit Token Bucket und Rate Limit Info.
curl http://localhost:8000/api/v1/status
{
"system": "healthy",
"version": "2.0.0",
"token_bucket": {
"tokens_available": 150,
"tokens_per_minute": 200,
"last_refill": "2026-02-20T11:59:00",
"total_tokens_consumed": 450
},
"rate_limit": {
"tokens_available": 150,
"refill_in_seconds": 45
}
}
Watches (Preis-Ueberwachung)
GET /api/v1/watches?user_id=UUID
Alle aktiven Watches eines Users auflisten.
curl "http://localhost:8000/api/v1/watches?user_id=550e8400-e29b-41d4-a716-446655440000"
[
{
"id": "uuid...",
"asin": "B07W6JN8V8",
"target_price": 45.00,
"current_price": 49.99,
"status": "ACTIVE",
"last_checked_at": "2026-02-20T06:00:00",
"created_at": "2026-02-15T10:30:00"
}
]
POST /api/v1/watches?user_id=UUID
Neue Watch erstellen. Fragt sofort den aktuellen Preis bei Keepa ab.
curl -X POST "http://localhost:8000/api/v1/watches?user_id=UUID" \
-H "Content-Type: application/json" \
-d '{"asin": "B07W6JN8V8", "target_price": 45.00}'
Request Body:
{
"asin": "B07W6JN8V8", // Genau 10 Zeichen
"target_price": 45.00 // EUR, muss > 0 sein
}
Response: Watch-Objekt mit aktuellem Preis (201 Created)
Fehler:
- 400 β Ungueltige ASIN oder target_price
- 500 β Keepa API Fehler
DELETE /api/v1/watches/{watch_id}?user_id=UUID
Watch loeschen (Soft Delete β Status wird INACTIVE).
curl -X DELETE "http://localhost:8000/api/v1/watches/uuid...?user_id=UUID"
Preis-Check
POST /api/v1/price/check
Manueller Preis-Check fuer eine einzelne ASIN. Ruft Keepa API auf.
curl -X POST http://localhost:8000/api/v1/price/check \
-H "Content-Type: application/json" \
-d '{"asin": "B07W6JN8V8"}'
{
"asin": "B07W6JN8V8",
"title": "Logitech K380 Multi-Device Bluetooth Tastatur",
"current_price": 49.99,
"list_price": 59.99,
"rating": 4.5,
"category": "340843031",
"timestamp": "2026-02-20T12:00:00"
}
Kosten: ~15 Keepa-Tokens
POST /api/v1/price/check-all
Alle aktiven Watches pruefen. Wie ein manueller Scheduler-Durchlauf.
curl -X POST http://localhost:8000/api/v1/price/check-all
{
"status": "completed",
"watches_checked": 12,
"price_changes": 3,
"alerts_triggered": 1,
"timestamp": "2026-02-20T12:05:00"
}
Achtung: Kostet 15 Tokens PRO Watch. Bei 50 Watches = 750 Tokens.
Deals
POST /api/v1/deals/search
Deal-Suche via Keepa API (oder Product-Fallback).
curl -X POST http://localhost:8000/api/v1/deals/search \
-H "Content-Type: application/json" \
-d '{
"categories": ["340843031"],
"min_discount": 20,
"max_discount": 80,
"min_price": 15,
"max_price": 200,
"min_rating": 4.0
}'
[
{
"asin": "B07W6JN8V8",
"title": "Logitech K380 QWERTZ",
"current_price": 39.99,
"list_price": 59.99,
"discount_percent": 33.4,
"rating": 4.5,
"reviews": 1847,
"prime_eligible": true,
"url": "https://amazon.de/dp/B07W6JN8V8",
"deal_score": 8.7,
"source": "product_api"
}
]
Fehler:
- 429 β Token Limit erreicht
- 403 β Deal-API nicht verfuegbar (NoDealAccessError)
POST /api/v1/deals/es-search
Deal-Suche via Elasticsearch (Volltextsuche + Aggregationen).
curl -X POST http://localhost:8000/api/v1/deals/es-search \
-H "Content-Type: application/json" \
-d '{
"query": "logitech mechanisch",
"min_discount": 15,
"min_rating": 4.0,
"page": 0,
"size": 10
}'
{
"total": 47,
"deals": [
{
"asin": "B07W6JN8V8",
"title": "Logitech MX Mechanical",
"current_price": 119.99,
"discount_percent": 25.0,
"_score": 12.5
}
],
"aggregations": {
"by_category": { ... },
"by_domain": { ... },
"price_stats": { "min": 15.99, "max": 299.99, "avg": 65.50 },
"discount_stats": { "min": 15.0, "max": 70.0, "avg": 32.5 }
}
}
Features:
multi_matchmit Fuzziness (Tippfehler-tolerant)titlewird 3x hoeher gewichtet als description- Aggregationen fuer Dashboard-Widgets
- Sortierung: deal_score desc, dann timestamp desc
GET /api/v1/deals/aggregations?min_discount=20&min_rating=4
Deal-Statistiken aus Elasticsearch.
POST /api/v1/deals/index
Manuell ein Deal-Dokument in Elasticsearch indexieren.
Preis-Historie
GET /api/v1/prices/{asin}/history?days=30
Preishistorie aus PostgreSQL (price_history Tabelle).
curl "http://localhost:8000/api/v1/prices/B07W6JN8V8/history?days=30"
{
"asin": "B07W6JN8V8",
"history": [
{"price": 49.99, "recorded_at": "2026-02-01T12:00:00", "source": "kafka_deals"},
{"price": 45.99, "recorded_at": "2026-02-05T12:00:00", "source": null},
{"price": 39.99, "recorded_at": "2026-02-10T12:00:00", "source": "kafka_deals"}
],
"count": 3,
"period_days": 30
}
GET /api/v1/prices/{asin}/stats
Preis-Statistiken aus Elasticsearch (Aggregationen).
curl "http://localhost:8000/api/v1/prices/B07W6JN8V8/stats"
{
"asin": "B07W6JN8V8",
"min": 29.99,
"max": 59.99,
"avg": 42.50,
"current": 39.99,
"data_points": 47,
"price_over_time": [
{"date": "2026-02-01", "avg_price": 49.99, "min_price": 45.99, "max_price": 52.99}
]
}
Token & Rate Limit
GET /api/v1/tokens
Token Bucket Status (intern, nicht Keepa API).
GET /api/v1/rate-limit
Rate Limit Status direkt von der Keepa API.
Pydantic Models
Alle Request/Response Models sind in src/api/main.py definiert:
| Model | Verwendung |
|---|---|
WatchCreateRequest |
POST /watches Body |
WatchResponse |
GET/POST /watches Response |
WatchDeleteResponse |
DELETE /watches Response |
DealSearchRequest |
POST /deals/search Body |
DealResponse |
POST /deals/search Response Items |
ElasticsearchDealSearchRequest |
POST /deals/es-search Body |
ElasticsearchDealResponse |
POST /deals/es-search Response |
HealthResponse |
GET /health Response |
PriceCheckRequest |
POST /price/check Body |
PriceCheckResponse |
POST /price/check Response |
TriggerCheckResponse |
POST /price/check-all Response |
Konfiguration
In src/config.py:
app_name: str = "Keeper System"
debug: bool = False
log_level: str = "INFO"
In docker-compose.yml:
app:
build: .
ports:
- "8000:8000"
command: uvicorn src.api.main:app --host 0.0.0.0 --port 8000
Fehlerbehandlung
| HTTP Status | Bedeutung | Wann |
|---|---|---|
| 200 | OK | Erfolgreiche Abfrage |
| 201 | Created | Watch erstellt |
| 400 | Bad Request | Ungueltige ASIN, fehlende Parameter |
| 403 | Forbidden | Deal-API nicht im Plan |
| 404 | Not Found | ASIN nicht gefunden, Watch nicht gefunden |
| 429 | Too Many Requests | Keepa Token Limit |
| 500 | Internal Error | Unerwarteter Fehler |
| 503 | Service Unavailable | Elasticsearch nicht erreichbar |
Testen
# Health Check
curl http://localhost:8000/health
# Watch erstellen
curl -X POST "http://localhost:8000/api/v1/watches?user_id=00000000-0000-0000-0000-000000000001" \
-H "Content-Type: application/json" \
-d '{"asin": "B07W6JN8V8", "target_price": 45.00}'
# Preis checken
curl -X POST http://localhost:8000/api/v1/price/check \
-H "Content-Type: application/json" \
-d '{"asin": "B07W6JN8V8"}'
# Elasticsearch Deal-Suche
curl -X POST http://localhost:8000/api/v1/deals/es-search \
-H "Content-Type: application/json" \
-d '{"query": "cherry tastatur", "min_discount": 10}'