Parent: nyjc-computing/campus#816 (item 1 — SDK trace propagation)
What
Instrument the campus_python SDK's outbound HTTP so that calls made while the host app is handling a traced request carry Campus trace context headers:
X-Request-ID — the trace id of the host request (32-hex)
X-Parent-Span-ID — the span id of the host request's span
Receiving campus services (campus.auth, campus.api) already turn these headers into a child span of the caller's span (#794) — today only campus.api's embedded client does this, via campus.audit.middleware.tracing.instrument_requests_session in the campus repo. The SDK itself does not (code search confirms no trace headers anywhere in this repo).
Why
Every server-to-server call a client app's backend makes to campus.auth currently starts a brand-new 1-span trace with no parentage — the audit UI can show who (client_id, campus#802) and when, but not which route in the caller fired it or in what sequence. With SDK propagation (plus host-app tracing, see campus#816 item 2 / the classroom sub-issue), an SDK call lands as a child span and the waterfall answers those questions.
Implementation notes / constraints
- Reference implementation:
instrument_requests_session() wraps requests.Session.request, computes headers at call time from the active request context (safe for shared sessions; calls outside a request context — startup, background threads — stay unparented), and is idempotent.
- The SDK must stay host-agnostic: the flask dependency should be optional/guarded — read the host's request context if one exists (classroom is Flask), emit no headers otherwise. Decide whether to depend on
campus for the helper (couples the client package to the server monorepo — probably not) or replicate the ~30-line wrapper.
- The campus repo's Flask test harness patches the transport (
tests.flask_test), so cross-repo testing can lean on campus#816's acceptance flow rather than a live deployment.
Acceptance
Parent: nyjc-computing/campus#816 (item 1 — SDK trace propagation)
What
Instrument the campus_python SDK's outbound HTTP so that calls made while the host app is handling a traced request carry Campus trace context headers:
X-Request-ID— the trace id of the host request (32-hex)X-Parent-Span-ID— the span id of the host request's spanReceiving campus services (campus.auth, campus.api) already turn these headers into a child span of the caller's span (#794) — today only campus.api's embedded client does this, via
campus.audit.middleware.tracing.instrument_requests_sessionin the campus repo. The SDK itself does not (code search confirms no trace headers anywhere in this repo).Why
Every server-to-server call a client app's backend makes to campus.auth currently starts a brand-new 1-span trace with no parentage — the audit UI can show who (client_id, campus#802) and when, but not which route in the caller fired it or in what sequence. With SDK propagation (plus host-app tracing, see campus#816 item 2 / the classroom sub-issue), an SDK call lands as a child span and the waterfall answers those questions.
Implementation notes / constraints
instrument_requests_session()wrapsrequests.Session.request, computes headers at call time from the active request context (safe for shared sessions; calls outside a request context — startup, background threads — stay unparented), and is idempotent.campusfor the helper (couples the client package to the server monorepo — probably not) or replicate the ~30-line wrapper.tests.flask_test), so cross-repo testing can lean on campus#816's acceptance flow rather than a live deployment.Acceptance