Pydantic
Turbulette has an Ariadne bindable that can automatically add fields and annotations to a pydantic model from a given GraphQL type.
For this to work, Pydantic models must subclass GraphQLModel and define a __type__ class attribute
that indicates the corresponding GraphQL type:
type User {
username: String!
email: String!
age: Int
}
from turbulette.validation import GraphQLModel
class User(GraphQLModel):
__type__ = "User"
During schema binding, attributes username, email and age will be added to the User model
with proper Python annotations.
All GraphQL scalars will be converted to their Python equivalent :
| GraphQL Scalar | Python annotation |
|---|---|
| Int | int |
| Float | float |
| String | str |
| Boolean | bool |
| ID | Union[str, int] |
The same goes for wrapping types :
| GraphQL Wrapping type | Python annotation |
|---|---|
| List | List |
| Non-Null | Every nullable fields have None as default value, non-nullable ones are required |
For non scalar fields (i.e: other GraphQL types), the bindable will look
for an existing GraphQLModel that describes it. If it can't found it,
a PydanticBindError will be raised.
Provide the tooling to generate pydantic models from the GraphQL schema.
GraphQLModel
pydantic-model
Base pydantic model for GraphQL type binding.
The GraphQL type must be assigned to GraphQL.gql_type when subclassing.
__initialized__ is used at binding time, to avoid the model
to be processed multiple times.
(ex : when the GraphQL type is referenced by fields of other GraphQL types)
Config
Needed to allow referencing custom GraphQL types in models.
validator(*fields, *, pre=False, each_item=False, always=False, check_fields=False, whole=None, allow_reuse=False)
Shortcut to Pydantic @validator decorator with check_fields=False.
When check_fields is True validators are checked on class creation to
confirm that the fields they specify actually exist on the model.
Because models subclassing GraphQLModel won't declare any fields at creation
(as they'll be added dynamically later), but may declare validators,
this behavior becomes an undesirable effect and it's necessary to disable it.
Source code in turbulette/validation/pyd_model.py
def validator(
*fields: str,
pre: bool = False,
each_item: bool = False,
always: bool = False,
check_fields: bool = False,
whole: bool = None,
allow_reuse: bool = False,
) -> Callable[[AnyCallable], classmethod]:
"""Shortcut to Pydantic `@validator` decorator with `check_fields=False`.
When `check_fields` is `True` validators are checked on class creation to
confirm that the fields they specify actually exist on the model.
Because models subclassing `GraphQLModel` won't declare any fields at creation
(as they'll be added dynamically later), but may declare validators,
this behavior becomes an undesirable effect and it's necessary to disable it.
"""
return pyd_validator(
*fields,
pre=pre,
each_item=each_item,
always=always,
check_fields=check_fields,
whole=whole,
allow_reuse=allow_reuse,
)
Exceptions raised during pydantic binding.
PydanticBindError
Raised if Turbulette fails to bind GraphQL pydantic models.
Common causes are:
- The pydantic model does not defines a
__type__attribute. - The GraphQL type defined by
__type__does not exists. - The GraphQL type exists, but one of its fields refers to a GraphQL type that does not exist.