Truewire Core
Runtime for Truewire-generated API clients
Every client generated by Truewire depends on this package. It holds the parts of a client that are the same for every API — async HTTP and WebSocket transport, response validation, paging, timestamp conversion and the error hierarchy — so that generated code only has to carry what is genuinely specific to one API: envelope extraction, error mapping, request signing, wire quirks.
You do not normally install it directly; a generated client lists it as a dependency. You will import from it when catching errors, converting timestamps, or driving a paginated walk.
Installation
pip install truewire-core
Optional extras:
pip install 'truewire-core[grpc]' # gRPC transport (grpclib)
What it provides
| module | contents |
|---|---|
truewire_core.exceptions |
Error, NetworkError, ValidationError, ApiError (BadRequest, AuthError, RateLimited), LogicError |
truewire_core.http |
HttpClient, an async HTTP client wrapping httpx with lazy connection and NetworkError mapping |
truewire_core.ws |
WebSocket base classes: Socket, Streams, Rpc, StreamsRpc, SerialReplies |
truewire_core.grpc |
GrpcClient, GrpcEndpoint, wrap_exceptions (requires the grpc extra) |
truewire_core.validation |
validator[T], a cached pydantic adapter that validates and dumps wire shapes, and a base TypedDict that tolerates undocumented fields |
truewire_core.times |
TimeConverter, EpochConverter, IsoConverter, DateConverter — parse/dump between a wire timestamp and a real datetime/date |
truewire_core.types |
TimestampSeconds, TimestampMillis, TimestampMicros, TimestampNanos, TimestampIso, DateIso — the one alias per spec format that generated code imports, plus the converter instance behind each |
truewire_core.contract |
HttpEndpoint, CommandEndpoint, StreamEndpoint, ClientRoot, Composite — Protocols spelling out what a hand-written core provides to generated code |
truewire_core.util |
PaginatedResponse/Page, Stream/StreamManager, RateLimit, and small numeric/path helpers |
Errors
Every failure a client raises derives from truewire_core.exceptions.Error:
from truewire_core.exceptions import ApiError, AuthError, NetworkError, RateLimited
try:
order = await client.orders.get(id='ord_123')
except AuthError:
... # bad or missing credentials
except RateLimited:
... # the API told us to slow down
except ApiError as e:
... # any other error the API itself returned (BadRequest, ...)
except NetworkError:
... # couldn't reach the server, or the connection dropped
Generated clients re-export these from their own package root, so from my_client import AuthError works too. Route such re-exports through lazy_loader.attach_stub (with a matching
__init__.pyi), not a plain from truewire_core.exceptions import ... in an __init__.py —
the latter breaks type-checking for every downstream consumer of a py.typed package.
Timestamps
APIs put timestamps on the wire in many shapes: epoch seconds, milliseconds, microseconds or
nanoseconds; RFC 3339 strings with or without a Z; plain calendar dates. Each converter
turns one such shape into a real datetime (or date) and back:
from datetime import timezone
from truewire_core.times import DateConverter, EpochConverter, IsoConverter
timestamp_millis = EpochConverter.milliseconds(tz=timezone.utc) # 1717072496123 <-> datetime
timestamp_seconds = EpochConverter.seconds(tz=timezone.utc) # 1717072496 <-> datetime
timestamp_iso = IsoConverter() # '2024-05-30T12:34:56Z' <-> datetime
calendar_date = DateConverter() # '2024-05-30' <-> date
dt = timestamp_iso.parse('2024-05-30T12:34:56.123456789Z') # any fraction length, any Python >= 3.10
timestamp_millis.dump(dt) # 1717072496123
A generated client wires these into its field types through pydantic, so a response field
declared as a millisecond epoch arrives as a datetime and a request parameter typed as one
is serialized back to the wire format the API expects.
Paging
Every generated <method>_paged returns a PaginatedResponse: awaitable (every row,
flattened) and async-iterable (one page of rows at a time). Each page is one pure
next(state) call, so a caller can retry or resume a single page rather than the whole walk.
from truewire_core import PaginatedResponse
paging = client.orders.list_paged(status='open')
orders = await paging # every row, flattened
async for rows in paging: ... # one page at a time
async for page in paging.pages(): # Page(rows, state, next), for checkpointing
checkpoint(page.next)
paging.resume(saved_state) # restart from a checkpointed state
paging.via(retried) # route every page fetch through a middleware
via(call) hands each page fetch to call as one zero-argument coroutine function, so a
retry or logging layer wraps a page without unrolling the loop by hand.
Validation
Generated response types are TypedDicts. validator wraps a cached pydantic TypeAdapter
around one and raises truewire_core.exceptions.ValidationError (not pydantic's own) when
the wire body doesn't match:
from truewire_core.validation import TypedDict, validator
class Order(TypedDict):
id: str
amount: str
order = validator(Order)(b'{"id": "ord_123", "amount": "10.5", "extra": true}')
# {'id': 'ord_123', 'amount': '10.5', 'extra': True} -- undocumented fields are kept, not rejected
validator(Order).dump(order) # b'{"id":"ord_123","amount":"10.5","extra":true}'
License
MIT — see LICENSE.
Metadata
Release files for truewire-core 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| truewire_core-0.2.0.tar.gz | 35.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| truewire_core-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 68.4 kB
Release files / truewire_core-0.2.0.tar.gz
| Download URL | truewire_core-0.2.0.tar.gz |
|---|---|
| Size | 35.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a6dc53020d384af201f00bffcfaf169f1d60b3292d4edf91005a9d9edf5889fb
|
|
BLAKE2b-256 checksum How to use checksums |
6a409e2ad0c4d65830dc1dbfd597429c9622c1ece6082ec8d989afb7d8b63125
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency logRelease files / truewire_core-0.2.0-py3-none-any.whl
| Download URL | truewire_core-0.2.0-py3-none-any.whl |
|---|---|
| Size | 32.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a1739384b90291a318dba108143c47a17ea541978e8ddb6a7cebe2842fe2abcb
|
|
BLAKE2b-256 checksum How to use checksums |
5f67802784384714cc839342a6f0a97f0c85247ecb165d072d0be6c441bd5ef6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency log