New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add support for before_request hooks #1629
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good!
- Let's also add tests for
ModelView
classes withbefore_request
- Add a reference on the docs for the
ModelView
also
This supports multiple before_request
is there a use case for it? Should we add tests with multiple before_request
?
attr = getattr(view_or_api_instance, attr_name) | ||
if hasattr(attr, "_before_request_hook") and attr._before_request_hook is True: | ||
before_request_hooks.append(attr) | ||
return before_request_hooks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
totally optional, a list comprehension could look good here and can be slightly more efficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like tests began to fail. let me take a look at that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any failing tests, where do you see them failing?
No worries, was a temporary failure on packages microsoft |
@dpgaspar I added more comprehensive tests and updated to add type hints. As for the docs, I am happy to make more updates, but where I added it is the API reference section, which AFAICT is general API reference, not tied to FAB API vs FAB view. Let me know what you think. |
self._before_request_can_read = False | ||
self._before_request_can_write = False | ||
|
||
uri = "api/v1/model1beforerequest/basic" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional: we could do a for loop here to DRY these tests a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I like keeping test code "damp" rather than DRY because I think that writing out each case explicitly is easier to read, serving as documentation. Also, less likely to introduce a bug into tests if you avoid "programming" in tests.
That being said, I am happy to change it if you feel strongly.
Description
This PR adds support for a
before_request
hook that can be used in FAB's view and API classes to execute some code just before the route handler is invoked. It has the same semantics as Flask'sbefore_request
, but it is scoped only to the routes within a given FAB class and can be scoped even further to a subset of handlers within the class.Examples
Motivation
It seems like we could implement the conditional logic directly in route handlers. Why do we need a new pattern?
In many cases, implementing the conditional logic in the handler itself is preferred. To justify this change, consider the following scenario:
While technically possible to workaround these issues, the hook provides an elegant pattern for developers that enables consistency across classes, a way to keep some endpoint logic DRY and decoupled from handlers, and prevents the need to override/implement FAB's automatic route handling in some cases.
FAB Menus/Separators
FAB supports constructing UI menu items and separators, which is registered with its view. If the
before_request
hook in a view is able to dynamically enabled/disable a route, wouldn't we want the same for the menu item?I would imagine that in most (all?) cases, if a route was disabled the menu item should be unavailable too. However, I believe that exposing one pattern that handles both Flask endpoints/responses and UI component availability is hard to do elegantly.
Therefore, I propose treating the request handling and menu item separately. This PR implements the request piece, and a subsequent PR I plan to open will implement an option for executing a callable to determine if menu item is available.