0

I am trying to abstract away some of the route class logic (i.e. I am looking to dynamically generate routes). api.add_resource seemed like the right place to do this.

So this is what I am trying to do:

# app.py

from flask import Flask
from flask_restplus import Api, Resource, fields
from mylib import MyPost

# Define my model
json_model = api.schema_model(...)

api.add_resource(
    MyPost,
    '/acme',
    resource_class_kwargs={"json_model": json_model}
)

And then in mylib:

# mylib.py

def validate_endpoint(f):
    def wrapper(*args, **kwargs):
        return api.expect(json_fprint)(f(*args, **kwargs))
    return wrapper

class MyPost(Resource):
    def __init__(self, *args, **kwargs):
        # Passed in via api.add_resource
        self.api = args[0]
        self.json_model = kwargs['json_model']

    # I can't do this because I don't have access to 'api' here...
    # @api.expect(json_model)

    # So I am trying to make this work
    @validate_endpoint
    def post(self):
        return {"data":'some data'}, 200

I don’t have access to the global api object here so I can’t call @api.expect(json_model). But I do have access to api and json_model inside of the post method. Which is why I am trying to create my own validate_endpoint decorator.

This does not work though. Is what I am trying to do here even possible? Is there a better approach I should be taking?

country_dev
  • 605
  • 4
  • 13
  • 23

1 Answers1

0

Stop using flask-restplus. Thats the most valuable answer I can give you (and anyone else).

Ownership is not there

Flask-restplus is a fork of flask-restful. Some engineers started developing features that suited them. The core guy has ghosted the project so its been officially forked again as Flask-Restx.

Poorly designed

I used to love flask when I was a yout’. I’ve realized since then that having global request, application, config that all magically update is not a good design. Their application factory pattern (to which flask-restplus conforms) is a style of statefully mutating the application object. First of all, Its hard to test. Second of all, it means that flask-restplus is wrapping the app and therefore all of the requests/handlers. How can anyone thing thats a good thing? A library whose main feature is endpoint documentation has its filthy hands all over every one of my requests?? (btw, this is whats leading to your problem above) Because my post is serious and thoughtful I’m skipping my thoughts on the Resource class pattern as it would probably push me into the waters of ranting.

Random Feature Set

A good library has a single purpose and it does that single thing well. Flask-restplus does 15 things (masking, swagger generation, postman generation, marshaling, request arg validation). Some features you can’t even tell are in the libraries code by reading the docs.

My solution to your problem

If you want to document your code via function decorators and models use a tool that does that alone and does it well. Use one that won’t touch your handlers or effect your actual request decorators. Use oapispec for swagger generation. For the other features of flask-restplus you’ve got marshmallow for marshaling request/response data, pydantic for validating request objects and args, and so on.

btw, I know all this because I had to build an api with it. After weeks of fighting the framework I forked it, ripped it apart, created oapispec, and trashed it from the project.

rayepps
  • 2,072
  • 1
  • 12
  • 22