sanic-org / sanic-openapi

Easily document your Sanic API with a UI
https://sanic-openapi.readthedocs.io/
MIT License
505 stars 108 forks source link

Support a validation library instead of custom modelling #6

Closed kszucs closed 5 years ago

kszucs commented 7 years ago

Like

Schematics might be the closest one. Now I need to duplicate of record definitions.

kszucs commented 7 years ago

I have a quick draft for schematics if anyone interested

from sanic_openapi.doc import summary, description, tag
from sanic_openapi.doc import route_specs

from schematics.types import StringType, IntType, DateTimeType, BooleanType, EmailType
from schematics.models import Model

from datetime import date, datetime

def to_native(field):
    if isinstance(field, list):
        return list(map(to_native, field))
    elif isinstance(field, type):
        if issubclass(field, Model):
            return {k: to_native(v) for k, v in field._fields.items()}
    elif isinstance(field, IntType):
        return int
    elif isinstance(field, BooleanType):
        return bool
    elif isinstance(field, DateTimeType):
        return datetime
    elif isinstance(field, StringType):
        return str
    else:
        raise ValueError('Unkown type: {}'.format(field))

# TODO support more args instead of just the first one
def consumes(*args, content_type=None):
    def inner(func):
        if args:
            route_specs[func].consumes = to_native(args[0])
            route_specs[func].consumes_content_type = content_type
        return func
    return inner

def produces(*args, content_type=None):
    def inner(func):
        if args:
            route_specs[func].produces = to_native(args[0])
            route_specs[func].produces_content_type = content_type
        return func
    return inner
tclarke commented 7 years ago

"jsonschema" would also be useful

tiangolo commented 7 years ago

There's also webargs: https://github.com/sloria/webargs


Reinami commented 7 years ago

This would be great to do. Would want to pick one thats most commonly used to start with but could potentially expand out to support more. Any ideas on which one? Maybe add a poll?

tiangolo commented 7 years ago

My 2 cents of what I've seen:

In comparison to the ones listed above, the closest related one would be Marshmallow which is just a bit more popular. It is a serializer / deserializer with validations.

I know that Webargs is based on the same Marshmallow fields and schemas.

But Webargs is specifically made to read parameters from requests (from JSON body, query strings, headers, etc) and Marshmallow is what does the work of serializing / deserializing.

I know that Apispec, Marshmallow and Webargs seem to be maintained by the same guys: @jmcarp and @sloria .

Apispec is the one I know that supports OpenAPI / Swagger.

Flask-Restful was considering migrating all the marshalling to Marshmallow but that project seems kind of abandoned now, I think...

It seems like Flask-restplus, which seems to be the successor of Flask-Restful, supports JSON Schema.

The maintainer of Flask-restplus, didn't like that Swagger didn't support JSON schema.

So it seems like JSON schema has quite some traction too. But still, if the idea is to support OpenAPI (a.k.a. Swagger), I don't know how hard will it be to do it.

kszucs commented 7 years ago

Asynchronous orms are good candidates too: [aio]peewee, sqlalchemy, asyncorm.

On Aug 27, 2017 4:40 PM, "Sebastián Ramírez" notifications@github.com wrote:

My 2 cents of what I've seen:

In comparison to the ones listed above, the closest related one would be Marshmallow https://github.com/marshmallow-code/marshmallow which is just a bit more popular. It is a serializer / deserializer with validations.

I know that Webargs is based on the same Marshmallow fields and schemas.

But `Webargs is specifically made to read parameters from requests (from JSON body, query strings, headers, etc) and Marshmallow is what does the work of serializing / deserializing.

I know that Apispec, Marshmallow and Webargs seem to be maintained by the same guys: @jmcarp https://github.com/jmcarp and @sloria https://github.com/sloria .

Apispec is the one I know that supports OpenAPI / Swagger.

Flask-Restful was considering migrating all the marshalling to Marshmallow https://github.com/flask-restful/flask-restful/issues/335 but that project seems kind of abandoned now, I think...

It seems like Flask-restplus supports JSON Schema http://flask-restplus.readthedocs.io/en/stable/marshalling.html#define-model-using-json-schema .

The maintainer of Flask-restplus, which seems to be the successor of Flask-Restful, didn't like that Swagger didn't support JSON schema https://github.com/noirbizarre/flask-restplus/issues/95#issuecomment-160419446

— You are receiving this because you authored the thread.

Reply to this email directly, view it on GitHub https://github.com/channelcat/sanic-openapi/issues/6#issuecomment-325202489, or mute the thread https://github.com/notifications/unsubscribe-auth/AA6s06CoTvw_ZrP_vIBhLM3PXMM20gimks5scX_mgaJpZM4Mmozu .

txomon commented 6 years ago

IMO, the best investement is to go directly for Marshmallow. It's the way people is handling (un)marshalling, it has a really stable API, and won't probably go down soon, as opposed to most of the other projects.

Finally, the fact of using sanic doesn't mean you will have an ORM below, and by supporting directly an ORM you are effectively doing vendor lock-in, and leaving out anyone not using an opinionated stack

skewty commented 5 years ago

I agree that ORM support is not a good direction. Relational databases / ORMs usually don't model complex objects nicely.

Marshmallow and JSON Schema are the two big players as far as I can tell.

JSON schema is more portable to other languages IMO. For example, JSON Schema has client side frameworks to help with web UI generation.

I'd vote for JSON schema because of the greater support outside of python on the server. The client side portion is also a huge component of modern web design and I feel marshmallow is lacking there unless I am unaware of some projects.

skewty commented 5 years ago

Also note, JSON schema works with pydantic

pydantic can export JSON schema

python json schema validator

javascript forms from json schema

tiangolo commented 5 years ago

A quick update from my side.

As @skewty says, Pydantic now supports standard JSON Schema (actually I implemented that :smile: ).

OpenAPI 3.0 (formerly known as Swagger in versions 2.0 and below) uses JSON Schema in its definitions.

So, now it's not OpenAPI OR JSON Schema. OpenAPI 3.0 includes JSON Schema (by this point I think I know those specs by memory :joy: ).

Note: OpenAPI uses a compatible but a little simplified version of JSON Schema in a couple of places. But Pydantic generates schemas compatible with both, so you would be safe with it.

~Also, APISpec doesn't support OpenAPI 3.0 just yet. So, Marshmallow would probably mean supporting only version 2.0 (a.k.a Swagger 2.0) for now.~ (check @sloria's clarification below).


I recently created FastAPI: https://github.com/tiangolo/fastapi, based on Starlette and Pydantic. To build APIs declaring everything using standard Python types (thanks to Pydantic), with automatic OpenAPI 3.0 support (including JSON Schema), validation, etc.

You might want to check the implementation to see how it could work with Pydantic.

sloria commented 5 years ago

Also, APISpec doesn't support OpenAPI 3.0 just yet. So, Marshmallow would probably mean supporting only version 2.0 (a.k.a Swagger 2.0) for now.

Minor correction: APISpec does support OpenAPI 3.0. You can pass 3.x.x to the openapi_version parameter, which will make spec.to_dict() generate an OpenAPI 3 spec.

spec = APISpec(
    openapi_version='3.0.3',
    # ...
)

https://github.com/marshmallow-code/apispec/issues/165 is still an open issue because v3 support can and will be improved. But it's already usable in newer versions of APISpec.

This isn't to put any pressure to use APISpec for the OP...use the right tool for the job. Just wanted to set the record straight =)

tiangolo commented 5 years ago

Awesome. Thanks @sloria ! I just updated that comment above.


Also, to set the record straight :smiley: :

Let me make it clear that I've been a huge fan of all the work you guys have done with Marshmallow, Webargs, APISpec and Flask-apispec (as I stated since a couple years ago, above, in this same thread).

And that combination of tools has been my main stack for a long time. And is still what I recommend in my Flask Docker image, when using Flask.

And also, those tools were a great inspiration for FastAPI as I state it in the docs, about each one of them.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this is incorrect, please respond with an update. Thank you for your contributions.