"""Disposable standard-project demonstration; creates real retained resources. Download alongside agenthotel.py. Run only against an authorized test project. No automatic retries: persist each operation's identity and exact input before adapting this example to a continuing task. Do not print secret-bearing results. """ from datetime import datetime, timedelta, timezone import hashlib import json import os from agenthotel import Client, segment, uuid7 def demonstrate(client, project): base = "/api/v1/projects/" + segment(project) def create(path, value): operation = uuid7() value = dict(value, operation_id=operation) response = client.request("POST", base + path, body=json.dumps(value).encode(), idempotency_key=operation) if response.status not in (200, 201): raise RuntimeError("creation failed; reconcile the saved request before retrying") return response.json() inbox = create("/inboxes", {"name": "CI result and continuation", "retention_seconds": 86400, "max_payload_bytes": 65536}) # The callback is a narrowly scoped bearer capability. A CI job needs only # this token, not the project key. Stable job identity prevents duplicate events. callback = Client(client_origin(), timeout=30) result = callback.request("POST", "/hooks/v1/" + segment(inbox["write_token"]), body=b'{"build":"example-build-1","result":"passed"}', idempotency_key="example-build-1") if result.status != 202: raise RuntimeError("callback not accepted") artifact = b"reviewed specification version 1" approval = create("/approvals", {"inbox_id": inbox["id"], "title": "Approve specification?", "description": "Review the exact artifact before choosing.", "options": ["Approve", "Reject"], "access_mode": "link", "ttl_seconds": 3600, "artifact_reference": {"reference": "specs/release", "version": "v1", "sha256": hashlib.sha256(artifact).hexdigest()}}) # Deliver the one-time approval capability to the authorized reviewer through # your own secure channel. Creating a request never constitutes approval. when = (datetime.now(timezone.utc) + timedelta(minutes=10)).isoformat().replace("+00:00", "Z") schedule = create("/schedules", {"kind": "one_shot", "inbox_id": inbox["id"], "name": "Recheck approval", "run_at": when, "payload": {"approval_id": approval["id"]}}) # After the scheduled event arrives, read the approval and verify terminal # approval AND the exact current artifact reference/version/hash before acting. # Consumers acknowledge only after their own durable processing has committed. return {"inbox_id": inbox["id"], "approval_id": approval["id"], "schedule_id": schedule["id"]} def client_origin(): return os.environ["AGENTHOTEL_ORIGIN"] if __name__ == "__main__": demonstrate(Client(client_origin(), os.environ["AGENTHOTEL_PROJECT_KEY"]), os.environ["AGENTHOTEL_PROJECT_ID"])