67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
|
|
"""Feed Pydantic schemas."""
|
||
|
|
from pydantic import BaseModel, ConfigDict, Field, HttpUrl
|
||
|
|
|
||
|
|
|
||
|
|
class FeedBase(BaseModel):
|
||
|
|
"""Base feed schema."""
|
||
|
|
|
||
|
|
url: HttpUrl
|
||
|
|
title: str | None = Field(default="", max_length=512)
|
||
|
|
description: str | None = ""
|
||
|
|
category: str | None = Field(default="", max_length=128)
|
||
|
|
is_active: bool = True
|
||
|
|
fetch_interval_minutes: int = Field(default=60, ge=15)
|
||
|
|
priority: int = Field(default=5, ge=1, le=10)
|
||
|
|
parser_config: dict = {}
|
||
|
|
proxy_policy: str = "auto"
|
||
|
|
|
||
|
|
|
||
|
|
class FeedCreate(FeedBase):
|
||
|
|
"""Feed creation schema."""
|
||
|
|
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
class FeedUpdate(BaseModel):
|
||
|
|
"""Feed update schema."""
|
||
|
|
|
||
|
|
title: str | None = Field(default=None, max_length=512)
|
||
|
|
description: str | None = None
|
||
|
|
category: str | None = Field(default=None, max_length=128)
|
||
|
|
is_active: bool | None = None
|
||
|
|
fetch_interval_minutes: int | None = Field(default=None, ge=15)
|
||
|
|
priority: int | None = Field(default=None, ge=1, le=10)
|
||
|
|
parser_config: dict | None = None
|
||
|
|
proxy_policy: str | None = None
|
||
|
|
|
||
|
|
|
||
|
|
class FeedOut(FeedBase):
|
||
|
|
"""Feed output schema."""
|
||
|
|
|
||
|
|
model_config = ConfigDict(from_attributes=True)
|
||
|
|
|
||
|
|
id: str
|
||
|
|
last_fetch_at: str | None = None
|
||
|
|
last_fetch_status: str | None = None
|
||
|
|
last_error: str | None = None
|
||
|
|
error_type: str | None = None
|
||
|
|
success_count: int = 0
|
||
|
|
fail_count: int = 0
|
||
|
|
article_count: int = 0
|
||
|
|
health_status: str = "unknown"
|
||
|
|
created_at: str
|
||
|
|
updated_at: str
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def model_validate(cls, obj):
|
||
|
|
"""Override to compute health_status and format datetimes."""
|
||
|
|
data = {}
|
||
|
|
for key in obj.__dict__:
|
||
|
|
value = getattr(obj, key)
|
||
|
|
if key in ("created_at", "updated_at", "last_fetch_at") and value is not None:
|
||
|
|
data[key] = value.isoformat()
|
||
|
|
else:
|
||
|
|
data[key] = value
|
||
|
|
data["health_status"] = obj.health_status()
|
||
|
|
return cls.model_construct(**data)
|