strawberry-graphql 0.288.4__py3-none-any.whl → 0.289.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.
@@ -0,0 +1,5 @@
1
+ """Execution utilities for Strawberry GraphQL."""
2
+
3
+ from .is_awaitable import optimized_is_awaitable
4
+
5
+ __all__ = ["optimized_is_awaitable"]
@@ -0,0 +1,59 @@
1
+ """Optimized is_awaitable implementation for GraphQL execution.
2
+
3
+ This module provides a highly optimized is_awaitable function that adds a fast path
4
+ for common synchronous types, significantly improving performance when dealing with
5
+ large result sets containing primitive values.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+
12
+ from graphql.pyutils.is_awaitable import is_awaitable as graphql_core_is_awaitable
13
+
14
+ __all__ = ["optimized_is_awaitable"]
15
+
16
+ # Common synchronous types that are never awaitable
17
+ # Using a frozenset for O(1) lookup
18
+ _NON_AWAITABLE_TYPES: frozenset[type] = frozenset(
19
+ {
20
+ type(None),
21
+ bool,
22
+ int,
23
+ float,
24
+ str,
25
+ bytes,
26
+ bytearray,
27
+ list,
28
+ tuple,
29
+ dict,
30
+ set,
31
+ frozenset,
32
+ }
33
+ )
34
+
35
+
36
+ def optimized_is_awaitable(value: Any) -> bool:
37
+ """Return true if object can be passed to an ``await`` expression.
38
+
39
+ This is an optimized version of graphql-core's is_awaitable that adds a fast path
40
+ for common synchronous types. For large result sets containing mostly primitive
41
+ values (ints, strings, lists, etc.), this can provide significant performance
42
+ improvements.
43
+
44
+ Performance characteristics:
45
+ - Fast path for primitives: O(1) type lookup
46
+ - Falls back to graphql-core's is_awaitable for other types
47
+
48
+ Args:
49
+ value: The value to check
50
+
51
+ Returns:
52
+ True if the value is awaitable, False otherwise
53
+ """
54
+ # Fast path: check if the type is a known non-awaitable type
55
+ if type(value) in _NON_AWAITABLE_TYPES:
56
+ return False
57
+
58
+ # Fallback to graphql-core's implementation for other types
59
+ return graphql_core_is_awaitable(value)
@@ -39,6 +39,7 @@ from graphql.validation import validate
39
39
  from strawberry import relay
40
40
  from strawberry.annotation import StrawberryAnnotation
41
41
  from strawberry.exceptions import MissingQueryError
42
+ from strawberry.execution import optimized_is_awaitable
42
43
  from strawberry.extensions import SchemaExtension
43
44
  from strawberry.extensions.directives import (
44
45
  DirectivesExtension,
@@ -617,6 +618,7 @@ class Schema(BaseSchema):
617
618
  operation_name=execution_context.operation_name,
618
619
  context_value=execution_context.context,
619
620
  execution_context_class=self.execution_context_class,
621
+ is_awaitable=optimized_is_awaitable,
620
622
  **custom_context_kwargs,
621
623
  )
622
624
  )
@@ -752,6 +754,7 @@ class Schema(BaseSchema):
752
754
  operation_name=execution_context.operation_name,
753
755
  context_value=execution_context.context,
754
756
  execution_context_class=self.execution_context_class,
757
+ is_awaitable=optimized_is_awaitable,
755
758
  **custom_context_kwargs,
756
759
  )
757
760
 
strawberry/types/enum.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import dataclasses
2
2
  from collections.abc import Callable, Iterable, Mapping
3
3
  from enum import EnumMeta
4
- from typing import TYPE_CHECKING, Any, TypeGuard, TypeVar, overload
4
+ from typing import TYPE_CHECKING, Any, Literal, TypeGuard, TypeVar, overload
5
5
 
6
6
  from strawberry.exceptions import ObjectIsNotAnEnumError
7
7
  from strawberry.types.base import (
@@ -103,6 +103,7 @@ def enum_value(
103
103
 
104
104
 
105
105
  EnumType = TypeVar("EnumType", bound=EnumMeta)
106
+ GraphqlEnumNameFrom = Literal["key", "value"]
106
107
 
107
108
 
108
109
  def _process_enum(
@@ -110,6 +111,7 @@ def _process_enum(
110
111
  name: str | None = None,
111
112
  description: str | None = None,
112
113
  directives: Iterable[object] = (),
114
+ graphql_name_from: GraphqlEnumNameFrom = "key",
113
115
  ) -> EnumType:
114
116
  if not isinstance(cls, EnumMeta):
115
117
  raise ObjectIsNotAnEnumError(cls)
@@ -119,6 +121,7 @@ def _process_enum(
119
121
 
120
122
  values = []
121
123
  for item in cls: # type: ignore
124
+ graphql_name = None
122
125
  item_value = item.value
123
126
  item_name = item.name
124
127
  deprecation_reason = None
@@ -135,13 +138,19 @@ def _process_enum(
135
138
  cls._value2member_map_[item_value.value] = item
136
139
  cls._member_map_[item_name]._value_ = item_value.value
137
140
 
138
- if item_value.graphql_name:
139
- item_name = item_value.graphql_name
140
-
141
+ graphql_name = item_value.graphql_name
141
142
  item_value = item_value.value
142
143
 
144
+ if not graphql_name:
145
+ if graphql_name_from == "key":
146
+ graphql_name = item_name
147
+ elif graphql_name_from == "value":
148
+ graphql_name = item_value
149
+ else:
150
+ raise ValueError(f"Invalid mode: {graphql_name_from}")
151
+
143
152
  value = EnumValue(
144
- item_name,
153
+ graphql_name,
145
154
  item_value,
146
155
  deprecation_reason=deprecation_reason,
147
156
  directives=item_directives,
@@ -174,6 +183,7 @@ def enum(
174
183
  name: str | None = None,
175
184
  description: str | None = None,
176
185
  directives: Iterable[object] = (),
186
+ graphql_name_from: GraphqlEnumNameFrom = "key",
177
187
  ) -> EnumType: ...
178
188
 
179
189
 
@@ -184,6 +194,7 @@ def enum(
184
194
  name: str | None = None,
185
195
  description: str | None = None,
186
196
  directives: Iterable[object] = (),
197
+ graphql_name_from: GraphqlEnumNameFrom = "key",
187
198
  ) -> Callable[[EnumType], EnumType]: ...
188
199
 
189
200
 
@@ -193,18 +204,20 @@ def enum(
193
204
  name: str | None = None,
194
205
  description: str | None = None,
195
206
  directives: Iterable[object] = (),
207
+ graphql_name_from: GraphqlEnumNameFrom = "key",
196
208
  ) -> EnumType | Callable[[EnumType], EnumType]:
197
209
  """Annotates an Enum class a GraphQL enum.
198
210
 
199
211
  GraphQL enums only have names, while Python enums have names and values,
200
- Strawberry will use the names of the Python enum as the names of the
201
- GraphQL enum values.
212
+ Strawberry will by default use the names of the Python enum as the names of the
213
+ GraphQL enum values. You can use the values instead by using mode="value".
202
214
 
203
215
  Args:
204
216
  cls: The Enum class to be annotated.
205
217
  name: The name of the GraphQL enum.
206
218
  description: The description of the GraphQL enum.
207
219
  directives: The directives to attach to the GraphQL enum.
220
+ graphql_name_from: Whether to use the names (key) or values of the Python enums in GraphQL.
208
221
 
209
222
  Returns:
210
223
  The decorated Enum class.
@@ -235,7 +248,13 @@ def enum(
235
248
  """
236
249
 
237
250
  def wrap(cls: EnumType) -> EnumType:
238
- return _process_enum(cls, name, description, directives=directives)
251
+ return _process_enum(
252
+ cls,
253
+ name,
254
+ description,
255
+ directives=directives,
256
+ graphql_name_from=graphql_name_from,
257
+ )
239
258
 
240
259
  if not cls:
241
260
  return wrap
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: strawberry-graphql
3
- Version: 0.288.4
3
+ Version: 0.289.1
4
4
  Summary: A library for creating GraphQL APIs
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -76,6 +76,8 @@ strawberry/exceptions/syntax.py,sha256=A8_qoYI-PEYCpxBCzrvDOrZOdz96rvh8Q4vxGgvtV
76
76
  strawberry/exceptions/unresolved_field_type.py,sha256=TZvJ_6Dg0IMhDE8IFx9ENLS5MR7m8u0R11MaOchX9xo,1864
77
77
  strawberry/exceptions/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
78
  strawberry/exceptions/utils/source_finder.py,sha256=PPgNivWC8M-Fj-Y-ZiAgOd3HD4kl3D6igdkuoyqAAdA,22487
79
+ strawberry/execution/__init__.py,sha256=DIWjV8COzSgVsingGeef-nZ6K8sJPGDrhhUqFpeOokE,138
80
+ strawberry/execution/is_awaitable.py,sha256=vOPp7x6Y8K3b0w_wuIhr7SFU7_b5Prl_u3uwB1kwWBM,1705
79
81
  strawberry/experimental/__init__.py,sha256=2HP5XtxL8ZKsPp4EDRAbMCqiP7p2V4Cca278JUGxnt0,102
80
82
  strawberry/experimental/pydantic/__init__.py,sha256=UpO8wHNXGpoCYp34YStViInO1tsrGsMyhTVubTpJY7Y,255
81
83
  strawberry/experimental/pydantic/_compat.py,sha256=7dJWzQ5Hs7mD0pSLbJdZvW0l3cROQjsu__GBqKmv_hk,9753
@@ -176,7 +178,7 @@ strawberry/schema/compat.py,sha256=ui3ZsRRo86PgtUxBHbjNF2tqqrPA9eUW-sFY8itGuvc,1
176
178
  strawberry/schema/config.py,sha256=1i80WOoml_9qzOV-kfcx-LYMXYwWYl0uisdcZX1vMEg,2330
177
179
  strawberry/schema/exceptions.py,sha256=SaEWtahVAg_f43coyg2h7H2UMZP10CZ_GJg72khBIAs,1105
178
180
  strawberry/schema/name_converter.py,sha256=G3yOj-BmZ6E0bcvvSbb2cWu8ngsXi8M6W0c6rKROMjc,6933
179
- strawberry/schema/schema.py,sha256=owMOE-Bgte2DTTN4OCXVpZpr6LkR77KOzzGrAWZkDeM,39416
181
+ strawberry/schema/schema.py,sha256=FKtqHGrOCnYMWhMwy1qWU_VXtw2IxyjpZZScL4PmVlg,39606
180
182
  strawberry/schema/schema_converter.py,sha256=nzTZIOyIwe9jCX66ZT7m7vm8UzpcUs-AW25XWnZC9J0,40791
181
183
  strawberry/schema/types/__init__.py,sha256=oHO3COWhL3L1KLYCJNY1XFf5xt2GGtHiMC-UaYbFfnA,68
182
184
  strawberry/schema/types/base_scalars.py,sha256=ajMeN4W45AALhCnJO8MIisRb9slDZRyIl1S61LvHfSQ,2678
@@ -210,7 +212,7 @@ strawberry/types/arguments.py,sha256=3Rt1WlVDMc0KKYmJOnMUckeTB0egJv96Uw7RMopM4DM
210
212
  strawberry/types/auto.py,sha256=4sDflIg-Kz-QpK7Qo7bCSFblw7VE-0752rgayukFznU,2954
211
213
  strawberry/types/base.py,sha256=Hubo7u6OsU1v1v-w-vBCwlNVTqHaNn4zPOJuX93WR5U,15699
212
214
  strawberry/types/cast.py,sha256=fx86MkLW77GIximBAwUk5vZxSGwDqUA6XicXvz8EXwQ,916
213
- strawberry/types/enum.py,sha256=Dc1emdlBi1m9pK9h6rdyq8VRaBLafQO7MQdKhVgYXvs,7286
215
+ strawberry/types/enum.py,sha256=sL7SMLx7W9h0-zxtKews6drfYtLUVZ1VorXuXp83mj4,8103
214
216
  strawberry/types/execution.py,sha256=z84AekAD_V_F4vGGHMPMGlAT0Htiw5JhEVvw1F9sGYQ,4019
215
217
  strawberry/types/field.py,sha256=-E5jfq7YXzI2CUepttfGzgmXFA1BTR2hmts44P-JpEk,20422
216
218
  strawberry/types/fields/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -238,8 +240,8 @@ strawberry/utils/logging.py,sha256=Dnivjd0ZhK_lAvjvuyCDkEWDhuURBoK9d3Kt_mIqbRg,7
238
240
  strawberry/utils/operation.py,sha256=Qs3ttbuC415xEVqmJ6YsWQpJNUo8CZJq9AoMB-yV65w,1215
239
241
  strawberry/utils/str_converters.py,sha256=-eH1Cl16IO_wrBlsGM-km4IY0IKsjhjnSNGRGOwQjVM,897
240
242
  strawberry/utils/typing.py,sha256=eE9NeMfASeXRstbjLnQFfOPymcSX8xwg3FGw_HCp95E,11828
241
- strawberry_graphql-0.288.4.dist-info/METADATA,sha256=LiS09hr9ulZqpMfHbqvHv4rVtV7Ej_WIgApx4CQU-C0,7627
242
- strawberry_graphql-0.288.4.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
243
- strawberry_graphql-0.288.4.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
244
- strawberry_graphql-0.288.4.dist-info/licenses/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
245
- strawberry_graphql-0.288.4.dist-info/RECORD,,
243
+ strawberry_graphql-0.289.1.dist-info/METADATA,sha256=bbupgRYRkCQ5q4LdqolspO2jFu9Xy8bCoX2qwvg8RjM,7627
244
+ strawberry_graphql-0.289.1.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
245
+ strawberry_graphql-0.289.1.dist-info/entry_points.txt,sha256=Nk7-aT3_uEwCgyqtHESV9H6Mc31cK-VAvhnQNTzTb4k,49
246
+ strawberry_graphql-0.289.1.dist-info/licenses/LICENSE,sha256=m-XnIVUKqlG_AWnfi9NReh9JfKhYOB-gJfKE45WM1W8,1072
247
+ strawberry_graphql-0.289.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.2.1
2
+ Generator: poetry-core 2.3.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any