Exception classes
The typed exception hierarchy raised by SonnyLabsClient — SonnyLabsError plus per-namespace subclasses for auth, scope, validation, idempotency, rate-limit, not-found, and server errors.
Every non-2xx response is parsed as an RFC 9457
application/problem+json envelope and raised as a SonnyLabsError
subclass. The from_problem helper dispatches on the dot-namespaced
code first (so auth.api_key.expired is always an
AuthenticationError regardless of HTTP status remapping by
intermediate proxies), then falls back to the HTTP status.
from sonnylabs import (
SonnyLabsError,
AuthenticationError,
RateLimitError,
ValidationError,
)
try:
client.create_scan(
surface="user_message",
content={"type": "text", "text": user_prompt},
)
except AuthenticationError as e:
# e.code is one of "auth.api_key.invalid" / "auth.api_key.revoked" / ...
...
except RateLimitError as e:
# honour e.retry_after
...
except ValidationError as e:
for field in e.errors:
print(f"{field['path']}: {field['code']}")
except SonnyLabsError:
# catch-all for any other Problem-shaped failure
raiseSonnyLabsError
Base class for every typed SDK exception. Carries the parsed Problem envelope plus convenience attributes.
Prop
Type
AuthenticationError
Raised for any code starting with auth. (or HTTP 401 envelopes
without a recognised code). Surface a re-credential UI.
Prop
Type
ScopeMissingError
Raised when the API key authenticated but lacks the scope this
endpoint demands (auth.scope.missing or HTTP 403). Mint a key with
the required scope. Named ScopeMissingError rather than
PermissionError to avoid shadowing the Python builtin.
Prop
Type
RateLimitError
Raised on HTTP 429. Carries a retry_after attribute parsed from the
server's Retry-After header so callers driving their own retry loop
can honour the server's hint.
Prop
Type
IdempotencyConflictError
Raised for any code starting with idempotency. or HTTP 409 with
the matching code. The canonical case is reusing the same
Idempotency-Key header with a different request body.
Prop
Type
ValidationError
Raised for any code starting with validation. or HTTP 400. The
inherited errors list contains per-field problems.
Prop
Type
NotFoundError
Raised on HTTP 404. The request_id is preserved on the instance
for correlating with server logs.
Prop
Type
ServerError
Raised for any 5xx response that isn't 503 (the SDK retries 503
internally before surfacing a ServerError). Treat as a permanent
server-side failure for that request — silently retrying risks
duplicating side effects.
Prop
Type
from_problem
Lower-level dispatch helper used internally by the client. Exposed in case you are building your own transport on top of the OpenAPI schema and want to reuse the same exception mapping.
Prop
Type
from sonnylabs.errors import from_problem
raise from_problem(
status=response.status_code,
problem=response.json(),
request_id=response.headers.get("X-Request-Id"),
retry_after=None,
)Constructor options
Constructor arguments for SonnyLabsClient — api_key, base_url, api_version, timeout_s, max_retries, and the httpx transport injection point.
Problem envelope
The RFC 9457 application/problem+json shape the SDK consumes, plus how it threads onto every SonnyLabsError as the raw problem attribute.