plangrid / flask-rebar

Flask-Rebar combines flask, marshmallow, and swagger for robust REST services.
MIT License
232 stars 38 forks source link

"only" option not used in Flask-Rebar #240

Open ghuser2021 opened 3 years ago

ghuser2021 commented 3 years ago

Seems like Flask-Rebar is not checking for "only" option for fields in a model. May be it could check for the use of "only" and when encountered, warn or error that it is currently not supported.

@jab suggested I create this issue.

Following is an example: @registry.handles( rule="get_upload_status/", method="GET", response_body_schema={ 200: Upload( only=[ "upload_status", "updated_time", ] ) }, tags=["General"], )

jab commented 3 years ago

Just to clarify what the problem is, when only is used in a Marshmallow schema for a particular endpoint, Flask-Rebar omits all the other fields in the corresponding model definition in the generated OpenAPI spec, even if other endpoints use the same Marshmallow schema without only or with a different set of only fields.

Here is a minimal, reproducible example:

# app.py
from marshmallow import Schema, fields
from flask_rebar import Rebar
from flask import Flask

class FooSchema(Schema):
    bar = fields.Int()
    baz = fields.Int()

rebar = Rebar()
registry = rebar.create_handler_registry(prefix="/api")

foo = {"bar": 1, "baz": 2}

@registry.handles(
    rule="/foo",
    response_body_schema=FooSchema(),
)
def foo():
    return foo

@registry.handles(
    rule="/foo/baz",
    response_body_schema=FooSchema(only=["baz"])
)
def only_baz():
    return foo

app = Flask("repro")
rebar.init_app(app)
$ curl localhost:5000/api/swagger
...
  "definitions": {
    "FooSchema": {
      "properties": {
        "baz": {
          "type": "integer"
        }
      },
...

Note that the bar field is missing for FooSchema in the generated OpenAPI spec.

Also note that this is exhibiting "last one wins" behavior. If you swap the order in which the foo() and the only_baz() endpoints are defined in app.py, you'll get a different result generated for FooSchema in the OpenAPI spec.

@ghuser2021 said he could work around the issue by not using only.