Skip to main content

Request-context propagation, JWT parsing, security headers and OpenTelemetry enrichment for Mobius Python (FastAPI) services.

Project description

mobius-tracer-py

Request-context propagation for Mobius Python (FastAPI / Starlette) services.

On every incoming request it extracts identity/trace headers and the JWT payload, exposes them request-scoped, forwards them onto downstream calls, sets security + trace response headers, and enriches OpenTelemetry spans.

  • PyPI: pip install mobius-tracer-py
  • Import package: mobius_tracer
  • Python: 3.10+

Install

pip install mobius-tracer-py

# optional features
pip install "mobius-tracer-py[otel]"        # set OTel span attributes
pip install "mobius-tracer-py[httpx]"       # TracedClient / httpx hook
pip install "mobius-tracer-py[resources]"   # CPU/mem span metrics (psutil)

Quick start

from fastapi import FastAPI
from mobius_tracer import setup_tracer, current

app = FastAPI()
setup_tracer(app)   # adds middleware + 401 handler for invalid tokens

@app.get("/me")
async def me():
    ctx = current()
    return {"tenant_id": ctx.tenant_id, "txn": ctx.req_transaction_id}

setup_tracer installs a middleware that, per request:

  1. extracts x-request-id, x-b3-traceid, x-b3-spanid, Authorization, appId, platformId, and X-Transaction-Id (generated if absent);
  2. parses the JWT payload into the request context (tenant/agent/user/email …);
  3. derives action_log_user_id from the token;
  4. sets security response headers + x-mb-trace-id + X-Transaction-Id;
  5. sets OpenTelemetry span attributes (txn.id, tenant.id, user.id).

Options

setup_tracer(
    app,
    skip_paths=("actuator", "health", "metrics", "error", "prometheus",
                "swagger", "api-docs", "arazzo"),  # paths with no token check
    require_token=True,          # 401 on protected paths without a valid token
    set_security_headers=True,   # HSTS/CSP/X-Frame-Options/...
    propagate_to_otel=True,      # txn/tenant/user span attributes
    integrate_logging=True,      # mirror fields into mobius-logging-py context
    measure_resources=True,      # CPU/mem of each request onto the span
    instrument_httpx=False,      # patch httpx so all outbound calls propagate (opt-in)
)

Request context

from mobius_tracer import current, get, HeadersHolder

ctx = current()           # HeadersHolder for this request
ctx.tenant_id             # e.g. "tenant-123"
ctx.action_log_user_id    # derived user id
get("trace_id")           # field accessor

Fields: request_id, trace_id, span_id, tenant_id, tenant_user_id, consumer_id, email, authorization, name, requester_type, platform_id, parent_tenant_id, app_id, action_log_user_id, agent_id, agent_user_id, req_transaction_id, b_agent_id.

The context uses contextvars, so it is isolated per request and correct across async tasks and threads.

Propagating to downstream calls

Forward the current context (and a W3C traceparent) to outbound requests:

import httpx
from mobius_tracer import traced_headers, httpx_auth_hook, TracedClient

# 1) build headers yourself
httpx.get(url, headers=traced_headers())

# 2) an httpx event hook
client = httpx.AsyncClient(event_hooks={"request": [httpx_auth_hook()]})

# 3) a ready-made traced client
with TracedClient(base_url="https://api.internal") as c:
    c.get("/orders/1")

# 4) globally patch httpx so ALL outbound calls propagate (internal-only!)
from mobius_tracer import instrument_httpx
instrument_httpx()   # or setup_tracer(app, instrument_httpx=True)

Forwarded headers: x-request-id, x-b3-traceid, x-b3-spanid, tenantId, tenantUserId, consumerId, email, name, Authorization, platformId, parentTenantId, appId, X-Transaction-Id, plus traceparent.

JWT parsing

from mobius_tracer import parse_token, TokenError

body = parse_token(jwt_string)   # decodes payload (no signature verification)
body.tenant_id, body.requester_type, body.email

Raises TokenError (HTTP 401) for missing or malformed tokens. A non-empty requester_type claim is required.

Resource metrics

With measure_resources=True (default), every request is measured and the metrics are attached to its OpenTelemetry span automatically. For a specific function or block:

from mobius_tracer import measure_resources, measure

@measure_resources
async def heavy(): ...

with measure():
    do_work()

Span attributes: wall_time_ms, cpu_used_ms, cpu_used_pct, cpu_cores, mem_rss_mb, mem_rss_delta_mb, mem_system_used_pct. Best-effort; never raises. Uses psutil when installed.

Integrating with mobius-logging-py

setup_tracer(app, integrate_logging=True)

When mobius-logging-py is installed, the middleware mirrors tenant_id, trace_id, txn_id, agent_id, and correlation_id into its logging context, so every log line carries the same identity fields.

Development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mobius_tracer_py-1.0.0.tar.gz (15.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mobius_tracer_py-1.0.0-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

Details for the file mobius_tracer_py-1.0.0.tar.gz.

File metadata

  • Download URL: mobius_tracer_py-1.0.0.tar.gz
  • Upload date:
  • Size: 15.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for mobius_tracer_py-1.0.0.tar.gz
Algorithm Hash digest
SHA256 662a9b87ae4fbefc402e987e01890b18e6bc6c696475f72af8bd5abec3db3044
MD5 5929dbd40a202ee742ef261d893d3a0b
BLAKE2b-256 b8ac3067f8a7f022ff132fe57dc4af387f55cc591d96cc41512a3482550a9a7c

See more details on using hashes here.

File details

Details for the file mobius_tracer_py-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for mobius_tracer_py-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6244f2a66c043b0561d83832895260713e37c303bd90eb59cf2d54c050404aed
MD5 4ce35465ec61cfec1e737b145c805f77
BLAKE2b-256 cca0b32842268bf3ccdf8a3866667754197eae8745058c1a790deabb4082e42c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page