Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions slack_bolt/kwargs_injection/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def handle_buttons(ack, respond, logger, context, body, client):
# middleware
next: Callable[[], None]
"""`next()` utility function, which tells the middleware chain that it can continue with the next one"""
next_: Callable[[], None]
"""An alias of `next()` for avoiding the Python built-in method overrides in middleware functions"""

def __init__(
self,
Expand All @@ -93,6 +95,9 @@ def __init__(
ack: Ack,
say: Say,
respond: Respond,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], None],
**kwargs # noqa
):
Expand All @@ -116,3 +121,4 @@ def __init__(
self.say: Say = say
self.respond: Respond = respond
self.next: Callable[[], None] = next
self.next_: Callable[[], None] = next
3 changes: 3 additions & 0 deletions slack_bolt/kwargs_injection/async_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ async def handle_buttons(ack, respond, logger, context, body, client):
# middleware
next: Callable[[], Awaitable[None]]
"""`next()` utility function, which tells the middleware chain that it can continue with the next one"""
next_: Callable[[], Awaitable[None]]
"""An alias of `next()` for avoiding the Python built-in method overrides in middleware functions"""

def __init__(
self,
Expand Down Expand Up @@ -115,3 +117,4 @@ def __init__(
self.say: AsyncSay = say
self.respond: AsyncRespond = respond
self.next: Callable[[], Awaitable[None]] = next
self.next_: Callable[[], Awaitable[None]] = next
1 change: 1 addition & 0 deletions slack_bolt/kwargs_injection/async_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def build_async_required_kwargs(
"respond": request.context.respond,
# middleware
"next": next_func,
"next_": next_func, # for the middleware using Python's built-in `next()` function
}
all_available_args["payload"] = (
all_available_args["options"]
Expand Down
1 change: 1 addition & 0 deletions slack_bolt/kwargs_injection/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def build_required_kwargs(
"respond": request.context.respond,
# middleware
"next": next_func,
"next_": next_func, # for the middleware using Python's built-in `next()` function

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this enables bolt-python to resolve the alias name as well.

}
all_available_args["payload"] = (
all_available_args["options"]
Expand Down
4 changes: 2 additions & 2 deletions slack_bolt/listener/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ def run_middleware(
for m in self.middleware:
middleware_state = {"next_called": False}

def next():
def next_():

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not an essential part of this PR. It's just a minor refactoring

middleware_state["next_called"] = True

resp = m.process(req=req, resp=resp, next=next)
resp = m.process(req=req, resp=resp, next=next_)
if not middleware_state["next_called"]:
# next() was not called in this middleware
return (resp, True)
Expand Down
2 changes: 1 addition & 1 deletion slack_bolt/logger/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def warning_unhandled_by_global_middleware( # type: ignore
name: str, req: Union[BoltRequest, "AsyncBoltRequest"] # type: ignore
) -> str: # type: ignore
return (
f"A global middleware ({name}) skipped calling `next()` "
f"A global middleware ({name}) skipped calling either `next()` or `next_()` "
f"without providing a response for the request ({req.body})"
)

Expand Down
3 changes: 3 additions & 0 deletions slack_bolt/middleware/async_custom_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ async def async_process(
*,
req: AsyncBoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], Awaitable[BoltResponse]],
) -> BoltResponse:
return await self.func(
Expand Down
11 changes: 11 additions & 0 deletions slack_bolt/middleware/async_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ async def async_process(
*,
req: AsyncBoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], Awaitable[BoltResponse]],
) -> Optional[BoltResponse]:
"""Processes a request data before other middleware and listeners.
Expand All @@ -24,6 +27,14 @@ async def simple_middleware(req, resp, next):
# do something here
await next()

This `async_process(req, resp, next)` method is supposed to be invoked only inside bolt-python.
If you want to avoid the name `next()` in your middleware functions, you can use `next_()` method instead.

@app.middleware
async def simple_middleware(req, resp, next_):
# do something here
await next_()

Args:
req: The incoming request
resp: The response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ async def async_process(
*,
req: AsyncBoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], Awaitable[BoltResponse]],
) -> BoltResponse:
if _is_no_auth_required(req):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ async def async_process(
*,
req: AsyncBoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], Awaitable[BoltResponse]],
) -> BoltResponse:
if _is_no_auth_required(req):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> BoltResponse:
if _is_no_auth_required(req):
Expand Down
3 changes: 3 additions & 0 deletions slack_bolt/middleware/custom_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> BoltResponse:
return self.func(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ async def async_process(
*,
req: AsyncBoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], Awaitable[BoltResponse]],
) -> BoltResponse:
text = req.body.get("event", {}).get("text", "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> BoltResponse:
text = req.body.get("event", {}).get("text", "")
Expand Down
11 changes: 11 additions & 0 deletions slack_bolt/middleware/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> Optional[BoltResponse]:
"""Processes a request data before other middleware and listeners.
Expand All @@ -24,6 +27,14 @@ def simple_middleware(req, resp, next):
# do something here
next()

This `process(req, resp, next)` method is supposed to be invoked only inside bolt-python.
If you want to avoid the name `next()` in your middleware functions, you can use `next_()` method instead.

@app.middleware
def simple_middleware(req, resp, next_):
# do something here
next_()

Args:
req: The incoming request
resp: The response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ async def async_process(
*,
req: AsyncBoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], Awaitable[BoltResponse]],
) -> BoltResponse:
if self._can_skip(req.mode, req.body):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> BoltResponse:
if self._can_skip(req.mode, req.body):
Expand Down
3 changes: 3 additions & 0 deletions slack_bolt/middleware/ssl_check/async_ssl_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ async def async_process(
*,
req: AsyncBoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], Awaitable[BoltResponse]],
) -> BoltResponse:
if self._is_ssl_check_request(req.body):
Expand Down
3 changes: 3 additions & 0 deletions slack_bolt/middleware/ssl_check/ssl_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> BoltResponse:
if self._is_ssl_check_request(req.body):
Expand Down
3 changes: 3 additions & 0 deletions slack_bolt/middleware/url_verification/url_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> BoltResponse:
if self._is_url_verification_request(req.body):
Expand Down
3 changes: 3 additions & 0 deletions slack_bolt/workflows/step/step_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ def process(
*,
req: BoltRequest,
resp: BoltResponse,
# As this method is not supposed to be invoked by bolt-python users,
# the naming conflict with the built-in one affects
# only the internals of this method
next: Callable[[], BoltResponse],
) -> Optional[BoltResponse]:

Expand Down
68 changes: 68 additions & 0 deletions tests/scenario_tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,53 @@ def test_next_call(self):
assert response.body == "acknowledged!"
assert_auth_test_count(self, 1)

def test_decorator_next_call(self):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking these test patterns should be helpful for knowing the purpose of the changes.

app = App(
client=self.web_client,
signing_secret=self.signing_secret,
)

@app.middleware
def just_next(next):
next()

app.shortcut("test-shortcut")(just_ack)

response = app.dispatch(self.build_request())
assert response.status == 200
assert response.body == "acknowledged!"
assert_auth_test_count(self, 1)

def test_next_call_(self):
app = App(
client=self.web_client,
signing_secret=self.signing_secret,
)
app.use(just_next_)
app.shortcut("test-shortcut")(just_ack)

response = app.dispatch(self.build_request())
assert response.status == 200
assert response.body == "acknowledged!"
assert_auth_test_count(self, 1)

def test_decorator_next_call_(self):
app = App(
client=self.web_client,
signing_secret=self.signing_secret,
)

@app.middleware
def just_next_(next_):
next_()

app.shortcut("test-shortcut")(just_ack)

response = app.dispatch(self.build_request())
assert response.status == 200
assert response.body == "acknowledged!"
assert_auth_test_count(self, 1)

def test_class_call(self):
class NextClass:
def __call__(self, next):
Expand All @@ -104,6 +151,23 @@ def __call__(self, next):
assert response.body == "acknowledged!"
assert_auth_test_count(self, 1)

def test_class_call_(self):
class NextUnderscoreClass:
def __call__(self, next_):
next_()

app = App(
client=self.web_client,
signing_secret=self.signing_secret,
)
app.use(NextUnderscoreClass())
app.shortcut("test-shortcut")(just_ack)

response = app.dispatch(self.build_request())
assert response.status == 200
assert response.body == "acknowledged!"
assert_auth_test_count(self, 1)


def just_ack(ack):
ack("acknowledged!")
Expand All @@ -115,3 +179,7 @@ def no_next():

def just_next(next):
next()


def just_next_(next_):
next_()
Loading