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 are pending
ci / test (push) Has started running

This commit is contained in:
2026-08-09 15:54:53 +00:00
parent 16d6b7e7ce
commit 00ff53324a

View File

@@ -1,36 +1,37 @@
from datetime import datetime, timezone
from datetime import UTC, datetime
from enum import StrEnum
from uuid import UUID
from pydantic import AnyHttpUrl, BaseModel, ConfigDict, Field
from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic.networks import AnyHttpUrl
def utc_now() -> datetime:
return datetime.now(timezone.utc)
class HealthState(StrEnum):
class State(StrEnum):
unknown = "unknown"
up = "up"
down = "down"
error = "error"
class MonitorCreate(BaseModel):
name: str = Field(min_length=1, max_length=120)
class MonitorInput(BaseModel):
name: str = Field(min_length=1, max_length=100)
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 MonitorUpdate(MonitorCreate):
pass
class CurrentStatus(BaseModel):
state: HealthState
checked_at: datetime
latency_ms: float = Field(ge=0)
class CheckSnapshot(BaseModel):
state: State = State.unknown
checked_at: datetime | None = None
latency_ms: float | None = None
http_status: int | None = None
error_code: str | None = None
error_message: str | None = None
error: str | None = None
class Monitor(BaseModel):
@@ -39,18 +40,16 @@ class Monitor(BaseModel):
id: UUID
name: str
url: AnyHttpUrl
timeout_seconds: float | None
created_at: datetime
updated_at: datetime
revision: int
current_status: CurrentStatus | None = None
status: CheckSnapshot
class CheckResponse(BaseModel):
class CheckResult(CheckSnapshot):
monitor_id: UUID
status: CurrentStatus
applied: bool
class ErrorDetail(BaseModel):
code: str
message: str
def now() -> datetime:
return datetime.now(UTC)