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.