3

I'd like to dynamically generate docstrings for a CRUD REST API I'm building. I make heavy use Flask's MethodView, and as the docstrings are very similar I thought I'd create a mixin that would dynamically generate this documentation for me.

The issue I'm running into is I can't dynamically set the __doc__ strings of a method.

I get the error:

AttributeError: attribute 'doc' of 'method' objects is not writable

For reference this is the code I'm currently using and I'm getting an error when I call setup_routes().

from flask.views import MethodView


class CrudDocStringMixin:
    GET_TEMPLATE = """
    {0} view
        ---
        description: Get a {0}
        responses:
          200:
            content:
              application/json:
                schema: {1}
    """

    DELETE_TEMPLATE = """
    {0} view
        ---
        description: Delete a {0}
    """

    PUT_TEMPLATE = """
    {0} view
        ---
        description: Update a {0}
        responses:
          200:
            content:
              application/json:
                schema: {1}
    """

    POST_TEMPLATE = """
    {0} view
        ---
        description: Create a {0}
        responses:
          200:
            content:
              application/json:
                schema: {1}
    """

    def setup_routes(self):
        meta = getattr(self, "Meta")
        schema = getattr(meta, "schema")
        get_func = getattr(self, "get")
        if get_func:
            get_func.__doc__ = CrudDocStringMixin.GET_TEMPLATE.format("MODEL_NAME", schema.__name__)
        put_func = getattr(self, "put")
        if put_func:
            put_func.__doc__ = CrudDocStringMixin.PUT_TEMPLATE.format("MODEL_NAME", schema.__name__)
        if post_func:
            post_func.__doc__ = CrudDocStringMixin.POST_TEMPLATE.format("MODEL_NAME", schema.__name__)
        delete_func = getattr(self, "delete")
        if delete_func:
            delete_func.__doc__ = CrudDocStringMixin.DELETE_TEMPLATE.format("MODEL_NAME", schema.__name__)


class GistApi(MethodView, CrudDocStringMixin):
    class Meta:
        schema = GistSchema

    def __init__(self):
        self.setup_routes()


    def get(self):
        pass

    def post(self):
        pass

method_view = GistApi().as_view("gist")
app.add_url_rule("/gist", view_func=method_view)
with app.test_request_context():
    spec.path(view=method_view)
pprint(dict(spec.to_dict()["paths"]["/gist"]))
davidism
  • 121,510
  • 29
  • 395
  • 339
CadentOrange
  • 3,263
  • 1
  • 34
  • 52
  • That may not work because documentation of instance will be taken of class. Try to add method dynamically and see if it appears in your documentation – Lee Aug 28 '19 at 14:37

0 Answers0