graphql-http 2.3.2__tar.gz → 2.3.3__tar.gz
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.
- {graphql_http-2.3.2 → graphql_http-2.3.3}/PKG-INFO +1 -1
- graphql_http-2.3.3/VERSION +1 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/helpers.py +18 -3
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/server.py +8 -5
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/PKG-INFO +1 -1
- graphql_http-2.3.2/VERSION +0 -1
- {graphql_http-2.3.2 → graphql_http-2.3.3}/.coverage +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/.github/workflows/pages.yml +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/.github/workflows/python-package.yml +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/.gitignore +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/.gitmodules +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/AGENTS.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/CLAUDE.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/LICENSE +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/README.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/.gitmodules +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/_index.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/_index.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/api-reference.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/authentication.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/configuration.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/examples.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/getting-started.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/testing.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/hugo.toml +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/index.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/example_advanced_server.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/README.md +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/__init__.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/advanced_server.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/auth_server.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/basic_server.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/graphql_api_server.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/__init__.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/error.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/graphiql/index.html +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/introspection.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/SOURCES.txt +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/dependency_links.txt +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/requires.txt +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/top_level.txt +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/pyproject.toml +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/setup.cfg +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/test_server.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/__init__.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/app.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/app_federation.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/conftest.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_auth.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_cors.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_examples.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_federation.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_graphql_api.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_introspection.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_linting.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_server.py +0 -0
- {graphql_http-2.3.2 → graphql_http-2.3.3}/uv.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.3.3
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from collections import namedtuple
|
|
3
3
|
from collections.abc import MutableMapping
|
|
4
|
+
from functools import lru_cache
|
|
4
5
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
|
|
5
6
|
|
|
6
7
|
from graphql import (
|
|
@@ -13,6 +14,7 @@ from graphql import (
|
|
|
13
14
|
validate,
|
|
14
15
|
)
|
|
15
16
|
from graphql.execution import ExecutionResult
|
|
17
|
+
from graphql.language import DocumentNode
|
|
16
18
|
from graphql.pyutils.awaitable_or_value import AwaitableOrValue
|
|
17
19
|
|
|
18
20
|
from .error import HttpQueryError
|
|
@@ -182,6 +184,20 @@ def format_execution_result(
|
|
|
182
184
|
return GraphQLResponse(response, status_code)
|
|
183
185
|
|
|
184
186
|
|
|
187
|
+
@lru_cache(maxsize=512)
|
|
188
|
+
def _parse_and_validate(
|
|
189
|
+
schema: GraphQLSchema, query: str
|
|
190
|
+
) -> Tuple[DocumentNode, Tuple[GraphQLError, ...]]:
|
|
191
|
+
"""Parse and validate a query, cached per (schema, query string).
|
|
192
|
+
|
|
193
|
+
Both depend only on the schema (fixed per server) and the query text, so
|
|
194
|
+
repeated queries skip the parse and validation passes entirely. Raised
|
|
195
|
+
parse errors are not cached by lru_cache, which is what we want.
|
|
196
|
+
"""
|
|
197
|
+
document = parse(query)
|
|
198
|
+
return document, tuple(validate(schema, document))
|
|
199
|
+
|
|
200
|
+
|
|
185
201
|
def execute_graphql_request(
|
|
186
202
|
schema: GraphQLSchema,
|
|
187
203
|
params: GraphQLParams,
|
|
@@ -193,7 +209,7 @@ def execute_graphql_request(
|
|
|
193
209
|
raise HttpQueryError(400, "Must provide query string.")
|
|
194
210
|
|
|
195
211
|
try:
|
|
196
|
-
document =
|
|
212
|
+
document, validation_errors = _parse_and_validate(schema, params.query)
|
|
197
213
|
except GraphQLError as e:
|
|
198
214
|
return ExecutionResult(data=None, errors=[e])
|
|
199
215
|
except Exception as e:
|
|
@@ -232,9 +248,8 @@ def execute_graphql_request(
|
|
|
232
248
|
# Note: the schema is not validated here for performance reasons.
|
|
233
249
|
# This should be done only once when starting the server.
|
|
234
250
|
|
|
235
|
-
validation_errors = validate(schema, document)
|
|
236
251
|
if validation_errors:
|
|
237
|
-
return ExecutionResult(data=None, errors=validation_errors)
|
|
252
|
+
return ExecutionResult(data=None, errors=list(validation_errors))
|
|
238
253
|
|
|
239
254
|
return execute(
|
|
240
255
|
schema,
|
|
@@ -10,6 +10,7 @@ import uvicorn
|
|
|
10
10
|
|
|
11
11
|
from graphql import GraphQLError, ExecutionResult
|
|
12
12
|
from graphql.execution.execute import ExecutionContext
|
|
13
|
+
from graphql.execution.middleware import MiddlewareManager
|
|
13
14
|
from graphql.type.schema import GraphQLSchema
|
|
14
15
|
from jwt import InvalidTokenError, PyJWKClient
|
|
15
16
|
from starlette.applications import Starlette
|
|
@@ -136,6 +137,12 @@ class GraphQLHTTP:
|
|
|
136
137
|
self.schema = schema
|
|
137
138
|
self.root_value = root_value
|
|
138
139
|
self.middleware = middleware
|
|
140
|
+
# Build the middleware chain once: graphql-core constructs a fresh
|
|
141
|
+
# MiddlewareManager per execution when handed a raw list, discarding
|
|
142
|
+
# its per-resolver wrapped-chain cache on every request.
|
|
143
|
+
self._middleware_manager = (
|
|
144
|
+
MiddlewareManager(*middleware) if middleware else None
|
|
145
|
+
)
|
|
139
146
|
self.context_value = context_value
|
|
140
147
|
self.serve_graphiql = serve_graphiql
|
|
141
148
|
self.graphiql_example_query = self._resolve_graphiql_example_query(
|
|
@@ -369,10 +376,6 @@ class GraphQLHTTP:
|
|
|
369
376
|
html_content = f.read()
|
|
370
377
|
html_content = html_content.replace("DEFAULT_QUERY", default_query)
|
|
371
378
|
|
|
372
|
-
# Inject Gemini API key from environment if set
|
|
373
|
-
gemini_api_key = os.environ.get("GRAPHIQL_GEMINI_API_KEY", "")
|
|
374
|
-
html_content = html_content.replace("__GEMINI_API_KEY__", gemini_api_key)
|
|
375
|
-
|
|
376
379
|
return HTMLResponse(html_content)
|
|
377
380
|
|
|
378
381
|
def _handle_options(self, request: Request) -> Optional[Response]:
|
|
@@ -539,7 +542,7 @@ class GraphQLHTTP:
|
|
|
539
542
|
allow_only_introspection=allow_only_introspection,
|
|
540
543
|
query_data=query_data,
|
|
541
544
|
root_value=self.root_value,
|
|
542
|
-
middleware=self.
|
|
545
|
+
middleware=self._middleware_manager,
|
|
543
546
|
context_value=context_value,
|
|
544
547
|
execution_context_class=self.execution_context_class,
|
|
545
548
|
)
|
graphql_http-2.3.2/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.3.2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|