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

Figure out a better way to manage "current view" context

Open taion opened this issue 5 years ago • 9 comments

In many places, we have to explicitly pass the view into helper classes, e.g. https://github.com/4Catalyzer/flask-resty/blob/438f439e3960118f1c9f0426bc1c0baf5a6424ac/flask_resty/view.py#L295. This is sort of clunky, and we end up passing those around in places where they may be unnecessary.

It would be better if we could bind the view object to helper class instances, or else have some flask_resty.current_view proxy.

taion avatar Feb 18 '19 23:02 taion

should be fairly easy to register the view dispatch_request no?

itajaja avatar Feb 19 '19 13:02 itajaja

yes, but that wouldn't let you do e.g. OtherView().query

taion avatar Feb 19 '19 14:02 taion

yeah. maybe something like

class FooView(...):
    authorization = FooAuth()  # insert some python magic here that does `self.authorization.view = self`, I am pretty sure it's possible

eg in the view constructor /shrug

itajaja avatar Feb 19 '19 18:02 itajaja

it works better if those are all classes, note. otherwise we'd be mutating objects or doing other magical things.

taion avatar Feb 19 '19 19:02 taion

Yeah, marshmallow and WTForms mutate field objects upon instantiation (marshmallow via a Field #_bind_to_schema(field_name, schema) hook). Using classes would be better.

Perhaps deprecate authorization in favor of authorization_class (or authorization_classes if we want to allow a collection like in DRF) which could also support the proposal in #236?

class WidgetView(GenericModelView):
    authorization_class = WidgetAuthorization | AdminAuthorization

sloria avatar Feb 26 '19 17:02 sloria

i'd call it Authorization to make inline defs a bit nicer-looking – class Authorization(FooView.Authorization) reads better than class authorization_class(FooView.authorization_class). we could take the same approach more broadly, though, e.g. with filtering, instead of doing:

filtering = Filtering(
    name=operator.eq,
)

we could have

class Filtering:
    name = operator.eq

would make it better to extend across views, too

class ExtendedView(BaseView):
    class Filtering(BaseView.Filtering):
        other_field = operator.eq

taion avatar Feb 26 '19 18:02 taion

I thought magical things are the norm in python (sqlalchemy?) :P I am fine with inlining things but it's a big change in terms of project structuring, in the sense that right now things are separated in modules by types, whereas with this approach they will be separated by functionality

itajaja avatar Feb 27 '19 00:02 itajaja

Yeah, I like the inlining idea in principle. Certainly a big change, though could be done iteratively. Also, views.py could get pretty huge...we might eventually want have a module per resource or even per view class.

sloria avatar Feb 27 '19 13:02 sloria

depends how you use FR, if you are really high in the microservices spectrum, having every view in one file is very convenient. but if we look at our big services (mgmt), that retaliates.

itajaja avatar Feb 27 '19 15:02 itajaja