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.
Files changed (57) hide show
  1. {graphql_http-2.3.2 → graphql_http-2.3.3}/PKG-INFO +1 -1
  2. graphql_http-2.3.3/VERSION +1 -0
  3. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/helpers.py +18 -3
  4. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/server.py +8 -5
  5. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/PKG-INFO +1 -1
  6. graphql_http-2.3.2/VERSION +0 -1
  7. {graphql_http-2.3.2 → graphql_http-2.3.3}/.coverage +0 -0
  8. {graphql_http-2.3.2 → graphql_http-2.3.3}/.github/workflows/pages.yml +0 -0
  9. {graphql_http-2.3.2 → graphql_http-2.3.3}/.github/workflows/python-package.yml +0 -0
  10. {graphql_http-2.3.2 → graphql_http-2.3.3}/.gitignore +0 -0
  11. {graphql_http-2.3.2 → graphql_http-2.3.3}/.gitmodules +0 -0
  12. {graphql_http-2.3.2 → graphql_http-2.3.3}/AGENTS.md +0 -0
  13. {graphql_http-2.3.2 → graphql_http-2.3.3}/CLAUDE.md +0 -0
  14. {graphql_http-2.3.2 → graphql_http-2.3.3}/LICENSE +0 -0
  15. {graphql_http-2.3.2 → graphql_http-2.3.3}/README.md +0 -0
  16. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/.gitmodules +0 -0
  17. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/_index.md +0 -0
  18. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/_index.md +0 -0
  19. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/api-reference.md +0 -0
  20. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/authentication.md +0 -0
  21. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/configuration.md +0 -0
  22. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/examples.md +0 -0
  23. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/getting-started.md +0 -0
  24. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/content/docs/testing.md +0 -0
  25. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/hugo.toml +0 -0
  26. {graphql_http-2.3.2 → graphql_http-2.3.3}/docs/index.md +0 -0
  27. {graphql_http-2.3.2 → graphql_http-2.3.3}/example_advanced_server.py +0 -0
  28. {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/README.md +0 -0
  29. {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/__init__.py +0 -0
  30. {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/advanced_server.py +0 -0
  31. {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/auth_server.py +0 -0
  32. {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/basic_server.py +0 -0
  33. {graphql_http-2.3.2 → graphql_http-2.3.3}/examples/graphql_api_server.py +0 -0
  34. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/__init__.py +0 -0
  35. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/error.py +0 -0
  36. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/graphiql/index.html +0 -0
  37. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http/introspection.py +0 -0
  38. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/SOURCES.txt +0 -0
  39. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/dependency_links.txt +0 -0
  40. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/requires.txt +0 -0
  41. {graphql_http-2.3.2 → graphql_http-2.3.3}/graphql_http.egg-info/top_level.txt +0 -0
  42. {graphql_http-2.3.2 → graphql_http-2.3.3}/pyproject.toml +0 -0
  43. {graphql_http-2.3.2 → graphql_http-2.3.3}/setup.cfg +0 -0
  44. {graphql_http-2.3.2 → graphql_http-2.3.3}/test_server.py +0 -0
  45. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/__init__.py +0 -0
  46. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/app.py +0 -0
  47. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/app_federation.py +0 -0
  48. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/conftest.py +0 -0
  49. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_auth.py +0 -0
  50. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_cors.py +0 -0
  51. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_examples.py +0 -0
  52. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_federation.py +0 -0
  53. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_graphql_api.py +0 -0
  54. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_introspection.py +0 -0
  55. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_linting.py +0 -0
  56. {graphql_http-2.3.2 → graphql_http-2.3.3}/tests/test_server.py +0 -0
  57. {graphql_http-2.3.2 → graphql_http-2.3.3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphql-http
3
- Version: 2.3.2
3
+ Version: 2.3.3
4
4
  Summary: HTTP Server for GraphQL.
5
5
  Author-email: Robert Parker <rob@parob.com>
6
6
  License: MIT
@@ -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 = parse(params.query)
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.middleware,
545
+ middleware=self._middleware_manager,
543
546
  context_value=context_value,
544
547
  execution_context_class=self.execution_context_class,
545
548
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphql-http
3
- Version: 2.3.2
3
+ Version: 2.3.3
4
4
  Summary: HTTP Server for GraphQL.
5
5
  Author-email: Robert Parker <rob@parob.com>
6
6
  License: MIT
@@ -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