strawberry-graphql 0.275.7__py3-none-any.whl → 0.284.3__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.
Potentially problematic release.
This version of strawberry-graphql might be problematic. Click here for more details.
- strawberry/__init__.py +2 -0
- strawberry/aiohttp/test/client.py +8 -15
- strawberry/aiohttp/views.py +15 -64
- strawberry/annotation.py +70 -25
- strawberry/asgi/__init__.py +22 -56
- strawberry/asgi/test/client.py +6 -6
- strawberry/chalice/views.py +13 -79
- strawberry/channels/handlers/base.py +7 -8
- strawberry/channels/handlers/http_handler.py +50 -32
- strawberry/channels/handlers/ws_handler.py +12 -14
- strawberry/channels/router.py +3 -4
- strawberry/channels/testing.py +7 -9
- strawberry/cli/__init__.py +7 -6
- strawberry/cli/commands/codegen.py +7 -7
- strawberry/cli/commands/dev.py +72 -0
- strawberry/cli/commands/schema_codegen.py +1 -2
- strawberry/cli/commands/server.py +3 -44
- strawberry/cli/commands/upgrade/__init__.py +3 -3
- strawberry/cli/commands/upgrade/_run_codemod.py +2 -2
- strawberry/cli/constants.py +1 -2
- strawberry/cli/{debug_server.py → dev_server.py} +3 -7
- strawberry/codegen/plugins/print_operation.py +2 -2
- strawberry/codegen/plugins/python.py +2 -2
- strawberry/codegen/query_codegen.py +20 -30
- strawberry/codegen/types.py +32 -32
- strawberry/codemods/__init__.py +9 -0
- strawberry/codemods/annotated_unions.py +2 -2
- strawberry/codemods/maybe_optional.py +118 -0
- strawberry/dataloader.py +28 -24
- strawberry/directive.py +6 -7
- strawberry/django/test/client.py +3 -3
- strawberry/django/views.py +21 -91
- strawberry/exceptions/__init__.py +4 -4
- strawberry/exceptions/conflicting_arguments.py +2 -2
- strawberry/exceptions/duplicated_type_name.py +4 -4
- strawberry/exceptions/exception.py +3 -3
- strawberry/exceptions/handler.py +8 -7
- strawberry/exceptions/invalid_argument_type.py +2 -2
- strawberry/exceptions/invalid_superclass_interface.py +2 -2
- strawberry/exceptions/invalid_union_type.py +4 -4
- strawberry/exceptions/missing_arguments_annotations.py +2 -2
- strawberry/exceptions/missing_dependencies.py +2 -4
- strawberry/exceptions/missing_field_annotation.py +2 -2
- strawberry/exceptions/missing_return_annotation.py +2 -2
- strawberry/exceptions/object_is_not_a_class.py +2 -2
- strawberry/exceptions/object_is_not_an_enum.py +2 -2
- strawberry/exceptions/permission_fail_silently_requires_optional.py +2 -2
- strawberry/exceptions/private_strawberry_field.py +2 -2
- strawberry/exceptions/scalar_already_registered.py +2 -2
- strawberry/exceptions/syntax.py +3 -3
- strawberry/exceptions/unresolved_field_type.py +2 -2
- strawberry/exceptions/utils/source_finder.py +25 -25
- strawberry/experimental/pydantic/_compat.py +8 -7
- strawberry/experimental/pydantic/conversion.py +2 -2
- strawberry/experimental/pydantic/conversion_types.py +2 -2
- strawberry/experimental/pydantic/error_type.py +10 -12
- strawberry/experimental/pydantic/fields.py +9 -15
- strawberry/experimental/pydantic/object_type.py +17 -25
- strawberry/experimental/pydantic/utils.py +1 -2
- strawberry/ext/mypy_plugin.py +12 -14
- strawberry/extensions/base_extension.py +2 -1
- strawberry/extensions/context.py +13 -18
- strawberry/extensions/directives.py +9 -3
- strawberry/extensions/field_extension.py +4 -4
- strawberry/extensions/mask_errors.py +24 -13
- strawberry/extensions/max_aliases.py +1 -3
- strawberry/extensions/parser_cache.py +1 -2
- strawberry/extensions/query_depth_limiter.py +18 -14
- strawberry/extensions/runner.py +2 -2
- strawberry/extensions/tracing/apollo.py +3 -3
- strawberry/extensions/tracing/datadog.py +3 -3
- strawberry/extensions/tracing/opentelemetry.py +6 -8
- strawberry/extensions/tracing/utils.py +3 -1
- strawberry/extensions/utils.py +2 -2
- strawberry/extensions/validation_cache.py +2 -3
- strawberry/fastapi/context.py +6 -6
- strawberry/fastapi/router.py +43 -42
- strawberry/federation/argument.py +4 -5
- strawberry/federation/enum.py +18 -21
- strawberry/federation/field.py +94 -97
- strawberry/federation/object_type.py +56 -58
- strawberry/federation/scalar.py +27 -35
- strawberry/federation/schema.py +15 -16
- strawberry/federation/schema_directive.py +7 -6
- strawberry/federation/schema_directives.py +11 -11
- strawberry/federation/union.py +4 -4
- strawberry/flask/views.py +16 -85
- strawberry/http/__init__.py +30 -20
- strawberry/http/async_base_view.py +208 -89
- strawberry/http/base.py +28 -11
- strawberry/http/exceptions.py +5 -7
- strawberry/http/ides.py +2 -3
- strawberry/http/sync_base_view.py +115 -69
- strawberry/http/types.py +3 -3
- strawberry/litestar/controller.py +43 -77
- strawberry/permission.py +4 -6
- strawberry/printer/ast_from_value.py +3 -5
- strawberry/printer/printer.py +18 -15
- strawberry/quart/views.py +16 -48
- strawberry/relay/exceptions.py +4 -4
- strawberry/relay/fields.py +33 -32
- strawberry/relay/types.py +32 -35
- strawberry/relay/utils.py +11 -23
- strawberry/resolvers.py +2 -1
- strawberry/sanic/context.py +1 -0
- strawberry/sanic/utils.py +3 -3
- strawberry/sanic/views.py +15 -54
- strawberry/scalars.py +2 -2
- strawberry/schema/_graphql_core.py +55 -0
- strawberry/schema/base.py +32 -33
- strawberry/schema/compat.py +9 -9
- strawberry/schema/config.py +10 -1
- strawberry/schema/exceptions.py +1 -3
- strawberry/schema/name_converter.py +9 -8
- strawberry/schema/schema.py +133 -100
- strawberry/schema/schema_converter.py +96 -58
- strawberry/schema/types/base_scalars.py +1 -1
- strawberry/schema/types/concrete_type.py +5 -5
- strawberry/schema/validation_rules/maybe_null.py +136 -0
- strawberry/schema_codegen/__init__.py +3 -3
- strawberry/schema_directive.py +7 -6
- strawberry/static/graphiql.html +5 -5
- strawberry/streamable.py +35 -0
- strawberry/subscriptions/protocols/graphql_transport_ws/handlers.py +5 -16
- strawberry/subscriptions/protocols/graphql_transport_ws/types.py +20 -20
- strawberry/subscriptions/protocols/graphql_ws/handlers.py +5 -12
- strawberry/subscriptions/protocols/graphql_ws/types.py +14 -14
- strawberry/test/client.py +18 -18
- strawberry/tools/create_type.py +2 -3
- strawberry/types/arguments.py +41 -28
- strawberry/types/auto.py +3 -4
- strawberry/types/base.py +25 -27
- strawberry/types/enum.py +22 -25
- strawberry/types/execution.py +21 -16
- strawberry/types/field.py +109 -130
- strawberry/types/fields/resolver.py +19 -21
- strawberry/types/info.py +5 -11
- strawberry/types/lazy_type.py +2 -3
- strawberry/types/maybe.py +12 -3
- strawberry/types/mutation.py +115 -118
- strawberry/types/nodes.py +2 -2
- strawberry/types/object_type.py +43 -63
- strawberry/types/scalar.py +37 -43
- strawberry/types/union.py +12 -14
- strawberry/utils/aio.py +12 -9
- strawberry/utils/await_maybe.py +3 -3
- strawberry/utils/deprecations.py +2 -2
- strawberry/utils/importer.py +1 -2
- strawberry/utils/inspect.py +4 -6
- strawberry/utils/logging.py +2 -2
- strawberry/utils/operation.py +4 -4
- strawberry/utils/typing.py +18 -83
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/METADATA +14 -8
- strawberry_graphql-0.284.3.dist-info/RECORD +243 -0
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/WHEEL +1 -1
- strawberry/utils/dataclasses.py +0 -37
- strawberry/utils/debug.py +0 -46
- strawberry/utils/graphql_lexer.py +0 -35
- strawberry_graphql-0.275.7.dist-info/RECORD +0 -241
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info}/entry_points.txt +0 -0
- {strawberry_graphql-0.275.7.dist-info → strawberry_graphql-0.284.3.dist-info/licenses}/LICENSE +0 -0
strawberry/federation/schema.py
CHANGED
|
@@ -44,18 +44,17 @@ FederationAny = scalar(NewType("_Any", object), name="_Any") # type: ignore
|
|
|
44
44
|
class Schema(BaseSchema):
|
|
45
45
|
def __init__(
|
|
46
46
|
self,
|
|
47
|
-
query:
|
|
48
|
-
mutation:
|
|
49
|
-
subscription:
|
|
47
|
+
query: type | None = None,
|
|
48
|
+
mutation: type | None = None,
|
|
49
|
+
subscription: type | None = None,
|
|
50
50
|
# TODO: we should update directives' type in the main schema
|
|
51
51
|
directives: Iterable[type] = (),
|
|
52
52
|
types: Iterable[type] = (),
|
|
53
53
|
extensions: Iterable[Union[type["SchemaExtension"], "SchemaExtension"]] = (),
|
|
54
|
-
execution_context_class:
|
|
54
|
+
execution_context_class: type["GraphQLExecutionContext"] | None = None,
|
|
55
55
|
config: Optional["StrawberryConfig"] = None,
|
|
56
|
-
scalar_overrides:
|
|
57
|
-
|
|
58
|
-
] = None,
|
|
56
|
+
scalar_overrides: dict[object, Union[type, "ScalarWrapper", "ScalarDefinition"]]
|
|
57
|
+
| None = None,
|
|
59
58
|
schema_directives: Iterable[object] = (),
|
|
60
59
|
enable_federation_2: bool = False,
|
|
61
60
|
) -> None:
|
|
@@ -85,9 +84,9 @@ class Schema(BaseSchema):
|
|
|
85
84
|
|
|
86
85
|
def _get_federation_query_type(
|
|
87
86
|
self,
|
|
88
|
-
query:
|
|
89
|
-
mutation:
|
|
90
|
-
subscription:
|
|
87
|
+
query: type[WithStrawberryObjectDefinition] | None,
|
|
88
|
+
mutation: type[WithStrawberryObjectDefinition] | None,
|
|
89
|
+
subscription: type[WithStrawberryObjectDefinition] | None,
|
|
91
90
|
additional_types: Iterable[type[WithStrawberryObjectDefinition]],
|
|
92
91
|
) -> type:
|
|
93
92
|
"""Returns a new query type that includes the _service field.
|
|
@@ -124,7 +123,7 @@ class Schema(BaseSchema):
|
|
|
124
123
|
|
|
125
124
|
if entity_type:
|
|
126
125
|
self.entities_resolver.__annotations__["return"] = list[
|
|
127
|
-
|
|
126
|
+
entity_type | None # type: ignore
|
|
128
127
|
]
|
|
129
128
|
|
|
130
129
|
entities_field = strawberry.field(
|
|
@@ -250,7 +249,7 @@ class Schema(BaseSchema):
|
|
|
250
249
|
directive_by_url[import_url].add(f"@{name}")
|
|
251
250
|
|
|
252
251
|
def _add_link_directives(
|
|
253
|
-
self, additional_directives:
|
|
252
|
+
self, additional_directives: list[object] | None = None
|
|
254
253
|
) -> None:
|
|
255
254
|
from .schema_directives import FederationDirective, Link
|
|
256
255
|
|
|
@@ -312,11 +311,11 @@ class Schema(BaseSchema):
|
|
|
312
311
|
|
|
313
312
|
|
|
314
313
|
def _get_entity_type(
|
|
315
|
-
query:
|
|
316
|
-
mutation:
|
|
317
|
-
subscription:
|
|
314
|
+
query: type[WithStrawberryObjectDefinition] | None,
|
|
315
|
+
mutation: type[WithStrawberryObjectDefinition] | None,
|
|
316
|
+
subscription: type[WithStrawberryObjectDefinition] | None,
|
|
318
317
|
additional_types: Iterable[type[WithStrawberryObjectDefinition]],
|
|
319
|
-
) ->
|
|
318
|
+
) -> StrawberryUnion | None:
|
|
320
319
|
# recursively iterate over the schema to find all types annotated with @key
|
|
321
320
|
# if no types are annotated with @key, then the _Entity union and Query._entities
|
|
322
321
|
# field should not be added to the schema
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import TypeVar
|
|
3
4
|
from typing_extensions import dataclass_transform
|
|
4
5
|
|
|
5
6
|
from strawberry.directive import directive_field
|
|
@@ -11,12 +12,12 @@ from strawberry.types.type_resolver import _get_fields
|
|
|
11
12
|
|
|
12
13
|
@dataclasses.dataclass
|
|
13
14
|
class ComposeOptions:
|
|
14
|
-
import_url:
|
|
15
|
+
import_url: str | None
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
@dataclasses.dataclass
|
|
18
19
|
class StrawberryFederationSchemaDirective(StrawberrySchemaDirective):
|
|
19
|
-
compose_options:
|
|
20
|
+
compose_options: ComposeOptions | None = None
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
T = TypeVar("T", bound=type)
|
|
@@ -30,12 +31,12 @@ T = TypeVar("T", bound=type)
|
|
|
30
31
|
def schema_directive(
|
|
31
32
|
*,
|
|
32
33
|
locations: list[Location],
|
|
33
|
-
description:
|
|
34
|
-
name:
|
|
34
|
+
description: str | None = None,
|
|
35
|
+
name: str | None = None,
|
|
35
36
|
repeatable: bool = False,
|
|
36
37
|
print_definition: bool = True,
|
|
37
38
|
compose: bool = False,
|
|
38
|
-
import_url:
|
|
39
|
+
import_url: str | None = None,
|
|
39
40
|
) -> Callable[[T], T]:
|
|
40
41
|
def _wrap(cls: T) -> T:
|
|
41
42
|
cls = _wrap_dataclass(cls) # type: ignore
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from typing import ClassVar
|
|
2
|
+
from typing import ClassVar
|
|
3
3
|
|
|
4
4
|
from strawberry import directive_field
|
|
5
5
|
from strawberry.schema_directive import Location, schema_directive
|
|
@@ -59,7 +59,7 @@ class Provides(FederationDirective):
|
|
|
59
59
|
)
|
|
60
60
|
class Key(FederationDirective):
|
|
61
61
|
fields: FieldSet
|
|
62
|
-
resolvable:
|
|
62
|
+
resolvable: bool | None = True
|
|
63
63
|
imported_from: ClassVar[ImportedFrom] = ImportedFrom(
|
|
64
64
|
name="key", url="https://specs.apollo.dev/federation/v2.7"
|
|
65
65
|
)
|
|
@@ -81,17 +81,17 @@ class Shareable(FederationDirective):
|
|
|
81
81
|
locations=[Location.SCHEMA], name="link", repeatable=True, print_definition=False
|
|
82
82
|
)
|
|
83
83
|
class Link:
|
|
84
|
-
url:
|
|
85
|
-
as_:
|
|
86
|
-
for_:
|
|
87
|
-
import_:
|
|
84
|
+
url: str | None
|
|
85
|
+
as_: str | None = directive_field(name="as")
|
|
86
|
+
for_: LinkPurpose | None = directive_field(name="for")
|
|
87
|
+
import_: list[LinkImport | None] | None = directive_field(name="import")
|
|
88
88
|
|
|
89
89
|
def __init__(
|
|
90
90
|
self,
|
|
91
|
-
url:
|
|
92
|
-
as_:
|
|
93
|
-
for_:
|
|
94
|
-
import_:
|
|
91
|
+
url: str | None = UNSET,
|
|
92
|
+
as_: str | None = UNSET,
|
|
93
|
+
for_: LinkPurpose | None = UNSET,
|
|
94
|
+
import_: list[LinkImport | None] | None = UNSET,
|
|
95
95
|
) -> None:
|
|
96
96
|
self.url = url
|
|
97
97
|
self.as_ = as_
|
|
@@ -128,7 +128,7 @@ class Tag(FederationDirective):
|
|
|
128
128
|
)
|
|
129
129
|
class Override(FederationDirective):
|
|
130
130
|
override_from: str = directive_field(name="from")
|
|
131
|
-
label:
|
|
131
|
+
label: str | None = UNSET
|
|
132
132
|
imported_from: ClassVar[ImportedFrom] = ImportedFrom(
|
|
133
133
|
name="override", url="https://specs.apollo.dev/federation/v2.7"
|
|
134
134
|
)
|
strawberry/federation/union.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from collections.abc import Collection, Iterable
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from strawberry.types.union import StrawberryUnion
|
|
5
5
|
from strawberry.types.union import union as base_union
|
|
@@ -7,12 +7,12 @@ from strawberry.types.union import union as base_union
|
|
|
7
7
|
|
|
8
8
|
def union(
|
|
9
9
|
name: str,
|
|
10
|
-
types:
|
|
10
|
+
types: Collection[type[Any]] | None = None,
|
|
11
11
|
*,
|
|
12
|
-
description:
|
|
12
|
+
description: str | None = None,
|
|
13
13
|
directives: Iterable[object] = (),
|
|
14
14
|
inaccessible: bool = False,
|
|
15
|
-
tags:
|
|
15
|
+
tags: Iterable[str] | None = (),
|
|
16
16
|
) -> StrawberryUnion:
|
|
17
17
|
"""Creates a new named Union type.
|
|
18
18
|
|
strawberry/flask/views.py
CHANGED
|
@@ -3,75 +3,34 @@ from __future__ import annotations
|
|
|
3
3
|
import warnings
|
|
4
4
|
from typing import (
|
|
5
5
|
TYPE_CHECKING,
|
|
6
|
-
Any,
|
|
7
6
|
ClassVar,
|
|
8
|
-
|
|
9
|
-
Union,
|
|
10
|
-
cast,
|
|
7
|
+
TypeGuard,
|
|
11
8
|
)
|
|
12
|
-
|
|
9
|
+
|
|
10
|
+
from lia import AsyncFlaskHTTPRequestAdapter, FlaskHTTPRequestAdapter, HTTPException
|
|
13
11
|
|
|
14
12
|
from flask import Request, Response, render_template_string, request
|
|
15
13
|
from flask.views import View
|
|
16
|
-
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
17
|
-
from strawberry.http.
|
|
18
|
-
from strawberry.http.sync_base_view import (
|
|
19
|
-
SyncBaseHTTPView,
|
|
20
|
-
SyncHTTPRequestAdapter,
|
|
21
|
-
)
|
|
22
|
-
from strawberry.http.types import FormData, HTTPMethod, QueryParams
|
|
14
|
+
from strawberry.http.async_base_view import AsyncBaseHTTPView
|
|
15
|
+
from strawberry.http.sync_base_view import SyncBaseHTTPView
|
|
23
16
|
from strawberry.http.typevars import Context, RootValue
|
|
24
17
|
|
|
25
18
|
if TYPE_CHECKING:
|
|
26
|
-
from collections.abc import Mapping
|
|
27
|
-
|
|
28
19
|
from flask.typing import ResponseReturnValue
|
|
20
|
+
|
|
29
21
|
from strawberry.http import GraphQLHTTPResponse
|
|
30
22
|
from strawberry.http.ides import GraphQL_IDE
|
|
31
23
|
from strawberry.schema.base import BaseSchema
|
|
32
24
|
|
|
33
25
|
|
|
34
|
-
class FlaskHTTPRequestAdapter(SyncHTTPRequestAdapter):
|
|
35
|
-
def __init__(self, request: Request) -> None:
|
|
36
|
-
self.request = request
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def query_params(self) -> QueryParams:
|
|
40
|
-
return self.request.args.to_dict()
|
|
41
|
-
|
|
42
|
-
@property
|
|
43
|
-
def body(self) -> Union[str, bytes]:
|
|
44
|
-
return self.request.data.decode()
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def method(self) -> HTTPMethod:
|
|
48
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
49
|
-
|
|
50
|
-
@property
|
|
51
|
-
def headers(self) -> Mapping[str, str]:
|
|
52
|
-
return self.request.headers # type: ignore
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def post_data(self) -> Mapping[str, Union[str, bytes]]:
|
|
56
|
-
return self.request.form
|
|
57
|
-
|
|
58
|
-
@property
|
|
59
|
-
def files(self) -> Mapping[str, Any]:
|
|
60
|
-
return self.request.files
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def content_type(self) -> Optional[str]:
|
|
64
|
-
return self.request.content_type
|
|
65
|
-
|
|
66
|
-
|
|
67
26
|
class BaseGraphQLView:
|
|
68
|
-
graphql_ide:
|
|
27
|
+
graphql_ide: GraphQL_IDE | None
|
|
69
28
|
|
|
70
29
|
def __init__(
|
|
71
30
|
self,
|
|
72
31
|
schema: BaseSchema,
|
|
73
|
-
graphiql:
|
|
74
|
-
graphql_ide:
|
|
32
|
+
graphiql: bool | None = None,
|
|
33
|
+
graphql_ide: GraphQL_IDE | None = "graphiql",
|
|
75
34
|
allow_queries_via_get: bool = True,
|
|
76
35
|
multipart_uploads_enabled: bool = False,
|
|
77
36
|
) -> None:
|
|
@@ -91,7 +50,9 @@ class BaseGraphQLView:
|
|
|
91
50
|
self.graphql_ide = graphql_ide
|
|
92
51
|
|
|
93
52
|
def create_response(
|
|
94
|
-
self,
|
|
53
|
+
self,
|
|
54
|
+
response_data: GraphQLHTTPResponse | list[GraphQLHTTPResponse],
|
|
55
|
+
sub_response: Response,
|
|
95
56
|
) -> Response:
|
|
96
57
|
sub_response.set_data(self.encode_json(response_data)) # type: ignore
|
|
97
58
|
|
|
@@ -110,7 +71,7 @@ class GraphQLView(
|
|
|
110
71
|
def get_context(self, request: Request, response: Response) -> Context:
|
|
111
72
|
return {"request": request, "response": response} # type: ignore
|
|
112
73
|
|
|
113
|
-
def get_root_value(self, request: Request) ->
|
|
74
|
+
def get_root_value(self, request: Request) -> RootValue | None:
|
|
114
75
|
return None
|
|
115
76
|
|
|
116
77
|
def get_sub_response(self, request: Request) -> Response:
|
|
@@ -129,36 +90,6 @@ class GraphQLView(
|
|
|
129
90
|
return render_template_string(self.graphql_ide_html) # type: ignore
|
|
130
91
|
|
|
131
92
|
|
|
132
|
-
class AsyncFlaskHTTPRequestAdapter(AsyncHTTPRequestAdapter):
|
|
133
|
-
def __init__(self, request: Request) -> None:
|
|
134
|
-
self.request = request
|
|
135
|
-
|
|
136
|
-
@property
|
|
137
|
-
def query_params(self) -> QueryParams:
|
|
138
|
-
return self.request.args.to_dict()
|
|
139
|
-
|
|
140
|
-
@property
|
|
141
|
-
def method(self) -> HTTPMethod:
|
|
142
|
-
return cast("HTTPMethod", self.request.method.upper())
|
|
143
|
-
|
|
144
|
-
@property
|
|
145
|
-
def content_type(self) -> Optional[str]:
|
|
146
|
-
return self.request.content_type
|
|
147
|
-
|
|
148
|
-
@property
|
|
149
|
-
def headers(self) -> Mapping[str, str]:
|
|
150
|
-
return self.request.headers # type: ignore
|
|
151
|
-
|
|
152
|
-
async def get_body(self) -> str:
|
|
153
|
-
return self.request.data.decode()
|
|
154
|
-
|
|
155
|
-
async def get_form_data(self) -> FormData:
|
|
156
|
-
return FormData(
|
|
157
|
-
files=self.request.files,
|
|
158
|
-
form=self.request.form,
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
|
|
162
93
|
class AsyncGraphQLView(
|
|
163
94
|
BaseGraphQLView,
|
|
164
95
|
AsyncBaseHTTPView[
|
|
@@ -173,7 +104,7 @@ class AsyncGraphQLView(
|
|
|
173
104
|
async def get_context(self, request: Request, response: Response) -> Context:
|
|
174
105
|
return {"request": request, "response": response} # type: ignore
|
|
175
106
|
|
|
176
|
-
async def get_root_value(self, request: Request) ->
|
|
107
|
+
async def get_root_value(self, request: Request) -> RootValue | None:
|
|
177
108
|
return None
|
|
178
109
|
|
|
179
110
|
async def get_sub_response(self, request: Request) -> Response:
|
|
@@ -195,11 +126,11 @@ class AsyncGraphQLView(
|
|
|
195
126
|
def is_websocket_request(self, request: Request) -> TypeGuard[Request]:
|
|
196
127
|
return False
|
|
197
128
|
|
|
198
|
-
async def pick_websocket_subprotocol(self, request: Request) ->
|
|
129
|
+
async def pick_websocket_subprotocol(self, request: Request) -> str | None:
|
|
199
130
|
raise NotImplementedError
|
|
200
131
|
|
|
201
132
|
async def create_websocket_response(
|
|
202
|
-
self, request: Request, subprotocol:
|
|
133
|
+
self, request: Request, subprotocol: str | None
|
|
203
134
|
) -> Response:
|
|
204
135
|
raise NotImplementedError
|
|
205
136
|
|
strawberry/http/__init__.py
CHANGED
|
@@ -1,26 +1,36 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import
|
|
5
|
-
from typing_extensions import
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
from typing_extensions import TypedDict
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
from strawberry.schema._graphql_core import (
|
|
8
|
+
GraphQLIncrementalExecutionResults,
|
|
9
|
+
ResultType,
|
|
10
|
+
)
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class GraphQLHTTPResponse(TypedDict, total=False):
|
|
12
|
-
data:
|
|
13
|
-
errors:
|
|
14
|
-
extensions:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
data: dict[str, object] | None
|
|
15
|
+
errors: list[object] | None
|
|
16
|
+
extensions: dict[str, object] | None
|
|
17
|
+
hasNext: bool | None
|
|
18
|
+
completed: list[Any] | None
|
|
19
|
+
pending: list[Any] | None
|
|
20
|
+
initial: list[Any] | None
|
|
21
|
+
incremental: list[Any] | None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def process_result(result: ResultType) -> GraphQLHTTPResponse:
|
|
25
|
+
if isinstance(result, GraphQLIncrementalExecutionResults):
|
|
26
|
+
return result
|
|
27
|
+
|
|
28
|
+
errors, extensions = result.errors, result.extensions
|
|
29
|
+
data: GraphQLHTTPResponse = {
|
|
30
|
+
"data": result.data,
|
|
31
|
+
**({"errors": [err.formatted for err in errors]} if errors else {}),
|
|
32
|
+
**({"extensions": extensions} if extensions else {}),
|
|
33
|
+
}
|
|
24
34
|
|
|
25
35
|
return data
|
|
26
36
|
|
|
@@ -29,10 +39,10 @@ def process_result(result: ExecutionResult) -> GraphQLHTTPResponse:
|
|
|
29
39
|
class GraphQLRequestData:
|
|
30
40
|
# query is optional here as it can be added by an extensions
|
|
31
41
|
# (for example an extension for persisted queries)
|
|
32
|
-
query:
|
|
33
|
-
variables:
|
|
34
|
-
operation_name:
|
|
35
|
-
extensions:
|
|
42
|
+
query: str | None
|
|
43
|
+
variables: dict[str, Any] | None
|
|
44
|
+
operation_name: str | None
|
|
45
|
+
extensions: dict[str, Any] | None
|
|
36
46
|
protocol: Literal["http", "multipart-subscription"] = "http"
|
|
37
47
|
|
|
38
48
|
|