Files
scrap/pricewatch/app/api/schemas.py
Gilles Soulier d0b73b9319 codex2
2026-01-14 21:54:55 +01:00

213 lines
4.8 KiB
Python

"""
Schemas API FastAPI pour Phase 3.
"""
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field
class HealthStatus(BaseModel):
db: bool
redis: bool
class ProductOut(BaseModel):
id: int
source: str
reference: str
url: str
title: Optional[str] = None
category: Optional[str] = None
description: Optional[str] = None
currency: Optional[str] = None
msrp: Optional[float] = None
first_seen_at: datetime
last_updated_at: datetime
latest_price: Optional[float] = None
latest_shipping_cost: Optional[float] = None
latest_stock_status: Optional[str] = None
latest_fetched_at: Optional[datetime] = None
images: list[str] = []
specs: dict[str, str] = {}
discount_amount: Optional[float] = None
discount_percent: Optional[float] = None
class ProductCreate(BaseModel):
source: str
reference: str
url: str
title: Optional[str] = None
category: Optional[str] = None
description: Optional[str] = None
currency: Optional[str] = None
msrp: Optional[float] = None
class ProductUpdate(BaseModel):
url: Optional[str] = None
title: Optional[str] = None
category: Optional[str] = None
description: Optional[str] = None
currency: Optional[str] = None
msrp: Optional[float] = None
class PriceHistoryOut(BaseModel):
id: int
product_id: int
price: Optional[float] = None
shipping_cost: Optional[float] = None
stock_status: Optional[str] = None
fetch_method: str
fetch_status: str
fetched_at: datetime
class PriceHistoryCreate(BaseModel):
product_id: int
price: Optional[float] = None
shipping_cost: Optional[float] = None
stock_status: Optional[str] = None
fetch_method: str
fetch_status: str
fetched_at: datetime
class PriceHistoryUpdate(BaseModel):
price: Optional[float] = None
shipping_cost: Optional[float] = None
stock_status: Optional[str] = None
fetch_method: Optional[str] = None
fetch_status: Optional[str] = None
fetched_at: Optional[datetime] = None
class ScrapingLogOut(BaseModel):
id: int
product_id: Optional[int] = None
url: str
source: str
reference: Optional[str] = None
fetch_method: str
fetch_status: str
fetched_at: datetime
duration_ms: Optional[int] = None
html_size_bytes: Optional[int] = None
errors: Optional[list[str]] = None
notes: Optional[list[str]] = None
class WebhookOut(BaseModel):
id: int
event: str
url: str
enabled: bool
secret: Optional[str] = None
created_at: datetime
class WebhookCreate(BaseModel):
event: str
url: str
enabled: bool = True
secret: Optional[str] = None
class WebhookUpdate(BaseModel):
event: Optional[str] = None
url: Optional[str] = None
enabled: Optional[bool] = None
secret: Optional[str] = None
class WebhookTestResponse(BaseModel):
status: str
class ScrapingLogCreate(BaseModel):
product_id: Optional[int] = None
url: str
source: str
reference: Optional[str] = None
fetch_method: str
fetch_status: str
fetched_at: datetime
duration_ms: Optional[int] = None
html_size_bytes: Optional[int] = None
errors: Optional[list[str]] = None
notes: Optional[list[str]] = None
class ScrapingLogUpdate(BaseModel):
product_id: Optional[int] = None
url: Optional[str] = None
source: Optional[str] = None
reference: Optional[str] = None
fetch_method: Optional[str] = None
fetch_status: Optional[str] = None
fetched_at: Optional[datetime] = None
duration_ms: Optional[int] = None
html_size_bytes: Optional[int] = None
errors: Optional[list[str]] = None
notes: Optional[list[str]] = None
class EnqueueRequest(BaseModel):
url: str = Field(..., description="URL du produit")
use_playwright: Optional[bool] = None
save_db: bool = True
class EnqueueResponse(BaseModel):
job_id: str
class ScheduleRequest(BaseModel):
url: str = Field(..., description="URL du produit")
interval_hours: int = Field(default=24, ge=1)
use_playwright: Optional[bool] = None
save_db: bool = True
class ScheduleResponse(BaseModel):
job_id: str
next_run: datetime
class ScrapePreviewRequest(BaseModel):
url: str
use_playwright: Optional[bool] = None
class ScrapePreviewResponse(BaseModel):
success: bool
snapshot: Optional[dict[str, object]] = None
error: Optional[str] = None
class ScrapeCommitRequest(BaseModel):
snapshot: dict[str, object]
class ScrapeCommitResponse(BaseModel):
success: bool
product_id: Optional[int] = None
error: Optional[str] = None
class VersionResponse(BaseModel):
api_version: str
class BackendLogEntry(BaseModel):
time: datetime
level: str
message: str
class UvicornLogEntry(BaseModel):
line: str