- FastAPI + SQLite backend: tenants, jobs and runs, with an idempotent /api/v1/ingest endpoint authenticated by per-collector API keys - Runs store started_at and finished_at; "Last Run" is the most recent finish, and in-progress runs show as Running - Job modal shows a 30-day daily strip, success rate, and a filterable run list with per-run messages - nginx: HTTPS plus basic auth, ingest endpoint exempt; systemd unit - manage.py for API keys, job cleanup and demo data; pytest suite Co-Authored-By: Claude Opus 5.5 <[email protected]>
13 lines
335 B
Python
13 lines
335 B
Python
from datetime import UTC, datetime
|
|
|
|
# Every timestamp in the DB uses this exact format, so string comparison == chronological comparison.
|
|
DB_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
|
|
|
|
|
def utcnow() -> datetime:
|
|
return datetime.now(UTC).replace(microsecond=0)
|
|
|
|
|
|
def to_db(dt: datetime) -> str:
|
|
return dt.astimezone(UTC).strftime(DB_FORMAT)
|