Skip to content

add OpenAPI schema initialization #6670

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
wants to merge 1 commit into from

Conversation

n2ygk
Copy link
Contributor

@n2ygk n2ygk commented May 13, 2019

Description

This adds the ability to provide an initial OpenAPI schema doc with some default content. Example:

class MyListView(views.ExampleListView):
    schema = AutoSchema(openapi_schema={'info': {'title': 'mytitle', 'version': 'myversion'}})

@carltongibson: I expect some of my changes are not quite correctly styled, so please review and suggest changes/reject, as you see fit.

@n2ygk
Copy link
Contributor Author

n2ygk commented May 20, 2019

@rpkilby @carltongibson ^ also this to be added to 3.10 milestone, please.

The DJA stuff I'm working on requires this as well as the others you've added to 3.10.

@rpkilby rpkilby added this to the 3.10 Release milestone May 20, 2019
@n2ygk
Copy link
Contributor Author

n2ygk commented Jun 6, 2019

@rpkilby @carltongibson FYI, In preparation of submitting PRs, I've prototyped the JSONAPI flavor of this at columbia-it/django-jsonapi-training#1 and ran into a number of limitations in the DRF implementation that lead me to override the generateschema command, and extendschemas.openapi.SchemaGenerator and schemas.openapi.AutoSchema.

The main issue with SchemaGenerator is that, with DJA, the urlpatterns can be expanded into several since we know the values of the kwarg. For example a single path:

path('v1/instructors/<pk>/relationships/<related_field>/',
        views.InstructorRelationshipView.as_view(),
        name='instructor-relationships'),

becomes two in the schema:

/instructors/{id}/relationships/course_terms/:
/instructors/{id}/relationships/person/:

I'm not sure how much of this would be appropriate to add to DRF or just let DJA override it. I'd appreciate your thoughts.

Live demo is currently at https://ac45devapp01.cc.columbia.edu/v1/openapi/

@carltongibson
Copy link
Collaborator

Hi @n2ygk. Almost certainly, subclassing SchemaGenerator is the way to go, since you need to adjust how the endpoint enumeration goes...

Q: Do we need a flag of the CLI to allow specifying a path to a SchemaGenerator class?

@n2ygk
Copy link
Contributor Author

n2ygk commented Jun 6, 2019

Q: Do we need a flag of the CLI to allow specifying a path to a SchemaGenerator class?

That might be a better way (and/or a setting) rather than having to implement an overriding command.

@carltongibson
Copy link
Collaborator

Happy to add the option. Not a setting though.

The other entry point get_schema_view() already takes a kwarg for the SchemaGenerator class, so a CLI option would make it symetrical.

Fancy making that PR? 🙂

@n2ygk
Copy link
Contributor Author

n2ygk commented Jun 6, 2019

@carltongibson #6735.

I think I may still override the generateschema command in DJA as it's cumbersome to have to do ./manage.py generateschema --generator_class=myapp.schemas.jsonapi.JSONAPISchemaGenerator

@carltongibson
Copy link
Collaborator

@ny2gk sure. The idea would be to to wrap it in a alias/script/make/etc.

Thanks for the PR!

@carltongibson
Copy link
Collaborator

Hi @n2ygk.

I think I'm going to say we should pass on this one at this point in time.

Maybe this kind of API is something we'll add but I want people to use this in the wild first.
I want to see what the common patterns are. Then we can adjust the API.

(We tried to guess the right API for v3.7. That wasn't so useful. I'd rather let people subclass and see what emerges.)

For now, just go with a SchemaGenerator subclass, as I think you have.

I hope that makes sense.

(cf "Feature Roadmap" comments I drafted for the release announcement.)

@n2ygk n2ygk deleted the openapi_initializer branch June 9, 2019 14:15
@rpkilby rpkilby removed this from the 3.10 Release milestone Jun 10, 2019
@n2ygk n2ygk restored the openapi_initializer branch August 20, 2020 16:55
@n2ygk
Copy link
Contributor Author

n2ygk commented Aug 20, 2020

@carltongibson @tomchristie I'm wondering if it's time to revisit this PR now that people have had a chance to try out the openapi schema. It undoubtedly needs to be reworked a bit but basically adds a parameter to AutoSchema which can pre-propulate anything in the OAS document rather than just the handful of info fields than can be set (title, description and version -- although that one doesn't work with generateschema management command). Here's my usage example:

class SchemaMixin(object):
    #: fill in some of the openapi schema
    openapi_schema = {
        'info': {
            'version': __version__,
            'title': __title__,
            'description':
                '![alt-text](https://cuit.columbia.edu/sites/default/files/logo/CUIT_Logo_286_web.jpg "CUIT logo")'
                '\n'
                '\n'
                '\n'
                'A sample API that uses courses as an example to demonstrate representing\n'
                '[JSON:API 1.0](http://jsonapi.org/format) in the OpenAPI 3.0 specification.\n'
                '\n'
                '\n'
                'See [https://columbia-it-django-jsonapi-training.readthedocs.io]'
                '(https://columbia-it-django-jsonapi-training.readthedocs.io)\n'
                'for more about this.\n'
                '\n'
                '\n' + __copyright__,
            'contact': {
                'name': __author__
            },
            'license': {
                'name': __license__,
                'url': __license_url__
            }
        },
        'servers': [
            {'url': 'https://localhost/v1', 'description': 'local docker'},
            {'url': 'http://localhost:8000/v1', 'description': 'local dev'},
            {'url': 'https://ac45devapp01.cc.columbia.edu/v1', 'description': 'demo'},
            {'url': '{serverURL}', 'description': 'provide your server URL',
             'variables': {'serverURL': {'default': 'http://localhost:8000/v1'}}}
        ]
    }
    schema = JSONAPIAutoSchema(openapi_schema=openapi_schema)

@carltongibson
Copy link
Collaborator

Hi @n2ygk -- there are lots of additions in master that will go into 3.12 that cover the main extension points folks have asked for. (We got most of them in already: there are a few more PRs there, which would be nice to pick up a couple of extra points if we can.)

I'm then inclined towards pointing folks to third-party provided AutoSchema/SchemaGenerator subclasses for additional bits that need.

The sketch you have here doesn't really make sense. servers for instance goes at the schema level (so would be provided by SchemaGenerator) rather than the individual view level, which is where AutoSchema comes in.

In fact, the whole example is schema level, so the correct approach is to subclass SchemaGenerator and implement get_schema() to add the extra keys you need.

@n2ygk
Copy link
Contributor Author

n2ygk commented Aug 20, 2020 via email

@carltongibson
Copy link
Collaborator

Well... I think my point is we already have it: Just subclass SchemaGenerator and implement get_schema() to add the info you want. — that's the exact extension point to add the extra data you've shown.

@n2ygk
Copy link
Contributor Author

n2ygk commented Aug 20, 2020 via email

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

Successfully merging this pull request may close these issues.

3 participants