flask-rebar icon indicating copy to clipboard operation
flask-rebar copied to clipboard

Using Docstrings to define additional swagger properties.

Open airstandley opened this issue 5 years ago • 7 comments

Related to #12

I've been thinking about this a bit, and I'd love to be able to extract some of the swagger properties from the doc-strings as well as from magic attributes (like __swagger_title__). (There is some precedent for this as we already support pulling the description of a path from the docstring.)

This might end up being un doable since enforcing formats in comments in notoriously hard. However I think it would be fantastic if

class UserResponseSchema(ResponseSchema):
    """
    User:
        A user's details.

    Example:
         {
             "first_name": "Bruce",
             "last_name": "Lee",
             "email": "[email protected]"
        }
    """
    first_name = fields.String()
    last_name = fields.String()
    email = fields.Email()

Rendered to a ResponseObject of

{
    "User": {
        "description": "A user's details.",
        "schema": {"$ref": "#/definitions/UserResponseSchema"},
        "examples": {
            "application/json": {
               "first_name": "Bruce",
               "last_name": "Lee",
               "email": "[email protected]"
            }
        }
    }
}

Interested in other's thoughts.

airstandley avatar Sep 27 '19 19:09 airstandley

To accomplish this in a more explicit way, maybe provide Swagger-flavored Marshmallow Field types that just add some ExampleMixin to __bases__, which allows passing an example kwarg. So you could do something like:

class User(Schema):
    first_name = fields.String(example="Bruce")
    last_name = fields.String(example="Lee")

Then we don't get ourselves into the messy business of parsing docstrings.

twosigmajab avatar Sep 27 '19 20:09 twosigmajab

I propose we close this in favor of supporting this in a more structured way than in docstrings, e.g. dedicated classes, params, attributes, and the like. What do you think, @airstandley et al.?

twosigmajab avatar Feb 08 '20 19:02 twosigmajab

I agree, I was also planning on creating new marshmallow fields for deprecated parameters.

Sytten avatar Feb 09 '20 04:02 Sytten

I'm still conflicted. I strongly feel that the "description" and "example" fields for a SchemaObject map well to python docstrings; their intention is non-function, they are documentation for a human reader. However expecting formatting on a docstring is generally a terrible idea so I can't see how to sensibly pull more than the "description".

@twosigmajab In either case I'd absolutely consider this an extension on top of a structured way of supporting these fields, not a replacement.

I'd like to leave this open as a placeholder unless there are strong objections.

airstandley avatar Feb 11 '20 18:02 airstandley

An idea I haven't put a lot of thought into yet so not sure if it has merit, but perhaps we could lean on some pre-existing format like YAML/TOML/JSON/whatever-we-think-is-least-obnoxious and then we can use an out of the box parser - if we encounter a docstring that the parser recognizes, we can look for particular fields (and ignore if it if's something unexpected if for some other reason somebody included a docstring with our chosen serialization flavor).. Feels like it might be an idea worth pursuing a bit - I do agree it would be nice if we could support human-readable stuff like that without requiring non-functional arguments, so I'm certainly in favor of leaving this one open in case we can come up with a best-of-both-worlds solution

RookieRick avatar Feb 11 '20 20:02 RookieRick

Marshmallow has few not very well documented field's parameter types: description, example, externalDocs which may be used for extra documentation on per field basis. Hovewer Rebar seems to support description parameter as metadata for Field only. I've tried to hack this behaviour with no great luck.

Please mention in Rebar documentation that description field is available for per field schema documentation, this will save few hours for people like me.

I'd wote for using these parameters instead of python docstrings since it's more handy to use the same field definition at multiple schemas instead of copying it with huge portion of doc everywhere.

serj-p avatar Jun 10 '20 13:06 serj-p

I think I'm convinced at this point that rendering the example using metadata in the Schema's fields is the way to go here. That's probably best suited to a separate ticket.

Still not decided as to whether using the docstring/part of the docstring as the description if some explicit description metadata is not given is a good or terrible idea. Either way we should do the same with paths so that we're consistent.

airstandley avatar Jun 15 '20 23:06 airstandley