Skip to content

feat(server): createUpstreamHttpClient + createTranslationMap (translator pattern helpers) #453

@bokelley

Description

@bokelley

Parent: #452

JS source

.changeset/adapter-translation-helpers.md (6.7).

What Python adopters write today

200+ lines of httpx.AsyncClient boilerplate per upstream — auth header injection, 404→None translation, retry/timeout policy, JSON decode. See examples/v3_reference_seller/src/upstream.py for the canonical hand-rolled version.

Plus per-adapter bidirectional code↔code translation maps (status enums, channel enums, etc.) hand-written as two parallel dicts that drift.

Proposed API

from adcp.decisioning import create_upstream_http_client, create_translation_map

client = create_upstream_http_client(
    base_url="https://api.vendor.com",
    auth={"type": "static_bearer", "token": "..."},      # or dynamic_bearer | api_key | none
    network_code="abc123",
    default_headers={...},
    timeout_s=30.0,
)
# Typed get/post/put/delete returning parsed JSON or None on 404.
account = await client.get("/accounts/{id}", params={...})

status_map = create_translation_map[AdcpStatus, UpstreamStatus]({
    "active": "ACTIVE",
    "paused": "PAUSED",
    ...
})
status_map.to_upstream("active")     # "ACTIVE"
status_map.to_adcp("ACTIVE")         # "active"
status_map.has_adcp("active")        # True
status_map.has_upstream("ACTIVE")    # True

Auth modes: static_bearer / dynamic_bearer (callable returning fresh token, used by OAuth passthrough in #6) / api_key / none.

Acceptance criteria

  • Both helpers exported from adcp.decisioning.
  • Tests cover: each auth mode, 404→None, retry on 5xx, JSON decode errors.
  • Translation map: round-trip identity, missing-key raises, generic typing.
  • examples/v3_reference_seller/src/upstream.py could be refactored to use them (defer that to a follow-up v3-ref-seller-uses-helpers PR).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions