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.
- graphql_http-2.3.3/AGENTS.md +47 -0
- graphql_http-2.3.3/CLAUDE.md +47 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/PKG-INFO +1 -1
- graphql_http-2.3.3/VERSION +1 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/graphiql/index.html +1 -1
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/helpers.py +18 -3
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/server.py +8 -5
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/PKG-INFO +1 -1
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/SOURCES.txt +2 -0
- graphql_http-2.3.1/VERSION +0 -1
- {graphql_http-2.3.1 → graphql_http-2.3.3}/.coverage +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/.github/workflows/pages.yml +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/.github/workflows/python-package.yml +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/.gitignore +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/.gitmodules +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/LICENSE +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/README.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/.gitmodules +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/_index.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/_index.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/api-reference.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/authentication.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/configuration.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/examples.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/getting-started.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/content/docs/testing.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/hugo.toml +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/docs/index.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/example_advanced_server.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/README.md +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/__init__.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/advanced_server.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/auth_server.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/basic_server.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/examples/graphql_api_server.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/__init__.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/error.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http/introspection.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/dependency_links.txt +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/requires.txt +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/graphql_http.egg-info/top_level.txt +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/pyproject.toml +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/setup.cfg +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/test_server.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/__init__.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/app.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/app_federation.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/conftest.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_auth.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_cors.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_examples.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_federation.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_graphql_api.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_introspection.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_linting.py +0 -0
- {graphql_http-2.3.1 → graphql_http-2.3.3}/tests/test_server.py +0 -0
- {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.
|
|
@@ -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: {
|
|
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 =
|
|
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.1/VERSION
DELETED
|
@@ -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
|
|
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
|