judgevet.adapters.outbound.http
Status: draft.
judgevet.adapters.outbound.http
HTTP outbound adapter with optional state redaction, gateway metadata and retries.
Error handling
The API error detail field is polymorphic:
- Array for validation errors (422): [{"type", "loc", "msg", "input"}]
- Object for auth errors (401/403): {"error_type", "message"}
- Absent, malformed or unrecognised: falls back to status line alone.
The input key in validation errors contains the caller's request payload
and is deliberately excluded from error messages to avoid leaking user data.
Helper functions
- _build_payload: Build the request payload.
- _parse_body: Parse the response body into a SystemOneResponse.
- _translate_status_error: Translate HTTP status errors to JevError subclasses.
- _translate_request_error: Translate request errors to JevServiceError.
- _convert_question_to_wire: Convert a Question object to its wire dict.
Examples:
from judgevet.adapters.outbound.http import HTTPSystemOneAdapter
from judgevet.domain.questions import Noul
from judgevet.domain.response import SystemOneResponse
adapter = HTTPSystemOneAdapter(api_key="your-api-key")
try:
response: SystemOneResponse = adapter.system_one(
state="Your content here",
questions={
"q1": Noul(instructions="Is this correct?"),
},
)
print(response)
print(response.model)
print(response.answers)
finally:
adapter.close()
See Also
- judgevet.ports.SystemOnePort: Protocol definition
- judgevet.domain.errors: Error types
- judgevet.adapters.inbound.cli: CLI adapter
- judgevet.domain.response_parser: Response parsing
Raises:
| Type | Description |
|---|---|
JevAuthError
|
If the API returns 401 or 403. |
JevRateLimitError
|
If the API returns 429 (rate limit exceeded). |
JevRequestError
|
If the API returns 4xx (except 401/403, 429). |
JevServiceError
|
If the API returns 5xx or a transport error occurs. |
JevResponseError
|
If the API returns 2xx with unparseable body. |
Async adapters
The async adapter provides aclose(), __aenter__, and __aexit__ for
lifecycle management. It does NOT provide sync names (close, __enter__,
__exit__) because calling self._client.aclose() without await would
return an un-awaited coroutine and close nothing silently. An AttributeError
is the better failure.
AsyncHTTPSystemOneAdapter
Async HTTP adapter with explicit network configuration and bounded retries.
This class satisfies AsyncSystemOnePort structurally without importing it. See: https://api.typesafe.ai/v1/systemone
Note
This adapter provides aclose(), __aenter__, and __aexit__ for
lifecycle management. It does NOT provide sync names (close,
__enter__, __exit__) because calling self._client.aclose()
without await would return an un-awaited coroutine and close nothing
silently. An AttributeError is the better failure.
Attributes:
| Name | Type | Description |
|---|---|---|
api_key |
str | None
|
The TypeSafe API key. |
base_url |
str
|
The API base URL. |
default_model |
str
|
The default model to use. |
Raises:
| Type | Description |
|---|---|
JevAuthError
|
If the API returns 401 or 403. |
JevRateLimitError
|
If the API returns 429 (rate limit exceeded). |
JevRequestError
|
If the API returns 4xx (except 401/403, 429). |
JevServiceError
|
If the API returns 5xx or a transport error occurs. |
JevResponseError
|
If the API returns 2xx with unparseable body. |
Error details
Validation errors (422) include an array of error objects. Each
object's input key contains the caller's request payload. The adapter
deliberately omits this key from the error message.
Auth errors (401/403) return an object with error_type and
message fields.
Unknown detail shapes fall back to the HTTP status line alone.
Transport errors (timeouts, connection failures) are mapped to
JevServiceError with status_code=None and retryable=True.
A retryable=True timeout is advisory: retrying a read timeout
may be double-billed because the service may still be processing
the first attempt.
Examples:
async def main() -> SystemOneResponse:
adapter = AsyncHTTPSystemOneAdapter(api_key="your-api-key")
try:
response: SystemOneResponse = await adapter.system_one(
state="Your content here",
questions={
"q1": {"type": "noul", "instructions": "Is this correct?"}
},
)
print(response)
return response
finally:
await adapter.aclose()
__aenter__()
async
Enter async context manager.
__aexit__(exc_type, exc_val, exc_tb)
async
Exit async context manager.
__init__(api_key=None, base_url=None, default_model='jev-latest', transport=None, timeout_seconds=30.0, *, retry=None, network=None, **options)
Initialize the async HTTP adapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str | None
|
TypeSafe API key. |
None
|
base_url
|
str | None
|
API base URL. Defaults to https://api.typesafe.ai. |
None
|
default_model
|
str
|
Default model to use. Defaults to jev-latest. |
'jev-latest'
|
transport
|
AsyncBaseTransport | None
|
Optional httpx async transport for testing. Defaults to None. |
None
|
timeout_seconds
|
float
|
Read timeout in seconds. Defaults to 30.0. |
30.0
|
retry
|
RetryPolicy | None
|
Validated retry policy. None preserves one attempt. |
None
|
network
|
NetworkConfig | None
|
Proxy and TLS options. None retains HTTPX defaults. |
None
|
Other Parameters:
| Name | Type | Description |
|---|---|---|
gateway |
GatewayConfig | None
|
Explicit authentication and metadata. Omission retains direct defaults. |
redactor |
StateRedactor | None
|
Synchronous caller-owned state transformation. Omission preserves state and the existing serialization path. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the key is absent, timeout is nonpositive, or the CA bundle cannot load. |
aclose()
async
Close the HTTP async client.
system_one(state, questions, model=None, *, metadata=None)
async
Prepare optional redaction once, then await bounded HTTP attempts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str | dict[str, Any] | list[Any]
|
The content to evaluate. |
required |
questions
|
Mapping[str, Any]
|
Mapping of question names to question definitions. |
required |
model
|
str | None
|
Model name override. |
None
|
metadata
|
RequestMetadata | None
|
Explicit per-call headers overriding gateway defaults. |
None
|
Returns:
| Type | Description |
|---|---|
SystemOneResponse
|
Typed SystemOneResponse with parsed answer objects. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If metadata or redacted JSON violates input rules. |
Exception
|
If a configured redactor or its input copy fails before IO. |
JevAuthError
|
If the API returns 401 or 403. |
JevRateLimitError
|
If the API returns 429 (rate limit exceeded). |
JevRequestError
|
If the API returns 4xx (except 401/403, 429). |
JevServiceError
|
If the API returns 5xx or a transport error occurs. |
JevResponseError
|
If the API returns 2xx with unparseable body. |
Error details
Validation errors (422) include an array of error objects. Each
object's input key contains the caller's request payload. The adapter
deliberately omits this key from the error message.
Auth errors (401/403) return an object with error_type and
message fields.
Unknown detail shapes fall back to the HTTP status line alone.
Transport errors (timeouts, connection failures) are mapped to
JevServiceError with status_code=None and retryable=True.
A retryable=True timeout is advisory: retrying a read timeout
may be double-billed because the service may still be processing
the first attempt.
HTTPSystemOneAdapter
HTTP adapter with explicit network configuration and opt-in retries.
This class satisfies SystemOnePort structurally without importing it. See: https://api.typesafe.ai/v1/systemone
See: https://api.typesafe.ai/v1/systemone
Attributes:
| Name | Type | Description |
|---|---|---|
api_key |
str | None
|
The TypeSafe API key. |
base_url |
str
|
The API base URL. |
default_model |
str
|
The default model to use. |
Raises:
| Type | Description |
|---|---|
JevAuthError
|
If the API returns 401 or 403. |
JevRateLimitError
|
If the API returns 429 (rate limit exceeded). |
JevRequestError
|
If the API returns 4xx (except 401/403, 429). |
JevServiceError
|
If the API returns 5xx or a transport error occurs. |
JevResponseError
|
If the API returns 2xx with unparseable body. |
Error details
Validation errors (422) include an array of error objects. Each
object's input key contains the caller's request payload. The adapter
deliberately omits this key from the error message.
Auth errors (401/403) return an object with error_type and
message fields.
Unknown detail shapes fall back to the HTTP status line alone.
Transport errors (timeouts, connection failures) are mapped to
JevServiceError with status_code=None and retryable=True.
A retryable=True timeout is advisory: retrying a read timeout
may be double-billed because the service may still be processing
the first attempt.
Examples:
adapter = HTTPSystemOneAdapter(api_key="your-api-key")
try:
response: SystemOneResponse = adapter.system_one(
state="Your content here",
questions={"q1": {"type": "noul", "instructions": "Is this correct?"}},
)
print(response)
finally:
adapter.close()
__enter__()
Enter context manager.
__exit__(exc_type, exc_val, exc_tb)
Exit context manager.
__init__(api_key=None, base_url=None, default_model='jev-latest', transport=None, timeout_seconds=30.0, *, retry=None, network=None, **options)
Initialize the HTTP adapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
str | None
|
TypeSafe API key. |
None
|
base_url
|
str | None
|
API base URL. Defaults to https://api.typesafe.ai. |
None
|
default_model
|
str
|
Default model to use. Defaults to jev-latest. |
'jev-latest'
|
transport
|
BaseTransport | None
|
Optional httpx transport for testing. Defaults to None. |
None
|
timeout_seconds
|
float
|
Read timeout in seconds. Defaults to 30.0. |
30.0
|
retry
|
RetryPolicy | None
|
Validated retry policy. None preserves one attempt. |
None
|
network
|
NetworkConfig | None
|
Proxy and TLS options. None retains HTTPX defaults. |
None
|
Other Parameters:
| Name | Type | Description |
|---|---|---|
gateway |
GatewayConfig | None
|
Explicit authentication and metadata. Omission retains direct defaults. |
redactor |
StateRedactor | None
|
Synchronous caller-owned state transformation. Omission preserves state and the existing serialization path. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the key is absent, timeout is nonpositive, or the CA bundle cannot load. |
close()
Close the HTTP client.
system_one(state, questions, model=None, *, metadata=None)
Prepare optional redaction once, call Jev and emit terminal metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str | dict[str, Any] | list[Any]
|
The content to evaluate. |
required |
questions
|
Mapping[str, Any]
|
Mapping of question names to question definitions. |
required |
model
|
str | None
|
Model name override. |
None
|
metadata
|
RequestMetadata | None
|
Explicit per-call headers overriding gateway defaults. |
None
|
Returns:
| Type | Description |
|---|---|
SystemOneResponse
|
Typed SystemOneResponse with parsed answer objects. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If metadata or redacted JSON violates input rules. |
Exception
|
If a configured redactor or its input copy fails before IO. |
JevAuthError
|
If the API returns 401 or 403. |
JevRateLimitError
|
If the API returns 429 (rate limit exceeded). |
JevRequestError
|
If the API returns 4xx (except 401/403, 429). |
JevServiceError
|
If the API returns 5xx or a transport error occurs. |
JevResponseError
|
If the API returns 2xx with unparseable body. |
Error details
Validation errors (422) include an array of error objects. Each
object's input key contains the caller's request payload. The adapter
deliberately omits this key from the error message.
Auth errors (401/403) return an object with error_type and
message fields.
Unknown detail shapes fall back to the HTTP status line alone.
Transport errors (timeouts, connection failures) are mapped to
JevServiceError with status_code=None and retryable=True.
A retryable=True timeout is advisory: retrying a read timeout
may be double-billed because the service may still be processing
the first attempt.
Implementation notes
Uses helper functions for payload building, response parsing, and error translation to ensure consistent behavior across adapters.