Skip to content

Optionally disable validation #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
multimeric opened this issue Jul 28, 2020 · 5 comments
Closed

Optionally disable validation #107

multimeric opened this issue Jul 28, 2020 · 5 comments
Labels
✨ enhancement New feature or improvement
Milestone

Comments

@multimeric
Copy link

Is your feature request related to a problem? Please describe.
It seems that some OpenAPI specifications aren't always correct, but it might be helpful to allow generation anyway.

For example, I installed the latest version from the main branch using:

poetry add git+https://github.com/triaxtec/openapi-python-client.git@main
pip install importlib_metadata
openapi-python-client generate --url https://api.biocontainers.pro/ga4gh/trs/v2/openapi.json

and the warnings I got were:

Traceback (most recent call last):
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/bin/openapi-python-client", line 33, in <module>
    sys.exit(load_entry_point('openapi-python-client', 'console_scripts', 'openapi-python-client')())
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/lib/python3.7/site-packages/typer/main.py", line 214, in __call__
    return get_command(self)(*args, **kwargs)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/lib/python3.7/site-packages/typer/main.py", line 497, in wrapper
    return callback(**use_params)  # type: ignore
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/src/openapi-python-client/openapi_python_client/cli.py", line 91, in generate
    create_new_client(url=url, path=path)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/src/openapi-python-client/openapi_python_client/__init__.py", line 48, in create_new_client
    project = _get_project_for_url_or_path(url=url, path=path)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/src/openapi-python-client/openapi_python_client/__init__.py", line 31, in _get_project_for_url_or_path
    openapi = GeneratorData.from_dict(data_dict)
  File "/media/michael/Storage2/Programming/BioBackhaul/venv/src/openapi-python-client/openapi_python_client/openapi_parser/openapi.py", line 243, in from_dict
    openapi = oai.OpenAPI.parse_obj(d)
  File "pydantic/main.py", line 455, in pydantic.main.BaseModel.parse_obj
  File "pydantic/main.py", line 346, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 93 validation errors for OpenAPI
paths -> /facets -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /facets -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /facets -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /facets -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /facets -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /facets -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /facets -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /facets -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /facets -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /service-info -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /stats -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /stats -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /stats -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /stats -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /stats -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /stats -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /stats -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /stats -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /stats -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /toolClasses -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /toolClasses -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /toolClasses -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /toolClasses -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /toolClasses -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /toolClasses -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /toolClasses -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /toolClasses -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /toolClasses -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /tools -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /tools -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> responses -> 200 -> headers
  extra fields not permitted (type=value_error.extra)
paths -> /tools -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id} -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/similars -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/similars -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id} -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/containerfile -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/descriptor -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/descriptor/{relative_path} -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/files -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> content -> application/json -> schema -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> content -> application/json -> schema -> items
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> content -> application/json -> schema -> type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> content -> application/json -> schema -> x-content-type
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> $ref
  field required (type=value_error.missing)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> content
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> responses -> 200 -> description
  extra fields not permitted (type=value_error.extra)
paths -> /tools/{id}/versions/{version_id}/{type}/tests -> get -> x-openapi-router-controller
  extra fields not permitted (type=value_error.extra)
components -> securitySchemes -> BEARER -> x-apikeyInfoFunc
  extra fields not permitted (type=value_error.extra)
components -> securitySchemes -> BEARER -> $ref
  field required (type=value_error.missing)
components -> securitySchemes -> BEARER -> in
  extra fields not permitted (type=value_error.extra)
components -> securitySchemes -> BEARER -> name
  extra fields not permitted (type=value_error.extra)
components -> securitySchemes -> BEARER -> type
  extra fields not permitted (type=value_error.extra)
components -> securitySchemes -> BEARER -> x-apikeyInfoFunc
  extra fields not permitted (type=value_error.extra)

Describe the solution you'd like
I would like a flag, for example --skip-validation, that disables the validation if the errors aren't fatal. In the above case, they're simply extra fields, so it shouldn't prohibit running the generator.

Describe alternatives you've considered
I was able to use openapi-generator with the --skip-validate-spec flag, which worked, but I would like to be able to do this in pure python.

@multimeric multimeric added the ✨ enhancement New feature or improvement label Jul 28, 2020
@dbanty
Copy link
Collaborator

dbanty commented Jul 28, 2020

Interestingly these would only be problems on main right now, not on the latest released version. Pydantic is much stricter than the parse-as-we-go method being used in 0.4.x.

There's certainly no reason not to allow extra fields here and Pydantic has that capability, so that should be fixed before 0.5.0 (what main will become) is released.

There are also some errors in your example above of fields that are missing which are required. If they are truly required (and not a mistake in the Pydantic schema) then it'll take some doing to ignore them. I don't believe Pydantic has a way to do this, so it will probably require some try/except looping around the parser. You're right in that it would be a better experience to just discard the pieces of the document that were wrong instead of the whole thing.

@dbanty dbanty added this to the 0.5.0 milestone Jul 28, 2020
@multimeric
Copy link
Author

Ah, well I was hitting some other issue with the released version (I think KeyError where it assumed a key would be present).

From using another validation library (OpenAPI Enforcer for JS), I know that the missing fields are .items in certain array schemas, but the above errors don't seem to specify where the missing fields are, really. It might be nice to do so. Also, that same validation library doesn't report these additional fields. So I wonder if both of these behaviours could be improved.

dbanty added a commit that referenced this issue Aug 1, 2020
- Create vendored version of openapi-pydantic-schema in `schema`.
  - Update to this projects quality standards.
  - Allow (ignore) extra keys when parsing schema
- Redo error handling to be much more robust so more pieces of the
generator can degrade gracefully instead of outright failing.
@dbanty
Copy link
Collaborator

dbanty commented Aug 1, 2020

@TMiguelT I believe error handling on main is now robust enough to handle the example you gave above no flags needed. It will ignore any extra keys and emit warnings for pieces of the document it can't generate but keep going.

I did not add any special error handling for if something in the document violates OpenAPI schema (e.g. missing a required field) but the generator should be much better at handling valid OpenAPI documents that it just doesn't support yet.

Please give it a shot and let me know how it goes. These changes will be available in 0.5.0 whenever that milestone is complete.

@multimeric
Copy link
Author

Yep, that seems to work quite well, I'm happy with the generator just ignoring the errors in the schema unless it breaks something. Thanks!

@cmin764
Copy link

cmin764 commented Oct 17, 2023

Related to it, can we still have an option to skip validation?

I get 55 errors with openapi-python-client generate --url https://robocorp.com/api/openapi.json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ enhancement New feature or improvement
Projects
None yet
Development

No branches or pull requests

3 participants