generated from coulomb/repo-seed
Add ISSUE_CORE_API_KEY auth to IssueCoreRestSink
Issue-core requires a shared ingestion key on POST /issues/. The REST sink now sends Authorization: Bearer using ISSUE_CORE_API_KEY and fails fast when the key is missing under ISSUE_SINK_TYPE=rest. Updates .env.example, emission boundary docs, and unit tests for the header contract and missing-key error.
This commit is contained in:
@@ -20,7 +20,8 @@ from activity_core.rules.models import TaskRef, TaskSpec
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ISSUE_CORE_URL = os.environ.get("ISSUE_CORE_URL", "http://127.0.0.1:8010")
|
||||
ISSUE_CORE_URL = os.environ.get("ISSUE_CORE_URL", "http://127.0.0.1:8765")
|
||||
ISSUE_CORE_API_KEY_ENV = "ISSUE_CORE_API_KEY"
|
||||
ISSUE_SINK_TYPE = os.environ.get("ISSUE_SINK_TYPE", "rest")
|
||||
|
||||
|
||||
@@ -30,10 +31,30 @@ class IssueSink(ABC):
|
||||
|
||||
|
||||
class IssueCoreRestSink(IssueSink):
|
||||
"""POSTs to issue-core REST API. Config: ISSUE_CORE_URL env var."""
|
||||
"""POSTs to issue-core REST API.
|
||||
|
||||
def __init__(self, base_url: str = ISSUE_CORE_URL) -> None:
|
||||
Config: ISSUE_CORE_URL and ISSUE_CORE_API_KEY env vars (shared key with
|
||||
the issue-core server).
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
base_url: str = ISSUE_CORE_URL,
|
||||
api_key: str | None = None,
|
||||
) -> None:
|
||||
self._base_url = base_url.rstrip("/")
|
||||
if api_key is not None:
|
||||
self._api_key = api_key.strip()
|
||||
else:
|
||||
self._api_key = os.environ.get(ISSUE_CORE_API_KEY_ENV, "").strip()
|
||||
|
||||
def _auth_headers(self) -> dict[str, str]:
|
||||
if not self._api_key:
|
||||
raise RuntimeError(
|
||||
f"{ISSUE_CORE_API_KEY_ENV} is not set. "
|
||||
"Required when ISSUE_SINK_TYPE=rest."
|
||||
)
|
||||
return {"Authorization": f"Bearer {self._api_key}"}
|
||||
|
||||
def emit(self, task_spec: TaskSpec) -> TaskRef:
|
||||
payload = {
|
||||
@@ -48,7 +69,12 @@ class IssueCoreRestSink(IssueSink):
|
||||
"triggering_event_id": task_spec.triggering_event_id,
|
||||
"activity_definition_id": task_spec.activity_definition_id,
|
||||
}
|
||||
resp = httpx.post(f"{self._base_url}/issues/", json=payload, timeout=10.0)
|
||||
resp = httpx.post(
|
||||
f"{self._base_url}/issues/",
|
||||
json=payload,
|
||||
headers=self._auth_headers(),
|
||||
timeout=10.0,
|
||||
)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
return TaskRef(
|
||||
|
||||
Reference in New Issue
Block a user