Skip to main content

Request Lifecycle

Request Lifecycle

Every request travels the same 14-step pipeline — from entry point to response.

Full Sequence Diagram

Client
Middleware Stack
Service Layer
Adapter Layer
External API
Sagittarius
1
→ HTTP /v1/{service}/{method}Entry: HTTP · CLI · MCP
2
→ CORS headers addedStateless middleware
3
→ Auth — validate JWT / API keyBearer · Access-Token · API key → 401 if invalid
4
→ Cache check (Redis DB 0)hash(method + params + tenant_id)CACHE HIT → skip steps 5–13
5
→ Metrics — start timer
6
→ OutputFormat — read Accept / ?format=json · text · agent
7
→ Context extraction → RequestContexttenant_id · user_email · bearer_token
8
→ ServiceClass(context=context)Instantiation
9
→ @service_method(params)Method invocation
10
→ AdapterFactory → httpx.AsyncClientExternal API HTTP call
10↩
← API response returned
11
→ Sagittarius trace (action endpoints)Decision trace → Redis DB 1
12
→ OutputFormat serializationjson / text / agent
13
→ Cache store (Redis DB 0, SWR)stale-while-revalidate headers
14
← Response → Client200 / 401 / 429 / 500
⚡ Cache Hit ShortcutStep 4 hits Redis DB 0 → returns cached response immediately, skipping steps 5–13

What & Why

Uniform pipeline

Every request — HTTP, CLI, or MCP — travels the same 14-step pipeline. There is no special-casing per entry point. The CLI proxies to the HTTP server; MCP tool execution does the same.

Stateless middleware

The middleware stack is entirely stateless. All per-request state is encapsulated in a single RequestContext object built in step 7. This makes the system horizontally scalable — any instance can handle any request without affinity.

RequestContext — The Only Coupling Point

@dataclass RequestContext
tenant_id: strMulti-tenancy key
user_email: strCalling user identity
bearer_token: strForwarded to adapters
Middleware (step 7)
↓
Service (step 8)
↓
Adapter (step 10)
Single responsibility

RequestContext is the only coupling point between middleware, services, and adapters. Nothing else is shared across layers.

Cache Layers

L1 — In-Process
cachetools (per-process)

Sub-millisecond lookups. Scoped to a single worker process. Evicted on process restart. No network hop.

TTLprocess lifetime
→
L2 — Cross-Process
Redis DB 0

Shared across all instances. Supports stale-while-revalidate (SWR): serve stale data instantly while refreshing in the background.

TTLconfigurable + SWR window
→
Cache Miss
Full pipeline executes

Steps 5–13 run in full. Response is stored back in L2 at step 13.

Cache Key =hash(method + params + tenant_id)Tenant-scoped — no cross-tenant data leakage

HTTP Reference

Request Headers
HeaderValue
AuthorizationBearer <JWT>
Access-Token<direct token>
X-Tenant-ID<tenant uuid>
Acceptapplication/json · text/plain
Query Parameters
ParamValues
?format=json · text · agent
Response Codes
CodeMeaning
200Success
401Auth failed — invalid/missing token
429Rate limit exceeded
500Unhandled service / adapter error