python-openapi / openapi-core

Openapi-core is a Python library that adds client-side and server-side support for the OpenAPI v3.0 and OpenAPI v3.1 specification.
BSD 3-Clause "New" or "Revised" License
303 stars 132 forks source link

No support for specifying any type #256

Open stojan-jovic opened 4 years ago

stojan-jovic commented 4 years ago

Swagger spec:

Query:
  type: object
  required:
    - select
  properties:
    select:
      type: array
      items:
        type: string
    where:
      type: array
      items:
        type: object
        required:
          - name
          - operator
          - value
        properties:
          name:
            type: string
          operator:
            type: string
          value:
            oneOf:
              - type: string
              - type: number
              - type: boolean
              - type: array
                items: {}

It failed to validate array type for value property (other types are validated fine, when array is removed).

Using lib in combination with Falcon, error is:

Traceback (most recent call last):
  File "D:\.venv\lib\site-packages\falcon\api.py", line 242, in __call__
    process_resource(req, resp, resource, params)
  File "D:\.venv\lib\site-packages\my_lib\falcon_svc.py", line 391, in process_resource
    result = validator.validate(openapi_request)
  File "D:\.venv\lib\site-packages\openapi_core\validation\request\validators.py", line 48, in validate
    body, body_errors = self._get_body(request, operation)
  File "D:\.venv\lib\site-packages\openapi_core\validation\request\validators.py", line 174, in _get_body
    body = self._unmarshal(media_type, casted)
  File "D:\.venv\lib\site-packages\openapi_core\validation\request\validators.py", line 221, in _unmarshal
    param_or_media_type, value, context=UnmarshalContext.REQUEST,
  File "D:\.venv\lib\site-packages\openapi_core\validation\validators.py", line 53, in _unmarshal
    return unmarshaller(value)
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 181, in __call__
    properties = self._unmarshal_properties(value)
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 225, in _unmarshal_properties
    prop)(prop_value)
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 146, in __call__
    return list(map(self.items_unmarshaller, value))
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 181, in __call__
    properties = self._unmarshal_properties(value)
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 225, in _unmarshal_properties
    prop)(prop_value)
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 244, in __call__
    return self.unmarshallers_factory.create(one_of_schema)(value)
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 146, in __call__
    return list(map(self.items_unmarshaller, value))
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\unmarshallers.py", line 141, in items_unmarshaller
    return self.unmarshallers_factory.create(self.schema.items)
  File "D:\.venv\lib\site-packages\openapi_core\unmarshalling\schemas\factories.py", line 48, in create
    raise TypeError("schema not type of Schema")
TypeError: schema not type of Schema

Maybe I'm doing something wrong (?!), but not found in OpenAPI documentation any limitation for array in usage with oneOf, so I assume that above spec is valid and issue is definitely in the lib validation.

stojan-jovic commented 4 years ago

Ok, I figured out that this is not specifically related to oneOf.

Issue is with syntax to support any type in array:

type: array
items: {}

The same issue is with following syntax (i.e. allow any type for value parameter):

value: {}

All above formats should be allowed according to the official page for working with Data Types (section for the working with arrays and objects, part for any types, at the very end of the page).

Solution for my original issue would be something like this:

value:
  oneOf:
    - type: string
    - type: number
    - type: boolean
    - type: array
      items:
        oneOf:
          - type: string
          - type: number
Stargateur commented 3 years ago

I also have get your error for no obvious reason for me.

But on a lot of route I get:

  File "falcon\app.py", line 371, in falcon.app.App.__call__
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\openapi_core\contrib\falcon\middlewares.py", line 38, in process_response
    resp_result = super(FalconOpenAPIMiddleware, self).process_response(
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\openapi_core\validation\processors.py", line 14, in process_response
    return self.response_validator.validate(request, response)
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\openapi_core\validation\response\validators.py", line 22, in validate
    _, operation, _, _, _ = self._find_path(request)
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\openapi_core\validation\validators.py", line 24, in _find_path
    return finder.find(request)
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\openapi_core\templating\paths\finders.py", line 25, in find
    if not paths_iter_peek:
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\more_itertools\more.py", line 302, in __bool__
    self.peek()
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\more_itertools\more.py", line 316, in peek
    self._cache.append(next(self._it))
  File "C:\Users\Star\AppData\Local\Programs\Python\Python39\lib\site-packages\openapi_core\templating\paths\finders.py", line 45, in _get_paths_iter
    paths = self.spec / 'paths'
TypeError: unsupported operand type(s) for /: '_io.TextIOWrapper' and 'str'

Hope this can help.