strawberry-graphql 0.279.0.dev1754156227__py3-none-any.whl → 0.280.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- strawberry/__init__.py +1 -2
- strawberry/aiohttp/views.py +2 -48
- strawberry/asgi/__init__.py +2 -37
- strawberry/chalice/views.py +7 -75
- strawberry/channels/handlers/http_handler.py +30 -6
- strawberry/cli/commands/upgrade/__init__.py +2 -0
- strawberry/codemods/__init__.py +9 -0
- strawberry/codemods/maybe_optional.py +118 -0
- strawberry/django/views.py +4 -73
- strawberry/experimental/pydantic/_compat.py +1 -0
- strawberry/experimental/pydantic/error_type.py +1 -0
- strawberry/experimental/pydantic/fields.py +1 -0
- strawberry/experimental/pydantic/utils.py +1 -0
- strawberry/fastapi/router.py +8 -4
- strawberry/flask/views.py +4 -74
- strawberry/http/async_base_view.py +5 -31
- strawberry/http/base.py +2 -1
- strawberry/http/exceptions.py +5 -7
- strawberry/http/sync_base_view.py +1 -34
- strawberry/litestar/controller.py +1 -39
- strawberry/quart/views.py +3 -33
- strawberry/sanic/views.py +4 -43
- strawberry/schema/schema.py +2 -0
- strawberry/schema/schema_converter.py +7 -0
- strawberry/schema/validation_rules/maybe_null.py +136 -0
- strawberry/types/arguments.py +16 -2
- strawberry/types/maybe.py +1 -1
- {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/METADATA +2 -1
- {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/RECORD +32 -34
- strawberry/pydantic/__init__.py +0 -22
- strawberry/pydantic/error.py +0 -51
- strawberry/pydantic/fields.py +0 -202
- strawberry/pydantic/object_type.py +0 -348
- {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
"""Object type decorators for Pydantic models in Strawberry GraphQL.
|
|
2
|
-
|
|
3
|
-
This module provides decorators to convert Pydantic BaseModel classes directly
|
|
4
|
-
into GraphQL types, inputs, and interfaces without requiring a separate wrapper class.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
from typing import TYPE_CHECKING, Any, Callable, Optional, Union, overload
|
|
10
|
-
|
|
11
|
-
if TYPE_CHECKING:
|
|
12
|
-
import builtins
|
|
13
|
-
from collections.abc import Sequence
|
|
14
|
-
|
|
15
|
-
from strawberry.experimental.pydantic._compat import PydanticCompat
|
|
16
|
-
from strawberry.experimental.pydantic.conversion import (
|
|
17
|
-
convert_strawberry_class_to_pydantic_model,
|
|
18
|
-
)
|
|
19
|
-
from strawberry.types.base import StrawberryObjectDefinition
|
|
20
|
-
from strawberry.types.cast import get_strawberry_type_cast
|
|
21
|
-
from strawberry.utils.str_converters import to_camel_case
|
|
22
|
-
|
|
23
|
-
from .fields import _get_pydantic_fields
|
|
24
|
-
|
|
25
|
-
if TYPE_CHECKING:
|
|
26
|
-
from graphql import GraphQLResolveInfo
|
|
27
|
-
|
|
28
|
-
from pydantic import BaseModel
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def _get_interfaces(cls: builtins.type[Any]) -> list[StrawberryObjectDefinition]:
|
|
32
|
-
"""Extract interfaces from a class's inheritance hierarchy."""
|
|
33
|
-
interfaces: list[StrawberryObjectDefinition] = []
|
|
34
|
-
|
|
35
|
-
for base in cls.__mro__[1:]: # Exclude current class
|
|
36
|
-
if hasattr(base, "__strawberry_definition__"):
|
|
37
|
-
type_definition = base.__strawberry_definition__
|
|
38
|
-
if type_definition.is_interface:
|
|
39
|
-
interfaces.append(type_definition)
|
|
40
|
-
|
|
41
|
-
return interfaces
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def _process_pydantic_type(
|
|
45
|
-
cls: type[BaseModel],
|
|
46
|
-
*,
|
|
47
|
-
name: Optional[str] = None,
|
|
48
|
-
is_input: bool = False,
|
|
49
|
-
is_interface: bool = False,
|
|
50
|
-
description: Optional[str] = None,
|
|
51
|
-
directives: Optional[Sequence[object]] = (),
|
|
52
|
-
include_computed: bool = False,
|
|
53
|
-
) -> type[BaseModel]:
|
|
54
|
-
"""Process a Pydantic BaseModel class and add GraphQL metadata.
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
cls: The Pydantic BaseModel class to process
|
|
58
|
-
name: The GraphQL type name (defaults to class name)
|
|
59
|
-
is_input: Whether this is an input type
|
|
60
|
-
is_interface: Whether this is an interface type
|
|
61
|
-
description: The GraphQL type description
|
|
62
|
-
directives: GraphQL directives to apply
|
|
63
|
-
include_computed: Whether to include computed fields
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
The processed BaseModel class with GraphQL metadata
|
|
67
|
-
"""
|
|
68
|
-
# Get the GraphQL type name
|
|
69
|
-
name = name or to_camel_case(cls.__name__)
|
|
70
|
-
|
|
71
|
-
# Get compatibility layer for this model
|
|
72
|
-
compat = PydanticCompat.from_model(cls)
|
|
73
|
-
|
|
74
|
-
# Extract fields using our custom function
|
|
75
|
-
# All fields from the Pydantic model are included by default, except strawberry.Private fields
|
|
76
|
-
fields = _get_pydantic_fields(
|
|
77
|
-
cls=cls,
|
|
78
|
-
original_type_annotations={},
|
|
79
|
-
is_input=is_input,
|
|
80
|
-
include_computed=include_computed,
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
# Get interfaces from inheritance hierarchy
|
|
84
|
-
interfaces = _get_interfaces(cls)
|
|
85
|
-
|
|
86
|
-
# Create the is_type_of method for proper type resolution
|
|
87
|
-
def is_type_of(obj: Any, _info: GraphQLResolveInfo) -> bool:
|
|
88
|
-
if (type_cast := get_strawberry_type_cast(obj)) is not None:
|
|
89
|
-
return type_cast is cls
|
|
90
|
-
return isinstance(obj, cls)
|
|
91
|
-
|
|
92
|
-
# Create the GraphQL type definition
|
|
93
|
-
cls.__strawberry_definition__ = StrawberryObjectDefinition( # type: ignore
|
|
94
|
-
name=name,
|
|
95
|
-
is_input=is_input,
|
|
96
|
-
is_interface=is_interface,
|
|
97
|
-
interfaces=interfaces,
|
|
98
|
-
description=description,
|
|
99
|
-
directives=directives,
|
|
100
|
-
origin=cls,
|
|
101
|
-
extend=False,
|
|
102
|
-
fields=fields,
|
|
103
|
-
is_type_of=is_type_of,
|
|
104
|
-
resolve_type=getattr(cls, "resolve_type", None),
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
# Add the is_type_of method to the class for testing purposes
|
|
108
|
-
cls.is_type_of = is_type_of # type: ignore
|
|
109
|
-
|
|
110
|
-
# Add conversion methods
|
|
111
|
-
def from_pydantic(
|
|
112
|
-
instance: BaseModel, extra: Optional[dict[str, Any]] = None
|
|
113
|
-
) -> BaseModel:
|
|
114
|
-
"""Convert a Pydantic model instance to a GraphQL-compatible instance."""
|
|
115
|
-
if extra:
|
|
116
|
-
# If there are extra fields, create a new instance with them
|
|
117
|
-
instance_dict = compat.model_dump(instance)
|
|
118
|
-
instance_dict.update(extra)
|
|
119
|
-
return cls(**instance_dict)
|
|
120
|
-
return instance
|
|
121
|
-
|
|
122
|
-
def to_pydantic(self: Any, **kwargs: Any) -> BaseModel:
|
|
123
|
-
"""Convert a GraphQL instance back to a Pydantic model."""
|
|
124
|
-
if isinstance(self, cls):
|
|
125
|
-
# If it's already the right type, return it
|
|
126
|
-
if not kwargs:
|
|
127
|
-
return self
|
|
128
|
-
# Create a new instance with the updated kwargs
|
|
129
|
-
instance_dict = compat.model_dump(self)
|
|
130
|
-
instance_dict.update(kwargs)
|
|
131
|
-
return cls(**instance_dict)
|
|
132
|
-
|
|
133
|
-
# If it's a different type, convert it
|
|
134
|
-
return convert_strawberry_class_to_pydantic_model(self, **kwargs)
|
|
135
|
-
|
|
136
|
-
# Add conversion methods if they don't exist
|
|
137
|
-
if not hasattr(cls, "from_pydantic"):
|
|
138
|
-
cls.from_pydantic = staticmethod(from_pydantic) # type: ignore
|
|
139
|
-
if not hasattr(cls, "to_pydantic"):
|
|
140
|
-
cls.to_pydantic = to_pydantic # type: ignore
|
|
141
|
-
|
|
142
|
-
return cls
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@overload
|
|
146
|
-
def type(
|
|
147
|
-
cls: type[BaseModel],
|
|
148
|
-
*,
|
|
149
|
-
name: Optional[str] = None,
|
|
150
|
-
description: Optional[str] = None,
|
|
151
|
-
directives: Optional[Sequence[object]] = (),
|
|
152
|
-
include_computed: bool = False,
|
|
153
|
-
) -> type[BaseModel]: ...
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
@overload
|
|
157
|
-
def type(
|
|
158
|
-
*,
|
|
159
|
-
name: Optional[str] = None,
|
|
160
|
-
description: Optional[str] = None,
|
|
161
|
-
directives: Optional[Sequence[object]] = (),
|
|
162
|
-
include_computed: bool = False,
|
|
163
|
-
) -> Callable[[type[BaseModel]], type[BaseModel]]: ...
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def type(
|
|
167
|
-
cls: Optional[type[BaseModel]] = None,
|
|
168
|
-
*,
|
|
169
|
-
name: Optional[str] = None,
|
|
170
|
-
description: Optional[str] = None,
|
|
171
|
-
directives: Optional[Sequence[object]] = (),
|
|
172
|
-
include_computed: bool = False,
|
|
173
|
-
) -> Union[type[BaseModel], Callable[[type[BaseModel]], type[BaseModel]]]:
|
|
174
|
-
"""Decorator to convert a Pydantic BaseModel directly into a GraphQL type.
|
|
175
|
-
|
|
176
|
-
This decorator allows you to use Pydantic models directly as GraphQL types
|
|
177
|
-
without needing to create a separate wrapper class.
|
|
178
|
-
|
|
179
|
-
Args:
|
|
180
|
-
cls: The Pydantic BaseModel class to convert
|
|
181
|
-
name: The GraphQL type name (defaults to class name)
|
|
182
|
-
description: The GraphQL type description
|
|
183
|
-
directives: GraphQL directives to apply to the type
|
|
184
|
-
include_computed: Whether to include computed fields
|
|
185
|
-
|
|
186
|
-
Returns:
|
|
187
|
-
The decorated BaseModel class with GraphQL metadata
|
|
188
|
-
|
|
189
|
-
Example:
|
|
190
|
-
@strawberry.pydantic.type
|
|
191
|
-
class User(BaseModel):
|
|
192
|
-
name: str
|
|
193
|
-
age: int
|
|
194
|
-
|
|
195
|
-
# All fields from the Pydantic model will be included in the GraphQL type
|
|
196
|
-
"""
|
|
197
|
-
|
|
198
|
-
def wrap(cls: type[BaseModel]) -> type[BaseModel]:
|
|
199
|
-
return _process_pydantic_type(
|
|
200
|
-
cls,
|
|
201
|
-
name=name,
|
|
202
|
-
is_input=False,
|
|
203
|
-
is_interface=False,
|
|
204
|
-
description=description,
|
|
205
|
-
directives=directives,
|
|
206
|
-
include_computed=include_computed,
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
if cls is None:
|
|
210
|
-
return wrap
|
|
211
|
-
|
|
212
|
-
return wrap(cls)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
@overload
|
|
216
|
-
def input(
|
|
217
|
-
cls: type[BaseModel],
|
|
218
|
-
*,
|
|
219
|
-
name: Optional[str] = None,
|
|
220
|
-
description: Optional[str] = None,
|
|
221
|
-
directives: Optional[Sequence[object]] = (),
|
|
222
|
-
) -> type[BaseModel]: ...
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
@overload
|
|
226
|
-
def input(
|
|
227
|
-
*,
|
|
228
|
-
name: Optional[str] = None,
|
|
229
|
-
description: Optional[str] = None,
|
|
230
|
-
directives: Optional[Sequence[object]] = (),
|
|
231
|
-
) -> Callable[[type[BaseModel]], type[BaseModel]]: ...
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
def input(
|
|
235
|
-
cls: Optional[type[BaseModel]] = None,
|
|
236
|
-
*,
|
|
237
|
-
name: Optional[str] = None,
|
|
238
|
-
description: Optional[str] = None,
|
|
239
|
-
directives: Optional[Sequence[object]] = (),
|
|
240
|
-
) -> Union[type[BaseModel], Callable[[type[BaseModel]], type[BaseModel]]]:
|
|
241
|
-
"""Decorator to convert a Pydantic BaseModel directly into a GraphQL input type.
|
|
242
|
-
|
|
243
|
-
This decorator allows you to use Pydantic models directly as GraphQL input types
|
|
244
|
-
without needing to create a separate wrapper class.
|
|
245
|
-
|
|
246
|
-
Args:
|
|
247
|
-
cls: The Pydantic BaseModel class to convert
|
|
248
|
-
name: The GraphQL input type name (defaults to class name)
|
|
249
|
-
description: The GraphQL input type description
|
|
250
|
-
directives: GraphQL directives to apply to the input type
|
|
251
|
-
|
|
252
|
-
Returns:
|
|
253
|
-
The decorated BaseModel class with GraphQL input metadata
|
|
254
|
-
|
|
255
|
-
Example:
|
|
256
|
-
@strawberry.pydantic.input
|
|
257
|
-
class CreateUserInput(BaseModel):
|
|
258
|
-
name: str
|
|
259
|
-
age: int
|
|
260
|
-
|
|
261
|
-
# All fields from the Pydantic model will be included in the GraphQL input type
|
|
262
|
-
"""
|
|
263
|
-
|
|
264
|
-
def wrap(cls: type[BaseModel]) -> type[BaseModel]:
|
|
265
|
-
return _process_pydantic_type(
|
|
266
|
-
cls,
|
|
267
|
-
name=name,
|
|
268
|
-
is_input=True,
|
|
269
|
-
is_interface=False,
|
|
270
|
-
description=description,
|
|
271
|
-
directives=directives,
|
|
272
|
-
include_computed=False, # Input types don't need computed fields
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
if cls is None:
|
|
276
|
-
return wrap
|
|
277
|
-
|
|
278
|
-
return wrap(cls)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
@overload
|
|
282
|
-
def interface(
|
|
283
|
-
cls: type[BaseModel],
|
|
284
|
-
*,
|
|
285
|
-
name: Optional[str] = None,
|
|
286
|
-
description: Optional[str] = None,
|
|
287
|
-
directives: Optional[Sequence[object]] = (),
|
|
288
|
-
include_computed: bool = False,
|
|
289
|
-
) -> type[BaseModel]: ...
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
@overload
|
|
293
|
-
def interface(
|
|
294
|
-
*,
|
|
295
|
-
name: Optional[str] = None,
|
|
296
|
-
description: Optional[str] = None,
|
|
297
|
-
directives: Optional[Sequence[object]] = (),
|
|
298
|
-
include_computed: bool = False,
|
|
299
|
-
) -> Callable[[type[BaseModel]], type[BaseModel]]: ...
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
def interface(
|
|
303
|
-
cls: Optional[type[BaseModel]] = None,
|
|
304
|
-
*,
|
|
305
|
-
name: Optional[str] = None,
|
|
306
|
-
description: Optional[str] = None,
|
|
307
|
-
directives: Optional[Sequence[object]] = (),
|
|
308
|
-
include_computed: bool = False,
|
|
309
|
-
) -> Union[type[BaseModel], Callable[[type[BaseModel]], type[BaseModel]]]:
|
|
310
|
-
"""Decorator to convert a Pydantic BaseModel directly into a GraphQL interface.
|
|
311
|
-
|
|
312
|
-
This decorator allows you to use Pydantic models directly as GraphQL interfaces
|
|
313
|
-
without needing to create a separate wrapper class.
|
|
314
|
-
|
|
315
|
-
Args:
|
|
316
|
-
cls: The Pydantic BaseModel class to convert
|
|
317
|
-
name: The GraphQL interface name (defaults to class name)
|
|
318
|
-
description: The GraphQL interface description
|
|
319
|
-
directives: GraphQL directives to apply to the interface
|
|
320
|
-
include_computed: Whether to include computed fields
|
|
321
|
-
|
|
322
|
-
Returns:
|
|
323
|
-
The decorated BaseModel class with GraphQL interface metadata
|
|
324
|
-
|
|
325
|
-
Example:
|
|
326
|
-
@strawberry.pydantic.interface
|
|
327
|
-
class Node(BaseModel):
|
|
328
|
-
id: str
|
|
329
|
-
"""
|
|
330
|
-
|
|
331
|
-
def wrap(cls: type[BaseModel]) -> type[BaseModel]:
|
|
332
|
-
return _process_pydantic_type(
|
|
333
|
-
cls,
|
|
334
|
-
name=name,
|
|
335
|
-
is_input=False,
|
|
336
|
-
is_interface=True,
|
|
337
|
-
description=description,
|
|
338
|
-
directives=directives,
|
|
339
|
-
include_computed=include_computed,
|
|
340
|
-
)
|
|
341
|
-
|
|
342
|
-
if cls is None:
|
|
343
|
-
return wrap
|
|
344
|
-
|
|
345
|
-
return wrap(cls)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
__all__ = ["input", "interface", "type"]
|
{strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/LICENSE
RENAMED
|
File without changes
|
{strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|