strawberry-graphql 0.229.2.dev1715881453__py3-none-any.whl → 0.230.0.dev1716318708__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.
@@ -31,6 +31,7 @@ def _impl_type(
31
31
  *,
32
32
  name: Optional[str] = None,
33
33
  description: Optional[str] = None,
34
+ one_of: Optional[bool] = None,
34
35
  directives: Iterable[object] = (),
35
36
  authenticated: bool = False,
36
37
  keys: Iterable[Union["Key", str]] = (),
@@ -54,6 +55,7 @@ def _impl_type(
54
55
  Shareable,
55
56
  Tag,
56
57
  )
58
+ from strawberry.schema_directives import OneOf
57
59
 
58
60
  directives = list(directives)
59
61
 
@@ -83,6 +85,9 @@ def _impl_type(
83
85
  if is_interface_object:
84
86
  directives.append(InterfaceObject())
85
87
 
88
+ if one_of:
89
+ directives.append(OneOf())
90
+
86
91
  return base_type( # type: ignore
87
92
  cls,
88
93
  name=name,
@@ -180,6 +185,7 @@ def input(
180
185
  cls: T,
181
186
  *,
182
187
  name: Optional[str] = None,
188
+ one_of: Optional[bool] = None,
183
189
  description: Optional[str] = None,
184
190
  directives: Sequence[object] = (),
185
191
  inaccessible: bool = UNSET,
@@ -197,6 +203,7 @@ def input(
197
203
  *,
198
204
  name: Optional[str] = None,
199
205
  description: Optional[str] = None,
206
+ one_of: Optional[bool] = None,
200
207
  directives: Sequence[object] = (),
201
208
  inaccessible: bool = UNSET,
202
209
  tags: Iterable[str] = (),
@@ -207,6 +214,7 @@ def input(
207
214
  cls: Optional[T] = None,
208
215
  *,
209
216
  name: Optional[str] = None,
217
+ one_of: Optional[bool] = None,
210
218
  description: Optional[str] = None,
211
219
  directives: Sequence[object] = (),
212
220
  inaccessible: bool = UNSET,
@@ -219,6 +227,7 @@ def input(
219
227
  directives=directives,
220
228
  inaccessible=inaccessible,
221
229
  is_input=True,
230
+ one_of=one_of,
222
231
  tags=tags,
223
232
  )
224
233
 
strawberry/object_type.py CHANGED
@@ -293,6 +293,7 @@ def input(
293
293
  cls: T,
294
294
  *,
295
295
  name: Optional[str] = None,
296
+ one_of: Optional[bool] = None,
296
297
  description: Optional[str] = None,
297
298
  directives: Optional[Sequence[object]] = (),
298
299
  ) -> T: ...
@@ -305,6 +306,7 @@ def input(
305
306
  def input(
306
307
  *,
307
308
  name: Optional[str] = None,
309
+ one_of: Optional[bool] = None,
308
310
  description: Optional[str] = None,
309
311
  directives: Optional[Sequence[object]] = (),
310
312
  ) -> Callable[[T], T]: ...
@@ -314,6 +316,7 @@ def input(
314
316
  cls: Optional[T] = None,
315
317
  *,
316
318
  name: Optional[str] = None,
319
+ one_of: Optional[bool] = None,
317
320
  description: Optional[str] = None,
318
321
  directives: Optional[Sequence[object]] = (),
319
322
  ):
@@ -324,6 +327,11 @@ def input(
324
327
  >>> field_abc: str = "ABC"
325
328
  """
326
329
 
330
+ from strawberry.schema_directives import OneOf
331
+
332
+ if one_of:
333
+ directives = (*(directives or ()), OneOf())
334
+
327
335
  return type( # type: ignore # not sure why mypy complains here
328
336
  cls,
329
337
  name=name,
strawberry/permission.py CHANGED
@@ -8,15 +8,12 @@ from typing import (
8
8
  TYPE_CHECKING,
9
9
  Any,
10
10
  Awaitable,
11
+ Dict,
11
12
  List,
12
- Literal,
13
13
  Optional,
14
- Tuple,
15
14
  Type,
16
- TypedDict,
17
15
  Union,
18
16
  )
19
- from typing_extensions import deprecated
20
17
 
21
18
  from strawberry.exceptions import StrawberryGraphQLError
22
19
  from strawberry.exceptions.permission_fail_silently_requires_optional import (
@@ -38,15 +35,6 @@ if TYPE_CHECKING:
38
35
  from strawberry.types import Info
39
36
 
40
37
 
41
- def unpack_maybe(
42
- value: Union[object, Tuple[bool, object]], default: object = None
43
- ) -> Tuple[object, object]:
44
- if isinstance(value, tuple) and len(value) == 2:
45
- return value
46
- else:
47
- return value, default
48
-
49
-
50
38
  class BasePermission(abc.ABC):
51
39
  """
52
40
  Base class for creating permissions
@@ -62,41 +50,18 @@ class BasePermission(abc.ABC):
62
50
 
63
51
  @abc.abstractmethod
64
52
  def has_permission(
65
- self, source: Any, info: Info, **kwargs: object
66
- ) -> Union[
67
- bool,
68
- Awaitable[bool],
69
- Tuple[Literal[False], dict],
70
- Awaitable[Tuple[Literal[False], dict]],
71
- ]:
72
- """
73
- This method is a required override in the permission class. It checks if the user has the necessary permissions to access a specific field.
74
-
75
- The method should return a boolean value:
76
- - True: The user has the necessary permissions.
77
- - False: The user does not have the necessary permissions. In this case, the `on_unauthorized` method will be invoked.
78
-
79
- Avoid raising exceptions in this method. Instead, use the `on_unauthorized` method to handle errors and customize the error response.
80
-
81
- If there's a need to pass additional information to the `on_unauthorized` method, return a tuple. The first element should be False, and the second element should be a dictionary containing the additional information.
82
-
83
- Args:
84
- source (Any): The source field that the permission check is being performed on.
85
- info (Info): The GraphQL resolve info associated with the field.
86
- **kwargs (Any): Additional arguments that are typically passed to the field resolver.
87
-
88
- Returns:
89
- bool or tuple: Returns True if the user has the necessary permissions. Returns False or a tuple (False, additional_info) if the user does not have the necessary permissions. In the latter case, the `on_unauthorized` method will be invoked.
90
- """
53
+ self, source: Any, info: Info, **kwargs: Any
54
+ ) -> Union[bool, Awaitable[bool]]:
91
55
  raise NotImplementedError(
92
56
  "Permission classes should override has_permission method"
93
57
  )
94
58
 
95
- def on_unauthorized(self, **kwargs: object) -> None:
59
+ def on_unauthorized(self) -> None:
96
60
  """
97
61
  Default error raising for permissions.
98
62
  This can be overridden to customize the behavior.
99
63
  """
64
+
100
65
  # Instantiate error class
101
66
  error = self.error_class(self.message or "")
102
67
 
@@ -109,9 +74,6 @@ class BasePermission(abc.ABC):
109
74
  raise error
110
75
 
111
76
  @property
112
- @deprecated(
113
- "@schema_directive is deprecated and will be disabled by default on 31.12.2024 with future removal planned. Use the new @permissions directive instead."
114
- )
115
77
  def schema_directive(self) -> object:
116
78
  if not self._schema_directive:
117
79
 
@@ -127,111 +89,6 @@ class BasePermission(abc.ABC):
127
89
 
128
90
  return self._schema_directive
129
91
 
130
- @cached_property
131
- def is_async(self) -> bool:
132
- return iscoroutinefunction(self.has_permission)
133
-
134
- def __and__(self, other: BasePermission):
135
- return AndPermission([self, other])
136
-
137
- def __or__(self, other: BasePermission):
138
- return OrPermission([self, other])
139
-
140
-
141
- class CompositePermissionContext(TypedDict):
142
- failed_permissions: List[Tuple[BasePermission, dict]]
143
-
144
-
145
- class CompositePermission(BasePermission, abc.ABC):
146
- def __init__(self, child_permissions: List[BasePermission]):
147
- self.child_permissions = child_permissions
148
-
149
- def on_unauthorized(self, **kwargs: object) -> Any:
150
- failed_permissions = kwargs.get("failed_permissions", [])
151
- for permission, context in failed_permissions:
152
- permission.on_unauthorized(**context)
153
-
154
- @cached_property
155
- def is_async(self) -> bool:
156
- return any(x.is_async for x in self.child_permissions)
157
-
158
-
159
- class AndPermission(CompositePermission):
160
- def has_permission(
161
- self, source: Any, info: Info, **kwargs: object
162
- ) -> Union[
163
- bool,
164
- Awaitable[bool],
165
- Tuple[Literal[False], CompositePermissionContext],
166
- Awaitable[Tuple[Literal[False], CompositePermissionContext]],
167
- ]:
168
- if self.is_async:
169
- return self._has_permission_async(source, info, **kwargs)
170
-
171
- for permission in self.child_permissions:
172
- has_permission, context = unpack_maybe(
173
- permission.has_permission(source, info, **kwargs), {}
174
- )
175
- if not has_permission:
176
- return False, {"failed_permissions": [(permission, context)]}
177
- return True
178
-
179
- async def _has_permission_async(
180
- self, source: Any, info: Info, **kwargs: object
181
- ) -> Union[bool, Tuple[Literal[False], CompositePermissionContext]]:
182
- for permission in self.child_permissions:
183
- permission_response = await await_maybe(
184
- permission.has_permission(source, info, **kwargs)
185
- )
186
- has_permission, context = unpack_maybe(permission_response, {})
187
- if not has_permission:
188
- return False, {"failed_permissions": [(permission, context)]}
189
- return True
190
-
191
- def __and__(self, other: BasePermission):
192
- return AndPermission([*self.child_permissions, other])
193
-
194
-
195
- class OrPermission(CompositePermission):
196
- def has_permission(
197
- self, source: Any, info: Info, **kwargs: object
198
- ) -> Union[
199
- bool,
200
- Awaitable[bool],
201
- Tuple[Literal[False], dict],
202
- Awaitable[Tuple[Literal[False], dict]],
203
- ]:
204
- if self.is_async:
205
- return self._has_permission_async(source, info, **kwargs)
206
- failed_permissions = []
207
- for permission in self.child_permissions:
208
- has_permission, context = unpack_maybe(
209
- permission.has_permission(source, info, **kwargs), {}
210
- )
211
- if has_permission:
212
- return True
213
- failed_permissions.append((permission, context))
214
-
215
- return False, {"failed_permissions": failed_permissions}
216
-
217
- async def _has_permission_async(
218
- self, source: Any, info: Info, **kwargs: object
219
- ) -> Union[bool, Tuple[Literal[False], dict]]:
220
- failed_permissions = []
221
- for permission in self.child_permissions:
222
- permission_response = await await_maybe(
223
- permission.has_permission(source, info, **kwargs)
224
- )
225
- has_permission, context = unpack_maybe(permission_response, {})
226
- if has_permission:
227
- return True
228
- failed_permissions.append((permission, context))
229
-
230
- return False, {"failed_permissions": failed_permissions}
231
-
232
- def __or__(self, other: BasePermission):
233
- return OrPermission([*self.child_permissions, other])
234
-
235
92
 
236
93
  class PermissionExtension(FieldExtension):
237
94
  """
@@ -243,8 +100,8 @@ class PermissionExtension(FieldExtension):
243
100
 
244
101
  NOTE:
245
102
  Currently, this is automatically added to the field, when using
246
- field.permission_classes. You are free to use whichever method you prefer.
247
- Use PermissionExtension if you want additional customization.
103
+ field.permission_classes
104
+ This is deprecated behavior, please manually add the extension to field.extensions
248
105
  """
249
106
 
250
107
  def __init__(
@@ -260,16 +117,12 @@ class PermissionExtension(FieldExtension):
260
117
 
261
118
  def apply(self, field: StrawberryField) -> None:
262
119
  """
263
- Applies all the permission directives to the schema
120
+ Applies all of the permission directives to the schema
264
121
  and sets up silent permissions
265
122
  """
266
123
  if self.use_directives:
267
124
  field.directives.extend(
268
- [
269
- p.schema_directive
270
- for p in self.permissions
271
- if not isinstance(p, CompositePermission)
272
- ]
125
+ p.schema_directive for p in self.permissions if p.schema_directive
273
126
  )
274
127
  # We can only fail silently if the field is optional or a list
275
128
  if self.fail_silently:
@@ -279,36 +132,28 @@ class PermissionExtension(FieldExtension):
279
132
  elif isinstance(field.type, StrawberryList):
280
133
  self.return_empty_list = True
281
134
  else:
282
- raise PermissionFailSilentlyRequiresOptionalError(field)
135
+ errror = PermissionFailSilentlyRequiresOptionalError(field)
136
+ raise errror
283
137
 
284
- def _on_unauthorized(self, permission: BasePermission, **kwargs: object) -> Any:
138
+ def _on_unauthorized(self, permission: BasePermission) -> Any:
285
139
  if self.fail_silently:
286
140
  return [] if self.return_empty_list else None
287
-
288
- if kwargs in (None, {}):
289
- return permission.on_unauthorized()
290
- return permission.on_unauthorized(**kwargs)
141
+ return permission.on_unauthorized()
291
142
 
292
143
  def resolve(
293
144
  self,
294
145
  next_: SyncExtensionResolver,
295
146
  source: Any,
296
147
  info: Info,
297
- **kwargs: object[str, Any],
148
+ **kwargs: Dict[str, Any],
298
149
  ) -> Any:
299
150
  """
300
151
  Checks if the permission should be accepted and
301
152
  raises an exception if not
302
153
  """
303
-
304
154
  for permission in self.permissions:
305
- has_permission, context = unpack_maybe(
306
- permission.has_permission(source, info, **kwargs), {}
307
- )
308
-
309
- if not has_permission:
310
- return self._on_unauthorized(permission, **context)
311
-
155
+ if not permission.has_permission(source, info, **kwargs):
156
+ return self._on_unauthorized(permission)
312
157
  return next_(source, info, **kwargs)
313
158
 
314
159
  async def resolve_async(
@@ -316,21 +161,15 @@ class PermissionExtension(FieldExtension):
316
161
  next_: AsyncExtensionResolver,
317
162
  source: Any,
318
163
  info: Info,
319
- **kwargs: object[str, Any],
164
+ **kwargs: Dict[str, Any],
320
165
  ) -> Any:
321
166
  for permission in self.permissions:
322
- permission_response = await await_maybe(
167
+ has_permission = await await_maybe(
323
168
  permission.has_permission(source, info, **kwargs)
324
169
  )
325
170
 
326
- context = {}
327
- if isinstance(permission_response, tuple):
328
- has_permission, context = permission_response
329
- else:
330
- has_permission = permission_response
331
-
332
171
  if not has_permission:
333
- return self._on_unauthorized(permission, **context)
172
+ return self._on_unauthorized(permission)
334
173
  next = next_(source, info, **kwargs)
335
174
  if inspect.isasyncgen(next):
336
175
  return next
@@ -340,4 +179,9 @@ class PermissionExtension(FieldExtension):
340
179
  def supports_sync(self) -> bool:
341
180
  """The Permission extension always supports async checking using await_maybe,
342
181
  but only supports sync checking if there are no async permissions"""
343
- return all(not permission.is_async for permission in self.permissions)
182
+ async_permissions = [
183
+ True
184
+ for permission in self.permissions
185
+ if iscoroutinefunction(permission.has_permission)
186
+ ]
187
+ return len(async_permissions) == 0
@@ -23,6 +23,7 @@ from graphql.validation import validate
23
23
 
24
24
  from strawberry.exceptions import MissingQueryError
25
25
  from strawberry.extensions.runner import SchemaExtensionsRunner
26
+ from strawberry.schema.validation_rules.one_of import OneOfInputValidationRule
26
27
  from strawberry.types import ExecutionResult
27
28
 
28
29
  from .exceptions import InvalidOperationTypeError
@@ -55,6 +56,10 @@ def validate_document(
55
56
  document: DocumentNode,
56
57
  validation_rules: Tuple[Type[ASTValidationRule], ...],
57
58
  ) -> List[GraphQLError]:
59
+ validation_rules = (
60
+ *validation_rules,
61
+ OneOfInputValidationRule,
62
+ )
58
63
  return validate(
59
64
  schema,
60
65
  document,
@@ -16,6 +16,8 @@ from typing import (
16
16
  )
17
17
 
18
18
  from graphql import (
19
+ GraphQLBoolean,
20
+ GraphQLField,
19
21
  GraphQLNamedType,
20
22
  GraphQLNonNull,
21
23
  GraphQLSchema,
@@ -168,6 +170,7 @@ class Schema(BaseSchema):
168
170
 
169
171
  self._warn_for_federation_directives()
170
172
  self._resolve_node_ids()
173
+ self._extend_introspection()
171
174
 
172
175
  # Validate schema early because we want developers to know about
173
176
  # possible issues as soon as possible
@@ -375,6 +378,14 @@ class Schema(BaseSchema):
375
378
  stacklevel=3,
376
379
  )
377
380
 
381
+ def _extend_introspection(self):
382
+ def _resolve_is_one_of(obj: Any, info: Any) -> bool:
383
+ return obj.extensions["strawberry-definition"].is_one_of
384
+
385
+ instrospection_type = self._schema.type_map["__Type"]
386
+ instrospection_type.fields["isOneOf"] = GraphQLField(GraphQLBoolean) # type: ignore[attr-defined]
387
+ instrospection_type.fields["isOneOf"].resolve = _resolve_is_one_of # type: ignore[attr-defined]
388
+
378
389
  def as_str(self) -> str:
379
390
  return print_schema(self)
380
391
 
@@ -26,6 +26,7 @@ from graphql import (
26
26
  GraphQLDirective,
27
27
  GraphQLEnumType,
28
28
  GraphQLEnumValue,
29
+ GraphQLError,
29
30
  GraphQLField,
30
31
  GraphQLInputField,
31
32
  GraphQLInputObjectType,
@@ -411,6 +412,27 @@ class GraphQLCoreConverter:
411
412
  assert isinstance(graphql_object_type, GraphQLInputObjectType) # For mypy
412
413
  return graphql_object_type
413
414
 
415
+ def check_one_of(value: dict[str, Any]) -> dict[str, Any]:
416
+ if len(value) != 1:
417
+ raise GraphQLError(
418
+ f"OneOf Input Object '{type_name}' must specify exactly one key."
419
+ )
420
+
421
+ first_key, first_value = next(iter(value.items()))
422
+
423
+ if first_value is None or first_value is UNSET:
424
+ raise GraphQLError(
425
+ f"Value for member field '{first_key}' must be non-null"
426
+ )
427
+
428
+ return value
429
+
430
+ out_type = (
431
+ check_one_of
432
+ if type_definition.is_input and type_definition.is_one_of
433
+ else None
434
+ )
435
+
414
436
  graphql_object_type = GraphQLInputObjectType(
415
437
  name=type_name,
416
438
  fields=lambda: self.get_graphql_input_fields(type_definition),
@@ -418,6 +440,7 @@ class GraphQLCoreConverter:
418
440
  extensions={
419
441
  GraphQLCoreConverter.DEFINITION_BACKREF: type_definition,
420
442
  },
443
+ out_type=out_type,
421
444
  )
422
445
 
423
446
  self.type_map[type_name] = ConcreteType(
File without changes
@@ -0,0 +1,80 @@
1
+ from typing import Any
2
+
3
+ from graphql import (
4
+ ExecutableDefinitionNode,
5
+ GraphQLError,
6
+ GraphQLNamedType,
7
+ ObjectValueNode,
8
+ ValidationContext,
9
+ ValidationRule,
10
+ VariableDefinitionNode,
11
+ get_named_type,
12
+ )
13
+
14
+
15
+ class OneOfInputValidationRule(ValidationRule):
16
+ def __init__(self, validation_context: ValidationContext) -> None:
17
+ super().__init__(validation_context)
18
+
19
+ def enter_operation_definition(
20
+ self, node: ExecutableDefinitionNode, *_args: Any
21
+ ) -> None:
22
+ self.variable_definitions: dict[str, VariableDefinitionNode] = {}
23
+
24
+ def enter_variable_definition(
25
+ self, node: VariableDefinitionNode, *_args: Any
26
+ ) -> None:
27
+ self.variable_definitions[node.variable.name.value] = node
28
+
29
+ def enter_object_value(self, node: ObjectValueNode, *_args: Any) -> None:
30
+ type_ = get_named_type(self.context.get_input_type())
31
+
32
+ if not type_:
33
+ return
34
+
35
+ strawberry_type = type_.extensions.get("strawberry-definition")
36
+
37
+ if strawberry_type and strawberry_type.is_one_of:
38
+ self.validate_one_of(node, type_)
39
+
40
+ def validate_one_of(self, node: ObjectValueNode, type: GraphQLNamedType) -> None:
41
+ field_node_map = {field.name.value: field for field in node.fields}
42
+ keys = list(field_node_map.keys())
43
+ is_not_exactly_one_field = len(keys) != 1
44
+
45
+ if is_not_exactly_one_field:
46
+ self.report_error(
47
+ GraphQLError(
48
+ f"OneOf Input Object '{type.name}' must specify exactly one key.",
49
+ nodes=[node],
50
+ )
51
+ )
52
+
53
+ return
54
+
55
+ value = field_node_map[keys[0]].value
56
+ is_null_literal = not value or value.kind == "null_value"
57
+ is_variable = value.kind == "variable"
58
+
59
+ if is_null_literal:
60
+ self.report_error(
61
+ GraphQLError(
62
+ f"Field '{type.name}.{keys[0]}' must be non-null.",
63
+ nodes=[node],
64
+ )
65
+ )
66
+
67
+ return
68
+
69
+ if is_variable:
70
+ variable_name = value.name.value # type: ignore
71
+ definition = self.variable_definitions[variable_name]
72
+ is_nullable_variable = definition.type.kind != "non_null_type"
73
+
74
+ if is_nullable_variable:
75
+ self.report_error(
76
+ GraphQLError(
77
+ f"Variable '{variable_name}' must be non-nullable to be used for OneOf Input Object '{type.name}'.",
78
+ nodes=[node],
79
+ )
80
+ )
@@ -0,0 +1,8 @@
1
+ from strawberry.schema_directive import Location, schema_directive
2
+
3
+
4
+ @schema_directive(locations=[Location.INPUT_OBJECT], name="oneOf")
5
+ class OneOf: ...
6
+
7
+
8
+ __all__ = ["OneOf"]
strawberry/type.py CHANGED
@@ -37,6 +37,10 @@ class StrawberryType(ABC):
37
37
  def type_params(self) -> List[TypeVar]:
38
38
  return []
39
39
 
40
+ @property
41
+ def is_one_of(self) -> bool:
42
+ return False
43
+
40
44
  @abstractmethod
41
45
  def copy_with(
42
46
  self,
strawberry/types/types.py CHANGED
@@ -225,6 +225,15 @@ class StrawberryObjectDefinition(StrawberryType):
225
225
  # All field mappings succeeded. This is a match
226
226
  return True
227
227
 
228
+ @property
229
+ def is_one_of(self) -> bool:
230
+ from strawberry.schema_directives import OneOf
231
+
232
+ if not self.is_input or not self.directives:
233
+ return False
234
+
235
+ return any(isinstance(directive, OneOf) for directive in self.directives)
236
+
228
237
 
229
238
  # TODO: remove when deprecating _type_definition
230
239
  if TYPE_CHECKING:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.229.2.dev1715881453
3
+ Version: 0.230.0.dev1716318708
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -130,7 +130,7 @@ strawberry/federation/argument.py,sha256=5qyJYlQGEZd6iXWseQ7dnnejCYj5HyglfK10jOC
130
130
  strawberry/federation/enum.py,sha256=riVfcf2Qe4ERE7SqPqFJ-yaKNG3ve47DniVC0IHZj2A,2969
131
131
  strawberry/federation/field.py,sha256=eEzEyNSrkbwHRsdT27Ti9RucuDI0hPoDT9ohrBCuI8o,6172
132
132
  strawberry/federation/mutation.py,sha256=0lV5HJwgw4HYR_59pwxWqnPs342HwakTNMc98w5Hb-c,43
133
- strawberry/federation/object_type.py,sha256=0ZzOavBSh8ZPORd70RmsfMYo2cVg6gfZPwaIziDO58o,9005
133
+ strawberry/federation/object_type.py,sha256=qY4LgXRc0bRXtOeaGruvv8fJDJ1wD73uB7RmFHu0Hrc,9270
134
134
  strawberry/federation/scalar.py,sha256=_dwlQyiDGQQF-Qz-ACSOT-LikxjXgIVz9i0HWlUjTSc,3799
135
135
  strawberry/federation/schema.py,sha256=9g7jp6eUTTP3atW81dLMtaqeY0tQB4YGdR8beKZ-JX8,13715
136
136
  strawberry/federation/schema_directive.py,sha256=V_8ytK_cbVoVRhFle0o9DTQkrP1k-xwCBTaideJOYag,1723
@@ -160,9 +160,9 @@ strawberry/litestar/controller.py,sha256=BCntaDTmQNoBRHINi8TztuF7G4-FiED-KxEPTZ6
160
160
  strawberry/litestar/handlers/graphql_transport_ws_handler.py,sha256=q_erlgzPsxarohRQXGp1yK0mjKyS8vsWntMYEmrQx4s,2008
161
161
  strawberry/litestar/handlers/graphql_ws_handler.py,sha256=vVpjd5rJOldF8aQWEGjmmNd60WE1p6q6hFmB_DtCzDU,2250
162
162
  strawberry/mutation.py,sha256=NROPvHJU1BBxZB7Wj4Okxw4hDIYM59MCpukAGEmSNYA,255
163
- strawberry/object_type.py,sha256=iQL2NqO7I28bS0moWgxPmCDc0w1HewPcXq8Xyh-xAWI,12539
163
+ strawberry/object_type.py,sha256=KQhSHqu4DvOLJX3Znr3_hjfRkFCW5fOLTc2yJ48vQgQ,12764
164
164
  strawberry/parent.py,sha256=rmedKjN4zdg4KTnNV8DENrzgNYVL67rXpHjHoBofMS4,825
165
- strawberry/permission.py,sha256=7ePOn4P_n32N_msMnWytzqKZa77HyOQ4u0hp9RliYJo,12098
165
+ strawberry/permission.py,sha256=dcKx4Zlg4ZhcxEDBOSWzz0CUN4WPkcc_kJUVuvLLs6w,5925
166
166
  strawberry/printer/__init__.py,sha256=DmepjmgtkdF5RxK_7yC6qUyRWn56U-9qeZMbkztYB9w,62
167
167
  strawberry/printer/ast_from_value.py,sha256=MFIX2V51d9ocRvD0Njemjk8YIzKh2BB1g2iUcX6a3d8,4946
168
168
  strawberry/printer/printer.py,sha256=HUUecFETXWgfQtMzxjx9pNOXP3tDevqlU3sG7TC3AD8,17449
@@ -186,16 +186,19 @@ strawberry/schema/base.py,sha256=lQBJyzG2ZhKc544oLbXEbpYOPOjaXBop3lxp68h_lfI,297
186
186
  strawberry/schema/compat.py,sha256=n0r3UPUcGemMqK8vklgtCkkuCA1p6tWAYbc6Vl4iNOw,1684
187
187
  strawberry/schema/config.py,sha256=XkWwmxEsmecscH29o4qU0iSe-hgwJJ2X0DPBVlka2OE,640
188
188
  strawberry/schema/exceptions.py,sha256=T-DsvBtjx9svkegIm1YrVPGPswpVEpMTFc0_7flLEkM,542
189
- strawberry/schema/execute.py,sha256=6OE7_5v4G3t_wxp1_mfwu8TTiIkTJNBQaeGCVAljUYw,10982
189
+ strawberry/schema/execute.py,sha256=dwxMrJrR2Qdd1nPGcIS9-Viq7h5qtPfsD6qdujALoMw,11153
190
190
  strawberry/schema/name_converter.py,sha256=UdNyd-QtqF2HsDCQK-nsOcLGxDTj4hJwYFNvMtZnpq4,6533
191
- strawberry/schema/schema.py,sha256=MOC8k6NHolFGrCyqrungv0ciCImLdXTlbmo7y7rLRas,13734
192
- strawberry/schema/schema_converter.py,sha256=_pVXXDoswZPhUGqwXK7oB68XZ4Lf6gkHehR-X_-GqCI,35885
191
+ strawberry/schema/schema.py,sha256=bfQdLmFXR_BQd80IGO8qa0431cQMUDr22XLNnBL7Tu0,14252
192
+ strawberry/schema/schema_converter.py,sha256=hxA1PKo8MwurxVC6-CscMnhQSSKyiD8B5jAaiqXc4JM,36605
193
193
  strawberry/schema/types/__init__.py,sha256=oHO3COWhL3L1KLYCJNY1XFf5xt2GGtHiMC-UaYbFfnA,68
194
194
  strawberry/schema/types/base_scalars.py,sha256=Z_BmgwLicNexLipGyw6MmZ7OBnkGJU3ySgaY9SwBWrw,1837
195
195
  strawberry/schema/types/concrete_type.py,sha256=HB30G1hMUuuvjAvfSe6ADS35iI_T_wKO-EprVOWTMSs,746
196
196
  strawberry/schema/types/scalar.py,sha256=SVJ8HiKncCvOw2xwABI5xYaHcC7KkGHG-tx2WDtSoCA,2802
197
+ strawberry/schema/validation_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
198
+ strawberry/schema/validation_rules/one_of.py,sha256=hO0Re1fQQWT9zIqo_7BHLM2bdSsmNJDbKia8AUTSXQQ,2588
197
199
  strawberry/schema_codegen/__init__.py,sha256=PcCVXjS0Y5Buxadm07YAZOVunkQ_DmmwsBrgsH1T4ds,24375
198
200
  strawberry/schema_directive.py,sha256=XGKwcsxRpHXJQ_qXXMi1gEXlZOG22SbDf4Phxf4tbQ0,1967
201
+ strawberry/schema_directives.py,sha256=KGKFWCODjm1Ah9qNV_bBwbic7Mld4qLWnWQkev-PG8A,175
199
202
  strawberry/starlite/__init__.py,sha256=v209swT8H9MljVL-npvANhEO1zz3__PSfxb_Ix-NoeE,134
200
203
  strawberry/starlite/controller.py,sha256=moo2HlaJT6w9AijwjHvXi4UibUydaZfA75JMFZVMJPw,12191
201
204
  strawberry/starlite/handlers/graphql_transport_ws_handler.py,sha256=WhfFVWdjRSk4A48MaBLGWqZdi2OnHajxdQlA_Gc4XBE,1981
@@ -216,7 +219,7 @@ strawberry/test/client.py,sha256=N_AkxLp-kWVTgQDcL8FkruJpAd6NpkChIDptzneu_uM,575
216
219
  strawberry/tools/__init__.py,sha256=pdGpZx8wpq03VfUZJyF9JtYxZhGqzzxCiipsalWxJX4,127
217
220
  strawberry/tools/create_type.py,sha256=QxLRT9-DrSgo6vsu_L818wtlbO3wRtI0dOos0gmn1xk,1593
218
221
  strawberry/tools/merge_types.py,sha256=YZ2GSMoDD82bfuvCT0COpN6SLFVRZpTXFFm9LHUyi10,1014
219
- strawberry/type.py,sha256=NW7cAOkhlEy49OFOucTCunBxeqQYoftJSFBgOyXjyKM,6518
222
+ strawberry/type.py,sha256=MS2y7VNugCIHkndJmU5V7VZA9QRcmf76JMzP3TH1jws,6587
220
223
  strawberry/types/__init__.py,sha256=APb1Cjy6bxqFxIfDfempP6eb9NE3LYDwQ3gX7r07lXI,139
221
224
  strawberry/types/execution.py,sha256=Dz4Y_M1ysKz3UxnBK_-h103DjvP6NwLElXXOEpQCkgw,2783
222
225
  strawberry/types/fields/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -225,7 +228,7 @@ strawberry/types/graphql.py,sha256=3SWZEsa0Zy1eVW6vy75BnB7t9_lJVi6TBV3_1j3RNBs,6
225
228
  strawberry/types/info.py,sha256=b1ZWW_wUop6XrGNcGHKBQeUYjlX-y8u3s2Wm_XhKPYI,3412
226
229
  strawberry/types/nodes.py,sha256=5tTYmxGpVDshbydicHTTBWEiUe8A7p7mdiaSV8Ry80Y,5027
227
230
  strawberry/types/type_resolver.py,sha256=wuAYCbEjdov0IrnTvkFMNtSwb3lruQsbYI11x35ADeU,6542
228
- strawberry/types/types.py,sha256=wgdZKrLal6uFeZFw5J9EWzPIify71sir30_VWcWPUxs,8122
231
+ strawberry/types/types.py,sha256=FWCZxclY47BgPDVtcYqA0kxTIN6DQ1uyjIbfBU9p4Z8,8387
229
232
  strawberry/union.py,sha256=bQ3QBOLLugGvN434vHTZRuelgJdblfy8aJMrUpLgG_g,9585
230
233
  strawberry/unset.py,sha256=4zYRN8vUD7lHQLLpulBFqEPfyvzpx8fl7ZDBUyfMqqk,1112
231
234
  strawberry/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -241,8 +244,8 @@ strawberry/utils/logging.py,sha256=flS7hV0JiIOEdXcrIjda4WyIWix86cpHHFNJL8gl1y4,7
241
244
  strawberry/utils/operation.py,sha256=Um-tBCPl3_bVFN2Ph7o1mnrxfxBes4HFCj6T0x4kZxE,1135
242
245
  strawberry/utils/str_converters.py,sha256=avIgPVLg98vZH9mA2lhzVdyyjqzLsK2NdBw9mJQ02Xk,813
243
246
  strawberry/utils/typing.py,sha256=SQVOw1nuFZk2Pe3iz0o8ebzpoyvBVoGSQZVZj6-8k7I,13483
244
- strawberry_graphql-0.229.2.dev1715881453.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
245
- strawberry_graphql-0.229.2.dev1715881453.dist-info/METADATA,sha256=alSm87ziLGjzNKwRfESeLKCG_cYypmHsmo7_U3_19_4,7835
246
- strawberry_graphql-0.229.2.dev1715881453.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
247
- strawberry_graphql-0.229.2.dev1715881453.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
248
- strawberry_graphql-0.229.2.dev1715881453.dist-info/RECORD,,
247
+ strawberry_graphql-0.230.0.dev1716318708.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
248
+ strawberry_graphql-0.230.0.dev1716318708.dist-info/METADATA,sha256=Wy5PRwq7RMIGV079Sot9Nk88btBrLmaMIoT2546uwgc,7835
249
+ strawberry_graphql-0.230.0.dev1716318708.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
250
+ strawberry_graphql-0.230.0.dev1716318708.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
251
+ strawberry_graphql-0.230.0.dev1716318708.dist-info/RECORD,,