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.
Files changed (36) hide show
  1. strawberry/__init__.py +1 -2
  2. strawberry/aiohttp/views.py +2 -48
  3. strawberry/asgi/__init__.py +2 -37
  4. strawberry/chalice/views.py +7 -75
  5. strawberry/channels/handlers/http_handler.py +30 -6
  6. strawberry/cli/commands/upgrade/__init__.py +2 -0
  7. strawberry/codemods/__init__.py +9 -0
  8. strawberry/codemods/maybe_optional.py +118 -0
  9. strawberry/django/views.py +4 -73
  10. strawberry/experimental/pydantic/_compat.py +1 -0
  11. strawberry/experimental/pydantic/error_type.py +1 -0
  12. strawberry/experimental/pydantic/fields.py +1 -0
  13. strawberry/experimental/pydantic/utils.py +1 -0
  14. strawberry/fastapi/router.py +8 -4
  15. strawberry/flask/views.py +4 -74
  16. strawberry/http/async_base_view.py +5 -31
  17. strawberry/http/base.py +2 -1
  18. strawberry/http/exceptions.py +5 -7
  19. strawberry/http/sync_base_view.py +1 -34
  20. strawberry/litestar/controller.py +1 -39
  21. strawberry/quart/views.py +3 -33
  22. strawberry/sanic/views.py +4 -43
  23. strawberry/schema/schema.py +2 -0
  24. strawberry/schema/schema_converter.py +7 -0
  25. strawberry/schema/validation_rules/maybe_null.py +136 -0
  26. strawberry/types/arguments.py +16 -2
  27. strawberry/types/maybe.py +1 -1
  28. {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/METADATA +2 -1
  29. {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/RECORD +32 -34
  30. strawberry/pydantic/__init__.py +0 -22
  31. strawberry/pydantic/error.py +0 -51
  32. strawberry/pydantic/fields.py +0 -202
  33. strawberry/pydantic/object_type.py +0 -348
  34. {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/LICENSE +0 -0
  35. {strawberry_graphql-0.279.0.dev1754156227.dist-info → strawberry_graphql-0.280.0.dist-info}/WHEEL +0 -0
  36. {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"]