Skip to content

OpenAPI 3? #88

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

Open
diogobaeder opened this issue Apr 7, 2018 · 18 comments
Open

OpenAPI 3? #88

diogobaeder opened this issue Apr 7, 2018 · 18 comments

Comments

@diogobaeder
Copy link

Hi,

Is there any plan to support OpenAPI 3? There's quite a few, and very important, changes on that version, which are immensely useful, like the support for oneOf for example.

I can try to implement the changes and send a pull request, but I'd like to see some sign that this project is being actively maintained.

Thanks!
Diogo

@sloria
Copy link
Collaborator

sloria commented Apr 8, 2018

This is underway in apispec: marshmallow-code/apispec#165.

You can pass in openapi_spec to the APISpec constructor.

app.config.update({
    'APISPEC_SPEC': APISpec(
        #...
        openapi_version='3.0.0',
        plugins=['apispec.ext.marshmallow'],
    ),
})

@diogobaeder
Copy link
Author

In theory, yes. But it breaks Swagger completely. Maybe it's just a matter of updating Swagger? (If so, then the work required should be much smaller :-) )

@diogobaeder
Copy link
Author

diogobaeder commented Apr 9, 2018

Alright, I'm using a Swagger UI I'm serving myself, with the latest code from them, and I just hit a bug in flask-apispec: in the apidoc module, at get_operation(), it forces the operation to use parameters instead of allowing requestBody to be used in case of POST requests. Please let me know if you want me to open a new ticket for it, but it's something that needs to be addressed. (I can try to create a pull request with the changes, but I'm still too inexperienced with the library yet.)

This is the problematic line: https://github.com/jmcarp/flask-apispec/blob/master/flask_apispec/apidoc.py#L51

@sloria
Copy link
Collaborator

sloria commented Apr 9, 2018

@diogobaeder We would certainly review and merge a PR addressing that bug.

Also, if you'd like to send a PR updating the Swagger UI version, we'd merge that too!

@diogobaeder
Copy link
Author

Nice! I'll try to push some improvements in that direction. :-)

@sloria
Copy link
Collaborator

sloria commented Apr 9, 2018

It might be worth evaluating ReDoc, which is actively developed and supports OpenAPI 2 and 3.

@diogobaeder
Copy link
Author

Nice, thanks for the hint :-)

@Sytten
Copy link

Sytten commented Feb 17, 2019

The related issue in apispec is done so it should be doable

@MrBones757
Copy link

MrBones757 commented Mar 27, 2019

Hello All,

EDIT:
It appears that by adding locations=parser.locations to the use_kwargs annotation, the request succeeds when issued by postman, but apispec still seems detect the location as "query".
specifically, when setting locations to ['json'] the request succeeds when using postman but swagger does not render the endpoint correctly and only populates 1 out of 8 possible fields as a json block.

image

Just wondering if there is any update on this issue as i'm experiencing the following error which appears to be a result of a call in flask-apispec which is perhaps not dealing the the locations parameter for @use_kwargs in the correct way...?

I've tried to wrap my head around what that code is doing but i'm getting alittle lost & had a look through the OAI 3.0.0 spec to figure out how this is supposed to be treated but havent had much luck there either as far as understanding goes.

Issue is as follows:

Traceback (most recent call last):
  File "<redacted>\site-packages\flask\app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "<redacted>\site-packages\werkzeug\middleware\proxy_fix.py", line 228, in __call__
    return self.app(environ, start_response)
  File "<redacted>\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "<redacted>\site-packages\flask_cors\extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "<redacted>\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "<redacted>\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "<redacted>\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "<redacted>\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "<redacted>\site-packages\flask_cors\extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "<redacted>\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "<redacted>\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "<redacted>\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "<redacted>\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "<redacted>\site-packages\flask\views.py", line 88, in view
    return self.dispatch_request(*args, **kwargs)
  File "<redacted>\site-packages\flask\views.py", line 158, in dispatch_request
    return meth(*args, **kwargs)
  File "<redacted>\site-packages\flask_apispec\annotations.py", line 118, in wrapped
    return wrapper(*args, **kwargs)
  File "<redacted>\site-packages\flask_apispec\wrapper.py", line 29, in __call__
    response = self.call_view(*args, **kwargs)
  File "<redacted>\site-packages\flask_apispec\wrapper.py", line 43, in call_view
    parsed = parser.parse(schema, locations=option['kwargs']['locations'])
  File "<redacted>\site-packages\webargs\core.py", line 367, in parse
    schema=schema, req=req, locations=locations or self.locations
  File "<redacted>\site-packages\webargs\core.py", line 274, in _parse_request
    parsed_value = self.parse_arg(argname, field_obj, req, locations)
  File "<redacted>\site-packages\webargs\core.py", line 243, in parse_arg
    locations_to_check = self._validated_locations(locations or self.locations)
  File "<redacted>\site-packages\webargs\core.py", line 204, in _validated_locations
    raise ValueError(msg)
ValueError: Invalid locations arguments: ['requestBody']

@jtc42
Copy link

jtc42 commented Dec 30, 2019

This seems stale but just in case, any updates on this? Looking to use flask-apispec but this is causing us problems.

@mdantonio
Copy link
Contributor

Any updates on OpenApi 3.0+ support?
I just tried and failed in the same way as reported in #170

@sloria
Copy link
Collaborator

sloria commented Feb 24, 2020

OpenAPI 3 has been supported by apispec for some time. I don't have time to look into what changes are needed in flask-apispec to fix compatibility, but I'd review a PR if someone sent one.

@cosmin-novac
Copy link

Anything new on this? Flask-apispec is a great package, but incompatibility with openApi 3 greatly limits its usefulness

@Hollow-Glitch
Copy link

Any updates on the broken swagger UI?

@sloria
Copy link
Collaborator

sloria commented Sep 14, 2020

No updates from me--I nor the original creator are actively adding features at the moment, but I do review/merge/release PRs occasionally. As I pointed out in my previous comment, apispec does support OpenAPI 3, so this is just waiting for someone to take this on and make a PR.

@carstencodes
Copy link

The change, that worked for me was the following:

Change line

from

        rule_params = rule_to_params(rule, docs.get('params')) or []

to

        rule_params = rule_to_params(rule, docs.get('params'), major_api_version=self.spec.openapi_version.major) or []

and method from

def rule_to_params(rule, overrides=None):
    overrides = (overrides or {})
    result = [
        argument_to_param(argument, rule, overrides.get(argument, {}))
        for argument in rule.arguments
    ]

to

def rule_to_params(rule, overrides=None, *, major_api_version = 2):
    overrides = (overrides or {})
    result = [
        argument_to_param(argument, rule, overrides.get(argument, {}), major_api_version=major_api_version)
        for argument in rule.arguments
    ]

The function argument_to_params must be updated as well to:

def argument_to_param(argument, rule, override=None, *, major_api_version=2):
    param = {
        'in': 'path',
        'name': argument,
        'required': True,
    }
    type_, format_ = CONVERTER_MAPPING.get(type(rule._converters[argument]), DEFAULT_TYPE)
    schema = {}
    schema['type'] = type_
    if format_ is not None:
        schema['format'] = format_
    if rule.defaults and argument in rule.defaults:
        param['default'] = rule.defaults[argument]
    if major_api_version == 2:
       param.update(schema)
    elif major_api_version == 3:
       param['schema'] = schema
    else:
       raise NotImplementedError("No support for OpenAPI / Swagger Major version {}".format(major_api_version))
    param.update(override or {})
    return param

Afterwards at least the rule-based methods work again, which might at least help to solve #138 , but I'm not sure, if this helps for entire support for OpenAPI 3.

I don't know if these are the only elements creating a spec here.

Should I submit a PR?

oldPadavan pushed a commit to oldPadavan/flask-apispec that referenced this issue Jan 25, 2021
@aprilahijriyan
Copy link

+1 if flask-apispec has OpenAPI v3 support

1 similar comment
@seahawks8
Copy link

+1 if flask-apispec has OpenAPI v3 support

QuentiumYT pushed a commit to Quentium-Forks/flask-apispec that referenced this issue Apr 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests