strawberry-graphql 0.235.1.dev1719337273__py3-none-any.whl → 0.236.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 +17 -11
- strawberry/aiohttp/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/aiohttp/handlers/graphql_ws_handler.py +3 -0
- strawberry/aiohttp/test/client.py +3 -0
- strawberry/aiohttp/views.py +3 -0
- strawberry/annotation.py +19 -22
- strawberry/asgi/__init__.py +3 -3
- strawberry/asgi/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/asgi/handlers/graphql_ws_handler.py +3 -0
- strawberry/asgi/test/client.py +3 -0
- strawberry/chalice/views.py +12 -3
- strawberry/channels/handlers/__init__.py +0 -0
- strawberry/channels/handlers/base.py +5 -5
- strawberry/channels/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/channels/handlers/graphql_ws_handler.py +3 -0
- strawberry/channels/handlers/http_handler.py +5 -2
- strawberry/channels/handlers/ws_handler.py +4 -1
- strawberry/channels/router.py +9 -5
- strawberry/channels/testing.py +11 -4
- strawberry/cli/commands/upgrade/__init__.py +13 -5
- strawberry/cli/commands/upgrade/_fake_progress.py +2 -1
- strawberry/cli/commands/upgrade/_run_codemod.py +18 -1
- strawberry/codegen/exceptions.py +8 -0
- strawberry/codegen/query_codegen.py +16 -7
- strawberry/codegen/types.py +32 -1
- strawberry/codemods/update_imports.py +136 -0
- strawberry/dataloader.py +13 -0
- strawberry/directive.py +52 -4
- strawberry/django/context.py +4 -1
- strawberry/django/test/client.py +3 -0
- strawberry/django/views.py +3 -0
- strawberry/exceptions/__init__.py +5 -5
- strawberry/exceptions/duplicated_type_name.py +1 -1
- strawberry/exceptions/invalid_argument_type.py +3 -3
- strawberry/exceptions/invalid_union_type.py +5 -6
- strawberry/exceptions/missing_arguments_annotations.py +1 -1
- strawberry/exceptions/missing_dependencies.py +10 -2
- strawberry/exceptions/missing_return_annotation.py +1 -1
- strawberry/exceptions/permission_fail_silently_requires_optional.py +3 -3
- strawberry/exceptions/scalar_already_registered.py +1 -1
- strawberry/exceptions/unresolved_field_type.py +2 -2
- strawberry/exceptions/utils/source_finder.py +5 -2
- strawberry/experimental/pydantic/conversion.py +5 -5
- strawberry/experimental/pydantic/conversion_types.py +4 -2
- strawberry/experimental/pydantic/error_type.py +2 -2
- strawberry/experimental/pydantic/fields.py +2 -2
- strawberry/experimental/pydantic/object_type.py +11 -7
- strawberry/experimental/pydantic/utils.py +4 -5
- strawberry/ext/dataclasses/dataclasses.py +2 -1
- strawberry/ext/mypy_plugin.py +10 -8
- strawberry/extensions/add_validation_rules.py +27 -23
- strawberry/extensions/base_extension.py +6 -4
- strawberry/extensions/directives.py +4 -1
- strawberry/extensions/disable_validation.py +15 -12
- strawberry/extensions/field_extension.py +11 -5
- strawberry/extensions/mask_errors.py +3 -0
- strawberry/extensions/max_aliases.py +21 -19
- strawberry/extensions/max_tokens.py +14 -16
- strawberry/extensions/parser_cache.py +22 -19
- strawberry/extensions/pyinstrument.py +4 -8
- strawberry/extensions/query_depth_limiter.py +22 -23
- strawberry/extensions/runner.py +3 -0
- strawberry/extensions/tracing/apollo.py +3 -0
- strawberry/extensions/tracing/datadog.py +7 -2
- strawberry/extensions/tracing/opentelemetry.py +3 -0
- strawberry/extensions/tracing/sentry.py +3 -0
- strawberry/extensions/tracing/utils.py +3 -0
- strawberry/extensions/utils.py +3 -0
- strawberry/extensions/validation_cache.py +23 -20
- strawberry/fastapi/context.py +3 -0
- strawberry/fastapi/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/fastapi/handlers/graphql_ws_handler.py +3 -0
- strawberry/fastapi/router.py +3 -0
- strawberry/federation/argument.py +4 -1
- strawberry/federation/enum.py +5 -3
- strawberry/federation/field.py +6 -3
- strawberry/federation/mutation.py +2 -0
- strawberry/federation/object_type.py +7 -4
- strawberry/federation/scalar.py +43 -20
- strawberry/federation/schema.py +12 -9
- strawberry/federation/schema_directive.py +2 -2
- strawberry/federation/schema_directives.py +19 -1
- strawberry/federation/types.py +5 -2
- strawberry/federation/union.py +27 -8
- strawberry/field_extensions/input_mutation.py +5 -2
- strawberry/file_uploads/scalars.py +3 -1
- strawberry/file_uploads/utils.py +3 -0
- strawberry/flask/views.py +8 -2
- strawberry/http/__init__.py +9 -0
- strawberry/http/async_base_view.py +4 -3
- strawberry/http/base.py +5 -7
- strawberry/http/exceptions.py +3 -0
- strawberry/http/ides.py +3 -0
- strawberry/http/sync_base_view.py +4 -3
- strawberry/http/temporal_response.py +3 -0
- strawberry/http/types.py +5 -2
- strawberry/http/typevars.py +3 -0
- strawberry/litestar/controller.py +6 -0
- strawberry/litestar/handlers/__init__.py +0 -0
- strawberry/litestar/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/litestar/handlers/graphql_ws_handler.py +3 -0
- strawberry/parent.py +27 -21
- strawberry/permission.py +70 -27
- strawberry/printer/ast_from_value.py +4 -1
- strawberry/printer/printer.py +8 -5
- strawberry/quart/views.py +3 -0
- strawberry/relay/exceptions.py +7 -0
- strawberry/relay/fields.py +70 -45
- strawberry/relay/types.py +78 -78
- strawberry/relay/utils.py +10 -1
- strawberry/resolvers.py +3 -0
- strawberry/sanic/context.py +3 -0
- strawberry/sanic/utils.py +10 -8
- strawberry/sanic/views.py +5 -9
- strawberry/scalars.py +6 -2
- strawberry/schema/base.py +7 -4
- strawberry/schema/compat.py +12 -2
- strawberry/schema/config.py +3 -0
- strawberry/schema/exceptions.py +3 -0
- strawberry/schema/execute.py +3 -0
- strawberry/schema/name_converter.py +12 -9
- strawberry/schema/schema.py +46 -9
- strawberry/schema/schema_converter.py +16 -14
- strawberry/schema/types/base_scalars.py +3 -1
- strawberry/schema/types/concrete_type.py +4 -4
- strawberry/schema/types/scalar.py +8 -1
- strawberry/schema/validation_rules/one_of.py +3 -0
- strawberry/schema_codegen/__init__.py +3 -0
- strawberry/schema_directive.py +2 -2
- strawberry/starlite/controller.py +3 -0
- strawberry/starlite/handlers/__init__.py +0 -0
- strawberry/starlite/handlers/graphql_transport_ws_handler.py +3 -0
- strawberry/starlite/handlers/graphql_ws_handler.py +3 -0
- strawberry/subscriptions/__init__.py +6 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py +5 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +12 -17
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +21 -25
- strawberry/subscriptions/protocols/graphql_ws/__init__.py +14 -0
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +8 -5
- strawberry/subscriptions/protocols/graphql_ws/types.py +11 -0
- strawberry/test/client.py +44 -29
- strawberry/tools/create_type.py +27 -8
- strawberry/tools/merge_types.py +5 -3
- strawberry/types/__init__.py +8 -1
- strawberry/{arguments.py → types/arguments.py} +44 -13
- strawberry/{auto.py → types/auto.py} +21 -3
- strawberry/types/{types.py → base.py} +234 -10
- strawberry/{enum.py → types/enum.py} +69 -9
- strawberry/types/execution.py +3 -0
- strawberry/{field.py → types/field.py} +46 -23
- strawberry/types/fields/resolver.py +2 -2
- strawberry/types/graphql.py +3 -0
- strawberry/types/info.py +50 -7
- strawberry/{lazy_type.py → types/lazy_type.py} +50 -0
- strawberry/types/mutation.py +351 -0
- strawberry/types/nodes.py +4 -2
- strawberry/{object_type.py → types/object_type.py} +108 -29
- strawberry/{private.py → types/private.py} +13 -6
- strawberry/{custom_scalar.py → types/scalar.py} +39 -23
- strawberry/types/type_resolver.py +21 -16
- strawberry/{union.py → types/union.py} +24 -9
- strawberry/{unset.py → types/unset.py} +20 -0
- strawberry/utils/aio.py +8 -0
- strawberry/utils/await_maybe.py +3 -0
- strawberry/utils/dataclasses.py +3 -0
- strawberry/utils/debug.py +5 -2
- strawberry/utils/deprecations.py +3 -0
- strawberry/utils/graphql_lexer.py +3 -0
- strawberry/utils/importer.py +3 -0
- strawberry/utils/inspect.py +39 -30
- strawberry/utils/logging.py +3 -0
- strawberry/utils/operation.py +3 -0
- strawberry/utils/str_converters.py +3 -0
- strawberry/utils/typing.py +33 -16
- {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/METADATA +1 -1
- strawberry_graphql-0.236.0.dist-info/RECORD +255 -0
- strawberry/mutation.py +0 -8
- strawberry/type.py +0 -232
- strawberry_graphql-0.235.1.dev1719337273.dist-info/RECORD +0 -252
- {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/LICENSE +0 -0
- {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/WHEEL +0 -0
- {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/entry_points.txt +0 -0
@@ -16,20 +16,19 @@ from typing import (
|
|
16
16
|
)
|
17
17
|
from typing_extensions import dataclass_transform
|
18
18
|
|
19
|
-
from .exceptions import (
|
19
|
+
from strawberry.exceptions import (
|
20
20
|
MissingFieldAnnotationError,
|
21
21
|
MissingReturnAnnotationError,
|
22
22
|
ObjectIsNotClassError,
|
23
23
|
)
|
24
|
+
from strawberry.types.base import get_object_definition
|
25
|
+
from strawberry.utils.dataclasses import add_custom_init_fn
|
26
|
+
from strawberry.utils.deprecations import DEPRECATION_MESSAGES, DeprecatedDescriptor
|
27
|
+
from strawberry.utils.str_converters import to_camel_case
|
28
|
+
|
29
|
+
from .base import StrawberryObjectDefinition
|
24
30
|
from .field import StrawberryField, field
|
25
|
-
from .
|
26
|
-
from .types.type_resolver import _get_fields
|
27
|
-
from .types.types import (
|
28
|
-
StrawberryObjectDefinition,
|
29
|
-
)
|
30
|
-
from .utils.dataclasses import add_custom_init_fn
|
31
|
-
from .utils.deprecations import DEPRECATION_MESSAGES, DeprecatedDescriptor
|
32
|
-
from .utils.str_converters import to_camel_case
|
31
|
+
from .type_resolver import _get_fields
|
33
32
|
|
34
33
|
T = TypeVar("T", bound=Type)
|
35
34
|
|
@@ -103,9 +102,7 @@ def _check_field_annotations(cls: Type[Any]) -> None:
|
|
103
102
|
|
104
103
|
|
105
104
|
def _wrap_dataclass(cls: Type[T]) -> Type[T]:
|
106
|
-
"""Wrap a strawberry.type class with a dataclass and check for any issues
|
107
|
-
before doing so"""
|
108
|
-
|
105
|
+
"""Wrap a strawberry.type class with a dataclass and check for any issues before doing so."""
|
109
106
|
# Ensure all Fields have been properly type-annotated
|
110
107
|
_check_field_annotations(cls)
|
111
108
|
|
@@ -232,11 +229,36 @@ def type(
|
|
232
229
|
) -> Union[T, Callable[[T], T]]:
|
233
230
|
"""Annotates a class as a GraphQL type.
|
234
231
|
|
232
|
+
Similar to `dataclasses.dataclass`, but with additional functionality for
|
233
|
+
defining GraphQL types.
|
234
|
+
|
235
|
+
Args:
|
236
|
+
cls: The class we want to create a GraphQL type from.
|
237
|
+
name: The name of the GraphQL type.
|
238
|
+
is_input: Whether the class is an input type. Used internally, use `@strawerry.input` instead of passing this flag.
|
239
|
+
is_interface: Whether the class is an interface. Used internally, use `@strawerry.interface` instead of passing this flag.
|
240
|
+
description: The description of the GraphQL type.
|
241
|
+
directives: The directives of the GraphQL type.
|
242
|
+
extend: Whether the class is extending an existing type.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
The class.
|
246
|
+
|
235
247
|
Example usage:
|
236
248
|
|
237
|
-
|
238
|
-
|
239
|
-
|
249
|
+
```python
|
250
|
+
@strawberry.type
|
251
|
+
class User:
|
252
|
+
name: str = "A name"
|
253
|
+
```
|
254
|
+
|
255
|
+
You can also pass parameters to the decorator:
|
256
|
+
|
257
|
+
```python
|
258
|
+
@strawberry.type(name="UserType", description="A user type")
|
259
|
+
class MyUser:
|
260
|
+
name: str = "A name"
|
261
|
+
```
|
240
262
|
"""
|
241
263
|
|
242
264
|
def wrap(cls: T) -> T:
|
@@ -321,12 +343,35 @@ def input(
|
|
321
343
|
directives: Optional[Sequence[object]] = (),
|
322
344
|
):
|
323
345
|
"""Annotates a class as a GraphQL Input type.
|
346
|
+
|
347
|
+
Similar to `@strawberry.type`, but for input types.
|
348
|
+
|
349
|
+
Args:
|
350
|
+
cls: The class we want to create a GraphQL input type from.
|
351
|
+
name: The name of the GraphQL input type.
|
352
|
+
description: The description of the GraphQL input type.
|
353
|
+
directives: The directives of the GraphQL input type.
|
354
|
+
one_of: Whether the input type is a `oneOf` type.
|
355
|
+
|
356
|
+
Returns:
|
357
|
+
The class.
|
358
|
+
|
324
359
|
Example usage:
|
325
|
-
>>> @strawberry.input
|
326
|
-
>>> class X:
|
327
|
-
>>> field_abc: str = "ABC"
|
328
|
-
"""
|
329
360
|
|
361
|
+
```python
|
362
|
+
@strawberry.input
|
363
|
+
class UserInput:
|
364
|
+
name: str
|
365
|
+
```
|
366
|
+
|
367
|
+
You can also pass parameters to the decorator:
|
368
|
+
|
369
|
+
```python
|
370
|
+
@strawberry.input(name="UserInputType", description="A user input type")
|
371
|
+
class MyUserInput:
|
372
|
+
name: str
|
373
|
+
```
|
374
|
+
"""
|
330
375
|
from strawberry.schema_directives import OneOf
|
331
376
|
|
332
377
|
if one_of:
|
@@ -377,12 +422,34 @@ def interface(
|
|
377
422
|
directives: Optional[Sequence[object]] = (),
|
378
423
|
):
|
379
424
|
"""Annotates a class as a GraphQL Interface.
|
425
|
+
|
426
|
+
Similar to `@strawberry.type`, but for interfaces.
|
427
|
+
|
428
|
+
Args:
|
429
|
+
cls: The class we want to create a GraphQL interface from.
|
430
|
+
name: The name of the GraphQL interface.
|
431
|
+
description: The description of the GraphQL interface.
|
432
|
+
directives: The directives of the GraphQL interface.
|
433
|
+
|
434
|
+
Returns:
|
435
|
+
The class.
|
436
|
+
|
380
437
|
Example usage:
|
381
|
-
>>> @strawberry.interface
|
382
|
-
>>> class X:
|
383
|
-
>>> field_abc: str
|
384
|
-
"""
|
385
438
|
|
439
|
+
```python
|
440
|
+
@strawberry.interface
|
441
|
+
class Node:
|
442
|
+
id: str
|
443
|
+
```
|
444
|
+
|
445
|
+
You can also pass parameters to the decorator:
|
446
|
+
|
447
|
+
```python
|
448
|
+
@strawberry.interface(name="NodeType", description="A node type")
|
449
|
+
class MyNode:
|
450
|
+
id: str
|
451
|
+
```
|
452
|
+
"""
|
386
453
|
return type( # type: ignore # not sure why mypy complains here
|
387
454
|
cls,
|
388
455
|
name=name,
|
@@ -394,15 +461,27 @@ def interface(
|
|
394
461
|
|
395
462
|
def asdict(obj: Any) -> Dict[str, object]:
|
396
463
|
"""Convert a strawberry object into a dictionary.
|
464
|
+
|
397
465
|
This wraps the dataclasses.asdict function to strawberry.
|
398
466
|
|
467
|
+
Args:
|
468
|
+
obj: The object to convert into a dictionary.
|
469
|
+
|
470
|
+
Returns:
|
471
|
+
A dictionary representation of the object.
|
472
|
+
|
399
473
|
Example usage:
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
474
|
+
|
475
|
+
```python
|
476
|
+
@strawberry.type
|
477
|
+
class User:
|
478
|
+
name: str
|
479
|
+
age: int
|
480
|
+
|
481
|
+
|
482
|
+
strawberry.asdict(User(name="Lorem", age=25))
|
483
|
+
# {"name": "Lorem", "age": 25}
|
484
|
+
```
|
406
485
|
"""
|
407
486
|
return dataclasses.asdict(obj)
|
408
487
|
|
@@ -10,17 +10,24 @@ class StrawberryPrivate: ...
|
|
10
10
|
T = TypeVar("T")
|
11
11
|
|
12
12
|
Private = Annotated[T, StrawberryPrivate()]
|
13
|
-
|
13
|
+
"""Represents a field that won't be exposed in the GraphQL schema.
|
14
14
|
|
15
15
|
Example:
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
```python
|
18
|
+
import strawberry
|
19
|
+
|
20
|
+
|
21
|
+
@strawberry.type
|
22
|
+
class User:
|
23
|
+
name: str
|
24
|
+
age: strawberry.Private[int]
|
25
|
+
```
|
22
26
|
"""
|
23
27
|
|
24
28
|
|
25
29
|
def is_private(type_: object) -> bool:
|
26
30
|
return type_has_annotation(type_, StrawberryPrivate)
|
31
|
+
|
32
|
+
|
33
|
+
__all__ = ["Private", "is_private"]
|
@@ -16,9 +16,8 @@ from typing import (
|
|
16
16
|
)
|
17
17
|
|
18
18
|
from strawberry.exceptions import InvalidUnionTypeError
|
19
|
-
from strawberry.
|
20
|
-
|
21
|
-
from .utils.str_converters import to_camel_case
|
19
|
+
from strawberry.types.base import StrawberryType
|
20
|
+
from strawberry.utils.str_converters import to_camel_case
|
22
21
|
|
23
22
|
if TYPE_CHECKING:
|
24
23
|
from graphql import GraphQLScalarType
|
@@ -166,30 +165,44 @@ def scalar(
|
|
166
165
|
) -> Any:
|
167
166
|
"""Annotates a class or type as a GraphQL custom scalar.
|
168
167
|
|
168
|
+
Args:
|
169
|
+
cls: The class or type to annotate.
|
170
|
+
name: The GraphQL name of the scalar.
|
171
|
+
description: The description of the scalar.
|
172
|
+
specified_by_url: The URL of the specification.
|
173
|
+
serialize: The function to serialize the scalar.
|
174
|
+
parse_value: The function to parse the value.
|
175
|
+
parse_literal: The function to parse the literal.
|
176
|
+
directives: The directives to apply to the scalar.
|
177
|
+
|
178
|
+
Returns:
|
179
|
+
The decorated class or type.
|
180
|
+
|
169
181
|
Example usages:
|
170
182
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
>>> Base64Encoded = strawberry.scalar(
|
178
|
-
>>> NewType("Base64Encoded", bytes),
|
179
|
-
>>> serialize=base64.b64encode,
|
180
|
-
>>> parse_value=base64.b64decode
|
181
|
-
>>> )
|
182
|
-
|
183
|
-
>>> @strawberry.scalar(
|
184
|
-
>>> serialize=lambda value: ",".join(value.items),
|
185
|
-
>>> parse_value=lambda value: CustomList(value.split(","))
|
186
|
-
>>> )
|
187
|
-
>>> class CustomList:
|
188
|
-
>>> def __init__(self, items):
|
189
|
-
>>> self.items = items
|
183
|
+
```python
|
184
|
+
strawberry.scalar(
|
185
|
+
datetime.date,
|
186
|
+
serialize=lambda value: value.isoformat(),
|
187
|
+
parse_value=datetime.parse_date,
|
188
|
+
)
|
190
189
|
|
191
|
-
|
190
|
+
Base64Encoded = strawberry.scalar(
|
191
|
+
NewType("Base64Encoded", bytes),
|
192
|
+
serialize=base64.b64encode,
|
193
|
+
parse_value=base64.b64decode,
|
194
|
+
)
|
192
195
|
|
196
|
+
|
197
|
+
@strawberry.scalar(
|
198
|
+
serialize=lambda value: ",".join(value.items),
|
199
|
+
parse_value=lambda value: CustomList(value.split(",")),
|
200
|
+
)
|
201
|
+
class CustomList:
|
202
|
+
def __init__(self, items):
|
203
|
+
self.items = items
|
204
|
+
```
|
205
|
+
"""
|
193
206
|
if parse_value is None:
|
194
207
|
parse_value = cls
|
195
208
|
|
@@ -209,3 +222,6 @@ def scalar(
|
|
209
222
|
return wrap
|
210
223
|
|
211
224
|
return wrap(cls)
|
225
|
+
|
226
|
+
|
227
|
+
__all__ = ["ScalarDefinition", "ScalarWrapper", "scalar"]
|
@@ -10,16 +10,16 @@ from strawberry.exceptions import (
|
|
10
10
|
FieldWithResolverAndDefaultValueError,
|
11
11
|
PrivateStrawberryFieldError,
|
12
12
|
)
|
13
|
-
from strawberry.
|
14
|
-
from strawberry.
|
15
|
-
from strawberry.
|
16
|
-
from strawberry.unset import UNSET
|
13
|
+
from strawberry.types.base import has_object_definition
|
14
|
+
from strawberry.types.field import StrawberryField
|
15
|
+
from strawberry.types.private import is_private
|
16
|
+
from strawberry.types.unset import UNSET
|
17
17
|
|
18
18
|
|
19
19
|
def _get_fields(
|
20
20
|
cls: Type[Any], original_type_annotations: Dict[str, Type[Any]]
|
21
21
|
) -> List[StrawberryField]:
|
22
|
-
"""Get all the strawberry fields off a strawberry.type cls
|
22
|
+
"""Get all the strawberry fields off a strawberry.type cls.
|
23
23
|
|
24
24
|
This function returns a list of StrawberryFields (one for each field item), while
|
25
25
|
also paying attention the name and typing of the field.
|
@@ -27,16 +27,19 @@ def _get_fields(
|
|
27
27
|
StrawberryFields can be defined on a strawberry.type class as either a dataclass-
|
28
28
|
style field or using strawberry.field as a decorator.
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
```python
|
31
|
+
import strawberry
|
32
|
+
|
33
|
+
|
34
|
+
@strawberry.type
|
35
|
+
class Query:
|
36
|
+
type_1a: int = 5
|
37
|
+
type_1b: int = strawberry.field(...)
|
38
|
+
type_1c: int = strawberry.field(resolver=...)
|
39
|
+
|
40
|
+
@strawberry.field
|
41
|
+
def type_2(self) -> int: ...
|
42
|
+
```
|
40
43
|
|
41
44
|
Type #1:
|
42
45
|
A pure dataclass-style field. Will not have a StrawberryField; one will need to
|
@@ -51,7 +54,6 @@ def _get_fields(
|
|
51
54
|
passing a named function (i.e. not an anonymous lambda) to strawberry.field
|
52
55
|
(typically as a decorator).
|
53
56
|
"""
|
54
|
-
|
55
57
|
fields: Dict[str, StrawberryField] = {}
|
56
58
|
|
57
59
|
# before trying to find any fields, let's first add the fields defined in
|
@@ -163,3 +165,6 @@ def _get_fields(
|
|
163
165
|
fields[field_name] = field
|
164
166
|
|
165
167
|
return list(fields.values())
|
168
|
+
|
169
|
+
|
170
|
+
__all__ = ["_get_fields"]
|
@@ -31,12 +31,12 @@ from strawberry.exceptions import (
|
|
31
31
|
WrongReturnTypeForUnion,
|
32
32
|
)
|
33
33
|
from strawberry.exceptions.handler import should_use_rich_exceptions
|
34
|
-
from strawberry.
|
35
|
-
from strawberry.type import (
|
34
|
+
from strawberry.types.base import (
|
36
35
|
StrawberryOptional,
|
37
36
|
StrawberryType,
|
38
37
|
has_object_definition,
|
39
38
|
)
|
39
|
+
from strawberry.types.lazy_type import LazyType
|
40
40
|
|
41
41
|
if TYPE_CHECKING:
|
42
42
|
from graphql import (
|
@@ -173,7 +173,7 @@ class StrawberryUnion(StrawberryType):
|
|
173
173
|
) -> str:
|
174
174
|
assert isinstance(type_, GraphQLUnionType)
|
175
175
|
|
176
|
-
from strawberry.types.
|
176
|
+
from strawberry.types.base import StrawberryObjectDefinition
|
177
177
|
|
178
178
|
# If the type given is not an Object type, try resolving using `is_type_of`
|
179
179
|
# defined on the union's inner types
|
@@ -250,15 +250,27 @@ def union(
|
|
250
250
|
) -> StrawberryUnion:
|
251
251
|
"""Creates a new named Union type.
|
252
252
|
|
253
|
+
Args:
|
254
|
+
name: The GraphQL name of the Union type.
|
255
|
+
types: The types that the Union can be.
|
256
|
+
(Deprecated, use `Annotated[U, strawberry.union("Name")]` instead)
|
257
|
+
description: The GraphQL description of the Union type.
|
258
|
+
directives: The directives to attach to the Union type.
|
259
|
+
|
253
260
|
Example usages:
|
254
261
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
262
|
+
```python
|
263
|
+
import strawberry
|
264
|
+
from typing import Annotated
|
265
|
+
|
266
|
+
@strawberry.type
|
267
|
+
class A: ...
|
268
|
+
|
269
|
+
@strawberry.type
|
270
|
+
class B: ...
|
261
271
|
|
272
|
+
MyUnion = Annotated[A | B, strawberry.union("Name")]
|
273
|
+
"""
|
262
274
|
if types is None:
|
263
275
|
union = StrawberryUnion(
|
264
276
|
name=name,
|
@@ -299,3 +311,6 @@ def union(
|
|
299
311
|
description=description,
|
300
312
|
directives=directives,
|
301
313
|
)
|
314
|
+
|
315
|
+
|
316
|
+
__all__ = ["StrawberryUnion", "union"]
|
@@ -28,6 +28,26 @@ class UnsetType:
|
|
28
28
|
|
29
29
|
|
30
30
|
UNSET: Any = UnsetType()
|
31
|
+
"""A special value that can be used to represent an unset value in a field or argument.
|
32
|
+
Similar to `undefined` in JavaScript, this value can be used to differentiate between
|
33
|
+
a field that was not set and a field that was set to `None` or `null`.
|
34
|
+
|
35
|
+
Example:
|
36
|
+
|
37
|
+
```python
|
38
|
+
import strawberry
|
39
|
+
|
40
|
+
|
41
|
+
@strawberry.input
|
42
|
+
class UserInput:
|
43
|
+
name: str | None = strawberry.UNSET
|
44
|
+
age: int | None = strawberry.UNSET
|
45
|
+
```
|
46
|
+
|
47
|
+
In the example above, if `name` or `age` are not provided when creating a `UserInput`
|
48
|
+
object, they will be set to `UNSET` instead of `None`. Use `is UNSET` to check
|
49
|
+
whether a value is unset.
|
50
|
+
"""
|
31
51
|
|
32
52
|
|
33
53
|
def _deprecated_is_unset(value: Any) -> bool:
|
strawberry/utils/aio.py
CHANGED
@@ -67,3 +67,11 @@ async def resolve_awaitable(
|
|
67
67
|
) -> _R:
|
68
68
|
"""Resolves an awaitable object and calls a callback with the resolved value."""
|
69
69
|
return callback(await awaitable)
|
70
|
+
|
71
|
+
|
72
|
+
__all__ = [
|
73
|
+
"aenumerate",
|
74
|
+
"aislice",
|
75
|
+
"asyncgen_to_list",
|
76
|
+
"resolve_awaitable",
|
77
|
+
]
|
strawberry/utils/await_maybe.py
CHANGED
strawberry/utils/dataclasses.py
CHANGED
strawberry/utils/debug.py
CHANGED
@@ -14,8 +14,8 @@ def pretty_print_graphql_operation(
|
|
14
14
|
) -> None:
|
15
15
|
"""Pretty print a GraphQL operation using pygments.
|
16
16
|
|
17
|
-
Won't print introspection operation to prevent noise in the output.
|
18
|
-
|
17
|
+
Won't print introspection operation to prevent noise in the output.
|
18
|
+
"""
|
19
19
|
try:
|
20
20
|
from pygments import highlight, lexers
|
21
21
|
from pygments.formatters import Terminal256Formatter
|
@@ -41,3 +41,6 @@ def pretty_print_graphql_operation(
|
|
41
41
|
print( # noqa: T201
|
42
42
|
highlight(variables_json, lexers.JsonLexer(), Terminal256Formatter())
|
43
43
|
)
|
44
|
+
|
45
|
+
|
46
|
+
__all__ = ["pretty_print_graphql_operation"]
|
strawberry/utils/deprecations.py
CHANGED
strawberry/utils/importer.py
CHANGED
strawberry/utils/inspect.py
CHANGED
@@ -12,7 +12,6 @@ from typing import (
|
|
12
12
|
)
|
13
13
|
from typing_extensions import get_args
|
14
14
|
|
15
|
-
from strawberry.type import has_object_definition
|
16
15
|
from strawberry.utils.typing import is_generic_alias
|
17
16
|
|
18
17
|
|
@@ -29,8 +28,7 @@ def in_async_context() -> bool:
|
|
29
28
|
|
30
29
|
@lru_cache(maxsize=250)
|
31
30
|
def get_func_args(func: Callable[[Any], Any]) -> List[str]:
|
32
|
-
"""Returns a list of arguments for the function"""
|
33
|
-
|
31
|
+
"""Returns a list of arguments for the function."""
|
34
32
|
sig = inspect.signature(func)
|
35
33
|
|
36
34
|
return [
|
@@ -45,38 +43,46 @@ def get_specialized_type_var_map(cls: type) -> Optional[Dict[str, type]]:
|
|
45
43
|
|
46
44
|
Consider the following:
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
46
|
+
```python
|
47
|
+
class Foo(Generic[T]): ...
|
48
|
+
|
49
|
+
|
50
|
+
class Bar(Generic[K]): ...
|
51
|
+
|
52
|
+
|
53
|
+
class IntBar(Bar[int]): ...
|
54
|
+
|
55
|
+
|
56
|
+
class IntBarSubclass(IntBar): ...
|
57
|
+
|
58
|
+
|
59
|
+
class IntBarFoo(IntBar, Foo[str]): ...
|
60
|
+
```
|
63
61
|
|
64
62
|
This would return:
|
65
63
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
64
|
+
```python
|
65
|
+
get_specialized_type_var_map(object)
|
66
|
+
# None
|
67
|
+
|
68
|
+
get_specialized_type_var_map(Foo)
|
69
|
+
# {}
|
70
|
+
|
71
|
+
get_specialized_type_var_map(Bar)
|
72
|
+
# {~T: ~T}
|
73
|
+
|
74
|
+
get_specialized_type_var_map(IntBar)
|
75
|
+
# {~T: int}
|
78
76
|
|
77
|
+
get_specialized_type_var_map(IntBarSubclass)
|
78
|
+
# {~T: int}
|
79
|
+
|
80
|
+
get_specialized_type_var_map(IntBarFoo)
|
81
|
+
# {~T: int, ~K: str}
|
82
|
+
```
|
79
83
|
"""
|
84
|
+
from strawberry.types.base import has_object_definition
|
85
|
+
|
80
86
|
orig_bases = getattr(cls, "__orig_bases__", None)
|
81
87
|
if orig_bases is None:
|
82
88
|
# Specialized generic aliases will not have __orig_bases__
|
@@ -114,3 +120,6 @@ def get_specialized_type_var_map(cls: type) -> Optional[Dict[str, type]]:
|
|
114
120
|
)
|
115
121
|
|
116
122
|
return type_var_map
|
123
|
+
|
124
|
+
|
125
|
+
__all__ = ["in_async_context", "get_func_args", "get_specialized_type_var_map"]
|
strawberry/utils/logging.py
CHANGED
strawberry/utils/operation.py
CHANGED
@@ -24,3 +24,6 @@ def capitalize_first(name: str) -> str:
|
|
24
24
|
def to_snake_case(name: str) -> str:
|
25
25
|
name = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
|
26
26
|
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", name).lower()
|
27
|
+
|
28
|
+
|
29
|
+
__all__ = ["to_camel_case", "to_kebab_case", "capitalize_first", "to_snake_case"]
|