satori-python-server 0.9.2__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  includes = ["src/satori/server"]
2
- raw-dependencies = ["satori-python-core >= 0.9.2"]
2
+ raw-dependencies = ["satori-python-core >= 0.11.0"]
3
3
 
4
4
  [project]
5
5
  name = "satori-python-server"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satori-python-server
3
- Version: 0.9.2
3
+ Version: 0.11.0
4
4
  Summary: Satori Protocol SDK for python, specify server part
5
5
  Home-page: https://github.com/RF-Tar-Railt/satori-python
6
6
  Author-Email: RF-Tar-Railt <rf_tar_railt@qq.com>
@@ -18,10 +18,10 @@ Project-URL: Homepage, https://github.com/RF-Tar-Railt/satori-python
18
18
  Project-URL: Repository, https://github.com/RF-Tar-Railt/satori-python
19
19
  Requires-Python: >=3.8
20
20
  Requires-Dist: launart>=0.8.2
21
- Requires-Dist: graia-amnesia>=0.8.2
22
- Requires-Dist: starlette>=0.32.0.post1
23
- Requires-Dist: uvicorn[standard]>=0.24.0.post1
24
- Requires-Dist: satori-python-core>=0.9.2
21
+ Requires-Dist: graia-amnesia>=0.9.0
22
+ Requires-Dist: starlette>=0.37.2
23
+ Requires-Dist: uvicorn[standard]>=0.28.0
24
+ Requires-Dist: satori-python-core>=0.11.0
25
25
  Description-Content-Type: text/markdown
26
26
 
27
27
  # satori-python
@@ -6,10 +6,10 @@ authors = [
6
6
  ]
7
7
  dependencies = [
8
8
  "launart>=0.8.2",
9
- "graia-amnesia>=0.8.2",
10
- "starlette>=0.32.0.post1",
11
- "uvicorn[standard]>=0.24.0.post1",
12
- "satori-python-core >= 0.9.2",
9
+ "graia-amnesia>=0.9.0",
10
+ "starlette>=0.37.2",
11
+ "uvicorn[standard]>=0.28.0",
12
+ "satori-python-core >= 0.11.0",
13
13
  ]
14
14
  description = "Satori Protocol SDK for python, specify server part"
15
15
  readme = "README.md"
@@ -25,7 +25,7 @@ classifiers = [
25
25
  "Programming Language :: Python :: 3.12",
26
26
  "Operating System :: OS Independent",
27
27
  ]
28
- version = "0.9.2"
28
+ version = "0.11.0"
29
29
 
30
30
  [project.license]
31
31
  text = "MIT"
@@ -36,19 +36,19 @@ repository = "https://github.com/RF-Tar-Railt/satori-python"
36
36
 
37
37
  [build-system]
38
38
  requires = [
39
- "mina-build>=0.5.1",
39
+ "mina-build<0.6,>=0.5.1",
40
40
  ]
41
41
  build-backend = "mina.backend"
42
42
 
43
43
  [tool.pdm.dev-dependencies]
44
44
  dev = [
45
- "isort>=5.12.0",
46
- "black>=23.11.0",
47
- "ruff>=0.1.5",
48
- "pre-commit>=3.5.0",
45
+ "isort>=5.13.2",
46
+ "black>=24.2.0",
47
+ "ruff>=0.3.2",
48
+ "pre-commit>=3.6.2",
49
49
  "fix-future-annotations>=0.5.0",
50
- "mina-build>=0.5.2",
51
- "pdm-mina>=0.3.1",
50
+ "mina-build<0.6,>=0.5.1",
51
+ "pdm-mina>=0.3.2",
52
52
  ]
53
53
 
54
54
  [tool.pdm.build]
@@ -61,7 +61,7 @@ includes = [
61
61
  composite = [
62
62
  "isort ./src/ ./example/",
63
63
  "black ./src/ ./example/",
64
- "ruff ./src/ ./example/",
64
+ "ruff check ./src/ ./example/",
65
65
  ]
66
66
 
67
67
  [tool.pdm.version]
@@ -82,6 +82,13 @@ extra_standard_library = [
82
82
  ]
83
83
 
84
84
  [tool.ruff]
85
+ line-length = 110
86
+ target-version = "py38"
87
+ exclude = [
88
+ "exam.py",
89
+ ]
90
+
91
+ [tool.ruff.lint]
85
92
  select = [
86
93
  "E",
87
94
  "W",
@@ -98,9 +105,10 @@ ignore = [
98
105
  "C901",
99
106
  "UP037",
100
107
  ]
101
- line-length = 110
102
- target-version = "py38"
103
108
 
104
109
  [tool.pyright]
105
110
  pythonPlatform = "All"
106
111
  pythonVersion = "3.8"
112
+ typeCheckingMode = "basic"
113
+ reportShadowedImports = false
114
+ disableBytesTypePromotions = true
@@ -4,7 +4,7 @@ import asyncio
4
4
  import signal
5
5
  from contextlib import suppress
6
6
  from traceback import print_exc
7
- from typing import Any, Awaitable, Callable, Iterable, cast
7
+ from typing import Callable, Iterable, Literal, cast, overload
8
8
 
9
9
  import aiohttp
10
10
  from creart import it
@@ -20,8 +20,9 @@ from yarl import URL
20
20
 
21
21
  from satori.config import WebhookInfo
22
22
  from satori.const import Api
23
- from satori.model import Event, Opcode
23
+ from satori.model import Event, ModelBase, Opcode
24
24
 
25
+ from . import route
25
26
  from .adapter import Adapter as Adapter
26
27
  from .conection import WebsocketConnection
27
28
  from .model import Provider
@@ -75,14 +76,167 @@ class Server(Service):
75
76
  else:
76
77
  raise TypeError(f"Unknown config type: {item}")
77
78
 
78
- def route(self, path: str | Api):
79
+ @overload
80
+ def route(
81
+ self, path: Literal[Api.MESSAGE_CREATE]
82
+ ) -> Callable[[route.MESSAGE_CREATE], route.MESSAGE_CREATE]: ...
83
+
84
+ @overload
85
+ def route(
86
+ self, path: Literal[Api.MESSAGE_UPDATE]
87
+ ) -> Callable[[route.MESSAGE_UPDATE], route.MESSAGE_UPDATE]: ...
88
+
89
+ @overload
90
+ def route(self, path: Literal[Api.MESSAGE_GET]) -> Callable[[route.MESSAGE_GET], route.MESSAGE_GET]: ...
91
+
92
+ @overload
93
+ def route(
94
+ self, path: Literal[Api.MESSAGE_DELETE]
95
+ ) -> Callable[[route.MESSAGE_DELETE], route.MESSAGE_DELETE]: ...
96
+
97
+ @overload
98
+ def route(
99
+ self, path: Literal[Api.MESSAGE_LIST]
100
+ ) -> Callable[[route.MESSAGE_LIST], route.MESSAGE_LIST]: ...
101
+
102
+ @overload
103
+ def route(self, path: Literal[Api.CHANNEL_GET]) -> Callable[[route.CHANNEL_GET], route.CHANNEL_GET]: ...
104
+
105
+ @overload
106
+ def route(
107
+ self, path: Literal[Api.CHANNEL_LIST]
108
+ ) -> Callable[[route.CHANNEL_LIST], route.CHANNEL_LIST]: ...
109
+
110
+ @overload
111
+ def route(
112
+ self, path: Literal[Api.CHANNEL_CREATE]
113
+ ) -> Callable[[route.CHANNEL_CREATE], route.CHANNEL_CREATE]: ...
114
+
115
+ @overload
116
+ def route(
117
+ self, path: Literal[Api.CHANNEL_UPDATE]
118
+ ) -> Callable[[route.CHANNEL_UPDATE], route.CHANNEL_UPDATE]: ...
119
+
120
+ @overload
121
+ def route(
122
+ self, path: Literal[Api.CHANNEL_DELETE]
123
+ ) -> Callable[[route.CHANNEL_DELETE], route.CHANNEL_DELETE]: ...
124
+
125
+ @overload
126
+ def route(
127
+ self, path: Literal[Api.CHANNEL_MUTE]
128
+ ) -> Callable[[route.CHANNEL_MUTE], route.CHANNEL_MUTE]: ...
129
+
130
+ @overload
131
+ def route(
132
+ self, path: Literal[Api.USER_CHANNEL_CREATE]
133
+ ) -> Callable[[route.ROUTE_USER_CHANNEL_CREATE], route.ROUTE_USER_CHANNEL_CREATE]: ...
134
+
135
+ @overload
136
+ def route(self, path: Literal[Api.GUILD_GET]) -> Callable[[route.GUILD_GET], route.GUILD_GET]: ...
137
+
138
+ @overload
139
+ def route(self, path: Literal[Api.GUILD_LIST]) -> Callable[[route.GUILD_LIST], route.GUILD_LIST]: ...
140
+
141
+ @overload
142
+ def route(self, path: Literal[Api.GUILD_APPROVE]) -> Callable[[route.APPROVE], route.APPROVE]: ...
143
+
144
+ @overload
145
+ def route(
146
+ self, path: Literal[Api.GUILD_MEMBER_LIST]
147
+ ) -> Callable[[route.GUILD_MEMBER_LIST], route.GUILD_MEMBER_LIST]: ...
148
+
149
+ @overload
150
+ def route(
151
+ self, path: Literal[Api.GUILD_MEMBER_GET]
152
+ ) -> Callable[[route.GUILD_MEMBER_GET], route.GUILD_MEMBER_GET]: ...
153
+
154
+ @overload
155
+ def route(
156
+ self, path: Literal[Api.GUILD_MEMBER_KICK]
157
+ ) -> Callable[[route.GUILD_MEMBER_KICK], route.GUILD_MEMBER_KICK]: ...
158
+
159
+ @overload
160
+ def route(
161
+ self, path: Literal[Api.GUILD_MEMBER_MUTE]
162
+ ) -> Callable[[route.GUILD_MEMBER_MUTE], route.GUILD_MEMBER_MUTE]: ...
163
+
164
+ @overload
165
+ def route(self, path: Literal[Api.GUILD_MEMBER_APPROVE]) -> Callable[[route.APPROVE], route.APPROVE]: ...
166
+
167
+ @overload
168
+ def route(
169
+ self, path: Literal[Api.GUILD_MEMBER_ROLE_SET]
170
+ ) -> Callable[[route.GUILD_MEMBER_ROLE_SET], route.GUILD_MEMBER_ROLE_SET]: ...
171
+
172
+ @overload
173
+ def route(
174
+ self, path: Literal[Api.GUILD_MEMBER_ROLE_UNSET]
175
+ ) -> Callable[[route.GUILD_MEMBER_ROLE_UNSET], route.GUILD_MEMBER_ROLE_UNSET]: ...
176
+
177
+ @overload
178
+ def route(
179
+ self, path: Literal[Api.GUILD_ROLE_LIST]
180
+ ) -> Callable[[route.GUILD_ROLE_LIST], route.GUILD_ROLE_LIST]: ...
181
+
182
+ @overload
183
+ def route(
184
+ self, path: Literal[Api.GUILD_ROLE_CREATE]
185
+ ) -> Callable[[route.GUILD_ROLE_CREATE], route.GUILD_ROLE_CREATE]: ...
186
+
187
+ @overload
188
+ def route(
189
+ self, path: Literal[Api.GUILD_ROLE_UPDATE]
190
+ ) -> Callable[[route.GUILD_ROLE_UPDATE], route.GUILD_ROLE_UPDATE]: ...
191
+
192
+ @overload
193
+ def route(
194
+ self, path: Literal[Api.GUILD_ROLE_DELETE]
195
+ ) -> Callable[[route.GUILD_ROLE_DELETE], route.GUILD_ROLE_DELETE]: ...
196
+
197
+ @overload
198
+ def route(
199
+ self, path: Literal[Api.REACTION_CREATE]
200
+ ) -> Callable[[route.REACTION_CREATE], route.REACTION_CREATE]: ...
201
+
202
+ @overload
203
+ def route(
204
+ self, path: Literal[Api.REACTION_DELETE]
205
+ ) -> Callable[[route.REACTION_DELETE], route.REACTION_DELETE]: ...
206
+
207
+ @overload
208
+ def route(
209
+ self, path: Literal[Api.REACTION_CLEAR]
210
+ ) -> Callable[[route.REACTION_CLEAR], route.REACTION_CLEAR]: ...
211
+
212
+ @overload
213
+ def route(
214
+ self, path: Literal[Api.REACTION_LIST]
215
+ ) -> Callable[[route.REACTION_LIST], route.REACTION_LIST]: ...
216
+
217
+ @overload
218
+ def route(self, path: Literal[Api.LOGIN_GET]) -> Callable[[route.LOGIN_GET], route.LOGIN_GET]: ...
219
+
220
+ @overload
221
+ def route(self, path: Literal[Api.USER_GET]) -> Callable[[route.USER_GET], route.USER_GET]: ...
222
+
223
+ @overload
224
+ def route(self, path: Literal[Api.FRIEND_LIST]) -> Callable[[route.FRIEND_LIST], route.FRIEND_LIST]: ...
225
+
226
+ @overload
227
+ def route(self, path: Literal[Api.FRIEND_APPROVE]) -> Callable[[route.APPROVE], route.APPROVE]: ...
228
+
229
+ @overload
230
+ def route(self, path: str) -> Callable[[route.INTERAL], route.INTERAL]: ...
231
+
232
+ def route(self, path: str | Api) -> Callable[[route.Router], route.Router]:
79
233
  """注册一个路由
80
234
 
81
235
  Args:
82
236
  path (str | Api): 路由路径;若 path 不属于 Api,则会被认为是内部接口
83
237
  """
84
238
 
85
- def wrapper(func: Callable[[Request], Awaitable[Any]]):
239
+ def wrapper(func: route.INTERAL):
86
240
  async def handler(request: StarletteRequest):
87
241
  res = await func(
88
242
  Request(
@@ -91,6 +245,10 @@ class Server(Service):
91
245
  await request.json(),
92
246
  )
93
247
  )
248
+ if isinstance(res, ModelBase):
249
+ return JSONResponse(content=res.dump())
250
+ if res and isinstance(res, list) and isinstance(res[0], ModelBase):
251
+ return JSONResponse(content=[_.dump() for _ in res]) # type: ignore
94
252
  return res if isinstance(res, Response) else JSONResponse(content=res)
95
253
 
96
254
  if isinstance(path, Api):
@@ -171,6 +329,10 @@ class Server(Service):
171
329
  await request.json(),
172
330
  )
173
331
  )
332
+ if isinstance(res, ModelBase):
333
+ return JSONResponse(content=res.dump())
334
+ if res and isinstance(res, list) and isinstance(res[0], ModelBase):
335
+ return JSONResponse(content=[_.dump() for _ in res])
174
336
  return res if isinstance(res, Response) else JSONResponse(content=res)
175
337
  return Response(status_code=401)
176
338
 
@@ -211,10 +373,18 @@ class Server(Service):
211
373
 
212
374
  def run(
213
375
  self,
376
+ manager: Launart | None = None,
214
377
  *,
215
378
  loop: asyncio.AbstractEventLoop | None = None,
216
379
  stop_signal: Iterable[signal.Signals] = (signal.SIGINT,),
217
380
  ):
218
- manager = it(Launart)
381
+ if manager is None:
382
+ manager = it(Launart)
219
383
  manager.add_component(self)
220
384
  manager.launch_blocking(loop=loop, stop_signal=stop_signal)
385
+
386
+ async def run_async(self, manager: Launart | None = None):
387
+ if manager is None:
388
+ manager = it(Launart)
389
+ manager.add_component(self)
390
+ await manager.launch()
@@ -3,40 +3,31 @@ from typing import Any, AsyncIterator, Dict, List
3
3
 
4
4
  from launart import Service
5
5
 
6
- from satori.const import Api
7
-
8
6
  from ..model import Event, Login
9
7
  from .model import Request
10
8
 
11
9
 
12
10
  class Adapter(Service):
13
11
  @abstractmethod
14
- def get_platform(self) -> str:
15
- ...
12
+ def get_platform(self) -> str: ...
16
13
 
17
14
  @abstractmethod
18
- def publisher(self) -> AsyncIterator[Event]:
19
- ...
15
+ def publisher(self) -> AsyncIterator[Event]: ...
20
16
 
21
17
  @abstractmethod
22
- def validate_headers(self, headers: Dict[str, Any]) -> bool:
23
- ...
18
+ def validate_headers(self, headers: Dict[str, Any]) -> bool: ...
24
19
 
25
20
  @abstractmethod
26
- def authenticate(self, token: str) -> bool:
27
- ...
21
+ def authenticate(self, token: str) -> bool: ...
28
22
 
29
23
  @abstractmethod
30
- async def get_logins(self) -> List[Login]:
31
- ...
24
+ async def get_logins(self) -> List[Login]: ...
32
25
 
33
26
  @abstractmethod
34
- async def call_api(self, request: Request[Api]) -> Any:
35
- ...
27
+ async def call_api(self, request: Request[Any]) -> Any: ...
36
28
 
37
29
  @abstractmethod
38
- async def call_internal_api(self, request: Request[str]) -> Any:
39
- ...
30
+ async def call_internal_api(self, request: Request[Any]) -> Any: ...
40
31
 
41
32
  @property
42
33
  def id(self):
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, AsyncIterator, Generic, Protocol, TypeVar, Union, runtime_checkable
5
+
6
+ from satori.const import Api
7
+ from satori.model import Event, Login
8
+
9
+ JsonType = Union[list, dict, str, int, bool, float, None]
10
+ TA = TypeVar("TA", str, Api)
11
+ TP = TypeVar("TP")
12
+
13
+
14
+ @dataclass
15
+ class Request(Generic[TP]):
16
+ headers: dict[str, Any]
17
+ action: str
18
+ params: TP
19
+
20
+
21
+ @runtime_checkable
22
+ class Provider(Protocol):
23
+ def publisher(self) -> AsyncIterator[Event]: ...
24
+
25
+ def authenticate(self, token: str) -> bool: ...
26
+
27
+ async def get_logins(self) -> list[Login]: ...
28
+
29
+
30
+ @runtime_checkable
31
+ class Router(Protocol):
32
+ def validate_headers(self, headers: dict[str, Any]) -> bool: ...
33
+
34
+ async def call_api(self, request: Request[Any]) -> Any: ...
35
+
36
+ async def call_internal_api(self, request: Request[Any]) -> Any: ...
@@ -0,0 +1,240 @@
1
+ from typing import Any, Awaitable, Dict, List, Protocol, TypeVar, Union
2
+ from typing_extensions import NotRequired, TypeAlias, TypedDict
3
+
4
+ from satori.model import Channel, Guild, Login, Member, MessageObject, ModelBase, PageResult, Role, User
5
+
6
+ from .model import Request
7
+
8
+ T = TypeVar("T")
9
+ R = TypeVar("R", covariant=True)
10
+
11
+
12
+ class Router(Protocol[T, R]):
13
+ def __call__(self, request: Request[T]) -> Awaitable[R]: ...
14
+
15
+
16
+ INTERAL: TypeAlias = Router[
17
+ Any, Union[ModelBase, List[ModelBase], Dict[str, Any], List[Dict[str, Any]], None]
18
+ ]
19
+
20
+
21
+ class MessageParam(TypedDict):
22
+ channel_id: str
23
+ content: str
24
+
25
+
26
+ MESSAGE_CREATE: TypeAlias = Router[MessageParam, Union[List[MessageObject], List[Dict[str, Any]]]]
27
+ MESSAGE_GET: TypeAlias = Router[MessageParam, Union[MessageObject, Dict[str, Any]]]
28
+ MESSAGE_DELETE: TypeAlias = Router[MessageParam, None]
29
+
30
+
31
+ class MessageUpdateParam(TypedDict):
32
+ channel_id: str
33
+ message_id: str
34
+ content: str
35
+
36
+
37
+ MESSAGE_UPDATE: TypeAlias = Router[MessageUpdateParam, None]
38
+
39
+
40
+ class MessageListParam(TypedDict):
41
+ channel_id: str
42
+ next: NotRequired[str]
43
+
44
+
45
+ MESSAGE_LIST: TypeAlias = Router[MessageListParam, Union[PageResult[MessageObject], Dict[str, Any]]]
46
+
47
+
48
+ class ChannelParam(TypedDict):
49
+ channel_id: str
50
+
51
+
52
+ CHANNEL_GET: TypeAlias = Router[ChannelParam, Union[Channel, Dict[str, Any]]]
53
+ CHANNEL_DELETE: TypeAlias = Router[ChannelParam, None]
54
+
55
+
56
+ class ChannelListParam(TypedDict):
57
+ guild_id: str
58
+ next: NotRequired[str]
59
+
60
+
61
+ CHANNEL_LIST: TypeAlias = Router[ChannelListParam, Union[PageResult[Channel], Dict[str, Any]]]
62
+
63
+
64
+ class ChanneCreateParam(TypedDict):
65
+ guild_id: str
66
+ data: dict
67
+
68
+
69
+ CHANNEL_CREATE: TypeAlias = Router[ChanneCreateParam, Union[Channel, Dict[str, Any]]]
70
+
71
+
72
+ class ChanneUpdateParam(TypedDict):
73
+ channel_id: str
74
+ data: dict
75
+
76
+
77
+ CHANNEL_UPDATE: TypeAlias = Router[ChanneUpdateParam, None]
78
+
79
+
80
+ class ChannelMuteParam(TypedDict):
81
+ channel_id: str
82
+ duration: float
83
+
84
+
85
+ CHANNEL_MUTE: TypeAlias = Router[ChannelMuteParam, None]
86
+
87
+
88
+ class UserChannelCreateParam(TypedDict):
89
+ user_id: str
90
+ guild_id: NotRequired[str]
91
+
92
+
93
+ ROUTE_USER_CHANNEL_CREATE: TypeAlias = Router[UserChannelCreateParam, Union[Channel, Dict[str, Any]]]
94
+
95
+
96
+ class GuildGetParam(TypedDict):
97
+ guild_id: str
98
+
99
+
100
+ GUILD_GET: TypeAlias = Router[GuildGetParam, Union[Guild, Dict[str, Any]]]
101
+
102
+
103
+ class GuildListParam(TypedDict):
104
+ next: NotRequired[str]
105
+
106
+
107
+ GUILD_LIST: TypeAlias = Router[GuildListParam, Union[PageResult[Guild], Dict[str, Any]]]
108
+
109
+
110
+ class GuildMemberGetParam(TypedDict):
111
+ guild_id: str
112
+ user_id: str
113
+
114
+
115
+ GUILD_MEMBER_GET: TypeAlias = Router[GuildMemberGetParam, Union[Member, Dict[str, Any]]]
116
+
117
+
118
+ class GuildXXXListParam(TypedDict):
119
+ guild_id: str
120
+ next: NotRequired[str]
121
+
122
+
123
+ GUILD_MEMBER_LIST: TypeAlias = Router[GuildXXXListParam, Union[PageResult[Member], Dict[str, Any]]]
124
+
125
+
126
+ class GuildMemberKickParam(TypedDict):
127
+ guild_id: str
128
+ user_id: str
129
+ permanent: NotRequired[bool]
130
+
131
+
132
+ GUILD_MEMBER_KICK: TypeAlias = Router[GuildMemberKickParam, None]
133
+
134
+
135
+ class GuildMemberMuteParam(TypedDict):
136
+ guild_id: str
137
+ user_id: str
138
+ duration: float
139
+
140
+
141
+ GUILD_MEMBER_MUTE: TypeAlias = Router[GuildMemberMuteParam, None]
142
+
143
+
144
+ class GuildMemberRoleParam(TypedDict):
145
+ guild_id: str
146
+ user_id: str
147
+ role_id: str
148
+
149
+
150
+ GUILD_MEMBER_ROLE_SET: TypeAlias = Router[GuildMemberRoleParam, None]
151
+ GUILD_MEMBER_ROLE_UNSET: TypeAlias = Router[GuildMemberRoleParam, None]
152
+
153
+ GUILD_ROLE_LIST: TypeAlias = Router[GuildXXXListParam, Union[PageResult[Role], Dict[str, Any]]]
154
+
155
+
156
+ class GuildRoleCreateParam(TypedDict):
157
+ guild: str
158
+ role: dict
159
+
160
+
161
+ GUILD_ROLE_CREATE: TypeAlias = Router[GuildRoleCreateParam, Union[Role, Dict[str, Any]]]
162
+
163
+
164
+ class GuildRoleUpdateParam(TypedDict):
165
+ guild: str
166
+ role_id: str
167
+ role: dict
168
+
169
+
170
+ GUILD_ROLE_UPDATE: TypeAlias = Router[GuildRoleUpdateParam, None]
171
+
172
+
173
+ class GuildRoleDeleteParam(TypedDict):
174
+ guild: str
175
+ role_id: str
176
+
177
+
178
+ GUILD_ROLE_DELETE: TypeAlias = Router[GuildRoleDeleteParam, None]
179
+
180
+
181
+ class ReactionCreateParam(TypedDict):
182
+ channel_id: str
183
+ message_id: str
184
+ emoji: str
185
+
186
+
187
+ REACTION_CREATE: TypeAlias = Router[ReactionCreateParam, None]
188
+
189
+
190
+ class ReactionDeleteParam(TypedDict):
191
+ channel_id: str
192
+ message_id: str
193
+ emoji: str
194
+ user_id: NotRequired[str]
195
+
196
+
197
+ REACTION_DELETE: TypeAlias = Router[ReactionDeleteParam, None]
198
+
199
+
200
+ class ReactionClearParam(TypedDict):
201
+ channel_id: str
202
+ message_id: str
203
+ emoji: NotRequired[str]
204
+
205
+
206
+ REACTION_CLEAR: TypeAlias = Router[ReactionClearParam, None]
207
+
208
+
209
+ class ReactionListParam(TypedDict):
210
+ channel_id: str
211
+ message_id: str
212
+ emoji: str
213
+ next: NotRequired[str]
214
+
215
+
216
+ REACTION_LIST: TypeAlias = Router[ReactionListParam, Union[PageResult[User], Dict[str, Any]]]
217
+ LOGIN_GET: TypeAlias = Router[Any, Union[Login, Dict[str, Any]]]
218
+
219
+
220
+ class UserGetParam(TypedDict):
221
+ user_id: str
222
+
223
+
224
+ USER_GET: TypeAlias = Router[UserGetParam, Union[User, Dict[str, Any]]]
225
+
226
+
227
+ class FriendListParam(TypedDict):
228
+ next: NotRequired[str]
229
+
230
+
231
+ FRIEND_LIST: TypeAlias = Router[FriendListParam, Union[PageResult[User], Dict[str, Any]]]
232
+
233
+
234
+ class ApproveParam(TypedDict):
235
+ message_id: str
236
+ approve: bool
237
+ comment: str
238
+
239
+
240
+ APPROVE: TypeAlias = Router[ApproveParam, None]
@@ -1,40 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import Any, AsyncIterator, Generic, Protocol, TypeVar, runtime_checkable
5
-
6
- from satori.const import Api
7
- from satori.model import Event, Login
8
-
9
- TA = TypeVar("TA", str, Api)
10
-
11
-
12
- @dataclass
13
- class Request(Generic[TA]):
14
- headers: dict[str, Any]
15
- action: TA
16
- params: Any
17
-
18
-
19
- @runtime_checkable
20
- class Provider(Protocol):
21
- def publisher(self) -> AsyncIterator[Event]:
22
- ...
23
-
24
- def authenticate(self, token: str) -> bool:
25
- ...
26
-
27
- async def get_logins(self) -> list[Login]:
28
- ...
29
-
30
-
31
- @runtime_checkable
32
- class Router(Protocol):
33
- def validate_headers(self, headers: dict[str, Any]) -> bool:
34
- ...
35
-
36
- async def call_api(self, request: Request[Api]) -> Any:
37
- ...
38
-
39
- async def call_internal_api(self, request: Request[str]) -> Any:
40
- ...