You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
An SDK call made inside a traced host request carries both headers; the same call outside any request context carries none.
End-to-end (with the host-app lane from campus#816): the auth service records the SDK call as a child span of the host's span, visible in the audit waterfall.
Delivered by #93 (merged, dd84fc7) and verified end-to-end on the dev deployment.
Acceptance:
SDK call inside a traced host request carries both headers — live-observed: a classroom request produced trace 5600b568ec804da2b2a3e3c524cb326d where the SDK call GET /auth/v1/sessions/campus/<id>/ ingested as a child span (parent_span_id = the classroom root span's id, waterfall depth 2 across services).
Same call outside any request context carries none — control trace 2181e77b5e534051a2fb7fd0312028c5 (no session → no SDK call) plus unit coverage; background/startup calls stay unparented by construction (headers computed at call time).
Shape: new campus_python.tracing mirrors the propagation half of campus.audit.middleware.tracing (same headers, same flask.g contract, same idempotency marker). Deliberately self-contained — the SDK doesn't import the server-side audit client stack to emit two headers; the two implementations are no-ops for each other. 243 unit tests pass (5 new). Wire-up is automatic at CampusRequest construction; campus.api's existing explicit instrumentation is now redundant but compatible.
Activity
nycomp commentedon Oct 5, 2026
Delivered by #93 (merged, dd84fc7) and verified end-to-end on the dev deployment.
Acceptance:
5600b568ec804da2b2a3e3c524cb326dwhere the SDK callGET /auth/v1/sessions/campus/<id>/ingested as a child span (parent_span_id = the classroom root span's id, waterfall depth 2 across services).2181e77b5e534051a2fb7fd0312028c5(no session → no SDK call) plus unit coverage; background/startup calls stay unparented by construction (headers computed at call time).Shape: new
campus_python.tracingmirrors the propagation half ofcampus.audit.middleware.tracing(same headers, same flask.g contract, same idempotency marker). Deliberately self-contained — the SDK doesn't import the server-side audit client stack to emit two headers; the two implementations are no-ops for each other. 243 unit tests pass (5 new). Wire-up is automatic atCampusRequestconstruction; campus.api's existing explicit instrumentation is now redundant but compatible.Parent: nyjc-computing/campus#816.