apryor6 / flask_accepts

Easy, opinionated Flask input/output handling mixing Marshmallow with flask-restx
BSD 3-Clause "New" or "Revised" License
169 stars 40 forks source link

Only swagger generation for end-point #83

Open vladarefiev opened 4 years ago

vladarefiev commented 4 years ago

Hello @apryor6 . I am happy using this library, but sometimes I want to do something before validation, for example pass context to Marshmallow Schema, but I still want to generate swagger for this API.

I'd like to contribute to the library implementing such functionality. What is the best way to do it to your opinion?

What do you think?

apryor6 commented 4 years ago

Hi there! A clarifying question so that I better understand the desire - are you referring to wanting to use the Marshmallow validators and have those requirements displayed within Swagger or something else?

vladarefiev commented 4 years ago

Hey @apryor6 Sometimes I can't use @accepts , but I still want to display model generated from Marshmallow schema in Swagger. So, I supposed two options how to implement it, I suggested creating a new decorator like @swagger(api, input_schema, output_schema) which helps to display your Marshmallow schemas in Swagger. What do you think?

vryazanov commented 4 years ago

@vladarefiev @apryor6 hey guys, I'm interesting in this topic as well. The main problem to me is that I cannot pass some extra params to Schema constructor directly, for one case I want to pass partial (but I know that it'is already implemented), for another case it could be a context. That's deffinetly not a problem with partial parameter, but there are some problems with context, since in many cases the context should be generated in runtime, not import time (like if a part of context should be some data from request or request itself). Maybe the high-level interface could look like:

def get_context():
    return {'request': flask.request}

class Resource(...):
        @responds(schema=WidgetSchema, schema_context=get_context, api=api)
        def post(self):
            pass

and somewhere under the hood:

def get_create_schema(schema_class, schema_context):
    return schema_class(...., context=schema_context())

wdyt? let me know if I can help somehow

vryazanov commented 4 years ago

let's just add schema_context:Optional[dict] parameter to respond decorator at the beginning. that will make me happy :smile:

vladarefiev commented 4 years ago

I need context in @accepts as well

vryazanov commented 4 years ago

oops, sure, I meant accepts, there is no point to pass it to respond

apryor6 commented 4 years ago

Ah okay now I follow you - thanks for the example. I think your implementation about is exactly what I would suggest. If you want to contribute an implementation with supporting tests, I would be happy to review and accept a PR.

vryazanov commented 4 years ago

Started implementation and realized that we can pass an instance of schema to the decorator, so it's not a problem to pass context into constructor directly. as well as many parameter. according to https://github.com/apryor6/flask_accepts/commit/c32b169e8d7099cc0a6fc85dc326160216a13185

apryor6 commented 4 years ago

That’s probably the simplest approach - does it fully resolve this issue, or is there a case where you might need schema construction to happen at request time outside of what can be dynamic via the context param?

vryazanov commented 4 years ago

@apryor6 yes, at least it's good to automatically update the schema context with query params

class Resource(...):
        @responds(schema=WidgetSchema, api=api)
        def post(self, some_id: int):
            pass

so that some_id should go to context without any extra code. may be before this line https://github.com/apryor6/flask_accepts/blob/master/flask_accepts/decorators/decorators.py#L119 should be something like this: schema.context.update(**kwargs)

wdyt?