-
Notifications
You must be signed in to change notification settings - Fork 289
Expand file tree
/
Copy pathasync_utils.py
More file actions
116 lines (108 loc) · 4.32 KB
/
async_utils.py
File metadata and controls
116 lines (108 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import inspect
import logging
from typing import Callable, Dict, MutableSequence, Optional, Any
from slack_bolt.request.async_request import AsyncBoltRequest
from slack_bolt.response import BoltResponse
from .async_args import AsyncArgs
from slack_bolt.request.payload_utils import (
to_options,
to_shortcut,
to_action,
to_view,
to_command,
to_event,
to_message,
to_step,
)
from ..logger.messages import warning_skip_uncommon_arg_name
def build_async_required_kwargs(
*,
logger: logging.Logger,
required_arg_names: MutableSequence[str],
request: AsyncBoltRequest,
response: Optional[BoltResponse],
next_func: Optional[Callable[[], None]] = None,
this_func: Optional[Callable] = None,
error: Optional[Exception] = None, # for error handlers
next_keys_required: bool = True, # False for listeners / middleware / error handlers
) -> Dict[str, Any]:
all_available_args: Dict[str, Any] = {
"logger": logger,
"client": request.context.client,
"req": request,
"request": request,
"resp": response,
"response": response,
"context": request.context,
"body": request.body,
# payload
"options": to_options(request.body),
"shortcut": to_shortcut(request.body),
"action": to_action(request.body),
"view": to_view(request.body),
"command": to_command(request.body),
"event": to_event(request.body),
"message": to_message(request.body),
"step": to_step(request.body),
# utilities
"ack": request.context.ack,
"say": request.context.say,
"respond": request.context.respond,
"complete": request.context.complete,
"fail": request.context.fail,
"set_status": request.context.set_status,
"set_title": request.context.set_title,
"set_suggested_prompts": request.context.set_suggested_prompts,
"get_thread_context": request.context.get_thread_context,
"save_thread_context": request.context.save_thread_context,
# middleware
"next": next_func,
"next_": next_func, # for the middleware using Python's built-in `next()` function
# error handler
"error": error, # Exception
}
if not next_keys_required:
all_available_args.pop("next")
all_available_args.pop("next_")
all_available_args["payload"] = (
all_available_args["options"]
or all_available_args["shortcut"]
or all_available_args["action"]
or all_available_args["view"]
or all_available_args["command"]
or all_available_args["event"]
or all_available_args["message"]
or all_available_args["step"]
or request.body
)
for k, v in request.context.items():
if k not in all_available_args:
all_available_args[k] = v
# Defer agent creation to avoid constructing AsyncBoltAgent on every request
if "agent" in required_arg_names or "args" in required_arg_names:
all_available_args["agent"] = request.context.agent
if len(required_arg_names) > 0:
# To support instance/class methods in a class for listeners/middleware,
# check if the first argument is either self or cls
first_arg_name = required_arg_names[0]
if first_arg_name in {"self", "cls"}:
required_arg_names.pop(0)
elif first_arg_name not in all_available_args.keys() and first_arg_name != "args":
if this_func is None:
logger.warning(warning_skip_uncommon_arg_name(first_arg_name))
required_arg_names.pop(0)
elif inspect.ismethod(this_func):
# We are sure that we should skip manipulating this arg
required_arg_names.pop(0)
kwargs: Dict[str, Any] = {k: v for k, v in all_available_args.items() if k in required_arg_names}
found_arg_names = kwargs.keys()
for name in required_arg_names:
if name == "args":
if isinstance(request, AsyncBoltRequest):
kwargs[name] = AsyncArgs(**all_available_args)
else:
logger.warning(f"Unknown Request object type detected ({type(request)})")
elif name not in found_arg_names:
logger.warning(f"{name} is not a valid argument")
kwargs[name] = None
return kwargs