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.
Files changed (182) hide show
  1. strawberry/__init__.py +17 -11
  2. strawberry/aiohttp/handlers/graphql_transport_ws_handler.py +3 -0
  3. strawberry/aiohttp/handlers/graphql_ws_handler.py +3 -0
  4. strawberry/aiohttp/test/client.py +3 -0
  5. strawberry/aiohttp/views.py +3 -0
  6. strawberry/annotation.py +19 -22
  7. strawberry/asgi/__init__.py +3 -3
  8. strawberry/asgi/handlers/graphql_transport_ws_handler.py +3 -0
  9. strawberry/asgi/handlers/graphql_ws_handler.py +3 -0
  10. strawberry/asgi/test/client.py +3 -0
  11. strawberry/chalice/views.py +12 -3
  12. strawberry/channels/handlers/__init__.py +0 -0
  13. strawberry/channels/handlers/base.py +5 -5
  14. strawberry/channels/handlers/graphql_transport_ws_handler.py +3 -0
  15. strawberry/channels/handlers/graphql_ws_handler.py +3 -0
  16. strawberry/channels/handlers/http_handler.py +5 -2
  17. strawberry/channels/handlers/ws_handler.py +4 -1
  18. strawberry/channels/router.py +9 -5
  19. strawberry/channels/testing.py +11 -4
  20. strawberry/cli/commands/upgrade/__init__.py +13 -5
  21. strawberry/cli/commands/upgrade/_fake_progress.py +2 -1
  22. strawberry/cli/commands/upgrade/_run_codemod.py +18 -1
  23. strawberry/codegen/exceptions.py +8 -0
  24. strawberry/codegen/query_codegen.py +16 -7
  25. strawberry/codegen/types.py +32 -1
  26. strawberry/codemods/update_imports.py +136 -0
  27. strawberry/dataloader.py +13 -0
  28. strawberry/directive.py +52 -4
  29. strawberry/django/context.py +4 -1
  30. strawberry/django/test/client.py +3 -0
  31. strawberry/django/views.py +3 -0
  32. strawberry/exceptions/__init__.py +5 -5
  33. strawberry/exceptions/duplicated_type_name.py +1 -1
  34. strawberry/exceptions/invalid_argument_type.py +3 -3
  35. strawberry/exceptions/invalid_union_type.py +5 -6
  36. strawberry/exceptions/missing_arguments_annotations.py +1 -1
  37. strawberry/exceptions/missing_dependencies.py +10 -2
  38. strawberry/exceptions/missing_return_annotation.py +1 -1
  39. strawberry/exceptions/permission_fail_silently_requires_optional.py +3 -3
  40. strawberry/exceptions/scalar_already_registered.py +1 -1
  41. strawberry/exceptions/unresolved_field_type.py +2 -2
  42. strawberry/exceptions/utils/source_finder.py +5 -2
  43. strawberry/experimental/pydantic/conversion.py +5 -5
  44. strawberry/experimental/pydantic/conversion_types.py +4 -2
  45. strawberry/experimental/pydantic/error_type.py +2 -2
  46. strawberry/experimental/pydantic/fields.py +2 -2
  47. strawberry/experimental/pydantic/object_type.py +11 -7
  48. strawberry/experimental/pydantic/utils.py +4 -5
  49. strawberry/ext/dataclasses/dataclasses.py +2 -1
  50. strawberry/ext/mypy_plugin.py +10 -8
  51. strawberry/extensions/add_validation_rules.py +27 -23
  52. strawberry/extensions/base_extension.py +6 -4
  53. strawberry/extensions/directives.py +4 -1
  54. strawberry/extensions/disable_validation.py +15 -12
  55. strawberry/extensions/field_extension.py +11 -5
  56. strawberry/extensions/mask_errors.py +3 -0
  57. strawberry/extensions/max_aliases.py +21 -19
  58. strawberry/extensions/max_tokens.py +14 -16
  59. strawberry/extensions/parser_cache.py +22 -19
  60. strawberry/extensions/pyinstrument.py +4 -8
  61. strawberry/extensions/query_depth_limiter.py +22 -23
  62. strawberry/extensions/runner.py +3 -0
  63. strawberry/extensions/tracing/apollo.py +3 -0
  64. strawberry/extensions/tracing/datadog.py +7 -2
  65. strawberry/extensions/tracing/opentelemetry.py +3 -0
  66. strawberry/extensions/tracing/sentry.py +3 -0
  67. strawberry/extensions/tracing/utils.py +3 -0
  68. strawberry/extensions/utils.py +3 -0
  69. strawberry/extensions/validation_cache.py +23 -20
  70. strawberry/fastapi/context.py +3 -0
  71. strawberry/fastapi/handlers/graphql_transport_ws_handler.py +3 -0
  72. strawberry/fastapi/handlers/graphql_ws_handler.py +3 -0
  73. strawberry/fastapi/router.py +3 -0
  74. strawberry/federation/argument.py +4 -1
  75. strawberry/federation/enum.py +5 -3
  76. strawberry/federation/field.py +6 -3
  77. strawberry/federation/mutation.py +2 -0
  78. strawberry/federation/object_type.py +7 -4
  79. strawberry/federation/scalar.py +43 -20
  80. strawberry/federation/schema.py +12 -9
  81. strawberry/federation/schema_directive.py +2 -2
  82. strawberry/federation/schema_directives.py +19 -1
  83. strawberry/federation/types.py +5 -2
  84. strawberry/federation/union.py +27 -8
  85. strawberry/field_extensions/input_mutation.py +5 -2
  86. strawberry/file_uploads/scalars.py +3 -1
  87. strawberry/file_uploads/utils.py +3 -0
  88. strawberry/flask/views.py +8 -2
  89. strawberry/http/__init__.py +9 -0
  90. strawberry/http/async_base_view.py +4 -3
  91. strawberry/http/base.py +5 -7
  92. strawberry/http/exceptions.py +3 -0
  93. strawberry/http/ides.py +3 -0
  94. strawberry/http/sync_base_view.py +4 -3
  95. strawberry/http/temporal_response.py +3 -0
  96. strawberry/http/types.py +5 -2
  97. strawberry/http/typevars.py +3 -0
  98. strawberry/litestar/controller.py +6 -0
  99. strawberry/litestar/handlers/__init__.py +0 -0
  100. strawberry/litestar/handlers/graphql_transport_ws_handler.py +3 -0
  101. strawberry/litestar/handlers/graphql_ws_handler.py +3 -0
  102. strawberry/parent.py +27 -21
  103. strawberry/permission.py +70 -27
  104. strawberry/printer/ast_from_value.py +4 -1
  105. strawberry/printer/printer.py +8 -5
  106. strawberry/quart/views.py +3 -0
  107. strawberry/relay/exceptions.py +7 -0
  108. strawberry/relay/fields.py +70 -45
  109. strawberry/relay/types.py +78 -78
  110. strawberry/relay/utils.py +10 -1
  111. strawberry/resolvers.py +3 -0
  112. strawberry/sanic/context.py +3 -0
  113. strawberry/sanic/utils.py +10 -8
  114. strawberry/sanic/views.py +5 -9
  115. strawberry/scalars.py +6 -2
  116. strawberry/schema/base.py +7 -4
  117. strawberry/schema/compat.py +12 -2
  118. strawberry/schema/config.py +3 -0
  119. strawberry/schema/exceptions.py +3 -0
  120. strawberry/schema/execute.py +3 -0
  121. strawberry/schema/name_converter.py +12 -9
  122. strawberry/schema/schema.py +46 -9
  123. strawberry/schema/schema_converter.py +16 -14
  124. strawberry/schema/types/base_scalars.py +3 -1
  125. strawberry/schema/types/concrete_type.py +4 -4
  126. strawberry/schema/types/scalar.py +8 -1
  127. strawberry/schema/validation_rules/one_of.py +3 -0
  128. strawberry/schema_codegen/__init__.py +3 -0
  129. strawberry/schema_directive.py +2 -2
  130. strawberry/starlite/controller.py +3 -0
  131. strawberry/starlite/handlers/__init__.py +0 -0
  132. strawberry/starlite/handlers/graphql_transport_ws_handler.py +3 -0
  133. strawberry/starlite/handlers/graphql_ws_handler.py +3 -0
  134. strawberry/subscriptions/__init__.py +6 -0
  135. strawberry/subscriptions/protocols/graphql_transport_ws/__init__.py +5 -0
  136. strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +12 -17
  137. strawberry/subscriptions/protocols/graphql_transport_ws/types.py +21 -25
  138. strawberry/subscriptions/protocols/graphql_ws/__init__.py +14 -0
  139. strawberry/subscriptions/protocols/graphql_ws/handlers.py +8 -5
  140. strawberry/subscriptions/protocols/graphql_ws/types.py +11 -0
  141. strawberry/test/client.py +44 -29
  142. strawberry/tools/create_type.py +27 -8
  143. strawberry/tools/merge_types.py +5 -3
  144. strawberry/types/__init__.py +8 -1
  145. strawberry/{arguments.py → types/arguments.py} +44 -13
  146. strawberry/{auto.py → types/auto.py} +21 -3
  147. strawberry/types/{types.py → base.py} +234 -10
  148. strawberry/{enum.py → types/enum.py} +69 -9
  149. strawberry/types/execution.py +3 -0
  150. strawberry/{field.py → types/field.py} +46 -23
  151. strawberry/types/fields/resolver.py +2 -2
  152. strawberry/types/graphql.py +3 -0
  153. strawberry/types/info.py +50 -7
  154. strawberry/{lazy_type.py → types/lazy_type.py} +50 -0
  155. strawberry/types/mutation.py +351 -0
  156. strawberry/types/nodes.py +4 -2
  157. strawberry/{object_type.py → types/object_type.py} +108 -29
  158. strawberry/{private.py → types/private.py} +13 -6
  159. strawberry/{custom_scalar.py → types/scalar.py} +39 -23
  160. strawberry/types/type_resolver.py +21 -16
  161. strawberry/{union.py → types/union.py} +24 -9
  162. strawberry/{unset.py → types/unset.py} +20 -0
  163. strawberry/utils/aio.py +8 -0
  164. strawberry/utils/await_maybe.py +3 -0
  165. strawberry/utils/dataclasses.py +3 -0
  166. strawberry/utils/debug.py +5 -2
  167. strawberry/utils/deprecations.py +3 -0
  168. strawberry/utils/graphql_lexer.py +3 -0
  169. strawberry/utils/importer.py +3 -0
  170. strawberry/utils/inspect.py +39 -30
  171. strawberry/utils/logging.py +3 -0
  172. strawberry/utils/operation.py +3 -0
  173. strawberry/utils/str_converters.py +3 -0
  174. strawberry/utils/typing.py +33 -16
  175. {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/METADATA +1 -1
  176. strawberry_graphql-0.236.0.dist-info/RECORD +255 -0
  177. strawberry/mutation.py +0 -8
  178. strawberry/type.py +0 -232
  179. strawberry_graphql-0.235.1.dev1719337273.dist-info/RECORD +0 -252
  180. {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/LICENSE +0 -0
  181. {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/WHEEL +0 -0
  182. {strawberry_graphql-0.235.1.dev1719337273.dist-info → strawberry_graphql-0.236.0.dist-info}/entry_points.txt +0 -0
@@ -16,25 +16,28 @@ from typing import (
16
16
  from typing_extensions import Annotated, get_args, get_origin
17
17
 
18
18
  from strawberry.annotation import StrawberryAnnotation
19
- from strawberry.enum import EnumDefinition
20
- from strawberry.lazy_type import LazyType, StrawberryLazyReference
21
- from strawberry.type import StrawberryList, StrawberryOptional, has_object_definition
22
-
23
- from .exceptions import MultipleStrawberryArgumentsError, UnsupportedTypeError
24
- from .scalars import is_scalar
25
- from .unset import UNSET as _deprecated_UNSET
26
- from .unset import _deprecated_is_unset # noqa # type: ignore
19
+ from strawberry.exceptions import MultipleStrawberryArgumentsError, UnsupportedTypeError
20
+ from strawberry.scalars import is_scalar
21
+ from strawberry.types.base import (
22
+ StrawberryList,
23
+ StrawberryOptional,
24
+ has_object_definition,
25
+ )
26
+ from strawberry.types.enum import EnumDefinition
27
+ from strawberry.types.lazy_type import LazyType, StrawberryLazyReference
28
+ from strawberry.types.unset import UNSET as _deprecated_UNSET
29
+ from strawberry.types.unset import _deprecated_is_unset # noqa # type: ignore
27
30
 
28
31
  if TYPE_CHECKING:
29
- from strawberry.custom_scalar import ScalarDefinition, ScalarWrapper
30
32
  from strawberry.schema.config import StrawberryConfig
31
- from strawberry.type import StrawberryType
33
+ from strawberry.types.base import StrawberryType
34
+ from strawberry.types.scalar import ScalarDefinition, ScalarWrapper
32
35
 
33
36
 
34
37
  DEPRECATED_NAMES: Dict[str, str] = {
35
38
  "UNSET": (
36
39
  "importing `UNSET` from `strawberry.arguments` is deprecated, "
37
- "import instead from `strawberry` or from `strawberry.unset`"
40
+ "import instead from `strawberry` or from `strawberry.types.unset`"
38
41
  ),
39
42
  "is_unset": "`is_unset` is deprecated use `value is UNSET` instead",
40
43
  }
@@ -202,8 +205,8 @@ def convert_arguments(
202
205
  """Converts a nested dictionary to a dictionary of actual types.
203
206
 
204
207
  It deals with conversion of input types to proper dataclasses and
205
- also uses a sentinel value for unset values."""
206
-
208
+ also uses a sentinel value for unset values.
209
+ """
207
210
  if not arguments:
208
211
  return {}
209
212
 
@@ -234,6 +237,34 @@ def argument(
234
237
  directives: Iterable[object] = (),
235
238
  metadata: Optional[Mapping[Any, Any]] = None,
236
239
  ) -> StrawberryArgumentAnnotation:
240
+ """Function to add metadata to an argument, like a description or deprecation reason.
241
+
242
+ Args:
243
+ description: The GraphQL description of the argument
244
+ name: The GraphQL name of the argument
245
+ deprecation_reason: The reason why this argument is deprecated,
246
+ setting this will mark the argument as deprecated
247
+ directives: The directives to attach to the argument
248
+ metadata: Metadata to attach to the argument, this can be used
249
+ to store custom data that can be used by custom logic or plugins
250
+
251
+ Returns:
252
+ A StrawberryArgumentAnnotation object that can be used to customise an argument
253
+
254
+ Example:
255
+ ```python
256
+ import strawberry
257
+
258
+
259
+ @strawberry.type
260
+ class Query:
261
+ @strawberry.field
262
+ def example(
263
+ self, info, value: int = strawberry.argument(description="The value")
264
+ ) -> int:
265
+ return value
266
+ ```
267
+ """
237
268
  return StrawberryArgumentAnnotation(
238
269
  description=description,
239
270
  name=name,
@@ -3,9 +3,8 @@ from __future__ import annotations
3
3
  from typing import Any, Optional, Union, cast
4
4
  from typing_extensions import Annotated, get_args, get_origin
5
5
 
6
- from strawberry.type import StrawberryType
7
-
8
- from .annotation import StrawberryAnnotation
6
+ from strawberry.annotation import StrawberryAnnotation
7
+ from strawberry.types.base import StrawberryType
9
8
 
10
9
 
11
10
  class StrawberryAutoMeta(type):
@@ -77,3 +76,22 @@ class StrawberryAuto(metaclass=StrawberryAutoMeta):
77
76
 
78
77
 
79
78
  auto = Annotated[Any, StrawberryAuto()]
79
+ """Special marker for automatic annotation.
80
+
81
+ A special value that can be used to automatically infer the type of a field
82
+ when using integrations like Strawberry Django or Strawberry Pydantic.
83
+
84
+ Example:
85
+ ```python
86
+ import strawberry
87
+
88
+ from my_user_app import models
89
+
90
+
91
+ @strawberry.django.type(models.User)
92
+ class User:
93
+ name: strawberry.auto
94
+ ```
95
+ """
96
+
97
+ __all__ = ["auto"]
@@ -1,10 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
+ from abc import ABC, abstractmethod
4
5
  from typing import (
5
6
  TYPE_CHECKING,
6
7
  Any,
7
8
  Callable,
9
+ ClassVar,
8
10
  Dict,
9
11
  List,
10
12
  Mapping,
@@ -13,29 +15,237 @@ from typing import (
13
15
  Type,
14
16
  TypeVar,
15
17
  Union,
18
+ overload,
16
19
  )
17
- from typing_extensions import Self, deprecated
20
+ from typing_extensions import Literal, Protocol, Self, deprecated
18
21
 
19
- from strawberry.type import (
20
- StrawberryList,
21
- StrawberryType,
22
- StrawberryTypeVar,
23
- WithStrawberryObjectDefinition,
24
- )
25
22
  from strawberry.utils.deprecations import DEPRECATION_MESSAGES, DeprecatedDescriptor
26
23
  from strawberry.utils.inspect import get_specialized_type_var_map
24
+ from strawberry.utils.typing import is_concrete_generic
27
25
  from strawberry.utils.typing import is_generic as is_type_generic
28
26
 
29
27
  if TYPE_CHECKING:
28
+ from typing_extensions import TypeGuard
29
+
30
30
  from graphql import GraphQLAbstractType, GraphQLResolveInfo
31
31
 
32
- from strawberry.field import StrawberryField
32
+ from strawberry.types.field import StrawberryField
33
+
34
+
35
+ class StrawberryType(ABC):
36
+ """The base class for all types that Strawberry uses.
37
+
38
+ Every type that is decorated by strawberry should have a dunder
39
+ `__strawberry_definition__` with an instance of a StrawberryType that contains
40
+ the parsed information that strawberry created.
41
+
42
+ NOTE: ATM this is only true for @type @interface @input follow
43
+ https://github.com/strawberry-graphql/strawberry/issues/2841 to see progress.
44
+ """
45
+
46
+ @property
47
+ def type_params(self) -> List[TypeVar]:
48
+ return []
49
+
50
+ @property
51
+ def is_one_of(self) -> bool:
52
+ return False
53
+
54
+ @abstractmethod
55
+ def copy_with(
56
+ self,
57
+ type_var_map: Mapping[
58
+ str, Union[StrawberryType, Type[WithStrawberryObjectDefinition]]
59
+ ],
60
+ ) -> Union[StrawberryType, Type[WithStrawberryObjectDefinition]]:
61
+ raise NotImplementedError()
62
+
63
+ @property
64
+ @abstractmethod
65
+ def is_graphql_generic(self) -> bool:
66
+ raise NotImplementedError()
67
+
68
+ def has_generic(self, type_var: TypeVar) -> bool:
69
+ return False
70
+
71
+ def __eq__(self, other: object) -> bool:
72
+ from strawberry.annotation import StrawberryAnnotation
73
+
74
+ if isinstance(other, StrawberryType):
75
+ return self is other
76
+
77
+ elif isinstance(other, StrawberryAnnotation):
78
+ return self == other.resolve()
79
+
80
+ else:
81
+ # This could be simplified if StrawberryAnnotation.resolve() always returned
82
+ # a StrawberryType
83
+ resolved = StrawberryAnnotation(other).resolve()
84
+ if isinstance(resolved, StrawberryType):
85
+ return self == resolved
86
+ else:
87
+ return NotImplemented
88
+
89
+ def __hash__(self) -> int:
90
+ # TODO: Is this a bad idea? __eq__ objects are supposed to have the same hash
91
+ return id(self)
92
+
93
+
94
+ class StrawberryContainer(StrawberryType):
95
+ def __init__(
96
+ self, of_type: Union[StrawberryType, Type[WithStrawberryObjectDefinition], type]
97
+ ) -> None:
98
+ self.of_type = of_type
99
+
100
+ def __hash__(self) -> int:
101
+ return hash((self.__class__, self.of_type))
102
+
103
+ def __eq__(self, other: object) -> bool:
104
+ if isinstance(other, StrawberryType):
105
+ if isinstance(other, StrawberryContainer):
106
+ return self.of_type == other.of_type
107
+ else:
108
+ return False
109
+
110
+ return super().__eq__(other)
111
+
112
+ @property
113
+ def type_params(self) -> List[TypeVar]:
114
+ if has_object_definition(self.of_type):
115
+ parameters = getattr(self.of_type, "__parameters__", None)
116
+
117
+ return list(parameters) if parameters else []
118
+
119
+ elif isinstance(self.of_type, StrawberryType):
120
+ return self.of_type.type_params
121
+
122
+ else:
123
+ return []
124
+
125
+ def copy_with(
126
+ self,
127
+ type_var_map: Mapping[
128
+ str, Union[StrawberryType, Type[WithStrawberryObjectDefinition]]
129
+ ],
130
+ ) -> Self:
131
+ of_type_copy = self.of_type
132
+
133
+ if has_object_definition(self.of_type):
134
+ type_definition = self.of_type.__strawberry_definition__
135
+
136
+ if type_definition.is_graphql_generic:
137
+ of_type_copy = type_definition.copy_with(type_var_map)
138
+
139
+ elif (
140
+ isinstance(self.of_type, StrawberryType) and self.of_type.is_graphql_generic
141
+ ):
142
+ of_type_copy = self.of_type.copy_with(type_var_map)
143
+
144
+ return type(self)(of_type_copy)
145
+
146
+ @property
147
+ def is_graphql_generic(self) -> bool:
148
+ from strawberry.schema.compat import is_graphql_generic
149
+
150
+ type_ = self.of_type
151
+
152
+ return is_graphql_generic(type_)
153
+
154
+ def has_generic(self, type_var: TypeVar) -> bool:
155
+ if isinstance(self.of_type, StrawberryType):
156
+ return self.of_type.has_generic(type_var)
157
+ return False
158
+
159
+
160
+ class StrawberryList(StrawberryContainer): ...
161
+
162
+
163
+ class StrawberryOptional(StrawberryContainer): ...
164
+
165
+
166
+ class StrawberryTypeVar(StrawberryType):
167
+ def __init__(self, type_var: TypeVar) -> None:
168
+ self.type_var = type_var
169
+
170
+ def copy_with(
171
+ self, type_var_map: Mapping[str, Union[StrawberryType, type]]
172
+ ) -> Union[StrawberryType, type]:
173
+ return type_var_map[self.type_var.__name__]
174
+
175
+ @property
176
+ def is_graphql_generic(self) -> bool:
177
+ return True
178
+
179
+ def has_generic(self, type_var: TypeVar) -> bool:
180
+ return self.type_var == type_var
181
+
182
+ @property
183
+ def type_params(self) -> List[TypeVar]:
184
+ return [self.type_var]
185
+
186
+ def __eq__(self, other: object) -> bool:
187
+ if isinstance(other, StrawberryTypeVar):
188
+ return self.type_var == other.type_var
189
+ if isinstance(other, TypeVar):
190
+ return self.type_var == other
191
+
192
+ return super().__eq__(other)
193
+
194
+ def __hash__(self) -> int:
195
+ return hash(self.type_var)
196
+
197
+
198
+ class WithStrawberryObjectDefinition(Protocol):
199
+ __strawberry_definition__: ClassVar[StrawberryObjectDefinition]
200
+
201
+
202
+ def has_object_definition(
203
+ obj: Any,
204
+ ) -> TypeGuard[Type[WithStrawberryObjectDefinition]]:
205
+ if hasattr(obj, "__strawberry_definition__"):
206
+ return True
207
+ # TODO: Generics remove dunder members here, so we inject it here.
208
+ # Would be better to avoid it somehow.
209
+ # https://github.com/python/cpython/blob/3a314f7c3df0dd7c37da7d12b827f169ee60e1ea/Lib/typing.py#L1152
210
+ if is_concrete_generic(obj):
211
+ concrete = obj.__origin__
212
+ if hasattr(concrete, "__strawberry_definition__"):
213
+ obj.__strawberry_definition__ = concrete.__strawberry_definition__
214
+ return True
215
+ return False
216
+
217
+
218
+ @overload
219
+ def get_object_definition(
220
+ obj: Any,
221
+ *,
222
+ strict: Literal[True],
223
+ ) -> StrawberryObjectDefinition: ...
224
+
225
+
226
+ @overload
227
+ def get_object_definition(
228
+ obj: Any,
229
+ *,
230
+ strict: bool = False,
231
+ ) -> Optional[StrawberryObjectDefinition]: ...
232
+
233
+
234
+ def get_object_definition(
235
+ obj: Any,
236
+ *,
237
+ strict: bool = False,
238
+ ) -> Optional[StrawberryObjectDefinition]:
239
+ definition = obj.__strawberry_definition__ if has_object_definition(obj) else None
240
+ if strict and definition is None:
241
+ raise TypeError(f"{obj!r} does not have a StrawberryObjectDefinition")
242
+
243
+ return definition
33
244
 
34
245
 
35
246
  @dataclasses.dataclass(eq=False)
36
247
  class StrawberryObjectDefinition(StrawberryType):
37
- """
38
- Encapsulates definitions for Input / Object / interface GraphQL Types.
248
+ """Encapsulates definitions for Input / Object / interface GraphQL Types.
39
249
 
40
250
  In order get the definition from a decorated object you can use
41
251
  `has_object_definition` or `get_object_definition` as a shortcut.
@@ -247,3 +457,17 @@ if TYPE_CHECKING:
247
457
 
248
458
  else:
249
459
  TypeDefinition = StrawberryObjectDefinition
460
+
461
+
462
+ __all__ = [
463
+ "StrawberryContainer",
464
+ "StrawberryList",
465
+ "StrawberryObjectDefinition",
466
+ "StrawberryOptional",
467
+ "StrawberryType",
468
+ "StrawberryTypeVar",
469
+ "TypeDefinition",
470
+ "WithStrawberryObjectDefinition",
471
+ "get_object_definition",
472
+ "has_object_definition",
473
+ ]
@@ -12,9 +12,8 @@ from typing import (
12
12
  overload,
13
13
  )
14
14
 
15
- from strawberry.type import StrawberryType
16
-
17
- from .exceptions import ObjectIsNotAnEnumError
15
+ from strawberry.exceptions import ObjectIsNotAnEnumError
16
+ from strawberry.types.base import StrawberryType
18
17
 
19
18
 
20
19
  @dataclasses.dataclass
@@ -67,6 +66,30 @@ def enum_value(
67
66
  directives: Iterable[object] = (),
68
67
  description: Optional[str] = None,
69
68
  ) -> EnumValueDefinition:
69
+ """Function to customise an enum value, for example to add a description or deprecation reason.
70
+
71
+ Args:
72
+ value: The value of the enum member.
73
+ deprecation_reason: The deprecation reason of the enum member,
74
+ setting this will mark the enum member as deprecated.
75
+ directives: The directives to attach to the enum member.
76
+ description: The GraphQL description of the enum member.
77
+
78
+ Returns:
79
+ An EnumValueDefinition object that can be used to customise an enum member.
80
+
81
+ Example:
82
+ ```python
83
+ from enum import Enum
84
+ import strawberry
85
+
86
+
87
+ @strawberry.enum
88
+ class MyEnum(Enum):
89
+ FIRST_VALUE = strawberry.enum_value(description="The first value")
90
+ SECOND_VALUE = strawberry.enum_value(description="The second value")
91
+ ```
92
+ """
70
93
  return EnumValueDefinition(
71
94
  value=value,
72
95
  deprecation_reason=deprecation_reason,
@@ -131,7 +154,7 @@ def _process_enum(
131
154
 
132
155
  @overload
133
156
  def enum(
134
- _cls: EnumType,
157
+ cls: EnumType,
135
158
  *,
136
159
  name: Optional[str] = None,
137
160
  description: Optional[str] = None,
@@ -141,7 +164,7 @@ def enum(
141
164
 
142
165
  @overload
143
166
  def enum(
144
- _cls: None = None,
167
+ cls: None = None,
145
168
  *,
146
169
  name: Optional[str] = None,
147
170
  description: Optional[str] = None,
@@ -150,13 +173,47 @@ def enum(
150
173
 
151
174
 
152
175
  def enum(
153
- _cls: Optional[EnumType] = None,
176
+ cls: Optional[EnumType] = None,
154
177
  *,
155
178
  name: Optional[str] = None,
156
179
  description: Optional[str] = None,
157
180
  directives: Iterable[object] = (),
158
181
  ) -> Union[EnumType, Callable[[EnumType], EnumType]]:
159
- """Registers the enum in the GraphQL type system.
182
+ """Annotates an Enum class a GraphQL enum.
183
+
184
+ GraphQL enums only have names, while Python enums have names and values,
185
+ Strawberry will use the names of the Python enum as the names of the
186
+ GraphQL enum values.
187
+
188
+ Args:
189
+ cls: The Enum class to be annotated.
190
+ name: The name of the GraphQL enum.
191
+ description: The description of the GraphQL enum.
192
+ directives: The directives to attach to the GraphQL enum.
193
+
194
+ Returns:
195
+ The decorated Enum class.
196
+
197
+ Example:
198
+ ```python
199
+ from enum import Enum
200
+ import strawberry
201
+
202
+
203
+ @strawberry.enum
204
+ class MyEnum(Enum):
205
+ FIRST_VALUE = "first_value"
206
+ SECOND_VALUE = "second_value"
207
+ ```
208
+
209
+ The above code will generate the following GraphQL schema:
210
+
211
+ ```graphql
212
+ enum MyEnum {
213
+ FIRST_VALUE
214
+ SECOND_VALUE
215
+ }
216
+ ```
160
217
 
161
218
  If name is passed, the name of the GraphQL type will be
162
219
  the value passed of name instead of the Enum class name.
@@ -165,7 +222,10 @@ def enum(
165
222
  def wrap(cls: EnumType) -> EnumType:
166
223
  return _process_enum(cls, name, description, directives=directives)
167
224
 
168
- if not _cls:
225
+ if not cls:
169
226
  return wrap
170
227
 
171
- return wrap(_cls)
228
+ return wrap(cls)
229
+
230
+
231
+ __all__ = ["EnumValue", "EnumDefinition", "EnumValueDefinition", "enum", "enum_value"]
@@ -94,3 +94,6 @@ class ExecutionResult:
94
94
 
95
95
  class ParseOptions(TypedDict):
96
96
  max_tokens: NotRequired[int]
97
+
98
+
99
+ __all__ = ["ExecutionContext", "ExecutionResult", "ParseOptions"]
@@ -24,25 +24,24 @@ from typing import (
24
24
 
25
25
  from strawberry.annotation import StrawberryAnnotation
26
26
  from strawberry.exceptions import InvalidArgumentTypeError, InvalidDefaultFactoryError
27
- from strawberry.type import (
27
+ from strawberry.types.base import (
28
28
  StrawberryType,
29
29
  WithStrawberryObjectDefinition,
30
30
  has_object_definition,
31
31
  )
32
- from strawberry.union import StrawberryUnion
32
+ from strawberry.types.union import StrawberryUnion
33
33
 
34
- from .types.fields.resolver import StrawberryResolver
34
+ from .fields.resolver import StrawberryResolver
35
35
 
36
36
  if TYPE_CHECKING:
37
37
  import builtins
38
38
  from typing_extensions import Literal, Self
39
39
 
40
- from strawberry.arguments import StrawberryArgument
41
40
  from strawberry.extensions.field_extension import FieldExtension
41
+ from strawberry.permission import BasePermission
42
+ from strawberry.types.arguments import StrawberryArgument
43
+ from strawberry.types.base import StrawberryObjectDefinition
42
44
  from strawberry.types.info import Info
43
- from strawberry.types.types import StrawberryObjectDefinition
44
-
45
- from .permission import BasePermission
46
45
 
47
46
  T = TypeVar("T")
48
47
 
@@ -64,7 +63,7 @@ UNRESOLVED = object()
64
63
 
65
64
 
66
65
  def _is_generic(resolver_type: Union[StrawberryType, type]) -> bool:
67
- """Returns True if `resolver_type` is generic else False"""
66
+ """Returns True if `resolver_type` is generic else False."""
68
67
  if isinstance(resolver_type, StrawberryType):
69
68
  return resolver_type.is_graphql_generic
70
69
 
@@ -149,7 +148,7 @@ class StrawberryField(dataclasses.Field):
149
148
 
150
149
  # Automatically add the permissions extension
151
150
  if len(self.permission_classes):
152
- from .permission import PermissionExtension
151
+ from strawberry.permission import PermissionExtension
153
152
 
154
153
  if not self.extensions:
155
154
  self.extensions = []
@@ -189,8 +188,7 @@ class StrawberryField(dataclasses.Field):
189
188
  return new_field
190
189
 
191
190
  def __call__(self, resolver: _RESOLVER_TYPE) -> Self:
192
- """Add a resolver to the field"""
193
-
191
+ """Add a resolver to the field."""
194
192
  # Allow for StrawberryResolvers or bare functions to be provided
195
193
  if not isinstance(resolver, StrawberryResolver):
196
194
  resolver = StrawberryResolver(resolver)
@@ -217,12 +215,11 @@ class StrawberryField(dataclasses.Field):
217
215
  def get_result(
218
216
  self, source: Any, info: Optional[Info], args: List[Any], kwargs: Any
219
217
  ) -> Union[Awaitable[Any], Any]:
220
- """
221
- Calls the resolver defined for the StrawberryField.
218
+ """Calls the resolver defined for the StrawberryField.
219
+
222
220
  If the field doesn't have a resolver defined we default
223
221
  to using the default resolver specified in StrawberryConfig.
224
222
  """
225
-
226
223
  if self.base_resolver:
227
224
  return self.base_resolver(*args, **kwargs)
228
225
 
@@ -230,8 +227,9 @@ class StrawberryField(dataclasses.Field):
230
227
 
231
228
  @property
232
229
  def is_basic_field(self) -> bool:
233
- """
234
- Flag indicating if this is a "basic" field that has no resolver or
230
+ """Returns a boolean indicating if the field is a basic field.
231
+
232
+ A "basic" field us a field that has no resolver or
235
233
  permission classes, i.e. it just returns the relevant attribute from
236
234
  the source object. If it is a basic field we can avoid constructing
237
235
  an `Info` object and running any permission checks in the resolver
@@ -538,19 +536,44 @@ def field(
538
536
  ) -> Any:
539
537
  """Annotates a method or property as a GraphQL field.
540
538
 
539
+ Args:
540
+ resolver: The resolver for the field. This can be a function or a `StrawberryResolver`.
541
+ name: The GraphQL name of the field.
542
+ is_subscription: Whether the field is a subscription field.
543
+ description: The GraphQL description of the field.
544
+ permission_classes: The permission classes required to access the field.
545
+ deprecation_reason: The deprecation reason for the field.
546
+ default: The default value for the field.
547
+ default_factory: The default factory for the field.
548
+ metadata: The metadata for the field.
549
+ directives: The directives for the field.
550
+ extensions: The extensions for the field.
551
+ graphql_type: The GraphQL type for the field, useful when you want to use a
552
+ different type in the resolver than the one in the schema.
553
+ init: This parameter is used by PyRight to determine whether this field is
554
+ added in the constructor or not. It is not used to change any behavior
555
+ at the moment.
556
+
557
+ Returns:
558
+ The field.
559
+
541
560
  This is normally used inside a type declaration:
542
561
 
543
- >>> @strawberry.type
544
- >>> class X:
545
- >>> field_abc: str = strawberry.field(description="ABC")
562
+ ```python
563
+ import strawberry
564
+
546
565
 
547
- >>> @strawberry.field(description="ABC")
548
- >>> def field_with_resolver(self) -> str:
549
- >>> return "abc"
566
+ @strawberry.type
567
+ class X:
568
+ field_abc: str = strawberry.field(description="ABC")
569
+
570
+ @strawberry.field(description="ABC")
571
+ def field_with_resolver(self) -> str:
572
+ return "abc"
573
+ ```
550
574
 
551
575
  it can be used both as decorator and as a normal function.
552
576
  """
553
-
554
577
  type_annotation = StrawberryAnnotation.from_annotation(graphql_type)
555
578
 
556
579
  field_ = StrawberryField(
@@ -23,13 +23,13 @@ from typing import (
23
23
  from typing_extensions import Annotated, Protocol, get_origin
24
24
 
25
25
  from strawberry.annotation import StrawberryAnnotation
26
- from strawberry.arguments import StrawberryArgument
27
26
  from strawberry.exceptions import (
28
27
  ConflictingArgumentsError,
29
28
  MissingArgumentsAnnotationsError,
30
29
  )
31
30
  from strawberry.parent import StrawberryParent
32
- from strawberry.type import StrawberryType, has_object_definition
31
+ from strawberry.types.arguments import StrawberryArgument
32
+ from strawberry.types.base import StrawberryType, has_object_definition
33
33
  from strawberry.types.info import Info
34
34
  from strawberry.utils.typing import type_has_annotation
35
35
 
@@ -25,3 +25,6 @@ class OperationType(enum.Enum):
25
25
  }
26
26
 
27
27
  raise ValueError(f"Unsupported HTTP method: {method}") # pragma: no cover
28
+
29
+
30
+ __all__ = ["OperationType"]