decomposer: generate deliverable files for Define the service contract and project architecture for the FastAPI endpoint monitoring service.; Implement the typed monitor CRUD API and concurrency-safe in-memory state according to the service design.; Implement secure on-demand endpoint checks with status updates, latency measurement, robust error handling, and redacted structured logs.; Add operational API endpoints and environment-driven runtime configuration to the monitoring service.; Create automated tests for the monitoring service.; Package the service with Docker and developer documentation.; Validate the complete project.
Some checks failed
ci / test (push) Has been cancelled

This commit is contained in:
2026-08-09 15:57:37 +00:00
parent d22f27f817
commit 14a443d589

View File

@@ -1,55 +1,45 @@
from datetime import UTC, datetime from datetime import datetime
from enum import StrEnum from enum import StrEnum
from uuid import UUID from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field, field_validator from pydantic import AnyHttpUrl, BaseModel, ConfigDict, Field
from pydantic.networks import AnyHttpUrl
class State(StrEnum): class MonitorState(StrEnum):
unknown = "unknown" UNKNOWN = "unknown"
up = "up" UP = "up"
down = "down" DOWN = "down"
error = "error" ERROR = "error"
BLOCKED = "blocked"
class MonitorInput(BaseModel): class MonitorCreate(BaseModel):
name: str = Field(min_length=1, max_length=100) name: str = Field(min_length=1, max_length=100)
url: AnyHttpUrl url: AnyHttpUrl
timeout_seconds: float | None = Field(default=None, gt=0, le=30)
@field_validator("url")
@classmethod
def reject_credentials(cls, value: AnyHttpUrl) -> AnyHttpUrl:
if value.username or value.password:
raise ValueError("URL credentials are not allowed")
return value
class CheckSnapshot(BaseModel): class MonitorUpdate(MonitorCreate):
state: State = State.unknown pass
class StatusSnapshot(BaseModel):
state: MonitorState = MonitorState.UNKNOWN
checked_at: datetime | None = None checked_at: datetime | None = None
latency_ms: float | None = None latency_ms: float | None = Field(default=None, ge=0)
http_status: int | None = None http_status: int | None = Field(default=None, ge=100, le=599)
error: str | None = None error: str | None = None
class Monitor(BaseModel): class Monitor(BaseModel):
model_config = ConfigDict(frozen=True) model_config = ConfigDict(from_attributes=True)
id: UUID id: UUID
name: str name: str
url: AnyHttpUrl url: AnyHttpUrl
timeout_seconds: float | None
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime
revision: int status: StatusSnapshot
status: CheckSnapshot
class CheckResult(CheckSnapshot): class Health(BaseModel):
monitor_id: UUID status: str
def now() -> datetime:
return datetime.now(UTC)