graphql-http 2.3.1__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.3/AGENTS.md +47 -0
  2. graphql_http-2.3.3/CLAUDE.md +47 -0
  3. {graphql_http-2.3.1 → graphql_http-2.3.3}/PKG-INFO +1 -1
  4. graphql_http-2.3.3/VERSION +1 -0
  5. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/graphiql/index.html +1 -1
  6. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/helpers.py +18 -3
  7. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/server.py +8 -5
  8. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/PKG-INFO +1 -1
  9. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/SOURCES.txt +2 -0
  10. graphql_http-2.3.1/VERSION +0 -1
  11. {graphql_http-2.3.1 → graphql_http-2.3.3}/.coverage +0 -0
  12. {graphql_http-2.3.1 → graphql_http-2.3.3}/.github/workflows/pages.yml +0 -0
  13. {graphql_http-2.3.1 → graphql_http-2.3.3}/.github/workflows/python-package.yml +0 -0
  14. {graphql_http-2.3.1 → graphql_http-2.3.3}/.gitignore +0 -0
  15. {graphql_http-2.3.1 → graphql_http-2.3.3}/.gitmodules +0 -0
  16. {graphql_http-2.3.1 → graphql_http-2.3.3}/LICENSE +0 -0
  17. {graphql_http-2.3.1 → graphql_http-2.3.3}/README.md +0 -0
  18. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/.gitmodules +0 -0
  19. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/_index.md +0 -0
  20. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/_index.md +0 -0
  21. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/api-reference.md +0 -0
  22. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/authentication.md +0 -0
  23. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/configuration.md +0 -0
  24. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/examples.md +0 -0
  25. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/getting-started.md +0 -0
  26. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/testing.md +0 -0
  27. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/hugo.toml +0 -0
  28. {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/index.md +0 -0
  29. {graphql_http-2.3.1 → graphql_http-2.3.3}/example_advanced_server.py +0 -0
  30. {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/README.md +0 -0
  31. {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/__init__.py +0 -0
  32. {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/advanced_server.py +0 -0
  33. {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/auth_server.py +0 -0
  34. {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/basic_server.py +0 -0
  35. {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/graphql_api_server.py +0 -0
  36. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/__init__.py +0 -0
  37. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/error.py +0 -0
  38. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/introspection.py +0 -0
  39. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/dependency_links.txt +0 -0
  40. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/requires.txt +0 -0
  41. {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/top_level.txt +0 -0
  42. {graphql_http-2.3.1 → graphql_http-2.3.3}/pyproject.toml +0 -0
  43. {graphql_http-2.3.1 → graphql_http-2.3.3}/setup.cfg +0 -0
  44. {graphql_http-2.3.1 → graphql_http-2.3.3}/test_server.py +0 -0
  45. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/__init__.py +0 -0
  46. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/app.py +0 -0
  47. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/app_federation.py +0 -0
  48. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/conftest.py +0 -0
  49. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_auth.py +0 -0
  50. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_cors.py +0 -0
  51. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_examples.py +0 -0
  52. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_federation.py +0 -0
  53. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_graphql_api.py +0 -0
  54. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_introspection.py +0 -0
  55. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_linting.py +0 -0
  56. {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_server.py +0 -0
  57. {graphql_http-2.3.1 → graphql_http-2.3.3}/uv.lock +0 -0
@@ -0,0 +1,47 @@
1
+ # GraphQL-HTTP
2
+
3
+ > Compatibility note: `AGENTS.md` and `CLAUDE.md` are both supported in this repo.
4
+ > Keep these files identical. Any change in one must be mirrored in the other.
5
+
6
+ HTTP transport layer for serving GraphQL schemas over Starlette/ASGI. Published on [PyPI](https://pypi.org/project/graphql-http/).
7
+
8
+ ## Project Structure
9
+
10
+ | Directory | Description |
11
+ |-----------|-------------|
12
+ | `graphql_http/` | Main package source |
13
+ | `tests/` | Test suite (11 files, pytest) |
14
+ | `docs/` | Documentation |
15
+ | `examples/` | Example server implementations |
16
+
17
+ ## Development
18
+
19
+ ```bash
20
+ # Install dependencies
21
+ uv sync
22
+
23
+ # Run tests
24
+ uv run pytest
25
+
26
+ # Run linter
27
+ uv run flake8 graphql_http tests
28
+ ```
29
+
30
+ ## Key Patterns
31
+
32
+ - Primary entry: `GraphQLHTTP.from_api(api)` — auto-wires schema + context from a `graphql-api` instance
33
+ - Serves GraphiQL IDE, supports GET (queries only) and POST (queries + mutations)
34
+ - Built-in JWT auth via JWKS (`auth_enabled`, `auth_jwks_uri`, `auth_issuer`, `auth_audience`); introspection bypasses auth by default
35
+ - Context injection: resolvers access HTTP request via `self.context.meta["http_request"]`
36
+
37
+ ## Releasing
38
+
39
+ See the ecosystem-level `CLAUDE.md` in the parent workspace for the full release process. In short:
40
+
41
+ ```bash
42
+ # Ensure CI is green on main, then:
43
+ git tag X.Y.Z
44
+ git push origin X.Y.Z
45
+ ```
46
+
47
+ CI publishes to PyPI and creates a GitHub Release automatically.
@@ -0,0 +1,47 @@
1
+ # GraphQL-HTTP
2
+
3
+ > Compatibility note: `AGENTS.md` and `CLAUDE.md` are both supported in this repo.
4
+ > Keep these files identical. Any change in one must be mirrored in the other.
5
+
6
+ HTTP transport layer for serving GraphQL schemas over Starlette/ASGI. Published on [PyPI](https://pypi.org/project/graphql-http/).
7
+
8
+ ## Project Structure
9
+
10
+ | Directory | Description |
11
+ |-----------|-------------|
12
+ | `graphql_http/` | Main package source |
13
+ | `tests/` | Test suite (11 files, pytest) |
14
+ | `docs/` | Documentation |
15
+ | `examples/` | Example server implementations |
16
+
17
+ ## Development
18
+
19
+ ```bash
20
+ # Install dependencies
21
+ uv sync
22
+
23
+ # Run tests
24
+ uv run pytest
25
+
26
+ # Run linter
27
+ uv run flake8 graphql_http tests
28
+ ```
29
+
30
+ ## Key Patterns
31
+
32
+ - Primary entry: `GraphQLHTTP.from_api(api)` — auto-wires schema + context from a `graphql-api` instance
33
+ - Serves GraphiQL IDE, supports GET (queries only) and POST (queries + mutations)
34
+ - Built-in JWT auth via JWKS (`auth_enabled`, `auth_jwks_uri`, `auth_issuer`, `auth_audience`); introspection bypasses auth by default
35
+ - Context injection: resolvers access HTTP request via `self.context.meta["http_request"]`
36
+
37
+ ## Releasing
38
+
39
+ See the ecosystem-level `CLAUDE.md` in the parent workspace for the full release process. In short:
40
+
41
+ ```bash
42
+ # Ensure CI is green on main, then:
43
+ git tag X.Y.Z
44
+ git push origin X.Y.Z
45
+ ```
46
+
47
+ CI publishes to PyPI and creates a GitHub Release automatically.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphql-http
3
- Version: 2.3.1
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
@@ -4692,7 +4692,7 @@ ${jsonInstruction}`;
4692
4692
  const requestBody = {
4693
4693
  systemInstruction: { parts: [{ text: systemPrompt }] },
4694
4694
  contents: contents,
4695
- generationConfig: { responseMimeType: 'application/json' }
4695
+ generationConfig: {}
4696
4696
  };
4697
4697
 
4698
4698
  if (toolsEnabled) {
@@ -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.1
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,6 +1,8 @@
1
1
  .coverage
2
2
  .gitignore
3
3
  .gitmodules
4
+ AGENTS.md
5
+ CLAUDE.md
4
6
  LICENSE
5
7
  README.md
6
8
  VERSION
@@ -1 +0,0 @@
1
- 2.3.1
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