@@ -43,13 +43,18 @@ bodies are modelled as typed Pythonic abstractions instead.
4343 ` from_form ` / ` from_stream ` / ` from_iter ` / ` from_file ` . ` ResponseBody `
4444 exposes ` iter_bytes ` / ` bytes ` / ` string ` . Single-use bodies (stream /
4545 iter) raise ` RuntimeError ` on second consumption — call ` to_replayable() `
46- before the first send if retries are needed.
46+ before the first send if retries are needed. ` AsyncRequestBody ` /
47+ ` AsyncResponseBody ` are the async twins (` aiter_bytes ` ), and
48+ ` MultipartField ` / ` MultipartRequestBody ` build ` multipart/form-data `
49+ payloads.
4750- ** Body capture for logging uses ` BytesIO ` .** ` LoggableRequestBody ` mirrors
4851 writes into a ` BytesIO ` tap; ` LoggableResponseBody ` caches drained bytes
4952 for repeatable reads. Both honour a configurable byte cap.
5053- ** Thread-safety where stated.** ` ContextStore ` is safe under concurrent
51- use; individual bodies and streams are not. Per-context lookups rely on
52- CPython's GIL for atomic dict ops and use a lock only for check-and-set.
54+ use; individual bodies and streams are not. Every store operation
55+ (` get ` / ` put ` / ` set ` / ` remove ` ) acquires a ` threading.Lock ` , so the
56+ guarantee survives free-threaded CPython (PEP 703) and runtimes without
57+ atomic dict ops rather than relying on the GIL.
5358- ** Public API is narrow.** Helpers and concrete adapter classes are
5459 module-private (leading underscore). The public surface for each subpackage
5560 is what its ` __init__.py ` re-exports.
@@ -103,14 +108,20 @@ python-sdk/
103108 │ │ │ ├── common/ # Headers, HttpHeaderName, MediaType,
104109 │ │ │ │ # Protocol, Url, QueryParams, ETag,
105110 │ │ │ │ # HttpRange, RequestConditions,
106- │ │ │ │ # common_media_types
107- │ │ │ ├── request/ # Request, RequestBody, FileRequestBody,
108- │ │ │ │ # LoggableRequestBody, Method
109- │ │ │ ├── response/ # Response, ResponseBody,
110- │ │ │ │ # LoggableResponseBody, Status
111+ │ │ │ │ # common_media_types; pagination.py
112+ │ │ │ │ # (ItemPaged/Pager + async twins),
113+ │ │ │ │ # streaming.py (jsonl/chunked-frame iters)
114+ │ │ │ ├── request/ # Request, RequestBody, AsyncRequestBody,
115+ │ │ │ │ # FileRequestBody, LoggableRequestBody,
116+ │ │ │ │ # MultipartField/MultipartRequestBody, Method
117+ │ │ │ ├── response/ # Response, AsyncResponse, ResponseBody,
118+ │ │ │ │ # AsyncResponseBody, LoggableResponseBody,
119+ │ │ │ │ # Status
111120 │ │ │ ├── context/ # CallContext, DispatchContext,
112121 │ │ │ │ # RequestContext, ExchangeContext,
113122 │ │ │ │ # ContextStore
123+ │ │ │ ├── sse/ # Server-Sent Events parser + connection
124+ │ │ │ ├── webhooks/ # webhook signature verification
114125 │ │ │ └── auth/ # TokenCredential, BearerTokenPolicy,
115126 │ │ │ # BasicAuthPolicy, KeyCredentialPolicy,
116127 │ │ │ # ChallengeHandler (Basic/Digest/Composite),
@@ -119,19 +130,24 @@ python-sdk/
119130 │ │ │ │ # Stage, StagedPipelineBuilder, defaults,
120131 │ │ │ │ # sans-io + transport runners under the hood
121132 │ │ │ │
122- │ │ │ ├── policies/ # retry, redirect, logging, tracing,
123- │ │ │ │ # set_date (+ async twins)
124- │ │ │ └── step/ # PipelineStep, StepMetadata, RetryConfig
133+ │ │ │ ├── policies/ # redirect, idempotency, retry, set_date,
134+ │ │ │ │ # client_identity, logging, tracing
135+ │ │ │ │ # (async twins only for the first five)
136+ │ │ │ └── step/ # PipelineStep, StepMetadata
125137 │ │ ├── client/ # HttpClient + AsyncHttpClient Protocols
126138 │ │ ├── config/ # Configuration
127139 │ │ ├── serde/ # Serde, Serializer, Deserializer Protocols
128140 │ │ ├── errors/ # SDK-level exception hierarchy
129141 │ │ ├── instrumentation/ # InstrumentationContext, Span, Tracer,
130- │ │ │ # TracingScope, noops
142+ │ │ │ # TracingScope, noops, metrics,
143+ │ │ │ # correlation, client_logger, http_tracer,
144+ │ │ │ # identifiers, log_level, url_redactor
145+ │ │ ├── pagination/ # Page, Paginator, link-header + strategy
131146 │ │ └── util/ # clock, proxy helpers
132147 │ └── tests/ # pytest suite — auth/, config/, context/,
133148 │ # errors/, http/, instrumentation/,
134- │ # pipeline/, serde/, sse/, util/
149+ │ # pagination/, pipeline/, serde/, sse/,
150+ │ # util/, webhooks/
135151 ├── dexpace-sdk-http-stdlib/ # reference stdlib transports:
136152 │ │ # UrllibHttpClient, AsyncioHttpClient
137153 │ └── src/dexpace/sdk/http/stdlib/
@@ -143,6 +159,10 @@ python-sdk/
143159 └── src/dexpace/sdk/http/requests/
144160```
145161
162+ Community-health and tooling files (` CHANGELOG.md ` , ` CONTRIBUTING.md ` ,
163+ ` SECURITY.md ` , ` CODE_OF_CONDUCT.md ` , ` conftest.py ` , ` tools/ ` ) are elided from
164+ the tree above.
165+
146166Every transport package depends on ` dexpace-sdk-core ` and adapts its HTTP
147167library to the ` HttpClient ` / ` AsyncHttpClient ` Protocols. Namespace
148168packaging (no ` __init__.py ` at ` src/dexpace/ ` , ` src/dexpace/sdk/ ` , or
@@ -185,12 +205,16 @@ Layered, bottom-up:
185205 evict on ` CallContext.close() ` .
1862064 . ** ` pipeline ` ** — ` Policy ` (and ` AsyncPolicy ` ) wrap the downstream chain;
187207 ` Pipeline ` / ` AsyncPipeline ` run an ordered set of policies grouped into
188- ` Stage ` s via ` StagedPipelineBuilder ` . Shipped policies: retry, redirect,
189- logging, tracing, set-date (each with an async twin under
190- ` pipeline/policies/ ` ). ` default_pipeline() ` / ` default_async_pipeline() `
191- assemble the standard stack. The lower-level ` pipeline/step/PipelineStep `
192- Protocol (` (input, context) -> output ` ) plus ` StepMetadata ` / ` RetryConfig `
193- remain for custom composition.
208+ ` Stage ` s via ` StagedPipelineBuilder ` . Shipped policies: redirect,
209+ idempotency, retry, set-date, client-identity, logging, tracing. Async
210+ twins under ` pipeline/policies/ ` exist only for redirect, idempotency,
211+ retry, set-date, and client-identity; logging and tracing are sync-only.
212+ ` default_pipeline() ` / ` default_async_pipeline() ` assemble the standard
213+ stack in the order redirect → idempotency → retry → set-date →
214+ client-identity → [ auth] → logging → tracing (the async pipeline omits
215+ logging and tracing). The lower-level ` pipeline/step/PipelineStep ` Protocol
216+ (` (input, context) -> output ` ) plus ` StepMetadata ` remain for custom
217+ composition.
1942185 . ** ` client/HttpClient ` ** — single-method Protocol
195219 (` execute(request) -> Response ` ). Transport is ** not** provided by ` core ` ;
196220 the ` dexpace-sdk-http-* ` packages (stdlib, httpx, aiohttp, requests) each
0 commit comments