schemathesis 3.15.4__py3-none-any.whl → 4.4.2__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.
Files changed (251) hide show
  1. schemathesis/__init__.py +53 -25
  2. schemathesis/auths.py +507 -0
  3. schemathesis/checks.py +190 -25
  4. schemathesis/cli/__init__.py +27 -1219
  5. schemathesis/cli/__main__.py +4 -0
  6. schemathesis/cli/commands/__init__.py +133 -0
  7. schemathesis/cli/commands/data.py +10 -0
  8. schemathesis/cli/commands/run/__init__.py +602 -0
  9. schemathesis/cli/commands/run/context.py +228 -0
  10. schemathesis/cli/commands/run/events.py +60 -0
  11. schemathesis/cli/commands/run/executor.py +157 -0
  12. schemathesis/cli/commands/run/filters.py +53 -0
  13. schemathesis/cli/commands/run/handlers/__init__.py +46 -0
  14. schemathesis/cli/commands/run/handlers/base.py +45 -0
  15. schemathesis/cli/commands/run/handlers/cassettes.py +464 -0
  16. schemathesis/cli/commands/run/handlers/junitxml.py +60 -0
  17. schemathesis/cli/commands/run/handlers/output.py +1750 -0
  18. schemathesis/cli/commands/run/loaders.py +118 -0
  19. schemathesis/cli/commands/run/validation.py +256 -0
  20. schemathesis/cli/constants.py +5 -0
  21. schemathesis/cli/core.py +19 -0
  22. schemathesis/cli/ext/fs.py +16 -0
  23. schemathesis/cli/ext/groups.py +203 -0
  24. schemathesis/cli/ext/options.py +81 -0
  25. schemathesis/config/__init__.py +202 -0
  26. schemathesis/config/_auth.py +51 -0
  27. schemathesis/config/_checks.py +268 -0
  28. schemathesis/config/_diff_base.py +101 -0
  29. schemathesis/config/_env.py +21 -0
  30. schemathesis/config/_error.py +163 -0
  31. schemathesis/config/_generation.py +157 -0
  32. schemathesis/config/_health_check.py +24 -0
  33. schemathesis/config/_operations.py +335 -0
  34. schemathesis/config/_output.py +171 -0
  35. schemathesis/config/_parameters.py +19 -0
  36. schemathesis/config/_phases.py +253 -0
  37. schemathesis/config/_projects.py +543 -0
  38. schemathesis/config/_rate_limit.py +17 -0
  39. schemathesis/config/_report.py +120 -0
  40. schemathesis/config/_validator.py +9 -0
  41. schemathesis/config/_warnings.py +89 -0
  42. schemathesis/config/schema.json +975 -0
  43. schemathesis/core/__init__.py +72 -0
  44. schemathesis/core/adapter.py +34 -0
  45. schemathesis/core/compat.py +32 -0
  46. schemathesis/core/control.py +2 -0
  47. schemathesis/core/curl.py +100 -0
  48. schemathesis/core/deserialization.py +210 -0
  49. schemathesis/core/errors.py +588 -0
  50. schemathesis/core/failures.py +316 -0
  51. schemathesis/core/fs.py +19 -0
  52. schemathesis/core/hooks.py +20 -0
  53. schemathesis/core/jsonschema/__init__.py +13 -0
  54. schemathesis/core/jsonschema/bundler.py +183 -0
  55. schemathesis/core/jsonschema/keywords.py +40 -0
  56. schemathesis/core/jsonschema/references.py +222 -0
  57. schemathesis/core/jsonschema/types.py +41 -0
  58. schemathesis/core/lazy_import.py +15 -0
  59. schemathesis/core/loaders.py +107 -0
  60. schemathesis/core/marks.py +66 -0
  61. schemathesis/core/media_types.py +79 -0
  62. schemathesis/core/output/__init__.py +46 -0
  63. schemathesis/core/output/sanitization.py +54 -0
  64. schemathesis/core/parameters.py +45 -0
  65. schemathesis/core/rate_limit.py +60 -0
  66. schemathesis/core/registries.py +34 -0
  67. schemathesis/core/result.py +27 -0
  68. schemathesis/core/schema_analysis.py +17 -0
  69. schemathesis/core/shell.py +203 -0
  70. schemathesis/core/transforms.py +144 -0
  71. schemathesis/core/transport.py +223 -0
  72. schemathesis/core/validation.py +73 -0
  73. schemathesis/core/version.py +7 -0
  74. schemathesis/engine/__init__.py +28 -0
  75. schemathesis/engine/context.py +152 -0
  76. schemathesis/engine/control.py +44 -0
  77. schemathesis/engine/core.py +201 -0
  78. schemathesis/engine/errors.py +446 -0
  79. schemathesis/engine/events.py +284 -0
  80. schemathesis/engine/observations.py +42 -0
  81. schemathesis/engine/phases/__init__.py +108 -0
  82. schemathesis/engine/phases/analysis.py +28 -0
  83. schemathesis/engine/phases/probes.py +172 -0
  84. schemathesis/engine/phases/stateful/__init__.py +68 -0
  85. schemathesis/engine/phases/stateful/_executor.py +364 -0
  86. schemathesis/engine/phases/stateful/context.py +85 -0
  87. schemathesis/engine/phases/unit/__init__.py +220 -0
  88. schemathesis/engine/phases/unit/_executor.py +459 -0
  89. schemathesis/engine/phases/unit/_pool.py +82 -0
  90. schemathesis/engine/recorder.py +254 -0
  91. schemathesis/errors.py +47 -0
  92. schemathesis/filters.py +395 -0
  93. schemathesis/generation/__init__.py +25 -0
  94. schemathesis/generation/case.py +478 -0
  95. schemathesis/generation/coverage.py +1528 -0
  96. schemathesis/generation/hypothesis/__init__.py +121 -0
  97. schemathesis/generation/hypothesis/builder.py +992 -0
  98. schemathesis/generation/hypothesis/examples.py +56 -0
  99. schemathesis/generation/hypothesis/given.py +66 -0
  100. schemathesis/generation/hypothesis/reporting.py +285 -0
  101. schemathesis/generation/meta.py +227 -0
  102. schemathesis/generation/metrics.py +93 -0
  103. schemathesis/generation/modes.py +20 -0
  104. schemathesis/generation/overrides.py +127 -0
  105. schemathesis/generation/stateful/__init__.py +37 -0
  106. schemathesis/generation/stateful/state_machine.py +294 -0
  107. schemathesis/graphql/__init__.py +15 -0
  108. schemathesis/graphql/checks.py +109 -0
  109. schemathesis/graphql/loaders.py +285 -0
  110. schemathesis/hooks.py +270 -91
  111. schemathesis/openapi/__init__.py +13 -0
  112. schemathesis/openapi/checks.py +467 -0
  113. schemathesis/openapi/generation/__init__.py +0 -0
  114. schemathesis/openapi/generation/filters.py +72 -0
  115. schemathesis/openapi/loaders.py +315 -0
  116. schemathesis/pytest/__init__.py +5 -0
  117. schemathesis/pytest/control_flow.py +7 -0
  118. schemathesis/pytest/lazy.py +341 -0
  119. schemathesis/pytest/loaders.py +36 -0
  120. schemathesis/pytest/plugin.py +357 -0
  121. schemathesis/python/__init__.py +0 -0
  122. schemathesis/python/asgi.py +12 -0
  123. schemathesis/python/wsgi.py +12 -0
  124. schemathesis/schemas.py +682 -257
  125. schemathesis/specs/graphql/__init__.py +0 -1
  126. schemathesis/specs/graphql/nodes.py +26 -2
  127. schemathesis/specs/graphql/scalars.py +77 -12
  128. schemathesis/specs/graphql/schemas.py +367 -148
  129. schemathesis/specs/graphql/validation.py +33 -0
  130. schemathesis/specs/openapi/__init__.py +9 -1
  131. schemathesis/specs/openapi/_hypothesis.py +555 -318
  132. schemathesis/specs/openapi/adapter/__init__.py +10 -0
  133. schemathesis/specs/openapi/adapter/parameters.py +729 -0
  134. schemathesis/specs/openapi/adapter/protocol.py +59 -0
  135. schemathesis/specs/openapi/adapter/references.py +19 -0
  136. schemathesis/specs/openapi/adapter/responses.py +368 -0
  137. schemathesis/specs/openapi/adapter/security.py +144 -0
  138. schemathesis/specs/openapi/adapter/v2.py +30 -0
  139. schemathesis/specs/openapi/adapter/v3_0.py +30 -0
  140. schemathesis/specs/openapi/adapter/v3_1.py +30 -0
  141. schemathesis/specs/openapi/analysis.py +96 -0
  142. schemathesis/specs/openapi/checks.py +748 -82
  143. schemathesis/specs/openapi/converter.py +176 -37
  144. schemathesis/specs/openapi/definitions.py +599 -4
  145. schemathesis/specs/openapi/examples.py +581 -165
  146. schemathesis/specs/openapi/expressions/__init__.py +52 -5
  147. schemathesis/specs/openapi/expressions/extractors.py +25 -0
  148. schemathesis/specs/openapi/expressions/lexer.py +34 -31
  149. schemathesis/specs/openapi/expressions/nodes.py +97 -46
  150. schemathesis/specs/openapi/expressions/parser.py +35 -13
  151. schemathesis/specs/openapi/formats.py +122 -0
  152. schemathesis/specs/openapi/media_types.py +75 -0
  153. schemathesis/specs/openapi/negative/__init__.py +93 -73
  154. schemathesis/specs/openapi/negative/mutations.py +294 -103
  155. schemathesis/specs/openapi/negative/utils.py +0 -9
  156. schemathesis/specs/openapi/patterns.py +458 -0
  157. schemathesis/specs/openapi/references.py +60 -81
  158. schemathesis/specs/openapi/schemas.py +647 -666
  159. schemathesis/specs/openapi/serialization.py +53 -30
  160. schemathesis/specs/openapi/stateful/__init__.py +403 -68
  161. schemathesis/specs/openapi/stateful/control.py +87 -0
  162. schemathesis/specs/openapi/stateful/dependencies/__init__.py +232 -0
  163. schemathesis/specs/openapi/stateful/dependencies/inputs.py +428 -0
  164. schemathesis/specs/openapi/stateful/dependencies/models.py +341 -0
  165. schemathesis/specs/openapi/stateful/dependencies/naming.py +491 -0
  166. schemathesis/specs/openapi/stateful/dependencies/outputs.py +34 -0
  167. schemathesis/specs/openapi/stateful/dependencies/resources.py +339 -0
  168. schemathesis/specs/openapi/stateful/dependencies/schemas.py +447 -0
  169. schemathesis/specs/openapi/stateful/inference.py +254 -0
  170. schemathesis/specs/openapi/stateful/links.py +219 -78
  171. schemathesis/specs/openapi/types/__init__.py +3 -0
  172. schemathesis/specs/openapi/types/common.py +23 -0
  173. schemathesis/specs/openapi/types/v2.py +129 -0
  174. schemathesis/specs/openapi/types/v3.py +134 -0
  175. schemathesis/specs/openapi/utils.py +7 -6
  176. schemathesis/specs/openapi/warnings.py +75 -0
  177. schemathesis/transport/__init__.py +224 -0
  178. schemathesis/transport/asgi.py +26 -0
  179. schemathesis/transport/prepare.py +126 -0
  180. schemathesis/transport/requests.py +278 -0
  181. schemathesis/transport/serialization.py +329 -0
  182. schemathesis/transport/wsgi.py +175 -0
  183. schemathesis-4.4.2.dist-info/METADATA +213 -0
  184. schemathesis-4.4.2.dist-info/RECORD +192 -0
  185. {schemathesis-3.15.4.dist-info → schemathesis-4.4.2.dist-info}/WHEEL +1 -1
  186. schemathesis-4.4.2.dist-info/entry_points.txt +6 -0
  187. {schemathesis-3.15.4.dist-info → schemathesis-4.4.2.dist-info/licenses}/LICENSE +1 -1
  188. schemathesis/_compat.py +0 -57
  189. schemathesis/_hypothesis.py +0 -123
  190. schemathesis/auth.py +0 -214
  191. schemathesis/cli/callbacks.py +0 -240
  192. schemathesis/cli/cassettes.py +0 -351
  193. schemathesis/cli/context.py +0 -38
  194. schemathesis/cli/debug.py +0 -21
  195. schemathesis/cli/handlers.py +0 -11
  196. schemathesis/cli/junitxml.py +0 -41
  197. schemathesis/cli/options.py +0 -70
  198. schemathesis/cli/output/__init__.py +0 -1
  199. schemathesis/cli/output/default.py +0 -521
  200. schemathesis/cli/output/short.py +0 -40
  201. schemathesis/constants.py +0 -88
  202. schemathesis/exceptions.py +0 -257
  203. schemathesis/extra/_aiohttp.py +0 -27
  204. schemathesis/extra/_flask.py +0 -10
  205. schemathesis/extra/_server.py +0 -16
  206. schemathesis/extra/pytest_plugin.py +0 -251
  207. schemathesis/failures.py +0 -145
  208. schemathesis/fixups/__init__.py +0 -29
  209. schemathesis/fixups/fast_api.py +0 -30
  210. schemathesis/graphql.py +0 -5
  211. schemathesis/internal.py +0 -6
  212. schemathesis/lazy.py +0 -301
  213. schemathesis/models.py +0 -1113
  214. schemathesis/parameters.py +0 -91
  215. schemathesis/runner/__init__.py +0 -470
  216. schemathesis/runner/events.py +0 -242
  217. schemathesis/runner/impl/__init__.py +0 -3
  218. schemathesis/runner/impl/core.py +0 -791
  219. schemathesis/runner/impl/solo.py +0 -85
  220. schemathesis/runner/impl/threadpool.py +0 -367
  221. schemathesis/runner/serialization.py +0 -206
  222. schemathesis/serializers.py +0 -253
  223. schemathesis/service/__init__.py +0 -18
  224. schemathesis/service/auth.py +0 -10
  225. schemathesis/service/client.py +0 -62
  226. schemathesis/service/constants.py +0 -25
  227. schemathesis/service/events.py +0 -39
  228. schemathesis/service/handler.py +0 -46
  229. schemathesis/service/hosts.py +0 -74
  230. schemathesis/service/metadata.py +0 -42
  231. schemathesis/service/models.py +0 -21
  232. schemathesis/service/serialization.py +0 -184
  233. schemathesis/service/worker.py +0 -39
  234. schemathesis/specs/graphql/loaders.py +0 -215
  235. schemathesis/specs/openapi/constants.py +0 -7
  236. schemathesis/specs/openapi/expressions/context.py +0 -12
  237. schemathesis/specs/openapi/expressions/pointers.py +0 -29
  238. schemathesis/specs/openapi/filters.py +0 -44
  239. schemathesis/specs/openapi/links.py +0 -303
  240. schemathesis/specs/openapi/loaders.py +0 -453
  241. schemathesis/specs/openapi/parameters.py +0 -430
  242. schemathesis/specs/openapi/security.py +0 -129
  243. schemathesis/specs/openapi/validation.py +0 -24
  244. schemathesis/stateful.py +0 -358
  245. schemathesis/targets.py +0 -32
  246. schemathesis/types.py +0 -38
  247. schemathesis/utils.py +0 -475
  248. schemathesis-3.15.4.dist-info/METADATA +0 -202
  249. schemathesis-3.15.4.dist-info/RECORD +0 -99
  250. schemathesis-3.15.4.dist-info/entry_points.txt +0 -7
  251. /schemathesis/{extra → cli/ext}/__init__.py +0 -0
@@ -0,0 +1,285 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from functools import lru_cache
5
+ from os import PathLike
6
+ from pathlib import Path
7
+ from typing import IO, TYPE_CHECKING, Any, Callable, Dict, NoReturn, TypeVar, cast
8
+
9
+ from schemathesis.config import SchemathesisConfig
10
+ from schemathesis.core.errors import LoaderError, LoaderErrorKind
11
+ from schemathesis.core.loaders import load_from_url, prepare_request_kwargs, raise_for_status, require_relative_url
12
+ from schemathesis.hooks import HookContext, dispatch
13
+ from schemathesis.python import asgi, wsgi
14
+
15
+ if TYPE_CHECKING:
16
+ from graphql import DocumentNode
17
+
18
+ from schemathesis.specs.graphql.schemas import GraphQLSchema
19
+
20
+
21
+ def from_asgi(path: str, app: Any, *, config: SchemathesisConfig | None = None, **kwargs: Any) -> GraphQLSchema:
22
+ """Load GraphQL schema from an ASGI application via introspection.
23
+
24
+ Args:
25
+ path: Relative URL path to the GraphQL endpoint (e.g., "/graphql")
26
+ app: ASGI application instance
27
+ config: Custom configuration. If `None`, uses auto-discovered config
28
+ **kwargs: Additional request parameters passed to the ASGI test client.
29
+
30
+ Example:
31
+ ```python
32
+ from fastapi import FastAPI
33
+ import schemathesis
34
+
35
+ app = FastAPI()
36
+ schema = schemathesis.graphql.from_asgi("/graphql", app)
37
+ ```
38
+
39
+ """
40
+ require_relative_url(path)
41
+ kwargs.setdefault("json", {"query": get_introspection_query()})
42
+ client = asgi.get_client(app)
43
+ response = load_from_url(client.post, url=path, **kwargs)
44
+ schema = extract_schema_from_response(response, lambda r: r.json())
45
+ loaded = from_dict(schema=schema, config=config)
46
+ loaded.app = app
47
+ loaded.location = path
48
+ return loaded
49
+
50
+
51
+ def from_wsgi(path: str, app: Any, *, config: SchemathesisConfig | None = None, **kwargs: Any) -> GraphQLSchema:
52
+ """Load GraphQL schema from a WSGI application via introspection.
53
+
54
+ Args:
55
+ path: Relative URL path to the GraphQL endpoint (e.g., "/graphql")
56
+ app: WSGI application instance
57
+ config: Custom configuration. If `None`, uses auto-discovered config
58
+ **kwargs: Additional request parameters passed to the WSGI test client.
59
+
60
+ Example:
61
+ ```python
62
+ from flask import Flask
63
+ import schemathesis
64
+
65
+ app = Flask(__name__)
66
+ schema = schemathesis.graphql.from_wsgi("/graphql", app)
67
+ ```
68
+
69
+ """
70
+ require_relative_url(path)
71
+ prepare_request_kwargs(kwargs)
72
+ kwargs.setdefault("json", {"query": get_introspection_query()})
73
+ client = wsgi.get_client(app)
74
+ response = client.post(path=path, **kwargs)
75
+ raise_for_status(response)
76
+ schema = extract_schema_from_response(response, lambda r: r.json)
77
+ loaded = from_dict(schema=schema, config=config)
78
+ loaded.app = app
79
+ loaded.location = path
80
+ return loaded
81
+
82
+
83
+ def from_url(
84
+ url: str, *, config: SchemathesisConfig | None = None, wait_for_schema: float | None = None, **kwargs: Any
85
+ ) -> GraphQLSchema:
86
+ """Load GraphQL schema from a URL via introspection query.
87
+
88
+ Args:
89
+ url: Full URL to the GraphQL endpoint
90
+ config: Custom configuration. If `None`, uses auto-discovered config
91
+ wait_for_schema: Maximum time in seconds to wait for schema availability
92
+ **kwargs: Additional parameters passed to `requests.post()` (headers, timeout, auth, etc.).
93
+
94
+ Example:
95
+ ```python
96
+ import schemathesis
97
+
98
+ # Basic usage
99
+ schema = schemathesis.graphql.from_url("https://api.example.com/graphql")
100
+
101
+ # With authentication and timeout
102
+ schema = schemathesis.graphql.from_url(
103
+ "https://api.example.com/graphql",
104
+ headers={"Authorization": "Bearer token"},
105
+ timeout=30,
106
+ wait_for_schema=10.0
107
+ )
108
+ ```
109
+
110
+ """
111
+ import requests
112
+
113
+ kwargs.setdefault("json", {"query": get_introspection_query()})
114
+ response = load_from_url(requests.post, url=url, wait_for_schema=wait_for_schema, **kwargs)
115
+ schema = extract_schema_from_response(response, lambda r: r.json())
116
+ loaded = from_dict(schema, config=config)
117
+ loaded.location = url
118
+ return loaded
119
+
120
+
121
+ def from_path(
122
+ path: PathLike | str, *, config: SchemathesisConfig | None = None, encoding: str = "utf-8"
123
+ ) -> GraphQLSchema:
124
+ """Load GraphQL schema from a filesystem path.
125
+
126
+ Args:
127
+ path: File path to the GraphQL schema file (.graphql, .gql)
128
+ config: Custom configuration. If `None`, uses auto-discovered config
129
+ encoding: Text encoding for reading the file
130
+
131
+ Example:
132
+ ```python
133
+ import schemathesis
134
+
135
+ # Load from GraphQL SDL file
136
+ schema = schemathesis.graphql.from_path("./schema.graphql")
137
+ ```
138
+
139
+ """
140
+ with open(path, encoding=encoding) as file:
141
+ loaded = from_file(file=file, config=config)
142
+ loaded.location = Path(path).absolute().as_uri()
143
+ return loaded
144
+
145
+
146
+ def from_file(file: IO[str] | str, *, config: SchemathesisConfig | None = None) -> GraphQLSchema:
147
+ """Load GraphQL schema from a file-like object or string.
148
+
149
+ Args:
150
+ file: File-like object or raw string containing GraphQL SDL
151
+ config: Custom configuration. If `None`, uses auto-discovered config
152
+
153
+ Example:
154
+ ```python
155
+ import schemathesis
156
+
157
+ # From GraphQL SDL string
158
+ schema_sdl = '''
159
+ type Query {
160
+ user(id: ID!): User
161
+ }
162
+ type User {
163
+ id: ID!
164
+ name: String!
165
+ }
166
+ '''
167
+ schema = schemathesis.graphql.from_file(schema_sdl)
168
+
169
+ # From file object
170
+ with open("schema.graphql") as f:
171
+ schema = schemathesis.graphql.from_file(f)
172
+ ```
173
+
174
+ """
175
+ import graphql
176
+
177
+ if isinstance(file, str):
178
+ data = file
179
+ else:
180
+ data = file.read()
181
+ try:
182
+ document = graphql.build_schema(data)
183
+ result = graphql.execute(document, get_introspection_query_ast())
184
+ # TYPES: We don't pass `is_awaitable` above, therefore `result` is of the `ExecutionResult` type
185
+ result = cast(graphql.ExecutionResult, result)
186
+ # TYPES:
187
+ # - `document` is a valid schema, because otherwise `build_schema` will rise an error;
188
+ # - `INTROSPECTION_QUERY` is a valid query - it is known upfront;
189
+ # Therefore the execution result is always valid at this point and `result.data` is not `None`
190
+ schema = cast(Dict[str, Any], result.data)
191
+ except Exception as exc:
192
+ try:
193
+ schema = json.loads(data)
194
+ if not isinstance(schema, dict) or "__schema" not in schema:
195
+ _on_invalid_schema(exc)
196
+ except json.JSONDecodeError:
197
+ _on_invalid_schema(exc, extras=[entry for entry in str(exc).splitlines() if entry])
198
+ return from_dict(schema, config=config)
199
+
200
+
201
+ def from_dict(schema: dict[str, Any], *, config: SchemathesisConfig | None = None) -> GraphQLSchema:
202
+ """Load GraphQL schema from a dictionary containing introspection result.
203
+
204
+ Args:
205
+ schema: Dictionary containing GraphQL introspection result or wrapped in 'data' key
206
+ config: Custom configuration. If `None`, uses auto-discovered config
207
+
208
+ Example:
209
+ ```python
210
+ import schemathesis
211
+
212
+ # From introspection result
213
+ introspection = {
214
+ "__schema": {
215
+ "types": [...],
216
+ "queryType": {"name": "Query"},
217
+ # ... rest of introspection result
218
+ }
219
+ }
220
+ schema = schemathesis.graphql.from_dict(introspection)
221
+
222
+ # From GraphQL response format (with 'data' wrapper)
223
+ response_data = {
224
+ "data": {
225
+ "__schema": {
226
+ "types": [...],
227
+ "queryType": {"name": "Query"}
228
+ }
229
+ }
230
+ }
231
+ schema = schemathesis.graphql.from_dict(response_data)
232
+ ```
233
+
234
+ """
235
+ from schemathesis.specs.graphql.schemas import GraphQLSchema
236
+
237
+ if "data" in schema:
238
+ schema = schema["data"]
239
+ hook_context = HookContext()
240
+ dispatch("before_load_schema", hook_context, schema)
241
+
242
+ if config is None:
243
+ config = SchemathesisConfig.discover()
244
+ project_config = config.projects.get(schema)
245
+ instance = GraphQLSchema(schema, config=project_config)
246
+ instance.filter_set = project_config.operations.filter_set_with(include=instance.filter_set)
247
+ dispatch("after_load_schema", hook_context, instance)
248
+ return instance
249
+
250
+
251
+ @lru_cache
252
+ def get_introspection_query() -> str:
253
+ import graphql
254
+
255
+ return graphql.get_introspection_query()
256
+
257
+
258
+ @lru_cache
259
+ def get_introspection_query_ast() -> DocumentNode:
260
+ import graphql
261
+
262
+ query = get_introspection_query()
263
+ return graphql.parse(query)
264
+
265
+
266
+ R = TypeVar("R")
267
+
268
+
269
+ def extract_schema_from_response(response: R, callback: Callable[[R], Any]) -> dict[str, Any]:
270
+ try:
271
+ decoded = callback(response)
272
+ except json.JSONDecodeError as exc:
273
+ raise LoaderError(
274
+ LoaderErrorKind.UNEXPECTED_CONTENT_TYPE,
275
+ "Received unsupported content while expecting a JSON payload for GraphQL",
276
+ ) from exc
277
+ return decoded
278
+
279
+
280
+ def _on_invalid_schema(exc: Exception, extras: list[str] | None = None) -> NoReturn:
281
+ raise LoaderError(
282
+ LoaderErrorKind.GRAPHQL_INVALID_SCHEMA,
283
+ "The provided API schema does not appear to be a valid GraphQL schema",
284
+ extras=extras or [],
285
+ ) from exc