strawberry-graphql 0.221.0.dev1710955937__py3-none-any.whl → 0.221.1__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 CHANGED
@@ -14,6 +14,7 @@ from .private import Private
14
14
  from .scalars import ID
15
15
  from .schema import Schema
16
16
  from .schema_directive import schema_directive
17
+ from .types.info import Info
17
18
  from .union import union
18
19
  from .unset import UNSET
19
20
 
@@ -21,6 +22,7 @@ __all__ = [
21
22
  "BasePermission",
22
23
  "experimental",
23
24
  "ID",
25
+ "Info",
24
26
  "UNSET",
25
27
  "lazy",
26
28
  "LazyType",
@@ -65,7 +65,7 @@ class InputMutationExtension(FieldExtension):
65
65
  self,
66
66
  next_: SyncExtensionResolver,
67
67
  source: Any,
68
- info: Info[Any, Any],
68
+ info: Info,
69
69
  **kwargs: Any,
70
70
  ) -> Any:
71
71
  input_args = kwargs.pop("input")
@@ -2,9 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import dataclasses
4
4
  import keyword
5
- from collections import defaultdict
6
- from typing import TYPE_CHECKING, Tuple
7
- from typing_extensions import Protocol
8
5
 
9
6
  import libcst as cst
10
7
  from graphql import (
@@ -22,7 +19,6 @@ from graphql import (
22
19
  OperationType,
23
20
  ScalarTypeDefinitionNode,
24
21
  SchemaDefinitionNode,
25
- SchemaExtensionNode,
26
22
  StringValueNode,
27
23
  TypeNode,
28
24
  UnionTypeDefinitionNode,
@@ -31,14 +27,6 @@ from graphql import (
31
27
 
32
28
  from strawberry.utils.str_converters import to_snake_case
33
29
 
34
- if TYPE_CHECKING:
35
- from graphql.language.ast import ConstDirectiveNode
36
-
37
-
38
- class HasDirectives(Protocol):
39
- directives: Tuple[ConstDirectiveNode]
40
-
41
-
42
30
  _SCALAR_MAP = {
43
31
  "Int": cst.Name("int"),
44
32
  "Float": cst.Name("float"),
@@ -60,19 +48,6 @@ _SCALAR_MAP = {
60
48
  }
61
49
 
62
50
 
63
- def _is_federation_link_directive(directive: ConstDirectiveNode) -> bool:
64
- if directive.name.value != "link":
65
- return False
66
-
67
- for argument in directive.arguments:
68
- if argument.name.value == "url":
69
- return argument.value.value.startswith(
70
- "https://specs.apollo.dev/federation"
71
- )
72
-
73
- return False
74
-
75
-
76
51
  def _get_field_type(
77
52
  field_type: TypeNode, was_non_nullable: bool = False
78
53
  ) -> cst.BaseExpression:
@@ -110,10 +85,7 @@ def _get_field_type(
110
85
  )
111
86
 
112
87
 
113
- def _sanitize_argument(value: str | bool) -> cst.SimpleString | cst.Name:
114
- if isinstance(value, bool):
115
- return cst.Name(value=str(value))
116
-
88
+ def _get_argument(name: str, value: str) -> cst.Arg:
117
89
  if "\n" in value:
118
90
  argument_value = cst.SimpleString(f'"""\n{value}\n"""')
119
91
  elif '"' in value:
@@ -121,12 +93,6 @@ def _sanitize_argument(value: str | bool) -> cst.SimpleString | cst.Name:
121
93
  else:
122
94
  argument_value = cst.SimpleString(f'"{value}"')
123
95
 
124
- return argument_value
125
-
126
-
127
- def _get_argument(name: str, value: str | bool) -> cst.Arg:
128
- argument_value = _sanitize_argument(value)
129
-
130
96
  return cst.Arg(
131
97
  value=argument_value,
132
98
  keyword=cst.Name(name),
@@ -134,25 +100,7 @@ def _get_argument(name: str, value: str | bool) -> cst.Arg:
134
100
  )
135
101
 
136
102
 
137
- def _get_argument_list(name: str, values: list[str]) -> cst.Arg:
138
- value = cst.List(
139
- elements=[cst.Element(value=_sanitize_argument(value)) for value in values],
140
- )
141
-
142
- return cst.Arg(
143
- value=value,
144
- keyword=cst.Name(name),
145
- equal=cst.AssignEqual(cst.SimpleWhitespace(""), cst.SimpleWhitespace("")),
146
- )
147
-
148
-
149
- def _get_field_value(
150
- field: FieldDefinitionNode | InputValueDefinitionNode,
151
- alias: str | None,
152
- is_apollo_federation: bool,
153
- ) -> cst.Call | None:
154
- description = field.description.value if field.description else None
155
-
103
+ def _get_field_value(description: str | None, alias: str | None) -> cst.Call | None:
156
104
  args = list(
157
105
  filter(
158
106
  None,
@@ -163,24 +111,6 @@ def _get_field_value(
163
111
  )
164
112
  )
165
113
 
166
- directives = _get_directives(field)
167
-
168
- apollo_federation_args = _get_federation_arguments(directives)
169
-
170
- if is_apollo_federation and apollo_federation_args:
171
- args.extend(apollo_federation_args)
172
-
173
- return cst.Call(
174
- func=cst.Attribute(
175
- value=cst.Attribute(
176
- value=cst.Name("strawberry"),
177
- attr=cst.Name("federation"),
178
- ),
179
- attr=cst.Name("field"),
180
- ),
181
- args=args,
182
- )
183
-
184
114
  if args:
185
115
  return cst.Call(
186
116
  func=cst.Attribute(
@@ -195,7 +125,6 @@ def _get_field_value(
195
125
 
196
126
  def _get_field(
197
127
  field: FieldDefinitionNode | InputValueDefinitionNode,
198
- is_apollo_federation: bool,
199
128
  ) -> cst.SimpleStatementLine:
200
129
  name = to_snake_case(field.name.value)
201
130
  alias: str | None = None
@@ -212,67 +141,19 @@ def _get_field(
212
141
  _get_field_type(field.type),
213
142
  ),
214
143
  value=_get_field_value(
215
- field, alias=alias, is_apollo_federation=is_apollo_federation
144
+ description=field.description.value if field.description else None,
145
+ alias=alias if alias != name else None,
216
146
  ),
217
147
  )
218
148
  ]
219
149
  )
220
150
 
221
151
 
222
- def _get_directives(definition: HasDirectives) -> dict[str, list[dict[str, str]]]:
223
- directives = defaultdict(list)
224
-
225
- for directive in definition.directives:
226
- directive_name = directive.name.value
227
-
228
- directives[directive_name].append(
229
- {
230
- argument.name.value: argument.value.value
231
- for argument in directive.arguments
232
- }
233
- )
234
-
235
- return directives
236
-
237
-
238
- def _get_federation_arguments(
239
- directives: dict[str, list[dict[str, str]]],
240
- ) -> list[cst.Arg]:
241
- def append_arg_from_directive(
242
- directive: str, argument_name: str, keyword_name: str | None = None
243
- ):
244
- keyword_name = keyword_name or directive
245
-
246
- if directive in directives:
247
- arguments.append(
248
- _get_argument_list(
249
- keyword_name,
250
- [item[argument_name] for item in directives[directive]],
251
- )
252
- )
253
-
254
- arguments: list[cst.Arg] = []
255
-
256
- append_arg_from_directive("key", "fields", "keys")
257
- append_arg_from_directive("requires", "fields")
258
- append_arg_from_directive("provides", "fields")
259
- append_arg_from_directive("tag", "name", "tags")
260
-
261
- boolean_keys = ("shareable", "inaccessible", "external", "override")
262
-
263
- arguments.extend(
264
- _get_argument(key, True) for key in boolean_keys if directives.get(key, False)
265
- )
266
-
267
- return arguments
268
-
269
-
270
152
  def _get_strawberry_decorator(
271
153
  definition: ObjectTypeDefinitionNode
272
154
  | ObjectTypeExtensionNode
273
155
  | InterfaceTypeDefinitionNode
274
156
  | InputObjectTypeDefinitionNode,
275
- is_apollo_federation: bool,
276
157
  ) -> cst.Decorator:
277
158
  type_ = {
278
159
  ObjectTypeDefinitionNode: "type",
@@ -287,36 +168,15 @@ def _get_strawberry_decorator(
287
168
  else None
288
169
  )
289
170
 
290
- directives = _get_directives(definition)
291
-
292
171
  decorator: cst.BaseExpression = cst.Attribute(
293
172
  value=cst.Name("strawberry"),
294
173
  attr=cst.Name(type_),
295
174
  )
296
175
 
297
- arguments: list[cst.Arg] = []
298
-
299
176
  if description is not None:
300
- arguments.append(_get_argument("description", description.value))
301
-
302
- federation_arguments = _get_federation_arguments(directives)
303
-
304
- # and has any directive that is a federation directive
305
- if is_apollo_federation and federation_arguments:
306
- decorator = cst.Attribute(
307
- value=cst.Attribute(
308
- value=cst.Name("strawberry"),
309
- attr=cst.Name("federation"),
310
- ),
311
- attr=cst.Name(type_),
312
- )
313
-
314
- arguments.extend(federation_arguments)
315
-
316
- if arguments:
317
177
  decorator = cst.Call(
318
178
  func=decorator,
319
- args=arguments,
179
+ args=[_get_argument("description", description.value)],
320
180
  )
321
181
 
322
182
  return cst.Decorator(
@@ -329,9 +189,8 @@ def _get_class_definition(
329
189
  | ObjectTypeExtensionNode
330
190
  | InterfaceTypeDefinitionNode
331
191
  | InputObjectTypeDefinitionNode,
332
- is_apollo_federation: bool,
333
192
  ) -> cst.ClassDef:
334
- decorator = _get_strawberry_decorator(definition, is_apollo_federation)
193
+ decorator = _get_strawberry_decorator(definition)
335
194
 
336
195
  bases = (
337
196
  [cst.Arg(cst.Name(interface.name.value)) for interface in definition.interfaces]
@@ -345,11 +204,7 @@ def _get_class_definition(
345
204
  return cst.ClassDef(
346
205
  name=cst.Name(definition.name.value),
347
206
  bases=bases,
348
- body=cst.IndentedBlock(
349
- body=[
350
- _get_field(field, is_apollo_federation) for field in definition.fields
351
- ]
352
- ),
207
+ body=cst.IndentedBlock(body=[_get_field(field) for field in definition.fields]),
353
208
  decorators=[decorator],
354
209
  )
355
210
 
@@ -388,7 +243,6 @@ def _get_schema_definition(
388
243
  root_query_name: str | None,
389
244
  root_mutation_name: str | None,
390
245
  root_subscription_name: str | None,
391
- is_apollo_federation: bool,
392
246
  ) -> cst.SimpleStatementLine | None:
393
247
  if not any([root_query_name, root_mutation_name, root_subscription_name]):
394
248
  return None
@@ -411,40 +265,17 @@ def _get_schema_definition(
411
265
  if root_subscription_name:
412
266
  args.append(_get_arg("subscription", root_subscription_name))
413
267
 
414
- schema_call = cst.Call(
415
- func=cst.Attribute(
416
- value=cst.Name("strawberry"),
417
- attr=cst.Name("Schema"),
418
- ),
419
- args=args,
420
- )
421
-
422
- if is_apollo_federation:
423
- args.append(
424
- cst.Arg(
425
- keyword=cst.Name("enable_federation_2"),
426
- value=cst.Name("True"),
427
- equal=cst.AssignEqual(
428
- cst.SimpleWhitespace(""), cst.SimpleWhitespace("")
429
- ),
430
- )
431
- )
432
- schema_call = cst.Call(
433
- func=cst.Attribute(
434
- value=cst.Attribute(
435
- value=cst.Name(value="strawberry"),
436
- attr=cst.Name(value="federation"),
437
- ),
438
- attr=cst.Name(value="Schema"),
439
- ),
440
- args=args,
441
- )
442
-
443
268
  return cst.SimpleStatementLine(
444
269
  body=[
445
270
  cst.Assign(
446
271
  targets=[cst.AssignTarget(cst.Name("schema"))],
447
- value=schema_call,
272
+ value=cst.Call(
273
+ func=cst.Attribute(
274
+ value=cst.Name("strawberry"),
275
+ attr=cst.Name("Schema"),
276
+ ),
277
+ args=args,
278
+ ),
448
279
  )
449
280
  ]
450
281
  )
@@ -599,12 +430,6 @@ def codegen(schema: str) -> str:
599
430
 
600
431
  object_types: dict[str, cst.ClassDef] = {}
601
432
 
602
- # when we encounter a extend schema @link ..., we check if is an apollo federation schema
603
- # and we use this variable to keep track of it, but at the moment the assumption is that
604
- # the schema extension is always done at the top, this might not be the case all the
605
- # time
606
- is_apollo_federation = False
607
-
608
433
  for definition in document.definitions:
609
434
  if isinstance(
610
435
  definition,
@@ -615,7 +440,7 @@ def codegen(schema: str) -> str:
615
440
  ObjectTypeExtensionNode,
616
441
  ),
617
442
  ):
618
- class_definition = _get_class_definition(definition, is_apollo_federation)
443
+ class_definition = _get_class_definition(definition)
619
444
 
620
445
  object_types[definition.name.value] = class_definition
621
446
 
@@ -653,11 +478,6 @@ def codegen(schema: str) -> str:
653
478
  definitions.append(cst.EmptyLine())
654
479
  definitions.append(scalar_definition)
655
480
  definitions.append(cst.EmptyLine())
656
- elif isinstance(definition, SchemaExtensionNode):
657
- is_apollo_federation = any(
658
- _is_federation_link_directive(directive)
659
- for directive in definition.directives
660
- )
661
481
  else:
662
482
  raise NotImplementedError(f"Unknown definition {definition}")
663
483
 
@@ -676,7 +496,6 @@ def codegen(schema: str) -> str:
676
496
  root_query_name=root_query_name,
677
497
  root_mutation_name=root_mutation_name,
678
498
  root_subscription_name=root_subscription_name,
679
- is_apollo_federation=is_apollo_federation,
680
499
  )
681
500
 
682
501
  if schema_definition:
@@ -155,7 +155,7 @@ class ReservedType(NamedTuple):
155
155
  # Handle annotated arguments such as Private[str] and DirectiveValue[str]
156
156
  return type_has_annotation(other, self.type)
157
157
  else:
158
- # Handle both concrete and generic types (i.e Info, and Info[Any, Any])
158
+ # Handle both concrete and generic types (i.e Info, and Info)
159
159
  return (
160
160
  issubclass(origin, self.type)
161
161
  if isinstance(origin, type)
strawberry/types/info.py CHANGED
@@ -10,10 +10,11 @@ from typing import (
10
10
  Generic,
11
11
  List,
12
12
  Optional,
13
+ Tuple,
13
14
  Type,
14
- TypeVar,
15
15
  Union,
16
16
  )
17
+ from typing_extensions import TypeVar
17
18
 
18
19
  from .nodes import convert_selections
19
20
 
@@ -29,8 +30,8 @@ if TYPE_CHECKING:
29
30
 
30
31
  from .nodes import Selection
31
32
 
32
- ContextType = TypeVar("ContextType")
33
- RootValueType = TypeVar("RootValueType")
33
+ ContextType = TypeVar("ContextType", default=Any)
34
+ RootValueType = TypeVar("RootValueType", default=Any)
34
35
 
35
36
 
36
37
  @dataclasses.dataclass
@@ -38,6 +39,21 @@ class Info(Generic[ContextType, RootValueType]):
38
39
  _raw_info: GraphQLResolveInfo
39
40
  _field: StrawberryField
40
41
 
42
+ def __class_getitem__(cls, types: Union[type, Tuple[type, ...]]) -> Type[Info]:
43
+ """Workaround for when passing only one type.
44
+
45
+ Python doesn't yet support directly passing only one type to a generic class
46
+ that has typevars with defaults. This is a workaround for that.
47
+
48
+ See:
49
+ https://discuss.python.org/t/passing-only-one-typevar-of-two-when-using-defaults/49134
50
+ """
51
+
52
+ if not isinstance(types, tuple):
53
+ types = (types, Any) # type: ignore
54
+
55
+ return super().__class_getitem__(types) # type: ignore
56
+
41
57
  @property
42
58
  def field_name(self) -> str:
43
59
  return self._raw_info.field_name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strawberry-graphql
3
- Version: 0.221.0.dev1710955937
3
+ Version: 0.221.1
4
4
  Summary: A library for creating GraphQL APIs
5
5
  Home-page: https://strawberry.rocks/
6
6
  License: MIT
@@ -1,4 +1,4 @@
1
- strawberry/__init__.py,sha256=rq7MRtYXzCOd792dYdgZqS6Ejv7UiX7U2hqFfQhLkGk,1063
1
+ strawberry/__init__.py,sha256=NP_R8Benm6W-v3Qqj3MSPm_CMickSCJIMaW2sZZ5oGs,1104
2
2
  strawberry/__main__.py,sha256=3U77Eu21mJ-LY27RG-JEnpbh6Z63wGOom4i-EoLtUcY,59
3
3
  strawberry/aiohttp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  strawberry/aiohttp/handlers/__init__.py,sha256=7EeGIIwrgJYHAS9XJnZLfRGL_GHrligKm39rrVt7qDA,241
@@ -139,7 +139,7 @@ strawberry/federation/types.py,sha256=mM70g1aLgjplOc3SdtuJjy7NAKFLv35Z4BDC4s_j5u
139
139
  strawberry/federation/union.py,sha256=QXeh-nhApqFtXa3To9MX_IwvtwErZBhWYnssUK7JB2E,1005
140
140
  strawberry/field.py,sha256=2LvlnoQyRQHYcZV2Yy1E-2DYKXpOROUa8jyWgxG2QsI,18883
141
141
  strawberry/field_extensions/__init__.py,sha256=0z6RG9jEO7jpAuyEaQhRI5A_30rdcvsBM0qMhLs8y2s,96
142
- strawberry/field_extensions/input_mutation.py,sha256=G1nWnIdPS877MZXnDzGU4VvlRHT56KDpK-YBDOn6rDI,2660
142
+ strawberry/field_extensions/input_mutation.py,sha256=a2zK97Fc5biqBt2ZlUPEPTQgMTRx6sJCSd3hSsjLSxI,2650
143
143
  strawberry/file_uploads/__init__.py,sha256=v2-6FGBqnTnMPSUTFOiXpIutDMl-ga0PFtw5tKlcagk,50
144
144
  strawberry/file_uploads/scalars.py,sha256=jccJh-h7t4naRiDzrszGoYsp95zdF30c7y5Ht0Zrk_s,131
145
145
  strawberry/file_uploads/utils.py,sha256=U8gk1aHjWOBa_Opyvc47h6OpYToGq1QiSnEkI2kphdo,1112
@@ -194,7 +194,7 @@ strawberry/schema/types/__init__.py,sha256=oHO3COWhL3L1KLYCJNY1XFf5xt2GGtHiMC-Ua
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_codegen/__init__.py,sha256=bPWBUwYPGYRtLwLu1QtDWa0Knt0IgF0FcZnePvDkveI,20837
197
+ strawberry/schema_codegen/__init__.py,sha256=U-ABa02BAfCN6zEGlc2LJEju18ErtGjbf0S8BhJXc6w,15592
198
198
  strawberry/schema_directive.py,sha256=GxiOedFB-RJAflpQNUZv00C5Z6gavR-AYdsvoCA_0jc,1963
199
199
  strawberry/starlite/__init__.py,sha256=v209swT8H9MljVL-npvANhEO1zz3__PSfxb_Ix-NoeE,134
200
200
  strawberry/starlite/controller.py,sha256=x6Mm3r36cRfzo6hz9B4AYWbVh2QlYtndYcXFOr_3THM,11860
@@ -220,9 +220,9 @@ strawberry/type.py,sha256=KDztUFxVju4CEPPRzZYcyHtDNRrkFYxK-mI99GcqCgU,6511
220
220
  strawberry/types/__init__.py,sha256=APb1Cjy6bxqFxIfDfempP6eb9NE3LYDwQ3gX7r07lXI,139
221
221
  strawberry/types/execution.py,sha256=qCqDMJgdAFwdc3uPzVTAKsZlu6fgxPLrFwkoX_PFBq8,2775
222
222
  strawberry/types/fields/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
223
- strawberry/types/fields/resolver.py,sha256=7-fzFfQdf0uWuYyWiSIsGbt2qvpLpGPy6w1T_57cYL8,14140
223
+ strawberry/types/fields/resolver.py,sha256=Lwy2XVKnTbDyibk9pPsWsunlm22akXjy-gKCg22Tp1A,14130
224
224
  strawberry/types/graphql.py,sha256=3SWZEsa0Zy1eVW6vy75BnB7t9_lJVi6TBV3_1j3RNBs,687
225
- strawberry/types/info.py,sha256=AwYUVQgCiTGFU9x97ntF3v6W6qnknOBvuYnERdfIe4w,2776
225
+ strawberry/types/info.py,sha256=b1ZWW_wUop6XrGNcGHKBQeUYjlX-y8u3s2Wm_XhKPYI,3412
226
226
  strawberry/types/nodes.py,sha256=2ZVa1HOFgHZ96QTfz3QEr1fufi6Sz9hAzcZxsN7KtGE,5026
227
227
  strawberry/types/type_resolver.py,sha256=F0z_geS4VEun8EhD571LaTgI8ypjCeLfp910gF0Q3MY,6280
228
228
  strawberry/types/types.py,sha256=t5MOV4xiutPL2Ka02u3Z2V3eqy2R2JPYQxsqCnY2Aqk,7139
@@ -241,8 +241,8 @@ strawberry/utils/logging.py,sha256=flS7hV0JiIOEdXcrIjda4WyIWix86cpHHFNJL8gl1y4,7
241
241
  strawberry/utils/operation.py,sha256=Um-tBCPl3_bVFN2Ph7o1mnrxfxBes4HFCj6T0x4kZxE,1135
242
242
  strawberry/utils/str_converters.py,sha256=avIgPVLg98vZH9mA2lhzVdyyjqzLsK2NdBw9mJQ02Xk,813
243
243
  strawberry/utils/typing.py,sha256=Qxz1LwyVsNGV7LQW1dFsaUbsswj5LHBOdKLMom5eyEA,13491
244
- strawberry_graphql-0.221.0.dev1710955937.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
245
- strawberry_graphql-0.221.0.dev1710955937.dist-info/METADATA,sha256=l7sfrGtQwOGjYGDh5RVMKFg7bL4dvPYKnTzz6xo-eFU,7754
246
- strawberry_graphql-0.221.0.dev1710955937.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
247
- strawberry_graphql-0.221.0.dev1710955937.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
248
- strawberry_graphql-0.221.0.dev1710955937.dist-info/RECORD,,
244
+ strawberry_graphql-0.221.1.dist-info/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
245
+ strawberry_graphql-0.221.1.dist-info/METADATA,sha256=QBJJOv0_Ebod03n0Zma4nMx-93WpOn9K54NqT49Dk-w,7740
246
+ strawberry_graphql-0.221.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
247
+ strawberry_graphql-0.221.1.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
248
+ strawberry_graphql-0.221.1.dist-info/RECORD,,