satori-python 0.14.1__tar.gz → 0.14.2__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.
Files changed (29) hide show
  1. {satori_python-0.14.1 → satori_python-0.14.2}/PKG-INFO +1 -1
  2. {satori_python-0.14.1 → satori_python-0.14.2}/pyproject.toml +1 -1
  3. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/__init__.py +1 -1
  4. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/account.py +14 -0
  5. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/account.pyi +8 -0
  6. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/protocol.py +1 -1
  7. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/server/__init__.py +11 -10
  8. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/server/adapter.py +5 -0
  9. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/server/model.py +3 -0
  10. satori_python-0.14.2/src/satori/utils.py +17 -0
  11. {satori_python-0.14.1 → satori_python-0.14.2}/LICENSE +0 -0
  12. {satori_python-0.14.1 → satori_python-0.14.2}/README.md +0 -0
  13. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/__init__.py +0 -0
  14. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/network/__init__.py +0 -0
  15. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/network/base.py +0 -0
  16. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/network/util.py +0 -0
  17. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/network/webhook.py +0 -0
  18. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/client/network/websocket.py +0 -0
  19. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/config.py +0 -0
  20. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/const.py +0 -0
  21. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/element.py +0 -0
  22. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/event.py +0 -0
  23. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/exception.py +0 -0
  24. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/model.py +0 -0
  25. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/parser.py +0 -0
  26. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/server/conection.py +0 -0
  27. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/server/deque.py +0 -0
  28. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/server/formdata.py +0 -0
  29. {satori_python-0.14.1 → satori_python-0.14.2}/src/satori/server/route.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satori-python
3
- Version: 0.14.1
3
+ Version: 0.14.2
4
4
  Summary: Satori Protocol SDK for python
5
5
  Home-page: https://github.com/RF-Tar-Railt/satori-python
6
6
  Author-Email: RF-Tar-Railt <rf_tar_railt@qq.com>
@@ -29,7 +29,7 @@ classifiers = [
29
29
  "Programming Language :: Python :: 3.12",
30
30
  "Operating System :: OS Independent",
31
31
  ]
32
- version = "0.14.1"
32
+ version = "0.14.2"
33
33
 
34
34
  [project.license]
35
35
  text = "MIT"
@@ -43,4 +43,4 @@ from .model import Role as Role
43
43
  from .model import Upload as Upload
44
44
  from .model import User as User
45
45
 
46
- __version__ = "0.14.1"
46
+ __version__ = "0.14.2"
@@ -61,6 +61,20 @@ class Account(Generic[TP]):
61
61
  def identity(self):
62
62
  return f"{self.platform}/{self.self_id}"
63
63
 
64
+ def ensure_url(self, url: str) -> URL:
65
+ """确定链接形式。
66
+
67
+ 若链接符合以下条件之一,则返回链接的代理形式 ({host}/{path}/{version}/proxy/{url}):
68
+ - 链接以 "upload://" 开头
69
+ - 链接开头出现在 self_info.proxy_urls 中的某一项
70
+ """
71
+ if url.startswith("upload"):
72
+ return self.config.api_base / "proxy" / url.lstrip("/")
73
+ for proxy_url in self.self_info.proxy_urls:
74
+ if url.startswith(proxy_url):
75
+ return self.config.api_base / "proxy" / url.lstrip("/")
76
+ return URL(url)
77
+
64
78
  def __repr__(self):
65
79
  return f"<Account {self.self_id} ({self.platform})>"
66
80
 
@@ -63,6 +63,14 @@ class Account(Generic[TP]):
63
63
  def custom(
64
64
  self, *, protocol_cls: type[TP1] = ApiProtocol, host: str, port: int, token: str | None = None
65
65
  ) -> Account[TP1]: ...
66
+ def ensure_url(self, url: str) -> URL:
67
+ """确定链接形式。
68
+
69
+ 若链接符合以下条件之一,则返回链接的代理形式 ({host}/{path}/{version}/proxy/{url}):
70
+ - 链接以 "upload://" 开头
71
+ - 链接开头出现在 self_info.proxy_urls 中的某一项
72
+ """
73
+
66
74
  async def send(self, event: Event, message: str | Iterable[str | Element]) -> list[MessageObject]:
67
75
  """发送消息。返回一个 `MessageObject` 对象构成的数组。
68
76
 
@@ -37,7 +37,7 @@ class ApiProtocol:
37
37
 
38
38
  async def download(self, url: str):
39
39
  """访问内部链接。"""
40
- endpoint = self.account.config.api_base / "proxy" / url.lstrip("/")
40
+ endpoint = self.account.ensure_url(url)
41
41
  aio = Launart.current().get_component(AiohttpClientService)
42
42
  async with aio.session.get(endpoint) as resp:
43
43
  await validate_response(resp, noreturn=True)
@@ -20,7 +20,7 @@ from graia.amnesia.builtins.asgi import UvicornASGIService
20
20
  from launart import Launart, Service, any_completed
21
21
  from loguru import logger
22
22
  from starlette.applications import Starlette
23
- from starlette.datastructures import FormData
23
+ from starlette.datastructures import FormData as FormData
24
24
  from starlette.requests import Request as StarletteRequest
25
25
  from starlette.responses import JSONResponse, Response
26
26
  from starlette.routing import Route, WebSocketRoute
@@ -34,7 +34,7 @@ from satori.model import Event, ModelBase, Opcode
34
34
  from .adapter import Adapter as Adapter
35
35
  from .conection import WebsocketConnection
36
36
  from .deque import Deque
37
- from .formdata import parse_content_disposition
37
+ from .formdata import parse_content_disposition as parse_content_disposition
38
38
  from .model import Provider as Provider
39
39
  from .model import Request as Request
40
40
  from .model import Router as Router
@@ -94,6 +94,7 @@ class Server(Service, RouterMixin):
94
94
  self.path = path
95
95
  if self.path and not self.path.startswith("/"):
96
96
  self.path = f"/{self.path}"
97
+ self._url = f"http://{host}:{port}{self.path}/{version}"
97
98
  self._adapters = []
98
99
  self.providers = []
99
100
  self.routers = []
@@ -107,14 +108,13 @@ class Server(Service, RouterMixin):
107
108
 
108
109
  def apply(self, item: Provider | Router | Adapter):
109
110
  if isinstance(item, Adapter):
111
+ item.ensure_net(self._url)
110
112
  self._adapters.append(item)
111
113
  self.providers.append(item)
112
- for proxy_url_pf in item.proxy_urls():
113
- self.proxy_url_mapping[proxy_url_pf] = item
114
+ self.proxy_url_mapping[item.id] = item.proxy_urls()
114
115
  elif isinstance(item, Provider):
115
116
  self.providers.append(item)
116
- for proxy_url_pf in item.proxy_urls():
117
- self.proxy_url_mapping[proxy_url_pf] = item
117
+ self.proxy_url_mapping[item.id] = item.proxy_urls()
118
118
  elif isinstance(item, Router):
119
119
  self.routers.append(item)
120
120
  else:
@@ -232,10 +232,11 @@ class Server(Service, RouterMixin):
232
232
  for provider in self.providers:
233
233
  if provider.ensure(platform, self_id):
234
234
  return await provider.download_uploaded(platform, self_id, path)
235
- for proxy_url_pf, provider in self.proxy_url_mapping.items():
236
- if url.startswith(proxy_url_pf):
237
- async with self.session.get(url) as resp:
238
- return await resp.read()
235
+ for provider in self.providers:
236
+ for proxy_url_pf in self.proxy_url_mapping[provider.id]:
237
+ if url.startswith(proxy_url_pf):
238
+ async with self.session.get(url) as resp:
239
+ return await resp.read()
239
240
  raise ValueError(f"Unknown proxy url: {url}")
240
241
 
241
242
  def get_local_file(self, url: str):
@@ -9,6 +9,8 @@ from .route import RouterMixin
9
9
 
10
10
 
11
11
  class Adapter(Service, RouterMixin):
12
+ server_url: str
13
+
12
14
  @abstractmethod
13
15
  def get_platform(self) -> str: ...
14
16
 
@@ -38,3 +40,6 @@ class Adapter(Service, RouterMixin):
38
40
  @property
39
41
  def id(self):
40
42
  return f"satori-python.adapter.{self.get_platform()}#{id(self)}"
43
+
44
+ def ensure_net(self, url: str):
45
+ self.server_url = url
@@ -22,6 +22,9 @@ class Request(Generic[TP]):
22
22
 
23
23
  @runtime_checkable
24
24
  class Provider(Protocol):
25
+ @property
26
+ def id(self) -> str: ...
27
+
25
28
  def publisher(self) -> AsyncIterator[Event]: ...
26
29
 
27
30
  def authenticate(self, token: Optional[str]) -> bool: ...
@@ -0,0 +1,17 @@
1
+ import socket
2
+
3
+
4
+ def get_public_ip():
5
+ st = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
6
+ try:
7
+ st.connect(("10.255.255.255", 1))
8
+ IP = st.getsockname()[0]
9
+ except Exception:
10
+ IP = "localhost"
11
+ finally:
12
+ st.close()
13
+ return IP
14
+
15
+
16
+ if __name__ == "__main__":
17
+ print(get_public_ip()) # noqa: T201
File without changes
File without changes