Python API
Reference for Schemathesis public Python API.
Schema Loaders
Open API
from_url(url, *, config=None, wait_for_schema=None, **kwargs)
Load OpenAPI schema from a URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Full URL to the OpenAPI schema |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
wait_for_schema
|
float | None
|
Maximum time in seconds to wait for schema availability |
None
|
**kwargs
|
Any
|
Additional parameters passed to |
{}
|
Example
import schemathesis
# Basic usage
schema = schemathesis.openapi.from_url("https://api.example.com/openapi.json")
# With authentication and timeout
schema = schemathesis.openapi.from_url(
"https://api.example.com/openapi.json",
headers={"Authorization": "Bearer token"},
timeout=30,
wait_for_schema=10.0
)
from_path(path, *, config=None, encoding='utf-8')
Load OpenAPI schema from a filesystem path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
PathLike | str
|
File path to the OpenAPI schema (supports JSON / YAML) |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
encoding
|
str
|
Text encoding for reading the file |
'utf-8'
|
Example
import schemathesis
# Load from file
schema = schemathesis.openapi.from_path("./specs/openapi.yaml")
# With custom encoding
schema = schemathesis.openapi.from_path("./specs/openapi.json", encoding="cp1252")
from_file(file, *, config=None)
Load OpenAPI schema from a file-like object or string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
IO[str] | str
|
File-like object or raw string containing the OpenAPI schema |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
Example
import schemathesis
# From string
schema_content = '{"openapi": "3.0.0", "info": {"title": "API"}}'
schema = schemathesis.openapi.from_file(schema_content)
# From file object
with open("openapi.yaml") as f:
schema = schemathesis.openapi.from_file(f)
from_asgi(path, app, *, config=None, **kwargs)
Load OpenAPI schema from an ASGI application.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Relative URL path to the OpenAPI schema endpoint (e.g., "/openapi.json") |
required |
app
|
Any
|
ASGI application instance |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
**kwargs
|
Any
|
Additional request parameters passed to the ASGI test client |
{}
|
Example
from fastapi import FastAPI
import schemathesis
app = FastAPI()
schema = schemathesis.openapi.from_asgi("/openapi.json", app)
from_wsgi(path, app, *, config=None, **kwargs)
Load OpenAPI schema from a WSGI application.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Relative URL path to the OpenAPI schema endpoint (e.g., "/openapi.json") |
required |
app
|
Any
|
WSGI application instance |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
**kwargs
|
Any
|
Additional request parameters passed to the WSGI test client |
{}
|
Example
from flask import Flask
import schemathesis
app = Flask(__name__)
schema = schemathesis.openapi.from_wsgi("/openapi.json", app)
from_dict(schema, *, config=None)
Load OpenAPI schema from a dictionary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema
|
dict[str, Any]
|
Dictionary containing the parsed OpenAPI schema |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
Example
import schemathesis
schema_dict = {
"openapi": "3.0.0",
"info": {"title": "My API", "version": "1.0.0"},
"paths": {"/users": {"get": {"responses": {"200": {"description": "OK"}}}}}
}
schema = schemathesis.openapi.from_dict(schema_dict)
GraphQL
from_url(url, *, config=None, wait_for_schema=None, **kwargs)
Load GraphQL schema from a URL via introspection query.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Full URL to the GraphQL endpoint |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
wait_for_schema
|
float | None
|
Maximum time in seconds to wait for schema availability |
None
|
**kwargs
|
Any
|
Additional parameters passed to |
{}
|
Example
import schemathesis
# Basic usage
schema = schemathesis.graphql.from_url("https://api.example.com/graphql")
# With authentication and timeout
schema = schemathesis.graphql.from_url(
"https://api.example.com/graphql",
headers={"Authorization": "Bearer token"},
timeout=30,
wait_for_schema=10.0
)
from_path(path, *, config=None, encoding='utf-8')
Load GraphQL schema from a filesystem path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
PathLike | str
|
File path to the GraphQL schema file (.graphql, .gql) |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
encoding
|
str
|
Text encoding for reading the file |
'utf-8'
|
Example
import schemathesis
# Load from GraphQL SDL file
schema = schemathesis.graphql.from_path("./schema.graphql")
from_file(file, *, config=None)
Load GraphQL schema from a file-like object or string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
IO[str] | str
|
File-like object or raw string containing GraphQL SDL |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
Example
import schemathesis
# From GraphQL SDL string
schema_sdl = '''
type Query {
user(id: ID!): User
}
type User {
id: ID!
name: String!
}
'''
schema = schemathesis.graphql.from_file(schema_sdl)
# From file object
with open("schema.graphql") as f:
schema = schemathesis.graphql.from_file(f)
from_asgi(path, app, *, config=None, **kwargs)
Load GraphQL schema from an ASGI application via introspection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Relative URL path to the GraphQL endpoint (e.g., "/graphql") |
required |
app
|
Any
|
ASGI application instance |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
**kwargs
|
Any
|
Additional request parameters passed to the ASGI test client. |
{}
|
Example
from fastapi import FastAPI
import schemathesis
app = FastAPI()
schema = schemathesis.graphql.from_asgi("/graphql", app)
from_wsgi(path, app, *, config=None, **kwargs)
Load GraphQL schema from a WSGI application via introspection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Relative URL path to the GraphQL endpoint (e.g., "/graphql") |
required |
app
|
Any
|
WSGI application instance |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
**kwargs
|
Any
|
Additional request parameters passed to the WSGI test client. |
{}
|
Example
from flask import Flask
import schemathesis
app = Flask(__name__)
schema = schemathesis.graphql.from_wsgi("/graphql", app)
from_dict(schema, *, config=None)
Load GraphQL schema from a dictionary containing introspection result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schema
|
dict[str, Any]
|
Dictionary containing GraphQL introspection result or wrapped in 'data' key |
required |
config
|
SchemathesisConfig | None
|
Custom configuration. If |
None
|
Example
import schemathesis
# From introspection result
introspection = {
"__schema": {
"types": [...],
"queryType": {"name": "Query"},
# ... rest of introspection result
}
}
schema = schemathesis.graphql.from_dict(introspection)
# From GraphQL response format (with 'data' wrapper)
response_data = {
"data": {
"__schema": {
"types": [...],
"queryType": {"name": "Query"}
}
}
}
schema = schemathesis.graphql.from_dict(response_data)
Pytest
from_fixture(name)
Create a lazy schema loader that resolves a pytest fixture at test runtime.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the pytest fixture that returns a schema object |
required |
Example
import pytest
import schemathesis
@pytest.fixture
def api_schema():
return schemathesis.openapi.from_url("https://api.example.com/openapi.json")
# Create lazy schema from fixture
schema = schemathesis.pytest.from_fixture("api_schema")
# Use with parametrize to generate tests
@schema.parametrize()
def test_api(case):
case.call_and_validate()
parametrize(**schemas)
Return a decorator that parametrizes a test function over multiple named schemas.
Example::
@schemathesis.pytest.parametrize(
users=schemathesis.openapi.from_wsgi("/openapi.json", users_app),
orders=schemathesis.openapi.from_wsgi("/openapi.json", orders_app),
)
def test_api(case):
case.call_and_validate()
Core Data Structures
Response
HTTP response wrapper that normalizes different transport implementations.
Provides a consistent interface for accessing response data whether the request was made via HTTP, ASGI, or WSGI transports.
body_size
property
Size of response body in bytes, or None if no content.
content = content
instance-attribute
Raw response body as bytes.
elapsed = elapsed
instance-attribute
Response time in seconds.
encoded_body
property
Base64-encoded response body for binary-safe serialization.
encoding = encoding
instance-attribute
Character encoding for text content, if detected.
headers = {(key.lower()): value for key, value in (headers.items())}
instance-attribute
Response headers with lowercase keys and list values.
http_version = http_version
instance-attribute
HTTP protocol version ("1.0" or "1.1").
message = message
instance-attribute
HTTP status message (e.g., "OK", "Not Found").
request = request
instance-attribute
The request that generated this response.
status_code = status_code
instance-attribute
HTTP status code (e.g., 200, 404, 500).
text
property
Decode response content as text using the detected or default encoding.
verify = verify
instance-attribute
Whether TLS verification was enabled for the request.
clear_cache()
Drop the parsed-JSON cache so it doesn't pin memory after checks finish.
json()
Parse response content as JSON.
Returns:
| Type | Description |
|---|---|
Any
|
Parsed JSON data (dict, list, or primitive types) |
Raises:
| Type | Description |
|---|---|
JSONDecodeError
|
If content is not valid JSON |
Case
dataclass
Generated test case data for a single API operation.
body
instance-attribute
Generated request body
cookies
instance-attribute
Generated cookies
formatted_path
property
Path template with variables substituted (e.g., /users/{user_id} -> /users/123).
headers
instance-attribute
Generated HTTP headers
id
instance-attribute
Random ID sent in headers for log correlation
media_type
instance-attribute
Media type from OpenAPI schema (e.g., "multipart/form-data")
meta
property
Get metadata, revalidating if components were modified.
method
instance-attribute
HTTP verb (GET, POST, etc.)
multipart_content_types
instance-attribute
Selected content types for multipart form properties (e.g., {"image": "image/png"})
path
instance-attribute
Path template from schema (e.g., /users/{user_id})
path_parameters
instance-attribute
Generated path variables (e.g., {"user_id": "123"})
query
instance-attribute
Generated query parameters
__setattr__(name, value)
Track modifications to containers for metadata revalidation.
as_curl_command(headers=None, verify=True)
Generate a curl command that reproduces this test case.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
headers
|
Mapping[str, Any] | None
|
Additional headers to include in the command. |
None
|
verify
|
bool
|
When False, adds |
True
|
call(base_url=None, session=None, headers=None, params=None, cookies=None, **kwargs)
Make an HTTP request using this test case's data without validation.
Use when you need to validate response separately
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str | None
|
Override the schema's base URL. |
None
|
session
|
Session | None
|
Reuse an existing requests session. |
None
|
headers
|
dict[str, Any] | None
|
Additional headers. |
None
|
params
|
dict[str, Any] | None
|
Additional query parameters. |
None
|
cookies
|
dict[str, Any] | None
|
Additional cookies. |
None
|
**kwargs
|
Any
|
Additional transport-level arguments. |
{}
|
call_and_validate(base_url=None, session=None, headers=None, checks=None, additional_checks=None, excluded_checks=None, **kwargs)
Make an HTTP request and validates the response automatically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str | None
|
Override the schema's base URL. |
None
|
session
|
Session | None
|
Reuse an existing requests session. |
None
|
headers
|
dict[str, Any] | None
|
Additional headers to send. |
None
|
checks
|
list[CheckFunction] | None
|
Explicit set of checks to run. |
None
|
additional_checks
|
list[CheckFunction] | None
|
Additional custom checks to run. |
None
|
excluded_checks
|
list[CheckFunction] | None
|
Built-in checks to skip. |
None
|
**kwargs
|
Any
|
Additional transport-level arguments. |
{}
|
validate_response(response, checks=None, additional_checks=None, excluded_checks=None, headers=None, transport_kwargs=None, recorder=None)
Validate a response against the API schema and built-in checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Response | Response | Response | TestResponse
|
Response to validate. |
required |
checks
|
list[CheckFunction] | None
|
Explicit set of checks to run. |
None
|
additional_checks
|
list[CheckFunction] | None
|
Additional custom checks to run. |
None
|
excluded_checks
|
list[CheckFunction] | None
|
Built-in checks to skip. |
None
|
headers
|
dict[str, Any] | None
|
Headers used in the original request. |
None
|
transport_kwargs
|
dict[str, Any] | None
|
Transport arguments used in the original request. |
None
|
recorder
|
ScenarioRecorder | None
|
Recorder for stateful check context (case/response lookups). |
None
|
APIOperation
dataclass
Bases: Generic[P, R, S]
An API operation (e.g., GET /users).
Case(*, method=None, path_parameters=None, headers=None, cookies=None, query=None, body=NOT_SET, media_type=None, multipart_content_types=None, _meta=None)
Create a test case with specific data instead of generated values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str | None
|
Override HTTP method. |
None
|
path_parameters
|
dict[str, Any] | None
|
Override path variables. |
None
|
headers
|
dict[str, Any] | CaseInsensitiveDict | None
|
Override HTTP headers. |
None
|
cookies
|
dict[str, Any] | None
|
Override cookies. |
None
|
query
|
dict[str, Any] | None
|
Override query parameters. |
None
|
body
|
Body
|
Override request body. |
NOT_SET
|
media_type
|
str | None
|
Override media type. |
None
|
multipart_content_types
|
dict[str, str] | None
|
Selected content types for multipart form properties. |
None
|
as_strategy(generation_mode=GenerationMode.POSITIVE, **kwargs)
Create a Hypothesis strategy that generates test cases for this API operation.
Use with @given in non-Schemathesis tests.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
generation_mode
|
GenerationMode
|
Whether to generate positive or negative test data. |
POSITIVE
|
**kwargs
|
Any
|
Extra arguments to the underlying strategy function. |
{}
|
get_parameter_serializers()
Return all per-container parameter serializers defined on this operation.
is_valid_response(response)
Check if the provided response is valid against the API schema.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Response | Response | Response | TestResponse
|
The HTTP response to validate. Can be a |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
validate_response(response, *, case=None)
Validate a response against the API schema.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Response | Response | Response | TestResponse
|
The HTTP response to validate. Can be a |
required |
case
|
Case | None
|
The generated test case related to the provided response. |
None
|
Raises:
| Type | Description |
|---|---|
FailureGroup
|
If the response does not conform to the schema. |
BaseSchema
dataclass
Bases: Mapping
base_path
property
Base path for the schema.
adapt_to_null_byte_in_header_failure()
React to the engine probe finding that null bytes in headers crash the app under test.
adapt_to_path_decoder_rejection()
React to the engine probe finding that the app rejects unsafe characters in URL paths.
apply_auth(case, context)
Apply spec-specific authentication to a test case.
Returns True if authentication was applied, False otherwise. Subclasses should implement this to provide spec-specific auth mechanisms.
apply_stateful_inference(ctx)
Discover spec-specific stateful transitions; return the number available.
as_state_machine(*, error_feedback=None)
Create a state machine class for stateful testing of linked API operations.
Returns:
| Type | Description |
|---|---|
type[APIStateMachine]
|
APIStateMachine subclass configured for this schema. |
as_strategy(generation_mode=GenerationMode.POSITIVE, **kwargs)
Create a Hypothesis strategy that generates test cases for all schema operations.
Use with @given in non-Schemathesis tests.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
generation_mode
|
GenerationMode
|
Whether to generate positive or negative test data. |
POSITIVE
|
**kwargs
|
Any
|
Additional keywords for each strategy. |
{}
|
Returns:
| Type | Description |
|---|---|
SearchStrategy
|
Combined Hypothesis strategy for all valid operations in the schema. |
build_request_url(case, base_url)
Construct the request URL by templating the case path onto base_url.
compute_fuzz_operation_weights(operations)
Return per-operation sampling weights for the fuzz phase; default is uniform.
create_extra_data_source()
Create an extra data source for augmenting test generation with real data.
Returns:
| Type | Description |
|---|---|
ExtraDataSource | None
|
ExtraDataSource instance or None if not supported by this schema type. |
exclude(func=None, *, name=None, name_regex=None, method=None, method_regex=None, path=None, path_regex=None, tag=None, tag_regex=None, operation_id=None, operation_id_regex=None, deprecated=False)
Return a new schema excluding operations matching the specified criteria.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
MatcherFunc | None
|
Custom filter function that accepts operation context. |
None
|
name
|
FilterValue | None
|
Operation name(s) to exclude. |
None
|
name_regex
|
str | None
|
Regex pattern for operation names. |
None
|
method
|
FilterValue | None
|
HTTP method(s) to exclude. |
None
|
method_regex
|
str | None
|
Regex pattern for HTTP methods. |
None
|
path
|
FilterValue | None
|
API path(s) to exclude. |
None
|
path_regex
|
str | None
|
Regex pattern for API paths. |
None
|
tag
|
FilterValue | None
|
OpenAPI tag(s) to exclude. |
None
|
tag_regex
|
RegexValue | None
|
Regex pattern for OpenAPI tags. |
None
|
operation_id
|
FilterValue | None
|
Operation ID(s) to exclude. |
None
|
operation_id_regex
|
RegexValue | None
|
Regex pattern for operation IDs. |
None
|
deprecated
|
bool
|
Whether to exclude deprecated operations. |
False
|
Returns:
| Type | Description |
|---|---|
BaseSchema
|
New schema instance with applied exclude filters. |
get_coverage_capabilities()
Return spec-specific data the coverage phase asks of a schema.
get_custom_format_strategies(generation_config, mode)
Return spec-specific format strategies (mode-aware) for hypothesis-jsonschema generation.
get_unit_scheduler(operations, phase)
Return the scheduler that decides operation execution order in the unit phase.
given(*args, **kwargs)
Proxy to Hypothesis's given decorator for adding custom strategies.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*args
|
GivenInput
|
Positional arguments passed to |
()
|
**kwargs
|
GivenInput
|
Keyword arguments passed to |
{}
|
hook(hook)
Register a hook function for this schema only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hook
|
str | Callable
|
Hook name string or hook function to register. |
required |
include(func=None, *, name=None, name_regex=None, method=None, method_regex=None, path=None, path_regex=None, tag=None, tag_regex=None, operation_id=None, operation_id_regex=None)
Return a new schema containing only operations matching the specified criteria.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
MatcherFunc | None
|
Custom filter function that accepts operation context. |
None
|
name
|
FilterValue | None
|
Operation name(s) to include. |
None
|
name_regex
|
str | None
|
Regex pattern for operation names. |
None
|
method
|
FilterValue | None
|
HTTP method(s) to include. |
None
|
method_regex
|
str | None
|
Regex pattern for HTTP methods. |
None
|
path
|
FilterValue | None
|
API path(s) to include. |
None
|
path_regex
|
str | None
|
Regex pattern for API paths. |
None
|
tag
|
FilterValue | None
|
OpenAPI tag(s) to include. |
None
|
tag_regex
|
RegexValue | None
|
Regex pattern for OpenAPI tags. |
None
|
operation_id
|
FilterValue | None
|
Operation ID(s) to include. |
None
|
operation_id_regex
|
RegexValue | None
|
Regex pattern for operation IDs. |
None
|
Returns:
| Type | Description |
|---|---|
BaseSchema
|
New schema instance with applied include filters. |
iter_link_candidates(*, operation, case, response, operations_by_label, excluded_labels)
Return resolvable (target, overrides) link candidates from a response; empty for specs without links.
iter_schema_warnings()
Return spec-level static-analysis warnings collected from the schema.
parametrize()
Return a decorator that marks a test function for pytest parametrization.
The decorated test function will be parametrized with test cases generated from the schema's API operations. The same base function can be reused with multiple schemas by assigning the result of each call to a distinct name.
Returns:
| Type | Description |
|---|---|
Callable
|
Decorator function for test parametrization. |
Raises:
| Type | Description |
|---|---|
IncorrectUsage
|
If applied on top of another |
prepare_request_body(body)
Apply spec-specific transformations to a generated body before sending.
record_runtime_observations(*, store, recorder, case, response, transport_kwargs)
Spec-specific runtime observations from a response (e.g. auth inference). Default: no-op.
reset_coverage_state()
Reset spec-specific runtime state held across coverage runs; default is a no-op.
revalidate_case_metadata(case)
Refresh case metadata after a container was modified; default just clears the dirty markers.
Stateful Testing
APIStateMachine
Bases: RuleBasedStateMachine
State machine for executing API operation sequences based on inferred transitions.
Automatically generates test scenarios by chaining API operations according to spec-specific relationships (OpenAPI Links, GraphQL producer/consumer inference, etc.).
after_call(response, case)
before_call(case)
Called before each API operation in the scenario.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
Case
|
Test case data for the operation. |
required |
get_call_kwargs(case)
Returns keyword arguments for the API call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
Case
|
Test case being executed. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Dictionary passed to the |
run(*, settings=None)
classmethod
Execute the state machine test scenarios.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
settings | None
|
Hypothesis settings for test execution. |
None
|
setup()
Called once at the beginning of each test scenario.
teardown()
Called once at the end of each test scenario.
validate_response(response, case, additional_checks=None, **kwargs)
Validates the API response using configured checks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Response
|
HTTP response to validate. |
required |
case
|
Case
|
Test case that generated the response. |
required |
additional_checks
|
list[CheckFunction] | None
|
Extra validation functions to run. |
None
|
kwargs
|
Any
|
Transport-level keyword arguments. |
{}
|
Raises:
| Type | Description |
|---|---|
FailureGroup
|
When validation checks fail. |
Hooks
HookContext
dataclass
A context that is passed to some hook functions.
operation = operation
instance-attribute
API operation that is currently being processed.
hook(hook)
Register a new hook.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hook
|
str | Callable
|
Either a hook function (autodetecting its name) or a string matching one of the supported hook names. |
required |
Example
Can be used as a decorator in two ways:
-
Without arguments (auto-detect the hook name from the function name):
@schemathesis.hook def filter_query(ctx, query): """Skip cases where query is None or invalid""" return query and "user_id" in query @schemathesis.hook def before_call(ctx, case, **kwargs): """Modify headers before sending each request""" if case.headers is None: case.headers = {} case.headers["X-Test-Mode"] = "true" return None -
With an explicit hook name as the first argument:
@schemathesis.hook("map_headers") def add_custom_header(ctx, headers): """Inject a test header into every request""" if headers is None: headers = {} headers["X-Custom"] = "value" return headers
Checks
CheckContext
Runtime context passed to validation check functions during API testing.
Provides access to configuration for currently checked endpoint.
config = config
instance-attribute
Configuration settings for validation checks.
check(func)
Register a custom validation check to run against API responses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
CheckFunction
|
Function that takes |
required |
Example
import schemathesis
@schemathesis.check
def check_cors_headers(ctx, response, case):
"""Verify CORS headers are present"""
if "Access-Control-Allow-Origin" not in response.headers:
raise AssertionError("Missing CORS headers")
Authentication
AuthContext
dataclass
Runtime context passed to authentication providers during token generation.
Provides access to the current API operation and application instance when auth providers need operation-specific tokens or application state.
Example
@schemathesis.auth()
class ContextAwareAuth:
def get(self, case, context):
# Access operation details
if "/admin/" in context.operation.path:
return self.get_admin_token()
else:
return self.get_user_token()
def set(self, case, data, context):
case.headers = {"Authorization": f"Bearer {data}"}
app
instance-attribute
Python application instance (ASGI/WSGI app) when using app integration, None otherwise.
operation
instance-attribute
API operation currently being processed for authentication.
AuthProvider
Bases: Generic[Auth], Protocol
Protocol for implementing custom authentication in API tests.
get(case, ctx)
Obtain authentication data for the test case.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
Case
|
Generated test case requiring authentication. |
required |
ctx
|
AuthContext
|
Authentication state and configuration. |
required |
Returns:
| Type | Description |
|---|---|
Auth | None
|
Authentication data (e.g., token, credentials) or |
set(case, data, ctx)
Apply authentication data to the test case.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
Case
|
Test case to modify. |
required |
data
|
Auth
|
Authentication data from the |
required |
ctx
|
AuthContext
|
Authentication state and configuration. |
required |
auth(*, refresh_interval=DEFAULT_REFRESH_INTERVAL, cache_by_key=None)
Register a dynamic authentication provider for APIs with expiring tokens.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_interval
|
int | None
|
Seconds between token refreshes. Default is |
DEFAULT_REFRESH_INTERVAL
|
cache_by_key
|
CacheKeyFunction | None
|
Function to generate cache keys for different auth contexts (e.g., OAuth scopes) |
None
|
Example
import schemathesis
import requests
@schemathesis.auth()
class TokenAuth:
def get(self, case, context):
"""Fetch fresh authentication token"""
response = requests.post(
"http://localhost:8000/auth/token",
json={"username": "demo", "password": "test"}
)
return response.json()["access_token"]
def set(self, case, data, context):
"""Apply token to test case headers"""
case.headers = case.headers or {}
case.headers["Authorization"] = f"Bearer {data}"
Serialization
SerializationContext
dataclass
Context object passed to serializer functions.
It provides access to the generated test case and any related metadata.
case
instance-attribute
The generated test case.
serializer
Register a serializer for specified media types on HTTP, ASGI, and WSGI transports.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*media_types
|
str
|
One or more MIME types (e.g., "application/json") this serializer handles. |
()
|
Returns:
| Type | Description |
|---|---|
Callable[[_Serializer], None]
|
A decorator that wraps a function taking |
Example
@schemathesis.serializer("text/csv")
def csv_serializer(ctx, value):
# Convert value to CSV bytes
return csv_bytes
serializer.alias
Reuse an existing serializer for additional media types.
Register alias(es) for a built-in or previously registered serializer without duplicating implementation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str | list[str]
|
Media type(s) to register as aliases |
required |
source
|
str
|
Existing media type whose serializer to reuse |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If source media type has no registered serializer |
ValueError
|
If target is empty |
Example
# Reuse built-in YAML serializer for custom media type
schemathesis.serializer.alias("application/custom+yaml", "application/yaml")
# Reuse built-in JSON serializer for vendor-specific type
schemathesis.serializer.alias("application/vnd.api+json", "application/json")
# Register multiple aliases at once
schemathesis.serializer.alias(
["application/jsonrequest", "application/json-rpc"],
"application/json"
)
Response Deserialization
DeserializationContext
dataclass
Context passed to deserializers.
Attributes:
| Name | Type | Description |
|---|---|---|
operation |
APIOperation
|
The API operation being tested. |
case |
Case | None
|
The generated test case ( |
deserializer(*media_types)
Register a deserializer for custom response media types.
Converts API responses with custom content types (MessagePack, domain-specific formats, etc.) into Python objects for schema validation. Built-in formats (JSON, YAML) work automatically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*media_types
|
str
|
One or more MIME types (e.g., "application/msgpack", "application/vnd.custom+json") this deserializer handles. Wildcards are supported (e.g., "application/*"). |
()
|
Returns:
| Type | Description |
|---|---|
Callable[[ResponseDeserializer], ResponseDeserializer]
|
A decorator that wraps a function taking |
Callable[[ResponseDeserializer], ResponseDeserializer]
|
and returning the deserialized Python object for schema validation. |
Example
import schemathesis import msgpack
@schemathesis.deserializer("application/msgpack", "application/x-msgpack") ... def deserialize_msgpack(ctx, response): ... try: ... return msgpack.unpackb(response.content, raw=False) ... except Exception as exc: ... raise ValueError(f"Invalid MessagePack: {exc}")
Notes
- Raise appropriate exceptions if deserialization fails; Schemathesis will report them
ctx.operationprovides access to the API operation being tested (always available)ctx.caseprovides the generated test case (None when validating responses directly)- Responses with unsupported media types are silently skipped during validation
- Handle unexpected data defensively, especially during negative testing
Targeted Property-based Testing
MetricContext
dataclass
Context for evaluating a metric on a single test execution.
This object bundles together the test case that was sent and
the corresponding HTTP response. Metric functions receive an
instance of MetricContext to compute a numeric score.
case
instance-attribute
Generated test case.
response
instance-attribute
The HTTP response returned by the server for this test case.
metric(func)
Decorator to register a custom metric for targeted property-based testing.
Example
import schemathesis
@schemathesis.metric
def response_size(ctx: schemathesis.MetricContext) -> float:
return float(len(ctx.response.content))
Open API Extensions
format(name, strategy)
Register a custom Hypothesis strategy for generating string format data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
String format name that matches the "format" keyword in your API schema |
required |
strategy
|
SearchStrategy
|
Hypothesis strategy to generate values for this format |
required |
Example
import schemathesis
from hypothesis import strategies as st
# Register phone number format
phone_strategy = st.from_regex(r"\+1-\d{3}-\d{3}-\d{4}")
schemathesis.openapi.format("phone", phone_strategy)
# Register email with specific domain
email_strategy = st.from_regex(r"[a-z]+@company\.com")
schemathesis.openapi.format("company-email", email_strategy)
Schema usage
properties:
phone:
type: string
format: phone # Uses your phone_strategy
contact_email:
type: string
format: company-email # Uses your email_strategy
media_type(name, strategy, *, aliases=())
Register a custom Hypothesis strategy for generating media type content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Media type name that matches your OpenAPI requestBody content type |
required |
strategy
|
SearchStrategy[bytes]
|
Hypothesis strategy that generates bytes for this media type |
required |
aliases
|
Collection[str]
|
Additional media type names that use the same strategy |
()
|
Example
import schemathesis
from hypothesis import strategies as st
# Register PDF file strategy
pdf_strategy = st.sampled_from([
b"%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n>>\nendobj\n%%EOF",
b"%PDF-1.5\n%\xe2\xe3\xcf\xd3\n1 0 obj\n<<\n/Type /Catalog\n>>\nendobj\n%%EOF"
])
schemathesis.openapi.media_type("application/pdf", pdf_strategy)
# Dynamic content generation
@st.composite
def xml_content(draw):
tag = draw(st.text(min_size=3, max_size=10))
content = draw(st.text(min_size=1, max_size=50))
return f"<?xml version='1.0'?><{tag}>{content}</{tag}>".encode()
schemathesis.openapi.media_type("application/xml", xml_content())
Schema usage
requestBody:
content:
application/pdf: # Uses your PDF strategy
schema:
type: string
format: binary
application/xml: # Uses your XML strategy
schema:
type: string
format: binary
require_security_scheme(name)
Return a filter function matching operations that require the given security scheme.
Checks operation-level security first, then falls back to schema-level security.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Security scheme name as declared in |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
MatcherFunc
|
data: |
Example::
@schemathesis.auth().apply_to(
schemathesis.openapi.require_security_scheme("session")
)
class SessionAuth:
...
GraphQL Extensions
scalar(name, strategy)
Register a custom Hypothesis strategy for generating GraphQL scalar values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Scalar name that matches your GraphQL schema scalar definition |
required |
strategy
|
SearchStrategy[ValueNode]
|
Hypothesis strategy that generates GraphQL AST ValueNode objects |
required |
Example
import schemathesis
from hypothesis import strategies as st
from schemathesis.graphql import nodes
# Register email scalar
schemathesis.graphql.scalar("Email", st.emails().map(nodes.String))
# Register positive integer scalar
schemathesis.graphql.scalar(
"PositiveInt",
st.integers(min_value=1).map(nodes.Int)
)
# Register phone number scalar
schemathesis.graphql.scalar(
"Phone",
st.from_regex(r"\+1-\d{3}-\d{3}-\d{4}").map(nodes.String)
)
Schema usage
scalar Email
scalar PositiveInt
type Query {
getUser(email: Email!, rating: PositiveInt!): User
}
AST Node Factories
These factory functions from schemathesis.graphql.nodes convert Python values into GraphQL AST ValueNode objects for use with custom scalar strategies.
String
value(str): String value to wrap
from schemathesis.graphql import nodes
from hypothesis import strategies as st
# Email scalar using String node
st.emails().map(nodes.String)
Int
value(int): Integer value to wrap
# Positive integer scalar
st.integers(min_value=1).map(nodes.Int)
Float
value(float): Float value to wrap
# Price scalar with decimal precision
st.decimals(min_value=0, max_value=1000, places=2).map(nodes.Float)
Boolean
value(bool): Boolean value to wrap
# Active status scalar
st.booleans().map(nodes.Boolean)
Enum
value(str): Enum value name to wrap
# Status enum scalar
st.sampled_from(["ACTIVE", "INACTIVE", "PENDING"]).map(nodes.Enum)
Null
No arguments required. Represents GraphQL null values.
# Optional scalar that can be null
st.one_of(st.emails().map(nodes.String), st.just(nodes.Null))
List
values(list): List of ValueNode objects
# List of integers
st.lists(st.integers().map(nodes.Int), min_size=1, max_size=5).map(nodes.List)
Object
fields(list): List of ObjectFieldNode objects for object fields
import graphql
# JSON object scalar (simplified)
def create_object_field(key, value):
return graphql.ObjectFieldNode(
name=graphql.NameNode(value=key),
value=value
)
# Simple object with string fields
st.dictionaries(
keys=st.text(min_size=1, max_size=10),
values=st.text().map(nodes.String),
min_size=1, max_size=3
).map(lambda d: nodes.Object([
create_object_field(k, v) for k, v in d.items()
]))