Openapi-core is a Python library that adds client-side and server-side support for the OpenAPI Specification v3.

Overview

openapi-core

https://travis-ci.org/p1c2u/openapi-core.svg?branch=master https://img.shields.io/codecov/c/github/p1c2u/openapi-core/master.svg?style=flat

About

Openapi-core is a Python library that adds client-side and server-side support for the OpenAPI Specification v3.

Key features

  • Validation of requests and responses
  • Schema casting and unmarshalling
  • Media type and parameters deserialization
  • Security providers (API keys, Cookie, Basic and Bearer HTTP authentications)
  • Custom deserializers and formats
  • Integration with libraries and frameworks

Documentation

Check documentation to see more details about the features. All documentation is in the "docs" directory and online at openapi-core.readthedocs.io

Installation

Recommended way (via pip):

$ pip install openapi-core

Alternatively you can download the code and install from the repository:

$ pip install -e git+https://github.com/p1c2u/openapi-core.git#egg=openapi_core

Usage

Firstly create your specification object:

from json import load
from openapi_core import create_spec

with open('openapi.json', 'r') as spec_file:
   spec_dict = load(spec_file)

spec = create_spec(spec_dict)

Request

Now you can use it to validate against requests

from openapi_core.validation.request.validators import RequestValidator

validator = RequestValidator(spec)
result = validator.validate(request)

# raise errors if request invalid
result.raise_for_errors()

# get list of errors
errors = result.errors

and unmarshal request data from validation result

# get parameters object with path, query, cookies and headers parameters
validated_params = result.parameters
# or specific parameters
validated_path_params = result.parameters.path

# get body
validated_body = result.body

# get security data
validated_security = result.security

Request object should be instance of OpenAPIRequest class (See Integrations).

Response

You can also validate against responses

from openapi_core.validation.response.validators import ResponseValidator

validator = ResponseValidator(spec)
result = validator.validate(request, response)

# raise errors if response invalid
result.raise_for_errors()

# get list of errors
errors = result.errors

and unmarshal response data from validation result

# get headers
validated_headers = result.headers

# get data
validated_data = result.data

Response object should be instance of OpenAPIResponse class (See Integrations).

Related projects

Comments
  • 0.14.2: pytest is failing

    0.14.2: pytest is failing

    I'm trying to package your module as an rpm package. So I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.

    • python3 -sBm build -w --no-isolation
    • because I'm calling build with --no-isolation I'm using during all processes only locally installed modules
    • install .whl file in </install/prefix>
    • run pytest with PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>

    In below output pytest shows as well few warnings. Here is pytest output:

    + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-openapi-core-0.14.2-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-openapi-core-0.14.2-2.fc35.x86_64/usr/lib/python3.8/site-packages
    + /usr/bin/pytest -ra
    =========================================================================== test session starts ============================================================================
    platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- /usr/bin/python3
    cachedir: .pytest_cache
    rootdir: /home/tkloczko/rpmbuild/BUILD/openapi-core-0.14.2, configfile: setup.cfg
    plugins: cov-3.0.0, flake8-1.0.7
    collected 613 items / 2 errors / 611 selected
    /usr/lib64/python3.8/site-packages/coverage/control.py:768: CoverageWarning: No data was collected. (no-data-collected)
      self._warn("No data was collected.", slug="no-data-collected")
    
    ================================================================================== ERRORS ==================================================================================
    ________________________________________________ ERROR collecting tests/integration/validation/test_read_only_write_only.py ________________________________________________
    tests/integration/validation/test_read_only_write_only.py:22: in <module>
        ???
    /usr/lib/python3.8/site-packages/_pytest/fixtures.py:1333: in fixture
        return fixture_marker(fixture_function)
    /usr/lib/python3.8/site-packages/_pytest/fixtures.py:1210: in __call__
        function = wrap_function_to_error_out_if_called_directly(function, self)
    /usr/lib/python3.8/site-packages/_pytest/fixtures.py:1172: in wrap_function_to_error_out_if_called_directly
        ).format(name=fixture_marker.name or function.__name__)
    E   AttributeError: 'str' object has no attribute '__name__'
    _________________________________________________ ERROR collecting tests/integration/validation/test_security_override.py __________________________________________________
    tests/integration/validation/test_security_override.py:17: in <module>
        ???
    /usr/lib/python3.8/site-packages/_pytest/fixtures.py:1333: in fixture
        return fixture_marker(fixture_function)
    /usr/lib/python3.8/site-packages/_pytest/fixtures.py:1210: in __call__
        function = wrap_function_to_error_out_if_called_directly(function, self)
    /usr/lib/python3.8/site-packages/_pytest/fixtures.py:1172: in wrap_function_to_error_out_if_called_directly
        ).format(name=fixture_marker.name or function.__name__)
    E   AttributeError: 'str' object has no attribute '__name__'
    ============================================================================= warnings summary =============================================================================
    tests/integration/contrib/django/conftest.py:7
      /home/tkloczko/rpmbuild/BUILD/openapi-core-0.14.2/tests/integration/contrib/django/conftest.py:7: PytestDeprecationWarning: @pytest.yield_fixture is deprecated.
      Use @pytest.fixture instead; they are the same.
        @pytest.yield_fixture(autouse=True, scope='module')
    
    tests/integration/contrib/falcon/test_falcon_middlewares.py:30
      /home/tkloczko/rpmbuild/BUILD/openapi-core-0.14.2/tests/integration/contrib/falcon/test_falcon_middlewares.py:30: PytestDeprecationWarning: @pytest.yield_fixture is deprecated.
      Use @pytest.fixture instead; they are the same.
        def client(self, app):
    
    ../../../../../usr/lib/python3.8/site-packages/falcon/testing/client.py:1796
      /usr/lib/python3.8/site-packages/falcon/testing/client.py:1796: PytestCollectionWarning: cannot collect test class 'TestClient' because it has a __init__ constructor (from: tests/integration/contrib/falcon/test_falcon_middlewares.py)
        class TestClient:
    
    tests/integration/contrib/flask/test_flask_decorator.py:30
      /home/tkloczko/rpmbuild/BUILD/openapi-core-0.14.2/tests/integration/contrib/flask/test_flask_decorator.py:30: PytestDeprecationWarning: @pytest.yield_fixture is deprecated.
      Use @pytest.fixture instead; they are the same.
        def client(self, app):
    
    tests/integration/contrib/flask/test_flask_views.py:25
      /home/tkloczko/rpmbuild/BUILD/openapi-core-0.14.2/tests/integration/contrib/flask/test_flask_views.py:25: PytestDeprecationWarning: @pytest.yield_fixture is deprecated.
      Use @pytest.fixture instead; they are the same.
        def client(self, app):
    
    -- Docs: https://docs.pytest.org/en/stable/warnings.html
    ----------------------------------------- generated xml file: /home/tkloczko/rpmbuild/BUILD/openapi-core-0.14.2/reports/junit.xml ------------------------------------------
    
    ---------- coverage: platform linux, python 3.8.12-final-0 -----------
    Name                                                      Stmts   Miss  Cover   Missing
    ---------------------------------------------------------------------------------------
    openapi_core/__init__.py                                      8      8     0%   2-13
    openapi_core/casting/__init__.py                              0      0   100%
    openapi_core/casting/schemas/__init__.py                      0      0   100%
    openapi_core/casting/schemas/casters.py                      28     28     0%   1-41
    openapi_core/casting/schemas/exceptions.py                    8      8     0%   1-13
    openapi_core/casting/schemas/factories.py                    16     16     0%   1-30
    openapi_core/casting/schemas/util.py                          6      6     0%   2-10
    openapi_core/compat.py                                        9      9     0%   2-12
    openapi_core/contrib/__init__.py                              0      0   100%
    openapi_core/contrib/django/__init__.py                       5      5     0%   1-8
    openapi_core/contrib/django/backports.py                     19     19     0%   4-27
    openapi_core/contrib/django/compat.py                         5      5     0%   2-15
    openapi_core/contrib/django/requests.py                      20     20     0%   2-51
    openapi_core/contrib/django/responses.py                      6      6     0%   2-10
    openapi_core/contrib/falcon/__init__.py                       3      3     0%   1-5
    openapi_core/contrib/falcon/compat.py                        11     11     0%   2-23
    openapi_core/contrib/falcon/handlers.py                      22     22     0%   2-51
    openapi_core/contrib/falcon/middlewares.py                   37     37     0%   3-67
    openapi_core/contrib/falcon/requests.py                      19     19     0%   2-42
    openapi_core/contrib/falcon/responses.py                     12     12     0%   2-19
    openapi_core/contrib/falcon/views.py                          0      0   100%
    openapi_core/contrib/flask/__init__.py                        5      5     0%   1-8
    openapi_core/contrib/flask/decorators.py                     19     19     0%   2-45
    openapi_core/contrib/flask/handlers.py                       16     16     0%   2-39
    openapi_core/contrib/flask/providers.py                       5      5     0%   2-9
    openapi_core/contrib/flask/requests.py                       15     15     0%   2-34
    openapi_core/contrib/flask/responses.py                       5      5     0%   2-9
    openapi_core/contrib/flask/views.py                          14     14     0%   2-26
    openapi_core/contrib/requests/__init__.py                     5      5     0%   1-12
    openapi_core/contrib/requests/requests.py                    23     23     0%   2-62
    openapi_core/contrib/requests/responses.py                    6      6     0%   2-10
    openapi_core/deserializing/__init__.py                        0      0   100%
    openapi_core/deserializing/exceptions.py                      8      8     0%   1-13
    openapi_core/deserializing/media_types/__init__.py            0      0   100%
    openapi_core/deserializing/media_types/deserializers.py      10     10     0%   1-14
    openapi_core/deserializing/media_types/factories.py          15     15     0%   1-32
    openapi_core/deserializing/media_types/util.py               16     16     0%   1-24
    openapi_core/deserializing/parameters/__init__.py             0      0   100%
    openapi_core/deserializing/parameters/deserializers.py       19     19     0%   1-29
    openapi_core/deserializing/parameters/exceptions.py           7      7     0%   1-11
    openapi_core/deserializing/parameters/factories.py           11     11     0%   1-28
    openapi_core/exceptions.py                                   38     38     0%   2-69
    openapi_core/extensions/__init__.py                           0      0   100%
    openapi_core/extensions/models/__init__.py                    0      0   100%
    openapi_core/extensions/models/factories.py                  14     14     0%   2-25
    openapi_core/extensions/models/models.py                     14     14     0%   4-26
    openapi_core/schema/__init__.py                               0      0   100%
    openapi_core/schema/parameters.py                            16     16     0%   1-34
    openapi_core/schema/schemas.py                               14     14     0%   1-22
    openapi_core/schema/servers.py                               16     16     0%   1-24
    openapi_core/schema/specs.py                                  5      5     0%   1-8
    openapi_core/security/__init__.py                             0      0   100%
    openapi_core/security/exceptions.py                           3      3     0%   1-5
    openapi_core/security/factories.py                           10     10     0%   1-19
    openapi_core/security/providers.py                           29     29     0%   1-45
    openapi_core/shortcuts.py                                     6      6     0%   3-14
    openapi_core/spec/__init__.py                                 0      0   100%
    openapi_core/spec/accessors.py                               16     16     0%   1-23
    openapi_core/spec/paths.py                                    9      9     0%   1-14
    openapi_core/spec/shortcuts.py                               10     10     0%   2-21
    openapi_core/templating/__init__.py                           0      0   100%
    openapi_core/templating/datatypes.py                         10     10     0%   1-13
    openapi_core/templating/media_types/__init__.py               0      0   100%
    openapi_core/templating/media_types/exceptions.py             9      9     0%   1-16
    openapi_core/templating/media_types/finders.py               13     13     0%   2-21
    openapi_core/templating/paths/__init__.py                     0      0   100%
    openapi_core/templating/paths/exceptions.py                  19     19     0%   1-36
    openapi_core/templating/paths/finders.py                     63     63     0%   2-101
    openapi_core/templating/responses/__init__.py                 0      0   100%
    openapi_core/templating/responses/exceptions.py               9      9     0%   1-17
    openapi_core/templating/responses/finders.py                 14     14     0%   1-23
    openapi_core/templating/util.py                              20     20     0%   1-32
    openapi_core/testing/__init__.py                              4      4     0%   2-8
    openapi_core/testing/datatypes.py                            13     13     0%   1-18
    openapi_core/testing/factories.py                             8      8     0%   1-11
    openapi_core/testing/mock.py                                  3      3     0%   3-6
    openapi_core/testing/requests.py                             12     12     0%   2-27
    openapi_core/testing/responses.py                             5      5     0%   2-9
    openapi_core/types.py                                         1      1     0%   1
    openapi_core/unmarshalling/__init__.py                        0      0   100%
    openapi_core/unmarshalling/schemas/__init__.py                0      0   100%
    openapi_core/unmarshalling/schemas/enums.py                   4      4     0%   2-7
    openapi_core/unmarshalling/schemas/exceptions.py             27     27     0%   1-55
    openapi_core/unmarshalling/schemas/factories.py              45     45     0%   1-89
    openapi_core/unmarshalling/schemas/formatters.py             14     14     0%   1-18
    openapi_core/unmarshalling/schemas/unmarshallers.py         176    176     0%   1-311
    openapi_core/unmarshalling/schemas/util.py                   32     32     0%   2-50
    openapi_core/validation/__init__.py                           0      0   100%
    openapi_core/validation/datatypes.py                          7      7     0%   2-11
    openapi_core/validation/decorators.py                        36     36     0%   2-59
    openapi_core/validation/exceptions.py                         8      8     0%   2-15
    openapi_core/validation/processors.py                         8      8     0%   4-14
    openapi_core/validation/request/__init__.py                   0      0   100%
    openapi_core/validation/request/datatypes.py                 26     26     0%   2-68
    openapi_core/validation/request/shortcuts.py                 33     33     0%   2-57
    openapi_core/validation/request/validators.py               168    168     0%   2-255
    openapi_core/validation/response/__init__.py                  0      0   100%
    openapi_core/validation/response/datatypes.py                11     11     0%   2-29
    openapi_core/validation/response/shortcuts.py                19     19     0%   2-36
    openapi_core/validation/response/validators.py               74     74     0%   2-118
    openapi_core/validation/validators.py                        39     39     0%   2-66
    ---------------------------------------------------------------------------------------
    TOTAL                                                      1563   1563     0%
    Coverage XML written to file reports/coverage.xml
    
    ========================================================================= short test summary info ==========================================================================
    ERROR tests/integration/validation/test_read_only_write_only.py - AttributeError: 'str' object has no attribute '__name__'
    ERROR tests/integration/validation/test_security_override.py - AttributeError: 'str' object has no attribute '__name__'
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ====================================================================== 5 warnings, 2 errors in 4.95s =======================================================================
    
    opened by kloczek 14
  • Something funky is happening with paths after upgrade from 0.13.1 to 0.13.3

    Something funky is happening with paths after upgrade from 0.13.1 to 0.13.3

    I maintain an example Pyramid app that uses openapi-core under the hood. When upgrading the library from 0.13.1 to 0.13.3 I've encountered a strange bug: responses fail because they don't match schemas of other endpoints. Weird, right? Read on.

    In the PR linked above, you can see that I had to move the endpoint definition for /articles/{slug}/ to a position after endpoint definitions of more specific endpoints, such as /articles/{slug}/comments, /articles/{slug}/comments/{id} and /articles/{slug}/favorite. Otherwise, a valid request to /articles/{slug}/comments would fail during response validation with ValidationError:'article' is a required property.

    It seems that something changed in how paths are registered and this change now requires that more specific subpaths are now defined before less specific paths. I.e. /item/{id} needs to be defined below /item/{id}/foo in openapi.yaml file.

    I haven't yet managed to isolate this bug further. @p1c2u do you have any ideas off the top of your head what could cause this?

    opened by zupo 10
  • Update pytest to latest version

    Update pytest to latest version

    The tests/conftest.py is a bit of a hack, but needed to support running tests against a non-editable install (which is the recommended way as per https://docs.pytest.org/en/latest/explanation/goodpractices.html?highlight=tests%20outside#choosing-a-test-layout-import-rules )

    Closes https://github.com/p1c2u/openapi-core/pull/159

    opened by ashb 9
  • p1c2u/openapi-core#296: Adds support for OpenAPI 3.1

    p1c2u/openapi-core#296: Adds support for OpenAPI 3.1

    This PR is build on top of:

    • https://github.com/p1c2u/openapi-schema-validator/pull/18
    • https://github.com/p1c2u/openapi-spec-validator/pull/128

    Support for Python 3.6 is dropped as in the alpha release of jsonschema.

    opened by nezhar 8
  • PathFinder finds all patterns, who looks like my request path, and he return worst case

    PathFinder finds all patterns, who looks like my request path, and he return worst case

    Good day. Please start from comment in code: https://github.com/p1c2u/openapi-core/commit/dcb7161af7b273b824e57ed1f61e00bfe72d1899#r37991936

    In my case PathFinder find three path patterns (with all him staff like a response and more...): path_pattern (from request): api/some/reourse/{key}/this/path/ Matched patterns with important arg:

    1. api/some/reourse/{key}/ mimetype: json
    2. api/some/reourse/{key}/this/ mimetype: json
    3. api/some/reourse/{key}/this/path/ mimetype: text/csv

    Ok. Could be worse. We can see, number three - best match. But code from link say: I'll return first of them. Why? Why we use iterators everywhere, but still return one response for validation? Not the most accurate pattern. Just first. Please look like it be in 0.13.2 version. Radical changes. And I don't understand new logic =(

    This behaviour produce error in schema validation process. Schema right. I checked it.

    Thanks for help.

    kind/bug/confirmed resolution/duplicate 
    opened by mrkovalchuk 8
  • 0.12.0 regression regarding usability of validation messages

    0.12.0 regression regarding usability of validation messages

    Hey!

    I'm the author of https://github.com/Pylons/pyramid_openapi3, and today I realized a new release of openapi-core is out, yay!

    I immediately prepared a PR to bump pyramid_openapi3 to openapi-core 0.12.0, but tests on CI failed:

    ======================================================================
    FAIL: test_name_too_short (app.FunctionalTests)
    A name that is too short is picked up by openapi-core validation.
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/circleci/repo/examples/singlefile/app.py", line 142, in test_name_too_short
        res.text,
    AssertionError: 'Invalid parameter value for `name`: Value is shorter (2) than the minimum length of 3' not found in '400 Bad Request\n\nRequest validation failed.\n\n\nInvalid parameter value for `name`: Value not valid for schema\n\n'
    
    ----------------------------------------------------------------------
    

    The test above fails in a single-file example that I ship with pyramid_openapi3. It fails because in 0.11.0, the validation error is more descriptive than in 0.12.0:

    • 0.11.0: "Invalid parameter value for `name`: Value is shorter (2) than the minimum length of 3"
    • 0.12.0: "Invalid parameter value for `name`: Value not valid for schema"

    Is this an expected regression due to the move to a different validation engine that happened in 0.12.0 (or at least that is how I understood the commit messages)? Is it possible to configure the new validation to have more descriptive errors? Or am I completely missing the point here?

    opened by zupo 8
  • Mess with paths

    Mess with paths

    If you have url pattern in flask, you'll never get your paths validated.

    import yaml
    from flask import Flask, request
    from openapi_core import create_spec
    from openapi_core.validation.request.validators import RequestValidator
    from openapi_core.wrappers.flask import FlaskOpenAPIRequest
    
    spec = """openapi: "3.0.0"
    info:
        version: 1.0.0
        title: test
    servers:
    - url: http://127.0.0.1:8000
    components:
        parameters:
            some_param:
                name: some
                in: path
                required: true
                schema:
                    type: string
    paths:
        /{some}/path/:
            parameters:
            - $ref: '#/components/parameters/some_param'
            post:
                summary: anything
    """
    TEST_SPEC = create_spec(spec)
    
    FLASK_APP = Flask(__name__)
    
    @FLASK_APP.route('/<some>/path', methods=['POST'])
    def duh(some: str):
        validator = RequestValidator(TEST_SPEC)
        result = validator.validate(FlaskOpenAPIRequest(request))
        print(result.errors)
    

    Will always get an error

    [InvalidOperation('Unknown operation path /<some>/path with method post')]
    

    Because flask url pattern syntax and openapi pattern syntax do not match. An error hides here https://github.com/p1c2u/openapi-core/blob/master/openapi_core/validation/request/validators.py#L24

    1. path_pattern is not transformed to openapi format
    2. request.path_pattern is not used
    resolution/duplicate 
    opened by dbazhal 8
  • Library does not support optional request body

    Library does not support optional request body

    So, if we have definition for requestBody (e.g. for POST request) like this:

    requestBody:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/some_json_schema'
      required: false
    

    and if we try to make request without body, it will produce error like this:

    Traceback (most recent call last):
      ...
      File "D:\venvs\.test_venv\lib\site-packages\openapi_core\validation\datatypes.py", line 11, in raise_for_errors
        raise error
      File "D:\venvs\.test_venv\lib\site-packages\openapi_core\validation\request\validators.py", line 164, in _get_body
        deserialised = self._deserialise_media_type(media_type, raw_body)
      File "D:\venvs\.test_venv\lib\site-packages\openapi_core\validation\validators.py", line 28, in _deserialise_media_type
        return deserializer(value)
      File "D:\venvs\.test_venv\lib\site-packages\openapi_core\deserializing\media_types\deserializers.py", line 14, in __call__
        raise DeserializeError(value, self.mimetype)
    openapi_core.deserializing.exceptions.DeserializeError: Failed to deserialize value b'' with style application/json
    

    even it should allow it because of required: false.

    kind/bug/confirmed area/deserializing 
    opened by stojan-jovic 6
  • create_spec() method taking too much time

    create_spec() method taking too much time

    I am building a large product and in this stage i have an openapi-spec file with 28000 lines. Now i have,

    • 53 path objects.

    • 14 schema objects.

    openapi-core's create_spec() method is taking around 29 to 34 seconds. So my server is taking this much time to startup. Is there a remedy for this situation or is this the behaviour of openapi-core's validation ?? ps: So many Dereferencing log is present.

    opened by sarangsbabu367 6
  • Add support for one-of with any type

    Add support for one-of with any type

    This is a rebased version of my original PR rebased on p1c2u/master to get rid of the unnecessary strict validation changes. This pull requests adds support for various cases of oneOf in combination with a SchemaType.ANY schema that currently fail to unmarshal correctly, for example...

    Polymorphic:
      oneOf:
        Values:
          type:  array
          items:
            type: string
        Value:
          type: string
    
    opened by danielbradburn 6
  • Fix #124: Checking

    Fix #124: Checking "additionalProperties" in "oneOf" items.

    This is important because it does the correct validation over items that are restricted in "oneOf", so that it's possible to use schemas that are superset of one another as items of "oneOf".

    opened by diogobaeder 6
  • Add tornado support?

    Add tornado support?

    Thanks for openapi-core!

    We're looking at the challenges of updating to the more recent versions openapi-* versions on https://github.com/jupyterlab/jupyterlab_server/issues/359, and will likely end up wrapping our current server (tornado) in the appropriate protocols.

    Would these be welcome as PR in a future contrib/tornado?

    opened by bollwyvl 2
  • No way to validate webhook requests

    No way to validate webhook requests

    When validating requests, the library finds the schema to validate with by looking at the request url. This doesn't work for webhooks however, since these don't have the url they are going to in the spec. It would be nice if you could pass a path to the spec validator to override whatever it infers from the request, that way you could provide the location of the webhook spec.

    kind/enhancement spec/3.1 
    opened by SethThoburn 2
  • [0.16.2 regression]  `{

    [0.16.2 regression] `{"key": null}` fails to validate as `{"type": "object"}`

    In 0.16.1, {"key": null} validated successfully against {"type": "object"}—an object that includes a null value is still an object. But in 0.16.2 this incorrectly raises openapi_core.unmarshalling.schemas.exceptions.InvalidSchemaValue: Value None not valid for schema of type any: (<ValidationError: 'None for not nullable'>,).

    This regression was introduced by commit 692a9156abd99a63cfbaf018bf26470d0060b702 (#434).

    Full reproducible example:

    from openapi_core import Spec
    from openapi_core.testing import MockRequest
    from openapi_core.validation.request import openapi_request_validator
    
    spec = Spec.create(
        {
            "openapi": "3.0.3",
            "info": {"title": "test", "version": "0"},
            "paths": {
                "/test": {
                    "post": {
                        "parameters": [
                            {
                                "name": "obj",
                                "in": "query",
                                "content": {
                                    "application/json": {
                                        "schema": {"type": "object"},
                                    }
                                },
                            },
                        ],
                        "responses": {"200": {"description": ""}},
                    },
                },
            },
        },
    )
    request = MockRequest(
        "http://localhost/", "post", "/test", args={"obj": '{"key": null}'}
    )
    result = openapi_request_validator.validate(spec, request)
    print(result)
    result.raise_for_errors()
    
    kind/bug/confirmed area/unmarshalling 
    opened by andersk 2
  • Add reproducer for openapi-schema-validator#20

    Add reproducer for openapi-schema-validator#20

    This is the openapi-core counterpart to https://github.com/p1c2u/openapi-schema-validator/pull/55. I'm not sure if this is really needed, since a fix in openapi-schema-validator would fix this. I had it drafted though so I figured I would submit it. Perhaps the tox.ini file is useful?

    opened by stephenfin 1
  • Unmarshalling not working properly when the root does not have `type: object`

    Unmarshalling not working properly when the root does not have `type: object`

    Please see https://github.com/p1c2u/openapi-core/commit/3f821484bbcb16b31d9aa0d1a850dbe1e572d062 for a failing testcase.

    The docs (https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/#allof) have examples like

        Dog:     # "Dog" is a value for the pet_type property (the discriminator value)
          allOf: # Combines the main `Pet` schema with `Dog`-specific properties 
            - $ref: '#/components/schemas/Pet'
            - type: object
              # all other properties specific to a `Dog`
              properties:
                bark:
                  type: boolean
                breed:
                  type: string
                  enum: [Dingo, Husky, Retriever, Shepherd]
        Cat:     # "Cat" is a value for the pet_type property (the discriminator value)
          allOf: # Combines the main `Pet` schema with `Cat`-specific properties 
            - $ref: '#/components/schemas/Pet'
            - type: object
              # all other properties specific to a `Cat`
              properties:
                hunts:
                  type: boolean
                age:
                  type: integer
    

    So just a schema with allOf, no type: object. But using such a schema causes some unmarshalling to be skipped, as a date/datetime string would remain a string after spec_validate_body instead of being parsed.

    When type: object is used, (like the comment in the yaml in the commit) then the test case succeeds.

    kind/enhancement area/unmarshalling 
    opened by Wim-De-Clercq 2
Releases(0.16.4)
  • 0.16.4(Dec 21, 2022)

  • 0.16.3(Dec 20, 2022)

  • 0.16.2(Nov 25, 2022)

  • 0.16.1(Oct 10, 2022)

  • 0.16.0(Oct 4, 2022)

    Changelog

    • Switch to jsonschema-spec #416
    • Use auto-detect validator proxy #418
    • OpenAPI 3.1 support + Auto-detect proxies and request / response validator protocols #419
    • Add py.typed to mark package as supporting typing #420
    • Refuse to cast str or bytes to array #421
    • x-model extension import model class #422
    • Add deepObject support #379
    • Add anyOf support #423
    • Separate werkzeug support #426
    • Starlette support #427
    Source code(tar.gz)
    Source code(zip)
  • 0.15.0(Sep 12, 2022)

    Changelog

    • Parameter deserialize complex scenario support (#329)
    • Response headers support (#332)
    • Response headers support for contrib (#333)
    • Drop python 2.7 support (#335 #344 #351)
    • Drop python 3.5 support (#339)
    • Drop python 3.6 support #383
    • Add python 3.10 support #383
    • Falcon2 support drop (#353)
    • Django2 support drop (#358)
    • Support basic re_path for Django integration (#337)
    • unused NoValue type removed (#340)
    • attrs remove and use dataclasses backport for python 3.6 (#345)
    • Request validation parameters dataclass (#346)
    • Handle missing MIME type in MediaTypeFinder (#371)
    • Limit openapi dependencies upper bounds #386
    • switch to pathable #389
    • Get rid of create_spec shortcut #393
    • Request and Response protocols #407
    • validator factories removed from validation shortcuts #408
    • Predefined openapi validators #409
    • Customization refactor #412
    • Static types with mypy #414

    Backward incompatibilities

    • Python 3.6 and earlier no longer supported
    • headers attribute added to OpenAPIResponse datatype
    • RequestParameters' header attribute as Headers type
    • RequestParameters' cookie attribute as ImmutableMultiDict type
    • RequestValidationResult' parameters attribute as Parameters type
    • unused server, operation and path attributes removed from RequestValidationResult
    • EmptyParameterValue exception renamed to EmptyQueryParameterValue
    • FalconOpenAPIRequestFactory requires to be instantiated
    • create_spec shortcut replaced with Spec.create
    • OpenAPIRequest and OpenAPIResponse removed. All backward compabilities fromcontrib removed.
    • spec_validate_* shortcuts removed. Use validate_request and validate_response with validator parameter instead.
    • validate_{parameters,body,security} shortcuts removed. Use predefined openapi_request_parameters_validator, openapi_request_body_validator and openapi_request_security_validator from openapi_core.validation.request instead.
    • validate_{data,headers} shortcuts removed. Use predefined openapi_response_data_validator and openapi_response_headers_validator from openapi_core.validation.response instead.
    • custom_media_type_deserializers parameter for RequestValidator and ResponseValidator removed. Use MediaTypeDeserializersFactory with custom_deserializers parameter and pass it to validator with media_type_deserializers_factory parameter.
    • custom_formatters parameter for RequestValidator and ResponseValidator removed. Use SchemaUnmarshallersFactory with custom_formatters parameter and pass it to validator.
    Source code(tar.gz)
    Source code(zip)
  • 0.15.0a2(Sep 7, 2022)

    Changelog

    • Request and Response protocols #407
    • validator factories removed from validation shortcuts #408
    • Predefined openapi validators #409
    • Customization refactor #412

    Backward incompatibilities

    • OpenAPIRequest and OpenAPIResponse removed. All backward compabilities fromcontrib removed.
    • spec_validate_* shortcuts removed. Use validate_request and validate_response with validator parameter instead.
    • validate_{parameters,body,security} shortcuts removed. Use predefined openapi_request_parameters_validator, openapi_request_body_validator and openapi_request_security_validator from openapi_core.validation.request instead.
    • validate_{data,headers} shortcuts removed. Use predefined openapi_response_data_validator and openapi_response_headers_validator from openapi_core.validation.response instead.
    • custom_media_type_deserializers parameter for RequestValidator and ResponseValidator removed. Use MediaTypeDeserializersFactory with custom_deserializers parameter and pass it to validator with media_type_deserializers_factory parameter.
    • custom_formatters parameter for RequestValidator and ResponseValidator removed. Use SchemaUnmarshallersFactory with custom_formatters parameter and pass it to validator.
    Source code(tar.gz)
    Source code(zip)
  • 0.14.5(Sep 2, 2022)

  • 0.14.4(Sep 2, 2022)

  • 0.14.3(Sep 2, 2022)

  • 0.15.0a1(Jun 3, 2022)

    Changelog

    • Parameter deserialize complex scenario support (#329)
    • Response headers support (#332)
    • Response headers support for contrib (#333)
    • Drop python 2.7 support (#335 #344 #351)
    • Drop python 3.5 support (#339)
    • Drop python 3.6 support #383
    • Add python 3.10 support #383
    • Falcon2 support drop (#353)
    • Django2 support drop (#358)
    • Support basic re_path for Django integration (#337)
    • unused NoValue type removed (#340)
    • attrs remove and use dataclasses backport for python 3.6 (#345)
    • Request validation parameters dataclass (#346)
    • Handle missing MIME type in MediaTypeFinder (#371)
    • Limit openapi dependencies upper bounds #386
    • switch to pathable #389
    • Get rid of create_spec shortcut #393

    Backward incompatibilities

    • Python 3.6 and earlier no longer supported
    • headers attribute added to OpenAPIResponse datatype
    • RequestParameters' header attribute as Headers type
    • RequestParameters' cookie attribute as ImmutableMultiDict type
    • RequestValidationResult' parameters attribute as Parameters type
    • unused server, operation and path attributes removed from RequestValidationResult
    • EmptyParameterValue exception renamed to EmptyQueryParameterValue
    • FalconOpenAPIRequestFactory requires to be instantiated
    • create_spec shortcut replaced with Spec.create
    Source code(tar.gz)
    Source code(zip)
  • 0.14.2(May 14, 2021)

  • 0.14.1(May 8, 2021)

  • 0.14.0(May 7, 2021)

    openapi-core 0.14 is scheduled to be the last major version in the 0.x series.

    This release introduces SpecPath which reduces spec creation time and allows to get rid of big schema package

    Changes:

    • Spec replaced with SpecPath (#318)

    Backward incompatibilities:

    • create_spec shortcut returns SpecPath instead of Spec
    • removed Spec-related schema package
    • schema-related exceptions moved to top level exceptions module
    • readOnly/writeOnly invalid properties raise error (before were ommitted)
    • MediaTypeDeserializersFactory.create expects mimetype string instead of media_type
    • MediaTypeFinder.find returns media_type, mimetype tuple instead of just media_type
    Source code(tar.gz)
    Source code(zip)
  • 0.13.8(May 1, 2021)

    Changelog

    • use prepared request to format payload before converting (#271)
    • deserialize form urlencoded media type (#302)
    • deserialize data form media type (#303)
    • Media type finder (#307)
    • Add extensions support for the Parameter model (#308)
    • Response finder (#309)
    • Falcon3 support (#316)
    Source code(tar.gz)
    Source code(zip)
  • 0.13.7(Feb 15, 2021)

    Changelog

    • Any unmarshaller validate fix (#295)
    • Spec validation customization (#290)
    • Format checker deepcopy to shallowcopy (#291)
    • Format checker on validation scope (#292)
    • Basic documentation (#293)
    Source code(tar.gz)
    Source code(zip)
  • 0.13.6(Feb 9, 2021)

  • 0.13.5(Feb 1, 2021)

  • 0.13.4(Jul 20, 2020)

    Changelog

    • Paths finder relative url and simple paths check fix (#222)
    • Add documentation for custom formatters (#228)
    • Fix Requests.response factory (#227)
    • Case insensitive headers fix (#236)
    • Security HTTP provider fix (#225)
    • Unmarshalling nullable objects (#239)
    • Date-time format unmarshal tz fix (#237)
    • Templating parser path parameter search fix (#245)
    • Fix the Falcon integration to properly handle URLs with query strings. (#233)
    Source code(tar.gz)
    Source code(zip)
  • 0.13.3(Mar 11, 2020)

    Changelog

    • Path patterns finder (#202) - server and path with variables resolving
    • Requests integration (#209)
    • b64decode issue29427 fix (#210)
    • Extensible schema models (#211)
    • Use openapi-schema-validator library (#212)
    • Fix to force ConfigParser to correctly parse extra requirements (#214)
    • Falcon integration (#215)
    Source code(tar.gz)
    Source code(zip)
  • 0.13.2(Feb 24, 2020)

  • 0.13.1(Feb 18, 2020)

  • 0.13.0(Feb 17, 2020)

    Changelog

    • Validation result datatypes (#165)
    • OpenAPI request/response factories introduction (#166)
    • Django OpenAPI request/response factories (#167)
    • Schema exceptions refactor (#168)
    • Operations fields (#169)
    • Validation schema errors iter fix (#170)
    • webob support (#173)
    • CVE-2019-19844 fix (#182)
    • Move Unmarshallers to separate subpackage (#183)
    • Flask OpenAPI view & decorator (#177)
    • Flask OpenAPI request parameters (#185)
    • Move casters to separate subpackage (#184)
    • Move schema validator to separate subpackage (#186)
    • Move unmarshal out of schema models (#188)
    • Deserialise models without schema fix (#190)
    • Move deserialize/cast out of schema models (#191)
    • Custom media type deserializers (#192)
    • Missing Info models (#193)
    • Free-form objects unmarshal (#194)
    • Security validation with API Key and HTTP security types support (#195)
    • Missing path model fields (#196)
    • OpenAPI request datatype refactor (#197)
    • readOnly and writeOnly support (#152)

    Backward incompatibility

    • new datatype RequestParameters. That means parameters in RequestValidationResult is no longer dict type but you can still access parameter types (path, query, heder, cookie) lika a dict.
    • validate_body, validate_parameters and validate_data no longer accept wrapper_class, request_wrapper_class and response_wrapper_class keyword arguments. Use request_factory and response_factory instead.
    • openapi_core.wrappers.flask module moved to openapi_core.contrib.flask
    • openapi_core.wrappers.mock module moved to openapi_core.testing.mock
    • validation is now part of unmarshalling process
    • strict parameter removed
    • standardized formatting process with Formatter class. Custom formatters should inherit from the class.
    • unmarshalling process no longer raise InvalidMediaTypeValue and InvalidParameterValue exceptions
    • casting process no longer raise InvalidParameterValue exception
    • deserializing process no longer raise InvalidMediaTypeValue exception
    • OpenAPIRequest's host_url and path_pattern attributes replaced with full_url_pattern attribute
    Source code(tar.gz)
    Source code(zip)
  • 0.12.0(Sep 21, 2019)

    This release contains new Open API schema validation based on jsonschema (OAS Validator).

    Changelog

    • OAS validation with JSONSchema (#157)
    Source code(tar.gz)
    Source code(zip)
  • 0.11.1(Sep 7, 2019)

  • 0.11.0(Jun 18, 2019)

    openapi-core 0.11 is the last major version with schema validation based on internal validators (object validators). Next major versions is scheduled to be based on jsonschema validators (OAS Validator).

    Changelog

    • End of Python 3.4 support (#136)
    • Add support for one-of with any type (#133)
    • Modify FlaskOpenAPIRequest to accommodate path variables (#141)
    • Primitive types unmarshallers (#138)
    • attr errors hashable fix (#143)
    • Parameters on path item object support (#144)
    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(May 21, 2019)

    openapi-core 0.10 is the last major version with Python 3.4 support

    Changelog

    • Fix #124: Checking "additionalProperties" in "oneOf" items. (#125)
    • Add support for password string format (#132)
    • Add support for path-level parameters (#130)
    • Add support for "links" in Response (#131)
    • Fix number validator (#134)
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Mar 22, 2019)

    Changelog

    • Raw value type strict validation (#123
    • Object additionalProperties support (#121)
    • Properly formatting UUID if value is already a UUID (#112)
    • String byte format fix (#117)
    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Feb 28, 2019)

    Changelog

    • byte string format (#111)
    • Fix import in an example (#102)
    • Dont use value for determining any type (#106)
    • Test for non utc systems fix (#107)
    • Accepting uuid string format and validating accordingly (#109)
    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(Feb 28, 2019)

Owner
A
A
Sane and flexible OpenAPI 3 schema generation for Django REST framework.

drf-spectacular Sane and flexible OpenAPI 3.0 schema generation for Django REST framework. This project has 3 goals: Extract as much schema informatio

T. Franzel 1.4k Jan 8, 2023
SqlAlchemy Flask-Restful Swagger Json:API OpenAPI

SAFRS: Python OpenAPI & JSON:API Framework Overview Installation JSON:API Interface Resource Objects Relationships Methods Custom Methods Class Method

Thomas Pollet 361 Nov 16, 2022
Automated generation of real Swagger/OpenAPI 2.0 schemas from Django REST Framework code.

drf-yasg - Yet another Swagger generator Generate real Swagger/OpenAPI 2.0 specifications from a Django Rest Framework API. Compatible with Django Res

Cristi Vîjdea 3k Dec 31, 2022
Test utility for validating OpenAPI documentation

DRF OpenAPI Tester This is a test utility to validate DRF Test Responses against OpenAPI 2 and 3 schema. It has built-in support for: OpenAPI 2/3 yaml

snok 106 Jan 5, 2023
Type hints support for the Sphinx autodoc extension

sphinx-autodoc-typehints This extension allows you to use Python 3 annotations for documenting acceptable argument types and return value types of fun

Alex Grönholm 462 Dec 29, 2022
Searches a document for hash tags. Support multiple natural languages. Works in various contexts.

ht-getter Searches a document for hash tags. Supports multiple natural languages. Works in various contexts. This package uses a non-regex approach an

Rairye 1 Mar 1, 2022
Fastest Git client for Emacs.

EAF Git Client EAF Git is git client application for the Emacs Application Framework. The advantages of EAF Git are: Large log browse: support 1 milli

Emacs Application Framework 31 Dec 2, 2022
Watch a Sphinx directory and rebuild the documentation when a change is detected. Also includes a livereload enabled web server.

sphinx-autobuild Rebuild Sphinx documentation on changes, with live-reload in the browser. Installation sphinx-autobuild is available on PyPI. It can

Executable Books 440 Jan 6, 2023
A Python library for setting up projects using tabular data.

A Python library for setting up projects using tabular data. It can create project folders, standardize delimiters, and convert files to CSV from either individual files or a directory.

null 0 Dec 13, 2022
Simple yet powerful CAD (Computer Aided Design) library, written with Python.

Py-MADCAD >>> it's time to throw parametric softwares out ! Simple yet powerful CAD (Computer Aided Design) library, written with Python. Installation

jimy byerley 124 Jan 6, 2023
charcade is a string manipulation library that can animate, color, and bruteforce strings

charcade charcade is a string manipulation library that can animate, color, and bruteforce strings. Features Animating text for CLI applications with

Aaron 8 May 23, 2022
Fast syllable estimation library based on pattern matching.

Syllables: A fast syllable estimator for Python Syllables is a fast, simple syllable estimator for Python. It's intended for use in places where speed

ProseGrinder 26 Dec 14, 2022
A python package to avoid writing and maintaining duplicated python docstrings.

docstring-inheritance is a python package to avoid writing and maintaining duplicated python docstrings.

Antoine Dechaume 15 Dec 7, 2022
A comprehensive and FREE Online Python Development tutorial going step-by-step into the world of Python.

FREE Reverse Engineering Self-Study Course HERE Fundamental Python The book and code repo for the FREE Fundamental Python book by Kevin Thomas. FREE B

Kevin Thomas 7 Mar 19, 2022
A collection of simple python mini projects to enhance your python skills

A collection of simple python mini projects to enhance your python skills

PYTHON WORLD 12.1k Jan 5, 2023
Python Eacc is a minimalist but flexible Lexer/Parser tool in Python.

Python Eacc is a parsing tool it implements a flexible lexer and a straightforward approach to analyze documents.

Iury de oliveira gomes figueiredo 60 Nov 16, 2022
Repository for learning Python (Python Tutorial)

Repository for learning Python (Python Tutorial) Languages and Tools ?? Overview ?? Repository for learning Python (Python Tutorial) Languages and Too

Swiftman 2 Aug 22, 2022
advance python series: Data Classes, OOPs, python

Working With Pydantic - Built-in Data Process ========================== Normal way to process data (reading json file): the normal princiople, it's f

Phung Hưng Binh 1 Nov 8, 2021
A simple USI Shogi Engine written in python using python-shogi.

Revengeshogi My attempt at creating a USI Shogi Engine in python using python-shogi. Current State of Engine Currently only generating random moves us

null 1 Jan 6, 2022