Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Third-party compatibility fixups mechanism
- Loading branch information
1 parent
df77d4a
commit a880f24
Showing
16 changed files
with
268 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
.. _compatibility: | ||
|
||
Compatibility | ||
============= | ||
|
||
By default, Schemathesis is strict on Open API spec interpretation, but other 3rd-party tools often are more flexible | ||
and not always comply with the spec. | ||
|
||
FastAPI | ||
------- | ||
|
||
`FastAPI <https://github.com/tiangolo/fastapi>`_ uses `pydantic <https://github.com/samuelcolvin/pydantic>`_ for JSON Schema | ||
generation and it produces Draft 7 compatible schemas. But Open API 2 / 3.0.x use earlier versions of JSON Schema (Draft 4 and Wright Draft 00 respectively) which leads | ||
to incompatibilities when Schemathesis parses input schema. | ||
|
||
This is a `known issue <https://github.com/tiangolo/fastapi/issues/240>`_ on the FastAPI side | ||
and Schemathesis provides a way to handle such schemas. The idea is based on converting Draft 7 keywords syntax to Draft 4. | ||
|
||
To use it you need to add this code before you load your schema with Schemathesis: | ||
|
||
.. code:: python | ||
import schemathesis | ||
# will install all available compatibility fixups. | ||
schemathesis.fixups.install() | ||
# You can also provide a list of fixup names as the first argument | ||
# schemathesis.fixups.install(["fastapi"]) | ||
If you use CLI, then you can utilize ``--fixups=all`` option. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from typing import Iterable, List, Optional | ||
|
||
from . import fast_api | ||
|
||
ALL_FIXUPS = {"fast_api": fast_api} | ||
|
||
|
||
def install(fixups: Optional[Iterable[str]] = None) -> None: | ||
"""Install fixups. | ||
Without the first argument installs all available fixups. | ||
""" | ||
fixups = fixups or list(ALL_FIXUPS.keys()) | ||
for name in fixups: | ||
ALL_FIXUPS[name].install() # type: ignore | ||
|
||
|
||
def uninstall(fixups: Optional[Iterable[str]] = None) -> None: | ||
"""Uninstall fixups. | ||
Without the first argument uninstalls all available fixups. | ||
""" | ||
fixups = fixups or list(ALL_FIXUPS.keys()) | ||
for name in fixups: | ||
ALL_FIXUPS[name].uninstall() # type: ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from typing import Any, Dict | ||
|
||
from ..hooks import HookContext, register, unregister | ||
from ..utils import traverse_schema | ||
|
||
|
||
def install() -> None: | ||
register(before_load_schema) | ||
|
||
|
||
def uninstall() -> None: | ||
unregister(before_load_schema) | ||
|
||
|
||
def before_load_schema(context: HookContext, schema: Dict[str, Any]) -> None: | ||
traverse_schema(schema, _handle_boundaries) | ||
|
||
|
||
def _handle_boundaries(schema: Dict[str, Any]) -> Dict[str, Any]: | ||
"""Convert Draft 7 keywords to Draft 4 compatible versions. | ||
FastAPI uses ``pydantic``, which generates Draft 7 compatible schemas. | ||
""" | ||
for boundary_name, boundary_exclusive_name in (("maximum", "exclusiveMaximum"), ("minimum", "exclusiveMinimum")): | ||
value = schema.get(boundary_exclusive_name) | ||
# `bool` check is needed, since in Python `True` is an instance of `int` | ||
if isinstance(value, (int, float)) and not isinstance(value, bool): | ||
schema[boundary_exclusive_name] = True | ||
schema[boundary_name] = value | ||
return schema |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.