omnixys-graphql
Shared GraphQL toolkit for Omnixys Python services: strawberry/FastAPI wiring, a transport-independent error contract, typed error factories, sanitization, and pagination primitives.
Installation
pip install omnixys-graphql
Features
- Error catalog — the full
@omnixys/contracts-tsErrorCodeenum andERROR_DEFINITIONS(summary, default message, HTTP status, retryability, public metadata keys) ported to Python. - Typed errors —
BaseGraphQLExceptionand domain exceptions (UserNotFoundException,EventNotFoundException, …) that render stableextensions(code, summary, httpStatus, retryable, timestamp, metadata). - Factory helpers —
validation_graphql_error,unauthenticated_graphql_error,forbidden_graphql_error,not_found_graphql_error,conflict_graphql_error,rate_limit_graphql_error,dependency_unavailable_graphql_error,internal_graphql_error,access_blocked,step_up_required. - Error formatting —
create_graphql_format_errorstandardizes every response error, collapses internal details to safe defaults, and strips sensitive metadata; unknown codes map to a service-level internal code. - Pagination —
PageInput/PagePayloadstrawberry types. - Router wiring —
create_graphql_router/include_graphql_routerwith a Dishka-aware context getter.
Note: the package imports as
omnixys_graphql. It deliberately does not shadow thegraphqlmodule name, which belongs tographql-core(required by strawberry).
Quick start
import strawberry
from fastapi import FastAPI
from omnixys_graphql import create_graphql_router, include_graphql_router
@strawberry.type
class Query:
@strawberry.field
def ping(self) -> str:
return "pong"
schema = strawberry.Schema(query=Query)
app = FastAPI()
include_graphql_router(app, schema, graphiql=True)
Error handling
Raise a typed error from a resolver and it renders with stable extensions:
from omnixys_graphql import EventNotFoundException, UserNotFoundException
@strawberry.type
class Query:
@strawberry.field
def event(self, event_id: str) -> str:
raise EventNotFoundException(event_id)
Response extensions:
{
"code": "EVENT_NOT_FOUND",
"summary": "Event not found.",
"httpStatus": 404,
"retryable": false,
"timestamp": "2026-01-01T00:00:00Z",
"metadata": { "eventId": "evt_123" }
}
Only metadata keys listed for the code survive; sanitize_details also drops
anything sensitive (password, token, authorization, …), truncates nesting
beyond depth 5, and caps arrays at 50 entries.
Factories
from omnixys_graphql import (
access_blocked,
forbidden_graphql_error,
rate_limit_graphql_error,
step_up_required,
validation_graphql_error,
)
raise validation_graphql_error("bad input", {"field": "email"})
raise forbidden_graphql_error("no permission")
raise rate_limit_graphql_error()
raise access_blocked(["2fa_pending"])
raise step_up_required("mfa", ["low_risk_score"])
Standardizing responses
Attach GraphQLFormatErrorExtension to your schema to normalize every error to
the catalog contract:
from strawberry import Schema
from omnixys_graphql import GraphQLFormatErrorOptions, GraphQLFormatErrorExtension
schema = Schema(
query=Query,
extensions=[
lambda: GraphQLFormatErrorExtension(
GraphQLFormatErrorOptions(service_name="event-service"),
),
],
)
The extension keeps client-safe messages (httpStatus < 500) as-is and replaces
internal messages with the catalog default, so stack traces never leak. Unknown
codes normalize to the service internal code (e.g. EVENT_INTERNAL_ERROR).
Use the lambda factory so a fresh extension is built per request.
Error catalog
from omnixys_graphql import (
ERROR_CATALOG_VERSION,
ErrorCode,
get_error_definition,
get_public_error_metadata,
is_known_error_code,
)
definition = get_error_definition(ErrorCode.RATE_LIMIT_EXCEEDED.value)
assert definition.http_status == 429
assert definition.retryable is True
metadata = get_public_error_metadata("EVENT_NOT_FOUND", {"eventId": "e1", "secret": 1})
assert metadata == {"eventId": "e1"}
Pagination
from omnixys_graphql import PageInput, PagePayload
payload = PagePayload(items=[1, 2, 3], total=10, page=1, size=3)
assert payload.has_next() is True
Development
uv sync
uv run pytest -q
uv run ruff check .
uv run mypy src/
License
GPL-3.0-or-later
Metadata
Release files for omnixys-graphql 3.0.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 | |
|---|---|---|---|
| omnixys_graphql-3.0.0.tar.gz | 71.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| omnixys_graphql-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 89.4 kB
Release files / omnixys_graphql-3.0.0.tar.gz
| Download URL | omnixys_graphql-3.0.0.tar.gz |
|---|---|
| Size | 71.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
13a0801df6d2c2253ad4730ce8f86f95d1423217787c66bedaabca7ca1f9017d
|
|
BLAKE2b-256 checksum How to use checksums |
e60a497d5d0757e1fd534666d5ffa61830e9e0a30ec9d2d53eae7a2522b93d41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / omnixys_graphql-3.0.0-py3-none-any.whl
| Download URL | omnixys_graphql-3.0.0-py3-none-any.whl |
|---|---|
| Size | 17.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2fbf0930b4a206161395127f048f8ac9c28facccb68099d0d4cd0fd7fbd1a2d0
|
|
BLAKE2b-256 checksum How to use checksums |
9609bd7ebf2336dfaea15316504784627fe35d4d7c837aac3347880a64e5f359
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|