mirror of
https://github.com/LiteyukiStudio/LiteyukiBot.git
synced 2024-11-22 21:27:43 +08:00
⬇️ 更新文档样式
This commit is contained in:
parent
3a3ef4d6ae
commit
f12b6854b7
3
.github/workflows/deploy-docs.yml
vendored
3
.github/workflows/deploy-docs.yml
vendored
@ -42,7 +42,8 @@ jobs:
|
||||
- name: 生成API markdown
|
||||
run: |-
|
||||
python -m pip install pydantic
|
||||
python liteyuki/mkdoc.py
|
||||
python -m litedoc liteyuki -o docs/dev/api -l zh-Hans -t vuepress
|
||||
python -m litedoc liteyuki -o docs/en/dev/api -l en -t vuepress
|
||||
|
||||
|
||||
- name: 构建文档
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,22 +1,18 @@
|
||||
---
|
||||
title: liteyuki.bot
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `get_bot() -> LiteyukiBot`
|
||||
|
||||
获取轻雪实例
|
||||
### *func* `get_bot() -> LiteyukiBot`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 获取轻雪实例
|
||||
|
||||
|
||||
**返回**: LiteyukiBot: 当前的轻雪实例
|
||||
|
||||
LiteyukiBot: 当前的轻雪实例
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_bot() -> LiteyukiBot:
|
||||
@ -35,24 +31,21 @@ def get_bot() -> LiteyukiBot:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_config(key: str, default: Any) -> Any`
|
||||
|
||||
获取配置
|
||||
|
||||
Args:
|
||||
|
||||
key: 配置键
|
||||
|
||||
default: 默认值
|
||||
### *func* `get_config(key: str = None) -> Any`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 获取配置
|
||||
|
||||
**参数**:
|
||||
> - key: 配置键
|
||||
> - default: 默认值
|
||||
|
||||
**返回**: Any: 配置值
|
||||
|
||||
Any: 配置值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_config(key: str, default: Any=None) -> Any:
|
||||
@ -69,26 +62,22 @@ def get_config(key: str, default: Any=None) -> Any:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_config_with_compat(key: str, compat_keys: tuple[str], default: Any) -> Any`
|
||||
|
||||
获取配置,兼容旧版本
|
||||
|
||||
Args:
|
||||
|
||||
key: 配置键
|
||||
|
||||
compat_keys: 兼容键
|
||||
|
||||
default: 默认值
|
||||
### *func* `get_config_with_compat(key: str = None) -> Any`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 获取配置,兼容旧版本
|
||||
|
||||
**参数**:
|
||||
> - key: 配置键
|
||||
> - compat_keys: 兼容键
|
||||
> - default: 默认值
|
||||
|
||||
**返回**: Any: 配置值
|
||||
|
||||
Any: 配置值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_config_with_compat(key: str, compat_keys: tuple[str], default: Any=None) -> Any:
|
||||
@ -112,12 +101,11 @@ def get_config_with_compat(key: str, compat_keys: tuple[str], default: Any=None)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `print_logo() -> None`
|
||||
|
||||
### *func* `print_logo()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def print_logo():
|
||||
@ -125,22 +113,20 @@ def print_logo():
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `LiteyukiBot`
|
||||
### **class** `LiteyukiBot`
|
||||
### *method* `__init__(self) -> None`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
**说明**: 初始化轻雪实例
|
||||
|
||||
 初始化轻雪实例
|
||||
**参数**:
|
||||
> - *args:
|
||||
> - **kwargs: 配置
|
||||
|
||||
Args:
|
||||
|
||||
*args:
|
||||
|
||||
**kwargs: 配置
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
@ -177,12 +163,15 @@ def __init__(self, *args, **kwargs) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `run(self) -> None`
|
||||
### *method* `run(self)`
|
||||
|
||||
|
||||
|
||||
**说明**: 启动逻辑
|
||||
|
||||
 启动逻辑
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def run(self):
|
||||
@ -196,14 +185,15 @@ def run(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `keep_alive(self) -> None`
|
||||
### *method* `keep_alive(self)`
|
||||
|
||||
 保持轻雪运行
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 保持轻雪运行
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def keep_alive(self):
|
||||
@ -221,14 +211,46 @@ def keep_alive(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `restart(self, delay: int) -> None`
|
||||
### *method* `_handle_exit(self, signum, frame)`
|
||||
|
||||
 重启轻雪本体
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 信号处理
|
||||
|
||||
**参数**:
|
||||
> - signum:
|
||||
> - frame:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def _handle_exit(self, signum, frame):
|
||||
"""
|
||||
信号处理
|
||||
Args:
|
||||
signum:
|
||||
frame:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
logger.info('Received signal, stopping all processes.')
|
||||
self.stop()
|
||||
sys.exit(0)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `restart(self, delay: int = 0)`
|
||||
|
||||
|
||||
|
||||
**说明**: 重启轻雪本体
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def restart(self, delay: int=0):
|
||||
@ -257,18 +279,18 @@ def restart(self, delay: int=0):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `restart_process(self, name: Optional[str]) -> None`
|
||||
### *method* `restart_process(self, name: Optional[str] = None)`
|
||||
|
||||
 停止轻雪
|
||||
|
||||
Args:
|
||||
|
||||
name: 进程名称, 默认为None, 所有进程
|
||||
**说明**: 停止轻雪
|
||||
|
||||
**参数**:
|
||||
> - name: 进程名称, 默认为None, 所有进程
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def restart_process(self, name: Optional[str]=None):
|
||||
@ -290,14 +312,15 @@ def restart_process(self, name: Optional[str]=None):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `init(self) -> None`
|
||||
### *method* `init(self)`
|
||||
|
||||
 初始化轻雪, 自动调用
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 初始化轻雪, 自动调用
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def init(self, *args, **kwargs):
|
||||
@ -310,12 +333,11 @@ def init(self, *args, **kwargs):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `init_logger(self) -> None`
|
||||
### *method* `init_logger(self)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def init_logger(self):
|
||||
@ -323,14 +345,15 @@ def init_logger(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `stop(self) -> None`
|
||||
### *method* `stop(self)`
|
||||
|
||||
 停止轻雪
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 停止轻雪
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def stop(self):
|
||||
@ -344,20 +367,18 @@ def stop(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_start(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册启动前的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_before_start(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册启动前的函数
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_start(self, func: LIFESPAN_FUNC):
|
||||
@ -373,20 +394,18 @@ def on_before_start(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_start(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册启动后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_start(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册启动后的函数
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_start(self, func: LIFESPAN_FUNC):
|
||||
@ -402,20 +421,18 @@ def on_after_start(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_shutdown(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册停止后的函数:未实现
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_shutdown(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册停止后的函数:未实现
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_shutdown(self, func: LIFESPAN_FUNC):
|
||||
@ -431,20 +448,18 @@ def on_after_shutdown(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册进程停止前的函数,为子进程停止时调用
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_before_process_shutdown(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册进程停止前的函数,为子进程停止时调用
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_shutdown(self, func: LIFESPAN_FUNC):
|
||||
@ -460,20 +475,18 @@ def on_before_process_shutdown(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_restart(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册进程重启前的函数,为子进程重启时调用
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_before_process_restart(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册进程重启前的函数,为子进程重启时调用
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_restart(self, func: LIFESPAN_FUNC):
|
||||
@ -489,20 +502,18 @@ def on_before_process_restart(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_restart(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册重启后的函数:未实现
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_restart(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册重启后的函数:未实现
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_restart(self, func: LIFESPAN_FUNC):
|
||||
@ -518,20 +529,18 @@ def on_after_restart(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_nonebot_init(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册nonebot初始化后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_nonebot_init(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册nonebot初始化后的函数
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_nonebot_init(self, func: LIFESPAN_FUNC):
|
||||
@ -547,35 +556,7 @@ def on_after_nonebot_init(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `executable = sys.executable`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args = sys.argv`
|
||||
|
||||
|
||||
|
||||
### ***var*** `chan_active = get_channel(f'{name}-active')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'start'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `chan_active = get_channel(f'{process_name}-active')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'nohup'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'open'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'nohup'`
|
||||
|
||||
### ***var*** `_BOT_INSTANCE = NO_DEFAULT`
|
||||
|
||||
- **类型**: `LiteyukiBot`
|
||||
|
||||
|
@ -1,57 +1,16 @@
|
||||
---
|
||||
title: liteyuki.bot.lifespan
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### **class** `Lifespan`
|
||||
### *method* `__init__(self) -> None`
|
||||
|
||||
### ***def*** `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
|
||||
|
||||
运行函数
|
||||
|
||||
Args:
|
||||
**说明**: 轻雪生命周期管理,启动、停止、重启
|
||||
|
||||
funcs:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
def run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC], *args, **kwargs) -> None:
|
||||
"""
|
||||
运行函数
|
||||
Args:
|
||||
funcs:
|
||||
Returns:
|
||||
"""
|
||||
try:
|
||||
loop = asyncio.get_event_loop()
|
||||
except RuntimeError:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
tasks = []
|
||||
for func in funcs:
|
||||
if is_coroutine_callable(func):
|
||||
tasks.append(func(*args, **kwargs))
|
||||
else:
|
||||
tasks.append(async_wrapper(func)(*args, **kwargs))
|
||||
loop.run_until_complete(asyncio.gather(*tasks))
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `Lifespan`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
|
||||
 轻雪生命周期管理,启动、停止、重启
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self) -> None:
|
||||
@ -69,19 +28,19 @@ def __init__(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***@staticmethod***
|
||||
###   ***def*** `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
|
||||
### `@staticmethod`
|
||||
### *method* `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
|
||||
|
||||
 运行函数
|
||||
|
||||
Args:
|
||||
|
||||
funcs:
|
||||
**说明**: 运行函数
|
||||
|
||||
**参数**:
|
||||
> - funcs:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
@ -107,20 +66,20 @@ def run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC], *args, **kwarg
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册启动时的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**说明**: 注册启动时的函数
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
**返回**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -136,20 +95,20 @@ def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册启动时的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**说明**: 注册启动时的函数
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
**返回**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -165,20 +124,20 @@ def on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册停止前的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**说明**: 注册停止前的函数
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
**返回**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -194,22 +153,20 @@ def on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册停止后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册停止后的函数
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
**返回**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -227,20 +184,20 @@ def on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册重启时的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**说明**: 注册重启时的函数
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
**返回**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -256,20 +213,20 @@ def on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册重启后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**说明**: 注册重启后的函数
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
**返回**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -285,20 +242,18 @@ def on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_nonebot_init(self, func: Any) -> None`
|
||||
|
||||
 注册 NoneBot 初始化后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_nonebot_init(self, func)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 注册 NoneBot 初始化后的函数
|
||||
|
||||
**参数**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_nonebot_init(self, func):
|
||||
@ -315,14 +270,15 @@ def on_after_nonebot_init(self, func):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `before_start(self) -> None`
|
||||
### *method* `before_start(self) -> None`
|
||||
|
||||
 启动前
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 启动前
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def before_start(self) -> None:
|
||||
@ -335,14 +291,15 @@ def before_start(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `after_start(self) -> None`
|
||||
### *method* `after_start(self) -> None`
|
||||
|
||||
 启动后
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 启动后
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def after_start(self) -> None:
|
||||
@ -355,14 +312,15 @@ def after_start(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `before_process_shutdown(self) -> None`
|
||||
### *method* `before_process_shutdown(self) -> None`
|
||||
|
||||
 停止前
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 停止前
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def before_process_shutdown(self) -> None:
|
||||
@ -375,14 +333,15 @@ def before_process_shutdown(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `after_shutdown(self) -> None`
|
||||
### *method* `after_shutdown(self) -> None`
|
||||
|
||||
 停止后
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 停止后
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def after_shutdown(self) -> None:
|
||||
@ -395,14 +354,15 @@ def after_shutdown(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `before_process_restart(self) -> None`
|
||||
### *method* `before_process_restart(self) -> None`
|
||||
|
||||
 重启前
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 重启前
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def before_process_restart(self) -> None:
|
||||
@ -415,14 +375,15 @@ def before_process_restart(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `after_restart(self) -> None`
|
||||
### *method* `after_restart(self) -> None`
|
||||
|
||||
 重启后
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 重启后
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def after_restart(self) -> None:
|
||||
@ -436,15 +397,27 @@ def after_restart(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `tasks = []`
|
||||
### ***var*** `SYNC_LIFESPAN_FUNC = Callable[[], Any]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `ASYNC_LIFESPAN_FUNC = Callable[[], Awaitable[Any]]`
|
||||
|
||||
### ***var*** `loop = asyncio.get_event_loop()`
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `LIFESPAN_FUNC = SYNC_LIFESPAN_FUNC | ASYNC_LIFESPAN_FUNC`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `loop = asyncio.new_event_loop()`
|
||||
### ***var*** `SYNC_PROCESS_LIFESPAN_FUNC = Callable[[str], Any]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `ASYNC_PROCESS_LIFESPAN_FUNC = Callable[[str], Awaitable[Any]]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `PROCESS_LIFESPAN_FUNC = SYNC_PROCESS_LIFESPAN_FUNC | ASYNC_PROCESS_LIFESPAN_FUNC`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.comm
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,22 +1,19 @@
|
||||
---
|
||||
title: liteyuki.comm.channel
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `set_channel()`
|
||||
|
||||
### ***def*** `set_channel(name: str, channel: Channel) -> None`
|
||||
|
||||
设置通道实例
|
||||
|
||||
Args:
|
||||
**说明**: 设置通道实例
|
||||
|
||||
name: 通道名称
|
||||
**参数**:
|
||||
> - name: 通道名称
|
||||
> - channel: 通道实例
|
||||
|
||||
channel: 通道实例
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def set_channel(name: str, channel: Channel):
|
||||
@ -35,16 +32,18 @@ def set_channel(name: str, channel: Channel):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `set_channels(channels: dict[str, Channel]) -> None`
|
||||
### *func* `set_channels()`
|
||||
|
||||
设置通道实例
|
||||
|
||||
Args:
|
||||
|
||||
channels: 通道名称
|
||||
**说明**: 设置通道实例
|
||||
|
||||
**参数**:
|
||||
> - channels: 通道名称
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def set_channels(channels: dict[str, Channel]):
|
||||
@ -58,18 +57,18 @@ def set_channels(channels: dict[str, Channel]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_channel(name: str) -> Channel`
|
||||
### *func* `get_channel() -> Channel`
|
||||
|
||||
获取通道实例
|
||||
|
||||
Args:
|
||||
|
||||
name: 通道名称
|
||||
**说明**: 获取通道实例
|
||||
|
||||
**参数**:
|
||||
> - name: 通道名称
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_channel(name: str) -> Channel:
|
||||
@ -88,14 +87,15 @@ def get_channel(name: str) -> Channel:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_channels() -> dict[str, Channel]`
|
||||
### *func* `get_channels() -> dict[str, Channel]`
|
||||
|
||||
获取通道实例
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 获取通道实例
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_channels() -> dict[str, Channel]:
|
||||
@ -112,12 +112,12 @@ def get_channels() -> dict[str, Channel]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_set_channel(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'set_channel')`
|
||||
### *func* `on_set_channel()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'set_channel')
|
||||
@ -127,12 +127,12 @@ def on_set_channel(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get_channel(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channel')`
|
||||
### *func* `on_get_channel()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channel')
|
||||
@ -142,12 +142,12 @@ def on_get_channel(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get_channels(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channels')`
|
||||
### *func* `on_get_channels()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channels')
|
||||
@ -157,81 +157,23 @@ def on_get_channels(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: Callable[[T], Any]) -> Callable[[T], Any]`
|
||||
### **class** `Channel(Generic[T])`
|
||||
### *method* `__init__(self, _id: str = '', type_check: Optional[bool] = None)`
|
||||
|
||||
|
||||
|
||||
**说明**: 初始化通道
|
||||
|
||||
**参数**:
|
||||
> - _id: 通道ID
|
||||
> - type_check: 是否开启类型检查, 若为空,则传入泛型默认开启,否则默认关闭
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def decorator(func: Callable[[T], Any]) -> Callable[[T], Any]:
|
||||
global _func_id
|
||||
|
||||
async def wrapper(data: T) -> Any:
|
||||
if filter_func is not None:
|
||||
if is_coroutine_callable(filter_func):
|
||||
if not await filter_func(data):
|
||||
return
|
||||
elif not filter_func(data):
|
||||
return
|
||||
if is_coroutine_callable(func):
|
||||
return await func(data)
|
||||
else:
|
||||
return func(data)
|
||||
_callback_funcs[_func_id] = wrapper
|
||||
if IS_MAIN_PROCESS:
|
||||
self._on_main_receive_funcs.append(_func_id)
|
||||
else:
|
||||
self._on_sub_receive_funcs.append(_func_id)
|
||||
_func_id += 1
|
||||
return func
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***async def*** `wrapper(data: T) -> Any`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
async def wrapper(data: T) -> Any:
|
||||
if filter_func is not None:
|
||||
if is_coroutine_callable(filter_func):
|
||||
if not await filter_func(data):
|
||||
return
|
||||
elif not filter_func(data):
|
||||
return
|
||||
if is_coroutine_callable(func):
|
||||
return await func(data)
|
||||
else:
|
||||
return func(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `Channel(Generic[T])`
|
||||
|
||||
通道类,可以在进程间和进程内通信,双向但同时只能有一个发送者和一个接收者
|
||||
|
||||
有两种接收工作方式,但是只能选择一种,主动接收和被动接收,主动接收使用 `receive` 方法,被动接收使用 `on_receive` 装饰器
|
||||
|
||||
###   ***def*** `__init__(self, _id: str, type_check: Optional[bool]) -> None`
|
||||
|
||||
 初始化通道
|
||||
|
||||
Args:
|
||||
|
||||
_id: 通道ID
|
||||
|
||||
type_check: 是否开启类型检查, 若为空,则传入泛型默认开启,否则默认关闭
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def __init__(self, _id: str, type_check: Optional[bool]=None):
|
||||
def __init__(self, _id: str='', type_check: Optional[bool]=None):
|
||||
"""
|
||||
初始化通道
|
||||
Args:
|
||||
@ -254,16 +196,90 @@ def __init__(self, _id: str, type_check: Optional[bool]=None):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `send(self, data: T) -> None`
|
||||
### *method* `_get_generic_type(self) -> Optional[type]`
|
||||
|
||||
 发送数据
|
||||
|
||||
Args:
|
||||
|
||||
data: 数据
|
||||
**说明**: 获取通道传递泛型类型
|
||||
|
||||
|
||||
**返回**: Optional[type]: 泛型类型
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def _get_generic_type(self) -> Optional[type]:
|
||||
"""
|
||||
获取通道传递泛型类型
|
||||
|
||||
Returns:
|
||||
Optional[type]: 泛型类型
|
||||
"""
|
||||
if hasattr(self, '__orig_class__'):
|
||||
return get_args(self.__orig_class__)[0]
|
||||
return None
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_validate_structure(self, data: Any, structure: type) -> bool`
|
||||
|
||||
|
||||
|
||||
**说明**: 验证数据结构
|
||||
|
||||
**参数**:
|
||||
> - data: 数据
|
||||
> - structure: 结构
|
||||
|
||||
**返回**: bool: 是否通过验证
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def _validate_structure(self, data: Any, structure: type) -> bool:
|
||||
"""
|
||||
验证数据结构
|
||||
Args:
|
||||
data: 数据
|
||||
structure: 结构
|
||||
|
||||
Returns:
|
||||
bool: 是否通过验证
|
||||
"""
|
||||
if isinstance(structure, type):
|
||||
return isinstance(data, structure)
|
||||
elif isinstance(structure, tuple):
|
||||
if not isinstance(data, tuple) or len(data) != len(structure):
|
||||
return False
|
||||
return all((self._validate_structure(d, s) for d, s in zip(data, structure)))
|
||||
elif isinstance(structure, list):
|
||||
if not isinstance(data, list):
|
||||
return False
|
||||
return all((self._validate_structure(d, structure[0]) for d in data))
|
||||
elif isinstance(structure, dict):
|
||||
if not isinstance(data, dict):
|
||||
return False
|
||||
return all((k in data and self._validate_structure(data[k], structure[k]) for k in structure))
|
||||
return False
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `send(self, data: T)`
|
||||
|
||||
|
||||
|
||||
**说明**: 发送数据
|
||||
|
||||
**参数**:
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def send(self, data: T):
|
||||
@ -282,14 +298,15 @@ def send(self, data: T):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `receive(self) -> T`
|
||||
### *method* `receive(self) -> T`
|
||||
|
||||
 接收数据
|
||||
|
||||
Args:
|
||||
|
||||
**说明**: 接收数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def receive(self) -> T:
|
||||
@ -305,12 +322,15 @@ def receive(self) -> T:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `close(self) -> None`
|
||||
### *method* `close(self)`
|
||||
|
||||
|
||||
|
||||
**说明**: 关闭通道
|
||||
|
||||
 关闭通道
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def close(self):
|
||||
@ -323,20 +343,20 @@ def close(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_receive(self, filter_func: Optional[FILTER_FUNC]) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]`
|
||||
### *method* `on_receive(self, filter_func: Optional[FILTER_FUNC] = None) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]`
|
||||
|
||||
 接收数据并执行函数
|
||||
|
||||
Args:
|
||||
|
||||
filter_func: 过滤函数,为None则不过滤
|
||||
**说明**: 接收数据并执行函数
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - filter_func: 过滤函数,为None则不过滤
|
||||
|
||||
**返回**: 装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_receive(self, filter_func: Optional[FILTER_FUNC]=None) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]:
|
||||
@ -377,51 +397,159 @@ def on_receive(self, filter_func: Optional[FILTER_FUNC]=None) -> Callable[[Calla
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `T = TypeVar('T')`
|
||||
### *method* `_run_on_main_receive_funcs(self, data: Any)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `channel_deliver_active_channel = Channel(_id='channel_deliver_active_channel')`
|
||||
**说明**: 运行接收函数
|
||||
|
||||
**参数**:
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def _run_on_main_receive_funcs(self, data: Any):
|
||||
"""
|
||||
运行接收函数
|
||||
Args:
|
||||
data: 数据
|
||||
"""
|
||||
for func_id in self._on_main_receive_funcs:
|
||||
func = _callback_funcs[func_id]
|
||||
run_coroutine(func(data))
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_run_on_sub_receive_funcs(self, data: Any)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `channel_deliver_passive_channel = Channel(_id='channel_deliver_passive_channel')`
|
||||
**说明**: 运行接收函数
|
||||
|
||||
**参数**:
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def _run_on_sub_receive_funcs(self, data: Any):
|
||||
"""
|
||||
运行接收函数
|
||||
Args:
|
||||
data: 数据
|
||||
"""
|
||||
for func_id in self._on_sub_receive_funcs:
|
||||
func = _callback_funcs[func_id]
|
||||
run_coroutine(func(data))
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_start_main_receive_loop(self)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = data[1]['recv_chan']`
|
||||
**说明**: 开始接收数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def _start_main_receive_loop(self):
|
||||
"""
|
||||
开始接收数据
|
||||
"""
|
||||
self.is_main_receive_loop_running = True
|
||||
while not self._closed:
|
||||
data = self.conn_recv.recv()
|
||||
self._run_on_main_receive_funcs(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_start_sub_receive_loop(self)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = Channel[Channel[Any]]('recv_chan')`
|
||||
**说明**: 开始接收数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
### ***var*** `recv_chan = Channel[dict[str, Channel[Any]]]('recv_chan')`
|
||||
```python
|
||||
def _start_sub_receive_loop(self):
|
||||
"""
|
||||
开始接收数据
|
||||
"""
|
||||
self.is_sub_receive_loop_running = True
|
||||
while not self._closed:
|
||||
data = self.conn_recv.recv()
|
||||
self._run_on_sub_receive_funcs(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `SYNC_ON_RECEIVE_FUNC = Callable[[T], Any]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `type_check = self._get_generic_type() is not None`
|
||||
### ***var*** `ASYNC_ON_RECEIVE_FUNC = Callable[[T], Coroutine[Any, Any, Any]]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `ON_RECEIVE_FUNC = SYNC_ON_RECEIVE_FUNC | ASYNC_ON_RECEIVE_FUNC`
|
||||
|
||||
### ***var*** `data = self.conn_recv.recv()`
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `SYNC_FILTER_FUNC = Callable[[T], bool]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `func = _callback_funcs[func_id]`
|
||||
### ***var*** `ASYNC_FILTER_FUNC = Callable[[T], Coroutine[Any, Any, bool]]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `FILTER_FUNC = SYNC_FILTER_FUNC | ASYNC_FILTER_FUNC`
|
||||
|
||||
### ***var*** `func = _callback_funcs[func_id]`
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
### ***var*** `_func_id = 0`
|
||||
|
||||
- **类型**: `int`
|
||||
|
||||
### ***var*** `data = self.conn_recv.recv()`
|
||||
### ***var*** `_channel = {}`
|
||||
|
||||
- **类型**: `dict[str, 'Channel']`
|
||||
|
||||
### ***var*** `_callback_funcs = {}`
|
||||
|
||||
### ***var*** `data = self.conn_recv.recv()`
|
||||
- **类型**: `dict[int, ON_RECEIVE_FUNC]`
|
||||
|
||||
### ***var*** `active_channel = None`
|
||||
|
||||
- **类型**: `Optional['Channel']`
|
||||
|
||||
- **说明**: 子进程可用的主动和被动通道
|
||||
|
||||
### ***var*** `passive_channel = None`
|
||||
|
||||
- **类型**: `Optional['Channel']`
|
||||
|
||||
### ***var*** `publish_channel = Channel(_id='publish_channel')`
|
||||
|
||||
- **类型**: `Channel[tuple[str, dict[str, Any]]]`
|
||||
|
||||
### ***var*** `channel_deliver_active_channel = NO_DEFAULT`
|
||||
|
||||
- **类型**: `Channel[Channel[Any]]`
|
||||
|
||||
- **说明**: 通道传递通道,主进程创建单例,子进程初始化时实例化
|
||||
|
||||
### ***var*** `channel_deliver_passive_channel = NO_DEFAULT`
|
||||
|
||||
- **类型**: `Channel[tuple[str, dict[str, Any]]]`
|
||||
|
||||
|
@ -1,20 +1,12 @@
|
||||
---
|
||||
title: liteyuki.comm.event
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### **class** `Event`
|
||||
### *method* `__init__(self, name: str, data: dict[str, Any])`
|
||||
|
||||
### ***class*** `Event`
|
||||
|
||||
事件类
|
||||
|
||||
###   ***def*** `__init__(self, name: str, data: dict[str, Any]) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, name: str, data: dict[str, Any]):
|
||||
|
@ -1,46 +1,12 @@
|
||||
---
|
||||
title: liteyuki.comm.storage
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `run_subscriber_receive_funcs(channel_: str, data: Any) -> None`
|
||||
|
||||
运行订阅者接收函数
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
|
||||
data: 数据
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
def run_subscriber_receive_funcs(channel_: str, data: Any):
|
||||
"""
|
||||
运行订阅者接收函数
|
||||
Args:
|
||||
channel_: 频道
|
||||
data: 数据
|
||||
"""
|
||||
if IS_MAIN_PROCESS:
|
||||
if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
|
||||
elif channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get')`
|
||||
### *func* `on_get()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get')
|
||||
@ -52,12 +18,12 @@ def on_get(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_set(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'set')`
|
||||
### *func* `on_set()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'set')
|
||||
@ -68,12 +34,12 @@ def on_set(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_delete(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'delete')`
|
||||
### *func* `on_delete()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'delete')
|
||||
@ -83,12 +49,12 @@ def on_delete(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get_all(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get_all')`
|
||||
### *func* `on_get_all()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get_all')
|
||||
@ -98,12 +64,12 @@ def on_get_all(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_publish(data: tuple[str, Any]) -> None`
|
||||
|
||||
### `@channel.publish_channel.on_receive()`
|
||||
### *func* `on_publish()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@channel.publish_channel.on_receive()
|
||||
@ -113,59 +79,12 @@ def on_publish(data: tuple[str, Any]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: ON_RECEIVE_FUNC) -> ON_RECEIVE_FUNC`
|
||||
|
||||
### **class** `Subscriber`
|
||||
### *method* `__init__(self)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def decorator(func: ON_RECEIVE_FUNC) -> ON_RECEIVE_FUNC:
|
||||
|
||||
async def wrapper(data: Any):
|
||||
if is_coroutine_callable(func):
|
||||
await func(data)
|
||||
else:
|
||||
func(data)
|
||||
if IS_MAIN_PROCESS:
|
||||
if channel_ not in _on_main_subscriber_receive_funcs:
|
||||
_on_main_subscriber_receive_funcs[channel_] = []
|
||||
_on_main_subscriber_receive_funcs[channel_].append(wrapper)
|
||||
else:
|
||||
if channel_ not in _on_sub_subscriber_receive_funcs:
|
||||
_on_sub_subscriber_receive_funcs[channel_] = []
|
||||
_on_sub_subscriber_receive_funcs[channel_].append(wrapper)
|
||||
return wrapper
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***async def*** `wrapper(data: Any) -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
async def wrapper(data: Any):
|
||||
if is_coroutine_callable(func):
|
||||
await func(data)
|
||||
else:
|
||||
func(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `Subscriber`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self):
|
||||
@ -173,12 +92,11 @@ def __init__(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `receive(self) -> Any`
|
||||
### *method* `receive(self) -> Any`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def receive(self) -> Any:
|
||||
@ -186,12 +104,11 @@ def receive(self) -> Any:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `unsubscribe(self) -> None`
|
||||
### *method* `unsubscribe(self) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def unsubscribe(self) -> None:
|
||||
@ -199,16 +116,12 @@ def unsubscribe(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `KeyValueStore`
|
||||
### **class** `KeyValueStore`
|
||||
### *method* `__init__(self)`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self):
|
||||
@ -221,18 +134,19 @@ def __init__(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `set(self, key: str, value: Any) -> None`
|
||||
### *method* `set(self, key: str, value: Any) -> None`
|
||||
|
||||
 设置键值对
|
||||
|
||||
Args:
|
||||
|
||||
key: 键
|
||||
**说明**: 设置键值对
|
||||
|
||||
**参数**:
|
||||
> - key: 键
|
||||
> - value: 值
|
||||
|
||||
value: 值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def set(self, key: str, value: Any) -> None:
|
||||
@ -252,24 +166,21 @@ def set(self, key: str, value: Any) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `get(self, key: str, default: Optional[Any]) -> Optional[Any]`
|
||||
|
||||
 获取键值对
|
||||
|
||||
Args:
|
||||
|
||||
key: 键
|
||||
|
||||
default: 默认值
|
||||
### *method* `get(self, key: str, default: Optional[Any] = None) -> Optional[Any]`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 获取键值对
|
||||
|
||||
**参数**:
|
||||
> - key: 键
|
||||
> - default: 默认值
|
||||
|
||||
**返回**: Any: 值
|
||||
|
||||
Any: 值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get(self, key: str, default: Optional[Any]=None) -> Optional[Any]:
|
||||
@ -293,22 +204,19 @@ def get(self, key: str, default: Optional[Any]=None) -> Optional[Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `delete(self, key: str, ignore_key_error: bool) -> None`
|
||||
|
||||
 删除键值对
|
||||
|
||||
Args:
|
||||
|
||||
key: 键
|
||||
|
||||
ignore_key_error: 是否忽略键不存在的错误
|
||||
### *method* `delete(self, key: str, ignore_key_error: bool = True) -> None`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 删除键值对
|
||||
|
||||
**参数**:
|
||||
> - key: 键
|
||||
> - ignore_key_error: 是否忽略键不存在的错误
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def delete(self, key: str, ignore_key_error: bool=True) -> None:
|
||||
@ -335,16 +243,17 @@ def delete(self, key: str, ignore_key_error: bool=True) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `get_all(self) -> dict[str, Any]`
|
||||
### *method* `get_all(self) -> dict[str, Any]`
|
||||
|
||||
 获取所有键值对
|
||||
|
||||
Returns:
|
||||
|
||||
dict[str, Any]: 键值对
|
||||
**说明**: 获取所有键值对
|
||||
|
||||
**返回**: dict[str, Any]: 键值对
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_all(self) -> dict[str, Any]:
|
||||
@ -362,22 +271,19 @@ def get_all(self) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `publish(self, channel_: str, data: Any) -> None`
|
||||
|
||||
 发布消息
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
|
||||
data: 数据
|
||||
### *method* `publish(self, channel_: str, data: Any) -> None`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 发布消息
|
||||
|
||||
**参数**:
|
||||
> - channel_: 频道
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def publish(self, channel_: str, data: Any) -> None:
|
||||
@ -393,22 +299,20 @@ def publish(self, channel_: str, data: Any) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]`
|
||||
|
||||
 订阅者接收消息时的回调
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
### *method* `on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 订阅者接收消息时的回调
|
||||
|
||||
**参数**:
|
||||
> - channel_: 频道
|
||||
|
||||
**返回**: 装饰器
|
||||
|
||||
装饰器
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]:
|
||||
@ -447,19 +351,20 @@ def on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***@staticmethod***
|
||||
###   ***def*** `run_subscriber_receive_funcs(channel_: str, data: Any) -> None`
|
||||
### `@staticmethod`
|
||||
### *method* `run_subscriber_receive_funcs(channel_: str, data: Any)`
|
||||
|
||||
 运行订阅者接收函数
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
**说明**: 运行订阅者接收函数
|
||||
|
||||
**参数**:
|
||||
> - channel_: 频道
|
||||
> - data: 数据
|
||||
|
||||
data: 数据
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
@ -472,23 +377,48 @@ def run_subscriber_receive_funcs(channel_: str, data: Any):
|
||||
"""
|
||||
if IS_MAIN_PROCESS:
|
||||
if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
|
||||
run_coroutine_in_thread(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
|
||||
elif channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
|
||||
run_coroutine_in_thread(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `GlobalKeyValueStore`
|
||||
### *method* `_start_receive_loop(self)`
|
||||
|
||||
|
||||
|
||||
###   ***@classmethod***
|
||||
###   ***def*** `get_instance(cls: Any) -> None`
|
||||
**说明**: 启动发布订阅接收器循环,在主进程中运行,若有子进程订阅则推送给子进程
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def _start_receive_loop(self):
|
||||
"""
|
||||
启动发布订阅接收器循环,在主进程中运行,若有子进程订阅则推送给子进程
|
||||
"""
|
||||
if IS_MAIN_PROCESS:
|
||||
while True:
|
||||
data = self.active_chan.receive()
|
||||
if data[0] == 'publish':
|
||||
self.run_subscriber_receive_funcs(data[1]['channel'], data[1]['data'])
|
||||
self.publish_channel.send(data)
|
||||
else:
|
||||
while True:
|
||||
data = self.publish_channel.receive()
|
||||
if data[0] == 'publish':
|
||||
self.run_subscriber_receive_funcs(data[1]['channel'], data[1]['data'])
|
||||
```
|
||||
</details>
|
||||
|
||||
### **class** `GlobalKeyValueStore`
|
||||
### `@classmethod`
|
||||
### *method* `get_instance(cls)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@classmethod
|
||||
@ -501,63 +431,19 @@ def get_instance(cls):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***attr*** `_instance: None`
|
||||
### ***var*** `_on_main_subscriber_receive_funcs = {}`
|
||||
|
||||
###   ***attr*** `_lock: threading.Lock()`
|
||||
- **类型**: `dict[str, list[ASYNC_ON_RECEIVE_FUNC]]`
|
||||
|
||||
### ***var*** `key = data[1]['key']`
|
||||
- **说明**: 主进程订阅者接收函数
|
||||
|
||||
### ***var*** `_on_sub_subscriber_receive_funcs = {}`
|
||||
|
||||
- **类型**: `dict[str, list[ASYNC_ON_RECEIVE_FUNC]]`
|
||||
|
||||
### ***var*** `default = data[1]['default']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = data[1]['recv_chan']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `key = data[1]['key']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `value = data[1]['value']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `key = data[1]['key']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = data[1]['recv_chan']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `lock = _get_lock(key)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `lock = _get_lock(key)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = Channel[Optional[Any]]('recv_chan')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `lock = _get_lock(key)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = Channel[dict[str, Any]]('recv_chan')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = self.active_chan.receive()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = self.publish_channel.receive()`
|
||||
- **说明**: 子进程订阅者接收函数
|
||||
|
||||
### ***var*** `shared_memory = GlobalKeyValueStore.get_instance()`
|
||||
|
||||
- **类型**: `KeyValueStore`
|
||||
|
||||
|
@ -1,30 +1,22 @@
|
||||
---
|
||||
title: liteyuki.config
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `flat_config(config: dict[str, Any]) -> dict[str, Any]`
|
||||
|
||||
扁平化配置文件
|
||||
### *func* `flat_config() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**说明**: 扁平化配置文件
|
||||
|
||||
{a:{b:{c:1}}} -> {"a.b.c": 1}
|
||||
|
||||
Args:
|
||||
**参数**:
|
||||
> - config: 配置项目
|
||||
|
||||
config: 配置项目
|
||||
**返回**: 扁平化后的配置文件,但也包含原有的键值对
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
扁平化后的配置文件,但也包含原有的键值对
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def flat_config(config: dict[str, Any]) -> dict[str, Any]:
|
||||
@ -47,69 +39,80 @@ def flat_config(config: dict[str, Any]) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_yaml(file: str) -> dict[str, Any]`
|
||||
### *func* `load_from_yaml() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**说明**: Load config from yaml file
|
||||
|
||||
Load config from yaml file
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_yaml(file: str) -> dict[str, Any]:
|
||||
def load_from_yaml(file_: str) -> dict[str, Any]:
|
||||
"""
|
||||
Load config from yaml file
|
||||
|
||||
"""
|
||||
logger.debug(f'Loading YAML config from {file}')
|
||||
config = yaml.safe_load(open(file, 'r', encoding='utf-8'))
|
||||
logger.debug(f'Loading YAML config from {file_}')
|
||||
config = yaml.safe_load(open(file_, 'r', encoding='utf-8'))
|
||||
return flat_config(config if config is not None else {})
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_json(file: str) -> dict[str, Any]`
|
||||
### *func* `load_from_json() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**说明**: Load config from json file
|
||||
|
||||
Load config from json file
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_json(file: str) -> dict[str, Any]:
|
||||
def load_from_json(file_: str) -> dict[str, Any]:
|
||||
"""
|
||||
Load config from json file
|
||||
"""
|
||||
logger.debug(f'Loading JSON config from {file}')
|
||||
config = json.load(open(file, 'r', encoding='utf-8'))
|
||||
logger.debug(f'Loading JSON config from {file_}')
|
||||
config = json.load(open(file_, 'r', encoding='utf-8'))
|
||||
return flat_config(config if config is not None else {})
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_toml(file: str) -> dict[str, Any]`
|
||||
### *func* `load_from_toml() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**说明**: Load config from toml file
|
||||
|
||||
Load config from toml file
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_toml(file: str) -> dict[str, Any]:
|
||||
def load_from_toml(file_: str) -> dict[str, Any]:
|
||||
"""
|
||||
Load config from toml file
|
||||
"""
|
||||
logger.debug(f'Loading TOML config from {file}')
|
||||
config = toml.load(open(file, 'r', encoding='utf-8'))
|
||||
logger.debug(f'Loading TOML config from {file_}')
|
||||
config = toml.load(open(file_, 'r', encoding='utf-8'))
|
||||
return flat_config(config if config is not None else {})
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_files() -> dict[str, Any]`
|
||||
### *func* `load_from_files(*, no_warning: bool = False) -> dict[str, Any]`
|
||||
|
||||
从指定文件加载配置项,会自动识别文件格式
|
||||
|
||||
|
||||
**说明**: 从指定文件加载配置项,会自动识别文件格式
|
||||
默认执行扁平化选项
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_files(*files: str, no_warning: bool=False) -> dict[str, Any]:
|
||||
@ -134,16 +137,17 @@ def load_from_files(*files: str, no_warning: bool=False) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_configs_from_dirs() -> dict[str, Any]`
|
||||
### *func* `load_configs_from_dirs(*, no_waring: bool = False) -> dict[str, Any]`
|
||||
|
||||
从目录下加载配置文件,不递归
|
||||
|
||||
|
||||
**说明**: 从目录下加载配置文件,不递归
|
||||
按照读取文件的优先级反向覆盖
|
||||
|
||||
默认执行扁平化选项
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_configs_from_dirs(*directories: str, no_waring: bool=False) -> dict[str, Any]:
|
||||
@ -165,16 +169,17 @@ def load_configs_from_dirs(*directories: str, no_waring: bool=False) -> dict[str
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_config_in_default(no_waring: bool) -> dict[str, Any]`
|
||||
### *func* `load_config_in_default(no_waring: bool = False) -> dict[str, Any]`
|
||||
|
||||
从一个标准的轻雪项目加载配置文件
|
||||
|
||||
|
||||
**说明**: 从一个标准的轻雪项目加载配置文件
|
||||
项目目录下的config.*和config目录下的所有配置文件
|
||||
|
||||
项目目录下的配置文件优先
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_config_in_default(no_waring: bool=False) -> dict[str, Any]:
|
||||
@ -189,43 +194,3 @@ def load_config_in_default(no_waring: bool=False) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `SatoriNodeConfig(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `SatoriConfig(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `BasicConfig(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `new_config = copy.deepcopy(config)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = yaml.safe_load(open(file, 'r', encoding='utf-8'))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = json.load(open(file, 'r', encoding='utf-8'))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = toml.load(open(file, 'r', encoding='utf-8'))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = {}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = {}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = load_configs_from_dirs('config', no_waring=no_waring)`
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.core
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,20 +1,12 @@
|
||||
---
|
||||
title: liteyuki.core.manager
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### **class** `ChannelDeliver`
|
||||
### *method* `__init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_active: Channel[Channel[Any]], channel_deliver_passive: Channel[tuple[str, dict]], publish: Channel[tuple[str, Any]])`
|
||||
|
||||
### ***class*** `ChannelDeliver`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_active: Channel[Channel[Any]], channel_deliver_passive: Channel[tuple[str, dict]], publish: Channel[tuple[str, Any]]) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_active: Channel[Channel[Any]], channel_deliver_passive: Channel[tuple[str, dict]], publish: Channel[tuple[str, Any]]):
|
||||
@ -26,16 +18,12 @@ def __init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `ProcessManager`
|
||||
### **class** `ProcessManager`
|
||||
### *method* `__init__(self, lifespan: Lifespan)`
|
||||
|
||||
进程管理器
|
||||
|
||||
###   ***def*** `__init__(self, lifespan: 'Lifespan') -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, lifespan: 'Lifespan'):
|
||||
@ -45,18 +33,18 @@ def __init__(self, lifespan: 'Lifespan'):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `start(self, name: str) -> None`
|
||||
### *method* `start(self, name: str)`
|
||||
|
||||
 开启后自动监控进程,并添加到进程字典中
|
||||
|
||||
Args:
|
||||
|
||||
name:
|
||||
**说明**: 开启后自动监控进程,并添加到进程字典中
|
||||
|
||||
**参数**:
|
||||
> - name:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def start(self, name: str):
|
||||
@ -95,12 +83,15 @@ def start(self, name: str):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `start_all(self) -> None`
|
||||
### *method* `start_all(self)`
|
||||
|
||||
|
||||
|
||||
**说明**: 启动所有进程
|
||||
|
||||
 启动所有进程
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def start_all(self):
|
||||
@ -112,22 +103,21 @@ def start_all(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `add_target(self, name: str, target: TARGET_FUNC, args: tuple, kwargs: Any) -> None`
|
||||
### *method* `add_target(self, name: str, target: TARGET_FUNC, args: tuple = (), kwargs = None)`
|
||||
|
||||
 添加进程
|
||||
|
||||
Args:
|
||||
|
||||
name: 进程名,用于获取和唯一标识
|
||||
**说明**: 添加进程
|
||||
|
||||
target: 进程函数
|
||||
**参数**:
|
||||
> - name: 进程名,用于获取和唯一标识
|
||||
> - target: 进程函数
|
||||
> - args: 进程函数参数
|
||||
> - kwargs: 进程函数关键字参数,通常会默认传入chan_active和chan_passive
|
||||
|
||||
args: 进程函数参数
|
||||
|
||||
kwargs: 进程函数关键字参数,通常会默认传入chan_active和chan_passive
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def add_target(self, name: str, target: TARGET_FUNC, args: tuple=(), kwargs=None):
|
||||
@ -149,12 +139,11 @@ def add_target(self, name: str, target: TARGET_FUNC, args: tuple=(), kwargs=None
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `join_all(self) -> None`
|
||||
### *method* `join_all(self)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def join_all(self):
|
||||
@ -163,20 +152,18 @@ def join_all(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `terminate(self, name: str) -> None`
|
||||
|
||||
 终止进程并从进程字典中删除
|
||||
|
||||
Args:
|
||||
|
||||
name:
|
||||
### *method* `terminate(self, name: str)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 终止进程并从进程字典中删除
|
||||
|
||||
**参数**:
|
||||
> - name:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def terminate(self, name: str):
|
||||
@ -200,12 +187,11 @@ def terminate(self, name: str):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `terminate_all(self) -> None`
|
||||
### *method* `terminate_all(self)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def terminate_all(self):
|
||||
@ -214,20 +200,18 @@ def terminate_all(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `is_process_alive(self, name: str) -> bool`
|
||||
|
||||
 检查进程是否存活
|
||||
|
||||
Args:
|
||||
|
||||
name:
|
||||
### *method* `is_process_alive(self, name: str) -> bool`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 检查进程是否存活
|
||||
|
||||
**参数**:
|
||||
> - name:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def is_process_alive(self, name: str) -> bool:
|
||||
@ -245,31 +229,7 @@ def is_process_alive(self, name: str) -> bool:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `TIMEOUT = 10`
|
||||
|
||||
|
||||
|
||||
### ***var*** `chan_active = get_channel(f'{name}-active')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `channel_deliver = ChannelDeliver(active=chan_active, passive=chan_passive, channel_deliver_active=channel_deliver_active_channel, channel_deliver_passive=channel_deliver_passive_channel, publish=publish_channel)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `process = self.processes[name]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `process = Process(target=self.targets[name][0], args=self.targets[name][1], kwargs=self.targets[name][2], daemon=True)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = chan_active.receive()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `kwargs = {}`
|
||||
|
||||
### ***var*** `TARGET_FUNC = Callable[..., Any]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.dev
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
---
|
||||
title: liteyuki.dev.observer
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `debounce()`
|
||||
|
||||
### ***def*** `debounce(wait: Any) -> None`
|
||||
|
||||
防抖函数
|
||||
|
||||
**说明**: 防抖函数
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def debounce(wait):
|
||||
@ -32,24 +31,22 @@ def debounce(wait):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_file_system_event(directories: tuple[str], recursive: bool, event_filter: FILTER_FUNC) -> Callable[[CALLBACK_FUNC], CALLBACK_FUNC]`
|
||||
### *func* `on_file_system_event(directories: tuple[str] = True, recursive: bool = None) -> Callable[[CALLBACK_FUNC], CALLBACK_FUNC]`
|
||||
|
||||
注册文件系统变化监听器
|
||||
|
||||
Args:
|
||||
|
||||
directories: 监听目录们
|
||||
**说明**: 注册文件系统变化监听器
|
||||
|
||||
recursive: 是否递归监听子目录
|
||||
**参数**:
|
||||
> - directories: 监听目录们
|
||||
> - recursive: 是否递归监听子目录
|
||||
> - event_filter: 事件过滤器, 返回True则执行回调函数
|
||||
|
||||
event_filter: 事件过滤器, 返回True则执行回调函数
|
||||
**返回**: 装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
Returns:
|
||||
|
||||
装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_file_system_event(directories: tuple[str], recursive: bool=True, event_filter: FILTER_FUNC=None) -> Callable[[CALLBACK_FUNC], CALLBACK_FUNC]:
|
||||
@ -78,91 +75,13 @@ def on_file_system_event(directories: tuple[str], recursive: bool=True, event_fi
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: Any) -> None`
|
||||
|
||||
### **class** `CodeModifiedHandler(FileSystemEventHandler)`
|
||||
### `@debounce(1)`
|
||||
### *method* `on_modified(self, event)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def decorator(func):
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
nonlocal last_call_time
|
||||
current_time = time.time()
|
||||
if current_time - last_call_time > wait:
|
||||
last_call_time = current_time
|
||||
return func(*args, **kwargs)
|
||||
last_call_time = None
|
||||
return wrapper
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: CALLBACK_FUNC) -> CALLBACK_FUNC`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def decorator(func: CALLBACK_FUNC) -> CALLBACK_FUNC:
|
||||
|
||||
def wrapper(event: FileSystemEvent):
|
||||
if event_filter is not None and (not event_filter(event)):
|
||||
return
|
||||
func(event)
|
||||
code_modified_handler = CodeModifiedHandler()
|
||||
code_modified_handler.on_modified = wrapper
|
||||
for directory in directories:
|
||||
observer.schedule(code_modified_handler, directory, recursive=recursive)
|
||||
return func
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `wrapper() -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def wrapper(*args, **kwargs):
|
||||
nonlocal last_call_time
|
||||
current_time = time.time()
|
||||
if current_time - last_call_time > wait:
|
||||
last_call_time = current_time
|
||||
return func(*args, **kwargs)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `wrapper(event: FileSystemEvent) -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def wrapper(event: FileSystemEvent):
|
||||
if event_filter is not None and (not event_filter(event)):
|
||||
return
|
||||
func(event)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `CodeModifiedHandler(FileSystemEventHandler)`
|
||||
|
||||
Handler for code file changes
|
||||
|
||||
###   ***def*** `on_modified(self, event: Any) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@debounce(1)
|
||||
@ -171,12 +90,11 @@ def on_modified(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_created(self, event: Any) -> None`
|
||||
### *method* `on_created(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_created(self, event):
|
||||
@ -184,12 +102,11 @@ def on_created(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_deleted(self, event: Any) -> None`
|
||||
### *method* `on_deleted(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_deleted(self, event):
|
||||
@ -197,12 +114,11 @@ def on_deleted(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_moved(self, event: Any) -> None`
|
||||
### *method* `on_moved(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_moved(self, event):
|
||||
@ -210,12 +126,11 @@ def on_moved(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_any_event(self, event: Any) -> None`
|
||||
### *method* `on_any_event(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_any_event(self, event):
|
||||
@ -223,27 +138,15 @@ def on_any_event(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `liteyuki_bot = get_bot()`
|
||||
### ***var*** `CALLBACK_FUNC = Callable[[FileSystemEvent], None]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
- **说明**: 位置1为FileSystemEvent
|
||||
|
||||
### ***var*** `observer = Observer()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `last_call_time = None`
|
||||
|
||||
|
||||
|
||||
### ***var*** `code_modified_handler = CodeModifiedHandler()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `current_time = time.time()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `last_call_time = current_time`
|
||||
### ***var*** `FILTER_FUNC = Callable[[FileSystemEvent], bool]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
- **说明**: 位置1为FileSystemEvent
|
||||
|
||||
|
@ -1,20 +1,18 @@
|
||||
---
|
||||
title: liteyuki.dev.plugin
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `run_plugins()`
|
||||
|
||||
### ***def*** `run_plugins() -> None`
|
||||
|
||||
运行插件,无需手动初始化bot
|
||||
|
||||
Args:
|
||||
**说明**: 运行插件,无需手动初始化bot
|
||||
|
||||
**参数**:
|
||||
> - module_path: 插件路径,参考`liteyuki.load_plugin`的函数签名
|
||||
|
||||
module_path: 插件路径,参考`liteyuki.load_plugin`的函数签名
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def run_plugins(*module_path: str | Path):
|
||||
@ -32,15 +30,3 @@ def run_plugins(*module_path: str | Path):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `cfg = load_config_in_default()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `plugins = cfg.get('liteyuki.plugins', [])`
|
||||
|
||||
|
||||
|
||||
### ***var*** `bot = LiteyukiBot(**cfg)`
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +1,4 @@
|
||||
---
|
||||
title: liteyuki.exception
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `LiteyukiException(BaseException)`
|
||||
|
||||
Liteyuki的异常基类。
|
||||
|
||||
### **class** `LiteyukiException(BaseException)`
|
||||
|
@ -1,16 +1,11 @@
|
||||
---
|
||||
title: liteyuki.log
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `get_format(level: str) -> str`
|
||||
|
||||
### *func* `get_format() -> str`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_format(level: str) -> str:
|
||||
@ -21,14 +16,15 @@ def get_format(level: str) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `init_log(config: dict) -> None`
|
||||
### *func* `init_log()`
|
||||
|
||||
在语言加载完成后执行
|
||||
|
||||
Returns:
|
||||
|
||||
**说明**: 在语言加载完成后执行
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def init_log(config: dict):
|
||||
@ -48,11 +44,11 @@ def init_log(config: dict):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `logger = loguru.logger`
|
||||
### ***var*** `debug_format = '<c>{time:YYYY-MM-DD HH:mm:ss}</c> <lvl>[{level.icon}]</lvl> <c><{name}.{module}.{function}:{line}></c> {message}'`
|
||||
|
||||
- **类型**: `str`
|
||||
|
||||
### ***var*** `default_format = '<c>{time:MM-DD HH:mm:ss}</c> <lvl>[{level.icon}]</lvl> <c><{name}></c> {message}'`
|
||||
|
||||
### ***var*** `show_icon = config.get('log_icon', True)`
|
||||
|
||||
|
||||
- **类型**: `str`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.message
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,47 +1,19 @@
|
||||
---
|
||||
title: liteyuki.message.event
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `MessageEvent`
|
||||
### **class** `MessageEvent`
|
||||
### *method* `__init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, user_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]] = None)`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]]) -> None`
|
||||
**说明**: 轻雪抽象消息事件
|
||||
|
||||
 轻雪抽象消息事件
|
||||
|
||||
Args:
|
||||
|
||||
|
||||
|
||||
bot_id: 机器人ID
|
||||
|
||||
message: 消息,消息段数组[{type: str, data: dict[str, Any]}]
|
||||
|
||||
raw_message: 原始消息(通常为纯文本的格式)
|
||||
|
||||
message_type: 消息类型(private, group, other)
|
||||
|
||||
|
||||
|
||||
session_id: 会话ID(私聊通常为用户ID,群聊通常为群ID)
|
||||
|
||||
session_type: 会话类型(private, group)
|
||||
|
||||
receive_channel: 接收频道(用于回复消息)
|
||||
|
||||
|
||||
|
||||
data: 附加数据
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]]=None):
|
||||
def __init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, user_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]]=None):
|
||||
"""
|
||||
轻雪抽象消息事件
|
||||
Args:
|
||||
@ -66,22 +38,23 @@ def __init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_typ
|
||||
self.raw_message = raw_message
|
||||
self.session_id = session_id
|
||||
self.session_type = session_type
|
||||
self.user_id = user_id
|
||||
self.receive_channel = receive_channel
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `reply(self, message: str | dict[str, Any]) -> None`
|
||||
### *method* `reply(self, message: str | dict[str, Any])`
|
||||
|
||||
 回复消息
|
||||
|
||||
Args:
|
||||
|
||||
message:
|
||||
**说明**: 回复消息
|
||||
|
||||
**参数**:
|
||||
> - message:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def reply(self, message: str | dict[str, Any]):
|
||||
@ -96,11 +69,3 @@ def reply(self, message: str | dict[str, Any]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `reply_event = MessageEvent(message_type=self.session_type, message=message, raw_message='', data={'message': message}, bot_id=self.bot_id, session_id=self.session_id, session_type=self.session_type, receive_channel='_')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = {}`
|
||||
|
||||
|
||||
|
||||
|
@ -1,28 +1,21 @@
|
||||
---
|
||||
title: liteyuki.message.matcher
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `Matcher`
|
||||
### **class** `Matcher`
|
||||
### *method* `__init__(self, rule: Rule, priority: int, block: bool)`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, rule: Rule, priority: int, block: bool) -> None`
|
||||
**说明**: 匹配器
|
||||
|
||||
 匹配器
|
||||
**参数**:
|
||||
> - rule: 规则
|
||||
> - priority: 优先级 >= 0
|
||||
> - block: 是否阻断后续优先级更低的匹配器
|
||||
|
||||
Args:
|
||||
|
||||
rule: 规则
|
||||
|
||||
priority: 优先级 >= 0
|
||||
|
||||
block: 是否阻断后续优先级更低的匹配器
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, rule: Rule, priority: int, block: bool):
|
||||
@ -40,32 +33,65 @@ def __init__(self, rule: Rule, priority: int, block: bool):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `handle(self, handler: EventHandler) -> EventHandler`
|
||||
### *method* `handle(self) -> Callable[[EventHandler], EventHandler]`
|
||||
|
||||
 添加处理函数,装饰器
|
||||
|
||||
Args:
|
||||
|
||||
handler:
|
||||
**说明**: 添加处理函数,装饰器
|
||||
|
||||
Returns:
|
||||
**返回**: 装饰器 handler
|
||||
|
||||
EventHandler
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def handle(self, handler: EventHandler) -> EventHandler:
|
||||
def handle(self) -> Callable[[EventHandler], EventHandler]:
|
||||
"""
|
||||
添加处理函数,装饰器
|
||||
Args:
|
||||
handler:
|
||||
Returns:
|
||||
EventHandler
|
||||
装饰器 handler
|
||||
"""
|
||||
self.handlers.append(handler)
|
||||
return handler
|
||||
|
||||
def decorator(handler: EventHandler) -> EventHandler:
|
||||
self.handlers.append(handler)
|
||||
return handler
|
||||
return decorator
|
||||
```
|
||||
</details>
|
||||
|
||||
### *async method* `run(self, event: MessageEvent) -> None`
|
||||
|
||||
|
||||
|
||||
**说明**: 运行处理函数
|
||||
|
||||
**参数**:
|
||||
> - event:
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
async def run(self, event: MessageEvent) -> None:
|
||||
"""
|
||||
运行处理函数
|
||||
Args:
|
||||
event:
|
||||
Returns:
|
||||
"""
|
||||
if not await self.rule(event):
|
||||
return
|
||||
for handler in self.handlers:
|
||||
try:
|
||||
await handler(event)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `EventHandler = Callable[[MessageEvent], Coroutine[None, None, Any]]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
|
@ -1,19 +1,14 @@
|
||||
---
|
||||
title: liteyuki.message.on
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `on_message(rule: Rule, priority: int, block: bool) -> Matcher`
|
||||
|
||||
### *func* `on_message(rule: Rule = empty_rule, priority: int = 0, block: bool = False) -> Matcher`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def on_message(rule: Rule=Rule(), priority: int=0, block: bool=True) -> Matcher:
|
||||
def on_message(rule: Rule=empty_rule, priority: int=0, block: bool=False) -> Matcher:
|
||||
matcher = Matcher(rule, priority, block)
|
||||
for i, m in enumerate(_matcher_list):
|
||||
if m.priority < matcher.priority:
|
||||
@ -25,15 +20,27 @@ def on_message(rule: Rule=Rule(), priority: int=0, block: bool=True) -> Matcher:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `current_priority = -1`
|
||||
### *func* `on_keywords(keywords: list[str] = empty_rule, rule = 0, priority: int = False) -> Matcher`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
### ***var*** `matcher = Matcher(rule, priority, block)`
|
||||
```python
|
||||
def on_keywords(keywords: list[str], rule=empty_rule, priority: int=0, block: bool=False) -> Matcher:
|
||||
|
||||
@Rule
|
||||
async def on_keywords_rule(event: MessageEvent):
|
||||
return any((keyword in event.raw_message for keyword in keywords))
|
||||
return on_message(on_keywords_rule & rule, priority, block)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `_matcher_list = []`
|
||||
|
||||
### ***var*** `current_priority = matcher.priority`
|
||||
- **类型**: `list[Matcher]`
|
||||
|
||||
### ***var*** `_queue = Queue()`
|
||||
|
||||
- **类型**: `Queue`
|
||||
|
||||
|
@ -1,24 +1,98 @@
|
||||
---
|
||||
title: liteyuki.message.rule
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### `@Rule`
|
||||
### *async func* `empty_rule() -> bool`
|
||||
|
||||
### ***class*** `Rule`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, handler: Optional[RuleHandler]) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, handler: Optional[RuleHandler]=None):
|
||||
@Rule
|
||||
async def empty_rule(event: MessageEvent) -> bool:
|
||||
return True
|
||||
```
|
||||
</details>
|
||||
|
||||
### `@Rule`
|
||||
### *async func* `is_su_rule() -> bool`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@Rule
|
||||
async def is_su_rule(event: MessageEvent) -> bool:
|
||||
return str(event.user_id) in _superusers
|
||||
```
|
||||
</details>
|
||||
|
||||
### **class** `Rule`
|
||||
### *method* `__init__(self, handler: RuleHandlerFunc)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, handler: RuleHandlerFunc):
|
||||
self.handler = handler
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `__or__(self, other: Rule) -> Rule`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __or__(self, other: 'Rule') -> 'Rule':
|
||||
|
||||
async def combined_handler(event: MessageEvent) -> bool:
|
||||
return await self.handler(event) or await other.handler(event)
|
||||
return Rule(combined_handler)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `__and__(self, other: Rule) -> Rule`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def __and__(self, other: 'Rule') -> 'Rule':
|
||||
|
||||
async def combined_handler(event: MessageEvent) -> bool:
|
||||
return await self.handler(event) and await other.handler(event)
|
||||
return Rule(combined_handler)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *async method* `__call__(self, event: MessageEvent) -> bool`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
async def __call__(self, event: MessageEvent) -> bool:
|
||||
if self.handler is None:
|
||||
return True
|
||||
return await self.handler(event)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `_superusers = get_config('liteyuki.superusers', [])`
|
||||
|
||||
- **类型**: `list[str]`
|
||||
|
||||
### ***var*** `RuleHandlerFunc = Callable[[MessageEvent], Coroutine[None, None, bool]]`
|
||||
|
||||
- **类型**: `TypeAlias`
|
||||
|
||||
- **说明**: 规则函数签名
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.message.session
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,22 +1,19 @@
|
||||
---
|
||||
title: liteyuki.mkdoc
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `get_relative_path() -> str`
|
||||
|
||||
### ***def*** `get_relative_path(base_path: str, target_path: str) -> str`
|
||||
|
||||
获取相对路径
|
||||
|
||||
Args:
|
||||
**说明**: 获取相对路径
|
||||
|
||||
base_path: 基础路径
|
||||
**参数**:
|
||||
> - base_path: 基础路径
|
||||
> - target_path: 目标路径
|
||||
|
||||
target_path: 目标路径
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_relative_path(base_path: str, target_path: str) -> str:
|
||||
@ -30,16 +27,18 @@ def get_relative_path(base_path: str, target_path: str) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `write_to_files(file_data: dict[str, str]) -> None`
|
||||
### *func* `write_to_files()`
|
||||
|
||||
输出文件
|
||||
|
||||
Args:
|
||||
|
||||
file_data: 文件数据 相对路径
|
||||
**说明**: 输出文件
|
||||
|
||||
**参数**:
|
||||
> - file_data: 文件数据 相对路径
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def write_to_files(file_data: dict[str, str]):
|
||||
@ -56,12 +55,11 @@ def write_to_files(file_data: dict[str, str]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_file_list(module_folder: str) -> None`
|
||||
|
||||
### *func* `get_file_list()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_file_list(module_folder: str):
|
||||
@ -74,22 +72,21 @@ def get_file_list(module_folder: str):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_module_info_normal(file_path: str, ignore_private: bool) -> ModuleInfo`
|
||||
### *func* `get_module_info_normal(file_path: str = True) -> ModuleInfo`
|
||||
|
||||
获取函数和类
|
||||
|
||||
Args:
|
||||
|
||||
file_path: Python 文件路径
|
||||
**说明**: 获取函数和类
|
||||
|
||||
ignore_private: 忽略私有函数和类
|
||||
**参数**:
|
||||
> - file_path: Python 文件路径
|
||||
> - ignore_private: 忽略私有函数和类
|
||||
|
||||
Returns:
|
||||
**返回**: 模块信息
|
||||
|
||||
模块信息
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_module_info_normal(file_path: str, ignore_private: bool=True) -> ModuleInfo:
|
||||
@ -149,33 +146,33 @@ def get_module_info_normal(file_path: str, ignore_private: bool=True) -> ModuleI
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `generate_markdown(module_info: ModuleInfo, front_matter: Any) -> str`
|
||||
### *func* `generate_markdown(module_info: ModuleInfo = None, front_matter = 'zh-CN') -> str`
|
||||
|
||||
生成模块的Markdown
|
||||
|
||||
|
||||
**说明**: 生成模块的Markdown
|
||||
你可在此自定义生成的Markdown格式
|
||||
|
||||
Args:
|
||||
**参数**:
|
||||
> - module_info: 模块信息
|
||||
> - front_matter: 自定义选项title, index, icon, category
|
||||
> - lang: 语言
|
||||
|
||||
module_info: 模块信息
|
||||
**返回**: Markdown 字符串
|
||||
|
||||
front_matter: 自定义选项title, index, icon, category
|
||||
|
||||
Returns:
|
||||
|
||||
Markdown 字符串
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def generate_markdown(module_info: ModuleInfo, front_matter=None) -> str:
|
||||
def generate_markdown(module_info: ModuleInfo, front_matter=None, lang: str='zh-CN') -> str:
|
||||
"""
|
||||
生成模块的Markdown
|
||||
你可在此自定义生成的Markdown格式
|
||||
Args:
|
||||
module_info: 模块信息
|
||||
front_matter: 自定义选项title, index, icon, category
|
||||
lang: 语言
|
||||
Returns:
|
||||
Markdown 字符串
|
||||
"""
|
||||
@ -205,7 +202,11 @@ def generate_markdown(module_info: ModuleInfo, front_matter=None) -> str:
|
||||
content += f"###   ***{('async ' if method.is_async else '')}def*** `{method.name}({', '.join(args_with_type)}) -> {method.return_type}`\n\n"
|
||||
method.docstring = method.docstring.replace('\n', '\n\n')
|
||||
content += f' {method.docstring}\n\n'
|
||||
content += f'<details>\n<summary>源代码</summary>\n\n```python\n{method.source_code}\n```\n</details>\n\n'
|
||||
if lang == 'zh-CN':
|
||||
TEXT_SOURCE_CODE = '源代码'
|
||||
else:
|
||||
TEXT_SOURCE_CODE = 'Source Code'
|
||||
content += f'<details>\n<summary>{TEXT_SOURCE_CODE}</summary>\n\n```python\n{method.source_code}\n```\n</details>\n\n'
|
||||
for attr in cls.attributes:
|
||||
content += f'###   ***attr*** `{attr.name}: {attr.type}`\n\n'
|
||||
for attr in module_info.attributes:
|
||||
@ -219,25 +220,25 @@ def generate_markdown(module_info: ModuleInfo, front_matter=None) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `generate_docs(module_folder: str, output_dir: str, with_top: bool, ignored_paths: Any) -> None`
|
||||
### *func* `generate_docs(module_folder: str = False, output_dir: str = 'zh-CN', with_top: bool = None)`
|
||||
|
||||
生成文档
|
||||
|
||||
Args:
|
||||
|
||||
module_folder: 模块文件夹
|
||||
**说明**: 生成文档
|
||||
|
||||
output_dir: 输出文件夹
|
||||
**参数**:
|
||||
> - module_folder: 模块文件夹
|
||||
> - output_dir: 输出文件夹
|
||||
> - with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md
|
||||
> - ignored_paths: 忽略的路径
|
||||
> - lang: 语言
|
||||
|
||||
with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md
|
||||
|
||||
ignored_paths: 忽略的路径
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, ignored_paths=None):
|
||||
def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, lang: str='zh-CN', ignored_paths=None):
|
||||
"""
|
||||
生成文档
|
||||
Args:
|
||||
@ -245,6 +246,7 @@ def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, ign
|
||||
output_dir: 输出文件夹
|
||||
with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md
|
||||
ignored_paths: 忽略的路径
|
||||
lang: 语言
|
||||
"""
|
||||
if ignored_paths is None:
|
||||
ignored_paths = []
|
||||
@ -273,201 +275,8 @@ def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, ign
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `DefType(Enum)`
|
||||
|
||||
|
||||
|
||||
###   ***attr*** `FUNCTION: 'function'`
|
||||
|
||||
###   ***attr*** `METHOD: 'method'`
|
||||
|
||||
###   ***attr*** `STATIC_METHOD: 'staticmethod'`
|
||||
|
||||
###   ***attr*** `CLASS_METHOD: 'classmethod'`
|
||||
|
||||
###   ***attr*** `PROPERTY: 'property'`
|
||||
|
||||
### ***class*** `FunctionInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `AttributeInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `ClassInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `ModuleInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `NO_TYPE_ANY = 'Any'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `NO_TYPE_HINT = 'NoTypeHint'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `FUNCTION = 'function'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `METHOD = 'method'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `STATIC_METHOD = 'staticmethod'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `CLASS_METHOD = 'classmethod'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `PROPERTY = 'property'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `file_list = []`
|
||||
|
||||
|
||||
|
||||
### ***var*** `dot_sep_module_path = file_path.replace(os.sep, '.').replace('.py', '').replace('.pyi', '')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_docstring = ast.get_docstring(tree)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_info = ModuleInfo(module_path=dot_sep_module_path, functions=[], classes=[], attributes=[], docstring=module_docstring if module_docstring else '')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `content = ''`
|
||||
|
||||
|
||||
|
||||
### ***var*** `front_matter = '---\n' + '\n'.join([f'{k}: {v}' for k, v in front_matter.items()]) + '\n---\n\n'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `file_list = get_file_list(module_folder)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `replace_data = {'__init__': 'README', '.py': '.md'}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `file_content = file.read()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `tree = ast.parse(file_content)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args_with_type = [f'{arg[0]}: {arg[1]}' if arg[1] else arg[0] for arg in func.args]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `ignored_paths = []`
|
||||
|
||||
|
||||
|
||||
### ***var*** `no_module_name_pyfile_path = get_relative_path(module_folder, pyfile_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `rel_md_path = pyfile_path if with_top else no_module_name_pyfile_path`
|
||||
|
||||
|
||||
|
||||
### ***var*** `abs_md_path = os.path.join(output_dir, rel_md_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_info = get_module_info_normal(pyfile_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `md_content = generate_markdown(module_info, front_matter)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `inherit = f"({', '.join(cls.inherit)})" if cls.inherit else ''`
|
||||
|
||||
|
||||
|
||||
### ***var*** `rel_md_path = rel_md_path.replace(rk, rv)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `front_matter = {'title': module_info.module_path.replace('.__init__', '').replace('_', '\\n'), 'index': 'true', 'icon': 'laptop-code', 'category': 'API'}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `front_matter = {'title': module_info.module_path.replace('_', '\\n'), 'order': '1', 'icon': 'laptop-code', 'category': 'API'}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `function_docstring = ast.get_docstring(node)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `func_info = FunctionInfo(name=node.name, args=[(arg.arg, ast.unparse(arg.annotation) if arg.annotation else NO_TYPE_ANY) for arg in node.args.args], return_type=ast.unparse(node.returns) if node.returns else 'None', docstring=function_docstring if function_docstring else '', type=DefType.FUNCTION, is_async=isinstance(node, ast.AsyncFunctionDef), source_code=ast.unparse(node))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `class_docstring = ast.get_docstring(node)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `class_info = ClassInfo(name=node.name, docstring=class_docstring if class_docstring else '', methods=[], attributes=[], inherit=[ast.unparse(base) for base in node.bases])`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args_with_type = [f'{arg[0]}: {arg[1]}' if arg[1] else arg[0] for arg in method.args]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args_with_type = [f'{arg[0]}: {arg[1]}' if arg[1] and arg[0] != 'self' else arg[0] for arg in method.args]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `first_arg = node.args.args[0]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `method_docstring = ast.get_docstring(class_node)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.METHOD`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.STATIC_METHOD`
|
||||
|
||||
|
||||
|
||||
### ***var*** `attr_type = NO_TYPE_HINT`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.CLASS_METHOD`
|
||||
|
||||
|
||||
|
||||
### ***var*** `attr_type = ast.unparse(node.value.annotation)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.PROPERTY`
|
||||
|
||||
|
||||
|
||||
### **class** `DefType(Enum)`
|
||||
### **class** `FunctionInfo(BaseModel)`
|
||||
### **class** `AttributeInfo(BaseModel)`
|
||||
### **class** `ClassInfo(BaseModel)`
|
||||
### **class** `ModuleInfo(BaseModel)`
|
||||
|
@ -1,20 +1,17 @@
|
||||
---
|
||||
title: liteyuki.plugin
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `get_loaded_plugins() -> dict[str, Plugin]`
|
||||
|
||||
### ***def*** `get_loaded_plugins() -> dict[str, Plugin]`
|
||||
|
||||
获取已加载的插件
|
||||
|
||||
Returns:
|
||||
**说明**: 获取已加载的插件
|
||||
|
||||
**返回**: dict[str, Plugin]: 插件字典
|
||||
|
||||
dict[str, Plugin]: 插件字典
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def get_loaded_plugins() -> dict[str, Plugin]:
|
||||
|
@ -1,24 +1,20 @@
|
||||
---
|
||||
title: liteyuki.plugin.load
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `load_plugin(module_path: str | Path) -> Optional[Plugin]`
|
||||
|
||||
加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
||||
### *func* `load_plugin() -> Optional[Plugin]`
|
||||
|
||||
|
||||
|
||||
参数:
|
||||
**说明**: 加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
||||
|
||||
module_path: 插件名称 `path.to.your.plugin`
|
||||
|
||||
或插件路径 `pathlib.Path(path/to/your/plugin)`
|
||||
**参数**:
|
||||
> - module_path: 插件名称 `path.to.your.plugin`
|
||||
> - 或插件路径 `pathlib.Path(path/to/your/plugin)`:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_plugin(module_path: str | Path) -> Optional[Plugin]:
|
||||
@ -31,11 +27,21 @@ def load_plugin(module_path: str | Path) -> Optional[Plugin]:
|
||||
module_path = path_to_module_name(Path(module_path)) if isinstance(module_path, Path) else module_path
|
||||
try:
|
||||
module = import_module(module_path)
|
||||
_plugins[module.__name__] = Plugin(name=module.__name__, module=module, module_name=module_path, metadata=module.__dict__.get('__plugin_metadata__', None))
|
||||
display_name = module.__name__.split('.')[-1]
|
||||
if module.__dict__.get('__plugin_meta__'):
|
||||
_plugins[module.__name__] = Plugin(name=module.__name__, module=module, module_name=module_path)
|
||||
if module.__dict__.get('__plugin_metadata__', None):
|
||||
metadata: 'PluginMetadata' = module.__dict__['__plugin_metadata__']
|
||||
display_name = module.__name__.split('.')[-1]
|
||||
elif module.__dict__.get('__liteyuki_plugin_meta__', None):
|
||||
metadata: 'PluginMetadata' = module.__dict__['__liteyuki_plugin_meta__']
|
||||
display_name = format_display_name(f"{metadata.name}({module.__name__.split('.')[-1]})", metadata.type)
|
||||
elif module.__dict__.get('__plugin_meta__', None):
|
||||
metadata: 'PluginMetadata' = module.__dict__['__plugin_meta__']
|
||||
display_name = format_display_name(f"{metadata.name}({module.__name__.split('.')[-1]})", metadata.type)
|
||||
else:
|
||||
logger.opt(colors=True).warning(f'The metadata of Liteyuki plugin "{module.__name__}" is not specified, use empty.')
|
||||
metadata = PluginMetadata(name=module.__name__)
|
||||
display_name = module.__name__.split('.')[-1]
|
||||
_plugins[module.__name__].metadata = metadata
|
||||
logger.opt(colors=True).success(f'Succeeded to load liteyuki plugin "{display_name}"')
|
||||
return _plugins[module.__name__]
|
||||
except Exception as e:
|
||||
@ -45,20 +51,20 @@ def load_plugin(module_path: str | Path) -> Optional[Plugin]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_plugins() -> set[Plugin]`
|
||||
|
||||
导入文件夹下多个插件
|
||||
### *func* `load_plugins(*, ignore_warning: bool = True) -> set[Plugin]`
|
||||
|
||||
|
||||
|
||||
参数:
|
||||
**说明**: 导入文件夹下多个插件
|
||||
|
||||
plugin_dir: 文件夹路径
|
||||
|
||||
ignore_warning: 是否忽略警告,通常是目录不存在或目录为空
|
||||
**参数**:
|
||||
> - plugin_dir: 文件夹路径
|
||||
> - ignore_warning: 是否忽略警告,通常是目录不存在或目录为空
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def load_plugins(*plugin_dir: str, ignore_warning: bool=True) -> set[Plugin]:
|
||||
@ -97,24 +103,21 @@ def load_plugins(*plugin_dir: str, ignore_warning: bool=True) -> set[Plugin]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `format_display_name(display_name: str, plugin_type: PluginType) -> str`
|
||||
|
||||
设置插件名称颜色,根据不同类型插件设置颜色
|
||||
|
||||
Args:
|
||||
|
||||
display_name: 插件名称
|
||||
|
||||
plugin_type: 插件类型
|
||||
### *func* `format_display_name() -> str`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 设置插件名称颜色,根据不同类型插件设置颜色
|
||||
|
||||
**参数**:
|
||||
> - display_name: 插件名称
|
||||
> - plugin_type: 插件类型
|
||||
|
||||
**返回**: str: 设置后的插件名称 <y>name</y>
|
||||
|
||||
str: 设置后的插件名称 <y>name</y>
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def format_display_name(display_name: str, plugin_type: PluginType) -> str:
|
||||
@ -141,59 +144,19 @@ def format_display_name(display_name: str, plugin_type: PluginType) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `module_path = path_to_module_name(Path(module_path)) if isinstance(module_path, Path) else module_path`
|
||||
### ***var*** `_plugins = {}`
|
||||
|
||||
- **类型**: `dict[str, Plugin]`
|
||||
|
||||
### ***var*** `metadata = module.__dict__['__plugin_metadata__']`
|
||||
|
||||
### ***var*** `plugins = set()`
|
||||
- **类型**: `'PluginMetadata'`
|
||||
|
||||
### ***var*** `metadata = module.__dict__['__liteyuki_plugin_meta__']`
|
||||
|
||||
- **类型**: `'PluginMetadata'`
|
||||
|
||||
### ***var*** `color = 'y'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module = import_module(module_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `display_name = module.__name__.split('.')[-1]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `display_name = format_display_name(f"{metadata.name}({module.__name__.split('.')[-1]})", metadata.type)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `path = Path(os.path.join(dir_path, f))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_name = None`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'm'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'g'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'e'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'c'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_name = f'{path_to_module_name(Path(dir_path))}.{f[:-3]}'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_name = path_to_module_name(path)`
|
||||
|
||||
### ***var*** `metadata = module.__dict__['__plugin_meta__']`
|
||||
|
||||
- **类型**: `'PluginMetadata'`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.plugin.manager
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,89 +1,18 @@
|
||||
---
|
||||
title: liteyuki.plugin.model
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `PluginType(Enum)`
|
||||
|
||||
插件类型枚举值
|
||||
|
||||
###   ***attr*** `APPLICATION: 'application'`
|
||||
|
||||
###   ***attr*** `SERVICE: 'service'`
|
||||
|
||||
###   ***attr*** `MODULE: 'module'`
|
||||
|
||||
###   ***attr*** `UNCLASSIFIED: 'unclassified'`
|
||||
|
||||
###   ***attr*** `TEST: 'test'`
|
||||
|
||||
### ***class*** `PluginMetadata(BaseModel)`
|
||||
|
||||
轻雪插件元数据,由插件编写者提供,name为必填项
|
||||
|
||||
Attributes:
|
||||
|
||||
----------
|
||||
### **class** `PluginType(Enum)`
|
||||
### **class** `PluginMetadata(BaseModel)`
|
||||
### **class** `Plugin(BaseModel)`
|
||||
### *method* `__hash__(self)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
name: str
|
||||
|
||||
插件名称
|
||||
|
||||
description: str
|
||||
|
||||
插件描述
|
||||
|
||||
usage: str
|
||||
|
||||
插件使用方法
|
||||
|
||||
type: str
|
||||
|
||||
插件类型
|
||||
|
||||
author: str
|
||||
|
||||
插件作者
|
||||
|
||||
homepage: str
|
||||
|
||||
插件主页
|
||||
|
||||
extra: dict[str, Any]
|
||||
|
||||
额外信息
|
||||
|
||||
### ***class*** `Plugin(BaseModel)`
|
||||
|
||||
存储插件信息
|
||||
|
||||
###   ***attr*** `model_config: {'arbitrary_types_allowed': True}`
|
||||
|
||||
### ***var*** `APPLICATION = 'application'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `SERVICE = 'service'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `MODULE = 'module'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `UNCLASSIFIED = 'unclassified'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `TEST = 'test'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `model_config = {'arbitrary_types_allowed': True}`
|
||||
|
||||
|
||||
```python
|
||||
def __hash__(self):
|
||||
return hash(self.module_name)
|
||||
```
|
||||
</details>
|
||||
|
||||
|
17
docs/dev/api/plugins/liteecho.md
Normal file
17
docs/dev/api/plugins/liteecho.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: liteyuki.plugins.liteecho
|
||||
---
|
||||
### `@on_startswith(['liteecho'], rule=is_su_rule).handle()`
|
||||
### *async func* `liteecho()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
@on_startswith(['liteecho'], rule=is_su_rule).handle()
|
||||
async def liteecho(event: MessageEvent):
|
||||
event.reply(event.raw_message.strip()[8:].strip())
|
||||
```
|
||||
</details>
|
||||
|
25
docs/dev/api/plugins/plugin_loader/README.md
Normal file
25
docs/dev/api/plugins/plugin_loader/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: liteyuki.plugins.plugin_loader
|
||||
---
|
||||
### *func* `default_plugins_loader()`
|
||||
|
||||
|
||||
|
||||
**说明**: 默认插件加载器,应在初始化时调用
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def default_plugins_loader():
|
||||
"""
|
||||
默认插件加载器,应在初始化时调用
|
||||
"""
|
||||
for plugin in get_config('liteyuki.plugins', []):
|
||||
load_plugin(plugin)
|
||||
for plugin_dir in get_config('liteyuki.plugin_dirs', ['src/liteyuki_plugins']):
|
||||
load_plugins(plugin_dir)
|
||||
```
|
||||
</details>
|
||||
|
@ -1,24 +1,20 @@
|
||||
---
|
||||
title: liteyuki.utils
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `is_coroutine_callable() -> bool`
|
||||
|
||||
### ***def*** `is_coroutine_callable(call: Callable[..., Any]) -> bool`
|
||||
|
||||
判断是否为协程可调用对象
|
||||
|
||||
Args:
|
||||
**说明**: 判断是否为协程可调用对象
|
||||
|
||||
call: 可调用对象
|
||||
**参数**:
|
||||
> - call: 可调用对象
|
||||
|
||||
Returns:
|
||||
**返回**: bool: 是否为协程可调用对象
|
||||
|
||||
bool: 是否为协程可调用对象
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def is_coroutine_callable(call: Callable[..., Any]) -> bool:
|
||||
@ -38,20 +34,18 @@ def is_coroutine_callable(call: Callable[..., Any]) -> bool:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `run_coroutine() -> None`
|
||||
|
||||
运行协程
|
||||
|
||||
Args:
|
||||
|
||||
coro:
|
||||
### *func* `run_coroutine()`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**说明**: 运行协程
|
||||
|
||||
**参数**:
|
||||
> - coro:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def run_coroutine(*coro: Coroutine):
|
||||
@ -81,20 +75,47 @@ def run_coroutine(*coro: Coroutine):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `path_to_module_name(path: Path) -> str`
|
||||
### *func* `run_coroutine_in_thread()`
|
||||
|
||||
转换路径为模块名
|
||||
|
||||
Args:
|
||||
|
||||
path: 路径a/b/c/d -> a.b.c.d
|
||||
**说明**: 在新线程中运行协程
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - coro:
|
||||
|
||||
str: 模块名
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def run_coroutine_in_thread(*coro: Coroutine):
|
||||
"""
|
||||
在新线程中运行协程
|
||||
Args:
|
||||
coro:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
threading.Thread(target=run_coroutine, args=coro, daemon=True).start()
|
||||
```
|
||||
</details>
|
||||
|
||||
### *func* `path_to_module_name() -> str`
|
||||
|
||||
|
||||
|
||||
**说明**: 转换路径为模块名
|
||||
|
||||
**参数**:
|
||||
> - path: 路径a/b/c/d -> a.b.c.d
|
||||
|
||||
**返回**: str: 模块名
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def path_to_module_name(path: Path) -> str:
|
||||
@ -113,20 +134,20 @@ def path_to_module_name(path: Path) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `async_wrapper(func: Callable[..., Any]) -> Callable[..., Coroutine]`
|
||||
### *func* `async_wrapper() -> Callable[..., Coroutine]`
|
||||
|
||||
异步包装器
|
||||
|
||||
Args:
|
||||
|
||||
func: Sync Callable
|
||||
**说明**: 异步包装器
|
||||
|
||||
Returns:
|
||||
**参数**:
|
||||
> - func: Sync Callable
|
||||
|
||||
**返回**: Coroutine: Asynchronous Callable
|
||||
|
||||
Coroutine: Asynchronous Callable
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>源代码</b> </summary>
|
||||
|
||||
```python
|
||||
def async_wrapper(func: Callable[..., Any]) -> Callable[..., Coroutine]:
|
||||
@ -145,36 +166,3 @@ def async_wrapper(func: Callable[..., Any]) -> Callable[..., Coroutine]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***async def*** `wrapper() -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
async def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `IS_MAIN_PROCESS = multiprocessing.current_process().name == 'MainProcess'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `func_ = getattr(call, '__call__', None)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `rel_path = path.resolve().relative_to(Path.cwd().resolve())`
|
||||
|
||||
|
||||
|
||||
### ***var*** `loop = asyncio.get_event_loop()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `loop = asyncio.new_event_loop()`
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,22 +1,18 @@
|
||||
---
|
||||
title: liteyuki.bot
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `get_bot() -> LiteyukiBot`
|
||||
|
||||
获取轻雪实例
|
||||
### *func* `get_bot() -> LiteyukiBot`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 获取轻雪实例
|
||||
|
||||
|
||||
**Return**: LiteyukiBot: 当前的轻雪实例
|
||||
|
||||
LiteyukiBot: 当前的轻雪实例
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_bot() -> LiteyukiBot:
|
||||
@ -35,24 +31,21 @@ def get_bot() -> LiteyukiBot:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_config(key: str, default: Any) -> Any`
|
||||
|
||||
获取配置
|
||||
|
||||
Args:
|
||||
|
||||
key: 配置键
|
||||
|
||||
default: 默认值
|
||||
### *func* `get_config(key: str = None) -> Any`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 获取配置
|
||||
|
||||
**Arguments**:
|
||||
> - key: 配置键
|
||||
> - default: 默认值
|
||||
|
||||
**Return**: Any: 配置值
|
||||
|
||||
Any: 配置值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_config(key: str, default: Any=None) -> Any:
|
||||
@ -69,26 +62,22 @@ def get_config(key: str, default: Any=None) -> Any:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_config_with_compat(key: str, compat_keys: tuple[str], default: Any) -> Any`
|
||||
|
||||
获取配置,兼容旧版本
|
||||
|
||||
Args:
|
||||
|
||||
key: 配置键
|
||||
|
||||
compat_keys: 兼容键
|
||||
|
||||
default: 默认值
|
||||
### *func* `get_config_with_compat(key: str = None) -> Any`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 获取配置,兼容旧版本
|
||||
|
||||
**Arguments**:
|
||||
> - key: 配置键
|
||||
> - compat_keys: 兼容键
|
||||
> - default: 默认值
|
||||
|
||||
**Return**: Any: 配置值
|
||||
|
||||
Any: 配置值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_config_with_compat(key: str, compat_keys: tuple[str], default: Any=None) -> Any:
|
||||
@ -112,12 +101,11 @@ def get_config_with_compat(key: str, compat_keys: tuple[str], default: Any=None)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `print_logo() -> None`
|
||||
|
||||
### *func* `print_logo()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def print_logo():
|
||||
@ -125,22 +113,20 @@ def print_logo():
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `LiteyukiBot`
|
||||
### **class** `LiteyukiBot`
|
||||
### *method* `__init__(self) -> None`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
**Description**: 初始化轻雪实例
|
||||
|
||||
 初始化轻雪实例
|
||||
**Arguments**:
|
||||
> - *args:
|
||||
> - **kwargs: 配置
|
||||
|
||||
Args:
|
||||
|
||||
*args:
|
||||
|
||||
**kwargs: 配置
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
@ -177,12 +163,15 @@ def __init__(self, *args, **kwargs) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `run(self) -> None`
|
||||
### *method* `run(self)`
|
||||
|
||||
|
||||
|
||||
**Description**: 启动逻辑
|
||||
|
||||
 启动逻辑
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def run(self):
|
||||
@ -196,14 +185,15 @@ def run(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `keep_alive(self) -> None`
|
||||
### *method* `keep_alive(self)`
|
||||
|
||||
 保持轻雪运行
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 保持轻雪运行
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def keep_alive(self):
|
||||
@ -221,14 +211,46 @@ def keep_alive(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `restart(self, delay: int) -> None`
|
||||
### *method* `_handle_exit(self, signum, frame)`
|
||||
|
||||
 重启轻雪本体
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 信号处理
|
||||
|
||||
**Arguments**:
|
||||
> - signum:
|
||||
> - frame:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def _handle_exit(self, signum, frame):
|
||||
"""
|
||||
信号处理
|
||||
Args:
|
||||
signum:
|
||||
frame:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
logger.info('Received signal, stopping all processes.')
|
||||
self.stop()
|
||||
sys.exit(0)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `restart(self, delay: int = 0)`
|
||||
|
||||
|
||||
|
||||
**Description**: 重启轻雪本体
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def restart(self, delay: int=0):
|
||||
@ -257,18 +279,18 @@ def restart(self, delay: int=0):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `restart_process(self, name: Optional[str]) -> None`
|
||||
### *method* `restart_process(self, name: Optional[str] = None)`
|
||||
|
||||
 停止轻雪
|
||||
|
||||
Args:
|
||||
|
||||
name: 进程名称, 默认为None, 所有进程
|
||||
**Description**: 停止轻雪
|
||||
|
||||
**Arguments**:
|
||||
> - name: 进程名称, 默认为None, 所有进程
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def restart_process(self, name: Optional[str]=None):
|
||||
@ -290,14 +312,15 @@ def restart_process(self, name: Optional[str]=None):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `init(self) -> None`
|
||||
### *method* `init(self)`
|
||||
|
||||
 初始化轻雪, 自动调用
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 初始化轻雪, 自动调用
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def init(self, *args, **kwargs):
|
||||
@ -310,12 +333,11 @@ def init(self, *args, **kwargs):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `init_logger(self) -> None`
|
||||
### *method* `init_logger(self)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def init_logger(self):
|
||||
@ -323,14 +345,15 @@ def init_logger(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `stop(self) -> None`
|
||||
### *method* `stop(self)`
|
||||
|
||||
 停止轻雪
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 停止轻雪
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def stop(self):
|
||||
@ -344,20 +367,18 @@ def stop(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_start(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册启动前的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_before_start(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册启动前的函数
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_start(self, func: LIFESPAN_FUNC):
|
||||
@ -373,20 +394,18 @@ def on_before_start(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_start(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册启动后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_start(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册启动后的函数
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_start(self, func: LIFESPAN_FUNC):
|
||||
@ -402,20 +421,18 @@ def on_after_start(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_shutdown(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册停止后的函数:未实现
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_shutdown(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册停止后的函数:未实现
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_shutdown(self, func: LIFESPAN_FUNC):
|
||||
@ -431,20 +448,18 @@ def on_after_shutdown(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册进程停止前的函数,为子进程停止时调用
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_before_process_shutdown(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册进程停止前的函数,为子进程停止时调用
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_shutdown(self, func: LIFESPAN_FUNC):
|
||||
@ -460,20 +475,18 @@ def on_before_process_shutdown(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_restart(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册进程重启前的函数,为子进程重启时调用
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_before_process_restart(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册进程重启前的函数,为子进程重启时调用
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_restart(self, func: LIFESPAN_FUNC):
|
||||
@ -489,20 +502,18 @@ def on_before_process_restart(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_restart(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册重启后的函数:未实现
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_restart(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册重启后的函数:未实现
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_restart(self, func: LIFESPAN_FUNC):
|
||||
@ -518,20 +529,18 @@ def on_after_restart(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_nonebot_init(self, func: LIFESPAN_FUNC) -> None`
|
||||
|
||||
 注册nonebot初始化后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_nonebot_init(self, func: LIFESPAN_FUNC)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册nonebot初始化后的函数
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_nonebot_init(self, func: LIFESPAN_FUNC):
|
||||
@ -547,35 +556,7 @@ def on_after_nonebot_init(self, func: LIFESPAN_FUNC):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `executable = sys.executable`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args = sys.argv`
|
||||
|
||||
|
||||
|
||||
### ***var*** `chan_active = get_channel(f'{name}-active')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'start'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `chan_active = get_channel(f'{process_name}-active')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'nohup'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'open'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `cmd = 'nohup'`
|
||||
|
||||
### ***var*** `_BOT_INSTANCE = NO_DEFAULT`
|
||||
|
||||
- **Type**: `LiteyukiBot`
|
||||
|
||||
|
@ -1,57 +1,16 @@
|
||||
---
|
||||
title: liteyuki.bot.lifespan
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### **class** `Lifespan`
|
||||
### *method* `__init__(self) -> None`
|
||||
|
||||
### ***def*** `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
|
||||
|
||||
运行函数
|
||||
|
||||
Args:
|
||||
**Description**: 轻雪生命周期管理,启动、停止、重启
|
||||
|
||||
funcs:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
def run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC], *args, **kwargs) -> None:
|
||||
"""
|
||||
运行函数
|
||||
Args:
|
||||
funcs:
|
||||
Returns:
|
||||
"""
|
||||
try:
|
||||
loop = asyncio.get_event_loop()
|
||||
except RuntimeError:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
tasks = []
|
||||
for func in funcs:
|
||||
if is_coroutine_callable(func):
|
||||
tasks.append(func(*args, **kwargs))
|
||||
else:
|
||||
tasks.append(async_wrapper(func)(*args, **kwargs))
|
||||
loop.run_until_complete(asyncio.gather(*tasks))
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `Lifespan`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
|
||||
 轻雪生命周期管理,启动、停止、重启
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self) -> None:
|
||||
@ -69,19 +28,19 @@ def __init__(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***@staticmethod***
|
||||
###   ***def*** `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
|
||||
### `@staticmethod`
|
||||
### *method* `run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC]) -> None`
|
||||
|
||||
 运行函数
|
||||
|
||||
Args:
|
||||
|
||||
funcs:
|
||||
**Description**: 运行函数
|
||||
|
||||
**Arguments**:
|
||||
> - funcs:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
@ -107,20 +66,20 @@ def run_funcs(funcs: list[LIFESPAN_FUNC | PROCESS_LIFESPAN_FUNC], *args, **kwarg
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册启动时的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**Description**: 注册启动时的函数
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
**Return**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -136,20 +95,20 @@ def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册启动时的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**Description**: 注册启动时的函数
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
**Return**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -165,20 +124,20 @@ def on_after_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册停止前的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**Description**: 注册停止前的函数
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
**Return**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -194,22 +153,20 @@ def on_before_process_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册停止后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册停止后的函数
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
**Return**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -227,20 +184,20 @@ def on_after_shutdown(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册重启时的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**Description**: 注册重启时的函数
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
**Return**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -256,20 +213,20 @@ def on_before_process_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
### *method* `on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC`
|
||||
|
||||
 注册重启后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
**Description**: 注册重启后的函数
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
**Return**: LIFESPAN_FUNC:
|
||||
|
||||
LIFESPAN_FUNC:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
@ -285,20 +242,18 @@ def on_after_restart(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_after_nonebot_init(self, func: Any) -> None`
|
||||
|
||||
 注册 NoneBot 初始化后的函数
|
||||
|
||||
Args:
|
||||
|
||||
func:
|
||||
### *method* `on_after_nonebot_init(self, func)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 注册 NoneBot 初始化后的函数
|
||||
|
||||
**Arguments**:
|
||||
> - func:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_after_nonebot_init(self, func):
|
||||
@ -315,14 +270,15 @@ def on_after_nonebot_init(self, func):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `before_start(self) -> None`
|
||||
### *method* `before_start(self) -> None`
|
||||
|
||||
 启动前
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 启动前
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def before_start(self) -> None:
|
||||
@ -335,14 +291,15 @@ def before_start(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `after_start(self) -> None`
|
||||
### *method* `after_start(self) -> None`
|
||||
|
||||
 启动后
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 启动后
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def after_start(self) -> None:
|
||||
@ -355,14 +312,15 @@ def after_start(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `before_process_shutdown(self) -> None`
|
||||
### *method* `before_process_shutdown(self) -> None`
|
||||
|
||||
 停止前
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 停止前
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def before_process_shutdown(self) -> None:
|
||||
@ -375,14 +333,15 @@ def before_process_shutdown(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `after_shutdown(self) -> None`
|
||||
### *method* `after_shutdown(self) -> None`
|
||||
|
||||
 停止后
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 停止后
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def after_shutdown(self) -> None:
|
||||
@ -395,14 +354,15 @@ def after_shutdown(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `before_process_restart(self) -> None`
|
||||
### *method* `before_process_restart(self) -> None`
|
||||
|
||||
 重启前
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 重启前
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def before_process_restart(self) -> None:
|
||||
@ -415,14 +375,15 @@ def before_process_restart(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `after_restart(self) -> None`
|
||||
### *method* `after_restart(self) -> None`
|
||||
|
||||
 重启后
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 重启后
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def after_restart(self) -> None:
|
||||
@ -436,15 +397,27 @@ def after_restart(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `tasks = []`
|
||||
### ***var*** `SYNC_LIFESPAN_FUNC = Callable[[], Any]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `ASYNC_LIFESPAN_FUNC = Callable[[], Awaitable[Any]]`
|
||||
|
||||
### ***var*** `loop = asyncio.get_event_loop()`
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `LIFESPAN_FUNC = SYNC_LIFESPAN_FUNC | ASYNC_LIFESPAN_FUNC`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `loop = asyncio.new_event_loop()`
|
||||
### ***var*** `SYNC_PROCESS_LIFESPAN_FUNC = Callable[[str], Any]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `ASYNC_PROCESS_LIFESPAN_FUNC = Callable[[str], Awaitable[Any]]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `PROCESS_LIFESPAN_FUNC = SYNC_PROCESS_LIFESPAN_FUNC | ASYNC_PROCESS_LIFESPAN_FUNC`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.comm
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,22 +1,19 @@
|
||||
---
|
||||
title: liteyuki.comm.channel
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `set_channel()`
|
||||
|
||||
### ***def*** `set_channel(name: str, channel: Channel) -> None`
|
||||
|
||||
设置通道实例
|
||||
|
||||
Args:
|
||||
**Description**: 设置通道实例
|
||||
|
||||
name: 通道名称
|
||||
**Arguments**:
|
||||
> - name: 通道名称
|
||||
> - channel: 通道实例
|
||||
|
||||
channel: 通道实例
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def set_channel(name: str, channel: Channel):
|
||||
@ -35,16 +32,18 @@ def set_channel(name: str, channel: Channel):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `set_channels(channels: dict[str, Channel]) -> None`
|
||||
### *func* `set_channels()`
|
||||
|
||||
设置通道实例
|
||||
|
||||
Args:
|
||||
|
||||
channels: 通道名称
|
||||
**Description**: 设置通道实例
|
||||
|
||||
**Arguments**:
|
||||
> - channels: 通道名称
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def set_channels(channels: dict[str, Channel]):
|
||||
@ -58,18 +57,18 @@ def set_channels(channels: dict[str, Channel]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_channel(name: str) -> Channel`
|
||||
### *func* `get_channel() -> Channel`
|
||||
|
||||
获取通道实例
|
||||
|
||||
Args:
|
||||
|
||||
name: 通道名称
|
||||
**Description**: 获取通道实例
|
||||
|
||||
**Arguments**:
|
||||
> - name: 通道名称
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_channel(name: str) -> Channel:
|
||||
@ -88,14 +87,15 @@ def get_channel(name: str) -> Channel:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_channels() -> dict[str, Channel]`
|
||||
### *func* `get_channels() -> dict[str, Channel]`
|
||||
|
||||
获取通道实例
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 获取通道实例
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_channels() -> dict[str, Channel]:
|
||||
@ -112,12 +112,12 @@ def get_channels() -> dict[str, Channel]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_set_channel(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'set_channel')`
|
||||
### *func* `on_set_channel()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'set_channel')
|
||||
@ -127,12 +127,12 @@ def on_set_channel(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get_channel(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channel')`
|
||||
### *func* `on_get_channel()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channel')
|
||||
@ -142,12 +142,12 @@ def on_get_channel(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get_channels(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channels')`
|
||||
### *func* `on_get_channels()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@channel_deliver_passive_channel.on_receive(filter_func=lambda data: data[0] == 'get_channels')
|
||||
@ -157,81 +157,23 @@ def on_get_channels(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: Callable[[T], Any]) -> Callable[[T], Any]`
|
||||
### **class** `Channel(Generic[T])`
|
||||
### *method* `__init__(self, _id: str = '', type_check: Optional[bool] = None)`
|
||||
|
||||
|
||||
|
||||
**Description**: 初始化通道
|
||||
|
||||
**Arguments**:
|
||||
> - _id: 通道ID
|
||||
> - type_check: 是否开启类型检查, 若为空,则传入泛型默认开启,否则默认关闭
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def decorator(func: Callable[[T], Any]) -> Callable[[T], Any]:
|
||||
global _func_id
|
||||
|
||||
async def wrapper(data: T) -> Any:
|
||||
if filter_func is not None:
|
||||
if is_coroutine_callable(filter_func):
|
||||
if not await filter_func(data):
|
||||
return
|
||||
elif not filter_func(data):
|
||||
return
|
||||
if is_coroutine_callable(func):
|
||||
return await func(data)
|
||||
else:
|
||||
return func(data)
|
||||
_callback_funcs[_func_id] = wrapper
|
||||
if IS_MAIN_PROCESS:
|
||||
self._on_main_receive_funcs.append(_func_id)
|
||||
else:
|
||||
self._on_sub_receive_funcs.append(_func_id)
|
||||
_func_id += 1
|
||||
return func
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***async def*** `wrapper(data: T) -> Any`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
async def wrapper(data: T) -> Any:
|
||||
if filter_func is not None:
|
||||
if is_coroutine_callable(filter_func):
|
||||
if not await filter_func(data):
|
||||
return
|
||||
elif not filter_func(data):
|
||||
return
|
||||
if is_coroutine_callable(func):
|
||||
return await func(data)
|
||||
else:
|
||||
return func(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `Channel(Generic[T])`
|
||||
|
||||
通道类,可以在进程间和进程内通信,双向但同时只能有一个发送者和一个接收者
|
||||
|
||||
有两种接收工作方式,但是只能选择一种,主动接收和被动接收,主动接收使用 `receive` 方法,被动接收使用 `on_receive` 装饰器
|
||||
|
||||
###   ***def*** `__init__(self, _id: str, type_check: Optional[bool]) -> None`
|
||||
|
||||
 初始化通道
|
||||
|
||||
Args:
|
||||
|
||||
_id: 通道ID
|
||||
|
||||
type_check: 是否开启类型检查, 若为空,则传入泛型默认开启,否则默认关闭
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def __init__(self, _id: str, type_check: Optional[bool]=None):
|
||||
def __init__(self, _id: str='', type_check: Optional[bool]=None):
|
||||
"""
|
||||
初始化通道
|
||||
Args:
|
||||
@ -254,16 +196,90 @@ def __init__(self, _id: str, type_check: Optional[bool]=None):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `send(self, data: T) -> None`
|
||||
### *method* `_get_generic_type(self) -> Optional[type]`
|
||||
|
||||
 发送数据
|
||||
|
||||
Args:
|
||||
|
||||
data: 数据
|
||||
**Description**: 获取通道传递泛型类型
|
||||
|
||||
|
||||
**Return**: Optional[type]: 泛型类型
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def _get_generic_type(self) -> Optional[type]:
|
||||
"""
|
||||
获取通道传递泛型类型
|
||||
|
||||
Returns:
|
||||
Optional[type]: 泛型类型
|
||||
"""
|
||||
if hasattr(self, '__orig_class__'):
|
||||
return get_args(self.__orig_class__)[0]
|
||||
return None
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_validate_structure(self, data: Any, structure: type) -> bool`
|
||||
|
||||
|
||||
|
||||
**Description**: 验证数据结构
|
||||
|
||||
**Arguments**:
|
||||
> - data: 数据
|
||||
> - structure: 结构
|
||||
|
||||
**Return**: bool: 是否通过验证
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def _validate_structure(self, data: Any, structure: type) -> bool:
|
||||
"""
|
||||
验证数据结构
|
||||
Args:
|
||||
data: 数据
|
||||
structure: 结构
|
||||
|
||||
Returns:
|
||||
bool: 是否通过验证
|
||||
"""
|
||||
if isinstance(structure, type):
|
||||
return isinstance(data, structure)
|
||||
elif isinstance(structure, tuple):
|
||||
if not isinstance(data, tuple) or len(data) != len(structure):
|
||||
return False
|
||||
return all((self._validate_structure(d, s) for d, s in zip(data, structure)))
|
||||
elif isinstance(structure, list):
|
||||
if not isinstance(data, list):
|
||||
return False
|
||||
return all((self._validate_structure(d, structure[0]) for d in data))
|
||||
elif isinstance(structure, dict):
|
||||
if not isinstance(data, dict):
|
||||
return False
|
||||
return all((k in data and self._validate_structure(data[k], structure[k]) for k in structure))
|
||||
return False
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `send(self, data: T)`
|
||||
|
||||
|
||||
|
||||
**Description**: 发送数据
|
||||
|
||||
**Arguments**:
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def send(self, data: T):
|
||||
@ -282,14 +298,15 @@ def send(self, data: T):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `receive(self) -> T`
|
||||
### *method* `receive(self) -> T`
|
||||
|
||||
 接收数据
|
||||
|
||||
Args:
|
||||
|
||||
**Description**: 接收数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def receive(self) -> T:
|
||||
@ -305,12 +322,15 @@ def receive(self) -> T:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `close(self) -> None`
|
||||
### *method* `close(self)`
|
||||
|
||||
|
||||
|
||||
**Description**: 关闭通道
|
||||
|
||||
 关闭通道
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def close(self):
|
||||
@ -323,20 +343,20 @@ def close(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_receive(self, filter_func: Optional[FILTER_FUNC]) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]`
|
||||
### *method* `on_receive(self, filter_func: Optional[FILTER_FUNC] = None) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]`
|
||||
|
||||
 接收数据并执行函数
|
||||
|
||||
Args:
|
||||
|
||||
filter_func: 过滤函数,为None则不过滤
|
||||
**Description**: 接收数据并执行函数
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - filter_func: 过滤函数,为None则不过滤
|
||||
|
||||
**Return**: 装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_receive(self, filter_func: Optional[FILTER_FUNC]=None) -> Callable[[Callable[[T], Any]], Callable[[T], Any]]:
|
||||
@ -377,51 +397,159 @@ def on_receive(self, filter_func: Optional[FILTER_FUNC]=None) -> Callable[[Calla
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `T = TypeVar('T')`
|
||||
### *method* `_run_on_main_receive_funcs(self, data: Any)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `channel_deliver_active_channel = Channel(_id='channel_deliver_active_channel')`
|
||||
**Description**: 运行接收函数
|
||||
|
||||
**Arguments**:
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def _run_on_main_receive_funcs(self, data: Any):
|
||||
"""
|
||||
运行接收函数
|
||||
Args:
|
||||
data: 数据
|
||||
"""
|
||||
for func_id in self._on_main_receive_funcs:
|
||||
func = _callback_funcs[func_id]
|
||||
run_coroutine(func(data))
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_run_on_sub_receive_funcs(self, data: Any)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `channel_deliver_passive_channel = Channel(_id='channel_deliver_passive_channel')`
|
||||
**Description**: 运行接收函数
|
||||
|
||||
**Arguments**:
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def _run_on_sub_receive_funcs(self, data: Any):
|
||||
"""
|
||||
运行接收函数
|
||||
Args:
|
||||
data: 数据
|
||||
"""
|
||||
for func_id in self._on_sub_receive_funcs:
|
||||
func = _callback_funcs[func_id]
|
||||
run_coroutine(func(data))
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_start_main_receive_loop(self)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = data[1]['recv_chan']`
|
||||
**Description**: 开始接收数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def _start_main_receive_loop(self):
|
||||
"""
|
||||
开始接收数据
|
||||
"""
|
||||
self.is_main_receive_loop_running = True
|
||||
while not self._closed:
|
||||
data = self.conn_recv.recv()
|
||||
self._run_on_main_receive_funcs(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `_start_sub_receive_loop(self)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = Channel[Channel[Any]]('recv_chan')`
|
||||
**Description**: 开始接收数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
### ***var*** `recv_chan = Channel[dict[str, Channel[Any]]]('recv_chan')`
|
||||
```python
|
||||
def _start_sub_receive_loop(self):
|
||||
"""
|
||||
开始接收数据
|
||||
"""
|
||||
self.is_sub_receive_loop_running = True
|
||||
while not self._closed:
|
||||
data = self.conn_recv.recv()
|
||||
self._run_on_sub_receive_funcs(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `SYNC_ON_RECEIVE_FUNC = Callable[[T], Any]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `type_check = self._get_generic_type() is not None`
|
||||
### ***var*** `ASYNC_ON_RECEIVE_FUNC = Callable[[T], Coroutine[Any, Any, Any]]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `ON_RECEIVE_FUNC = SYNC_ON_RECEIVE_FUNC | ASYNC_ON_RECEIVE_FUNC`
|
||||
|
||||
### ***var*** `data = self.conn_recv.recv()`
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `SYNC_FILTER_FUNC = Callable[[T], bool]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `func = _callback_funcs[func_id]`
|
||||
### ***var*** `ASYNC_FILTER_FUNC = Callable[[T], Coroutine[Any, Any, bool]]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `FILTER_FUNC = SYNC_FILTER_FUNC | ASYNC_FILTER_FUNC`
|
||||
|
||||
### ***var*** `func = _callback_funcs[func_id]`
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
### ***var*** `_func_id = 0`
|
||||
|
||||
- **Type**: `int`
|
||||
|
||||
### ***var*** `data = self.conn_recv.recv()`
|
||||
### ***var*** `_channel = {}`
|
||||
|
||||
- **Type**: `dict[str, 'Channel']`
|
||||
|
||||
### ***var*** `_callback_funcs = {}`
|
||||
|
||||
### ***var*** `data = self.conn_recv.recv()`
|
||||
- **Type**: `dict[int, ON_RECEIVE_FUNC]`
|
||||
|
||||
### ***var*** `active_channel = None`
|
||||
|
||||
- **Type**: `Optional['Channel']`
|
||||
|
||||
- **Description**: 子进程可用的主动和被动通道
|
||||
|
||||
### ***var*** `passive_channel = None`
|
||||
|
||||
- **Type**: `Optional['Channel']`
|
||||
|
||||
### ***var*** `publish_channel = Channel(_id='publish_channel')`
|
||||
|
||||
- **Type**: `Channel[tuple[str, dict[str, Any]]]`
|
||||
|
||||
### ***var*** `channel_deliver_active_channel = NO_DEFAULT`
|
||||
|
||||
- **Type**: `Channel[Channel[Any]]`
|
||||
|
||||
- **Description**: 通道传递通道,主进程创建单例,子进程初始化时实例化
|
||||
|
||||
### ***var*** `channel_deliver_passive_channel = NO_DEFAULT`
|
||||
|
||||
- **Type**: `Channel[tuple[str, dict[str, Any]]]`
|
||||
|
||||
|
@ -1,20 +1,12 @@
|
||||
---
|
||||
title: liteyuki.comm.event
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### **class** `Event`
|
||||
### *method* `__init__(self, name: str, data: dict[str, Any])`
|
||||
|
||||
### ***class*** `Event`
|
||||
|
||||
事件类
|
||||
|
||||
###   ***def*** `__init__(self, name: str, data: dict[str, Any]) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, name: str, data: dict[str, Any]):
|
||||
|
@ -1,46 +1,12 @@
|
||||
---
|
||||
title: liteyuki.comm.storage
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `run_subscriber_receive_funcs(channel_: str, data: Any) -> None`
|
||||
|
||||
运行订阅者接收函数
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
|
||||
data: 数据
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
def run_subscriber_receive_funcs(channel_: str, data: Any):
|
||||
"""
|
||||
运行订阅者接收函数
|
||||
Args:
|
||||
channel_: 频道
|
||||
data: 数据
|
||||
"""
|
||||
if IS_MAIN_PROCESS:
|
||||
if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
|
||||
elif channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get')`
|
||||
### *func* `on_get()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get')
|
||||
@ -52,12 +18,12 @@ def on_get(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_set(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'set')`
|
||||
### *func* `on_set()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'set')
|
||||
@ -68,12 +34,12 @@ def on_set(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_delete(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'delete')`
|
||||
### *func* `on_delete()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'delete')
|
||||
@ -83,12 +49,12 @@ def on_delete(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_get_all(data: tuple[str, dict[str, Any]]) -> None`
|
||||
|
||||
### `@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get_all')`
|
||||
### *func* `on_get_all()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@shared_memory.passive_chan.on_receive(lambda d: d[0] == 'get_all')
|
||||
@ -98,12 +64,12 @@ def on_get_all(data: tuple[str, dict[str, Any]]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_publish(data: tuple[str, Any]) -> None`
|
||||
|
||||
### `@channel.publish_channel.on_receive()`
|
||||
### *func* `on_publish()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@channel.publish_channel.on_receive()
|
||||
@ -113,59 +79,12 @@ def on_publish(data: tuple[str, Any]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: ON_RECEIVE_FUNC) -> ON_RECEIVE_FUNC`
|
||||
|
||||
### **class** `Subscriber`
|
||||
### *method* `__init__(self)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def decorator(func: ON_RECEIVE_FUNC) -> ON_RECEIVE_FUNC:
|
||||
|
||||
async def wrapper(data: Any):
|
||||
if is_coroutine_callable(func):
|
||||
await func(data)
|
||||
else:
|
||||
func(data)
|
||||
if IS_MAIN_PROCESS:
|
||||
if channel_ not in _on_main_subscriber_receive_funcs:
|
||||
_on_main_subscriber_receive_funcs[channel_] = []
|
||||
_on_main_subscriber_receive_funcs[channel_].append(wrapper)
|
||||
else:
|
||||
if channel_ not in _on_sub_subscriber_receive_funcs:
|
||||
_on_sub_subscriber_receive_funcs[channel_] = []
|
||||
_on_sub_subscriber_receive_funcs[channel_].append(wrapper)
|
||||
return wrapper
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***async def*** `wrapper(data: Any) -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
async def wrapper(data: Any):
|
||||
if is_coroutine_callable(func):
|
||||
await func(data)
|
||||
else:
|
||||
func(data)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `Subscriber`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self):
|
||||
@ -173,12 +92,11 @@ def __init__(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `receive(self) -> Any`
|
||||
### *method* `receive(self) -> Any`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def receive(self) -> Any:
|
||||
@ -186,12 +104,11 @@ def receive(self) -> Any:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `unsubscribe(self) -> None`
|
||||
### *method* `unsubscribe(self) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def unsubscribe(self) -> None:
|
||||
@ -199,16 +116,12 @@ def unsubscribe(self) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `KeyValueStore`
|
||||
### **class** `KeyValueStore`
|
||||
### *method* `__init__(self)`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self):
|
||||
@ -221,18 +134,19 @@ def __init__(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `set(self, key: str, value: Any) -> None`
|
||||
### *method* `set(self, key: str, value: Any) -> None`
|
||||
|
||||
 设置键值对
|
||||
|
||||
Args:
|
||||
|
||||
key: 键
|
||||
**Description**: 设置键值对
|
||||
|
||||
**Arguments**:
|
||||
> - key: 键
|
||||
> - value: 值
|
||||
|
||||
value: 值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def set(self, key: str, value: Any) -> None:
|
||||
@ -252,24 +166,21 @@ def set(self, key: str, value: Any) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `get(self, key: str, default: Optional[Any]) -> Optional[Any]`
|
||||
|
||||
 获取键值对
|
||||
|
||||
Args:
|
||||
|
||||
key: 键
|
||||
|
||||
default: 默认值
|
||||
### *method* `get(self, key: str, default: Optional[Any] = None) -> Optional[Any]`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 获取键值对
|
||||
|
||||
**Arguments**:
|
||||
> - key: 键
|
||||
> - default: 默认值
|
||||
|
||||
**Return**: Any: 值
|
||||
|
||||
Any: 值
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get(self, key: str, default: Optional[Any]=None) -> Optional[Any]:
|
||||
@ -293,22 +204,19 @@ def get(self, key: str, default: Optional[Any]=None) -> Optional[Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `delete(self, key: str, ignore_key_error: bool) -> None`
|
||||
|
||||
 删除键值对
|
||||
|
||||
Args:
|
||||
|
||||
key: 键
|
||||
|
||||
ignore_key_error: 是否忽略键不存在的错误
|
||||
### *method* `delete(self, key: str, ignore_key_error: bool = True) -> None`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 删除键值对
|
||||
|
||||
**Arguments**:
|
||||
> - key: 键
|
||||
> - ignore_key_error: 是否忽略键不存在的错误
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def delete(self, key: str, ignore_key_error: bool=True) -> None:
|
||||
@ -335,16 +243,17 @@ def delete(self, key: str, ignore_key_error: bool=True) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `get_all(self) -> dict[str, Any]`
|
||||
### *method* `get_all(self) -> dict[str, Any]`
|
||||
|
||||
 获取所有键值对
|
||||
|
||||
Returns:
|
||||
|
||||
dict[str, Any]: 键值对
|
||||
**Description**: 获取所有键值对
|
||||
|
||||
**Return**: dict[str, Any]: 键值对
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_all(self) -> dict[str, Any]:
|
||||
@ -362,22 +271,19 @@ def get_all(self) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `publish(self, channel_: str, data: Any) -> None`
|
||||
|
||||
 发布消息
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
|
||||
data: 数据
|
||||
### *method* `publish(self, channel_: str, data: Any) -> None`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 发布消息
|
||||
|
||||
**Arguments**:
|
||||
> - channel_: 频道
|
||||
> - data: 数据
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def publish(self, channel_: str, data: Any) -> None:
|
||||
@ -393,22 +299,20 @@ def publish(self, channel_: str, data: Any) -> None:
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]`
|
||||
|
||||
 订阅者接收消息时的回调
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
### *method* `on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 订阅者接收消息时的回调
|
||||
|
||||
**Arguments**:
|
||||
> - channel_: 频道
|
||||
|
||||
**Return**: 装饰器
|
||||
|
||||
装饰器
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON_RECEIVE_FUNC]:
|
||||
@ -447,19 +351,20 @@ def on_subscriber_receive(self, channel_: str) -> Callable[[ON_RECEIVE_FUNC], ON
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***@staticmethod***
|
||||
###   ***def*** `run_subscriber_receive_funcs(channel_: str, data: Any) -> None`
|
||||
### `@staticmethod`
|
||||
### *method* `run_subscriber_receive_funcs(channel_: str, data: Any)`
|
||||
|
||||
 运行订阅者接收函数
|
||||
|
||||
Args:
|
||||
|
||||
channel_: 频道
|
||||
**Description**: 运行订阅者接收函数
|
||||
|
||||
**Arguments**:
|
||||
> - channel_: 频道
|
||||
> - data: 数据
|
||||
|
||||
data: 数据
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@staticmethod
|
||||
@ -472,23 +377,48 @@ def run_subscriber_receive_funcs(channel_: str, data: Any):
|
||||
"""
|
||||
if IS_MAIN_PROCESS:
|
||||
if channel_ in _on_main_subscriber_receive_funcs and _on_main_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
|
||||
run_coroutine_in_thread(*[func(data) for func in _on_main_subscriber_receive_funcs[channel_]])
|
||||
elif channel_ in _on_sub_subscriber_receive_funcs and _on_sub_subscriber_receive_funcs[channel_]:
|
||||
run_coroutine(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
|
||||
run_coroutine_in_thread(*[func(data) for func in _on_sub_subscriber_receive_funcs[channel_]])
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `GlobalKeyValueStore`
|
||||
### *method* `_start_receive_loop(self)`
|
||||
|
||||
|
||||
|
||||
###   ***@classmethod***
|
||||
###   ***def*** `get_instance(cls: Any) -> None`
|
||||
**Description**: 启动发布订阅接收器循环,在主进程中运行,若有子进程订阅则推送给子进程
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def _start_receive_loop(self):
|
||||
"""
|
||||
启动发布订阅接收器循环,在主进程中运行,若有子进程订阅则推送给子进程
|
||||
"""
|
||||
if IS_MAIN_PROCESS:
|
||||
while True:
|
||||
data = self.active_chan.receive()
|
||||
if data[0] == 'publish':
|
||||
self.run_subscriber_receive_funcs(data[1]['channel'], data[1]['data'])
|
||||
self.publish_channel.send(data)
|
||||
else:
|
||||
while True:
|
||||
data = self.publish_channel.receive()
|
||||
if data[0] == 'publish':
|
||||
self.run_subscriber_receive_funcs(data[1]['channel'], data[1]['data'])
|
||||
```
|
||||
</details>
|
||||
|
||||
### **class** `GlobalKeyValueStore`
|
||||
### `@classmethod`
|
||||
### *method* `get_instance(cls)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@classmethod
|
||||
@ -501,63 +431,19 @@ def get_instance(cls):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***attr*** `_instance: None`
|
||||
### ***var*** `_on_main_subscriber_receive_funcs = {}`
|
||||
|
||||
###   ***attr*** `_lock: threading.Lock()`
|
||||
- **Type**: `dict[str, list[ASYNC_ON_RECEIVE_FUNC]]`
|
||||
|
||||
### ***var*** `key = data[1]['key']`
|
||||
- **Description**: 主进程订阅者接收函数
|
||||
|
||||
### ***var*** `_on_sub_subscriber_receive_funcs = {}`
|
||||
|
||||
- **Type**: `dict[str, list[ASYNC_ON_RECEIVE_FUNC]]`
|
||||
|
||||
### ***var*** `default = data[1]['default']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = data[1]['recv_chan']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `key = data[1]['key']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `value = data[1]['value']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `key = data[1]['key']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = data[1]['recv_chan']`
|
||||
|
||||
|
||||
|
||||
### ***var*** `lock = _get_lock(key)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `lock = _get_lock(key)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = Channel[Optional[Any]]('recv_chan')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `lock = _get_lock(key)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `recv_chan = Channel[dict[str, Any]]('recv_chan')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = self.active_chan.receive()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = self.publish_channel.receive()`
|
||||
- **Description**: 子进程订阅者接收函数
|
||||
|
||||
### ***var*** `shared_memory = GlobalKeyValueStore.get_instance()`
|
||||
|
||||
- **Type**: `KeyValueStore`
|
||||
|
||||
|
@ -1,30 +1,22 @@
|
||||
---
|
||||
title: liteyuki.config
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `flat_config(config: dict[str, Any]) -> dict[str, Any]`
|
||||
|
||||
扁平化配置文件
|
||||
### *func* `flat_config() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**Description**: 扁平化配置文件
|
||||
|
||||
{a:{b:{c:1}}} -> {"a.b.c": 1}
|
||||
|
||||
Args:
|
||||
**Arguments**:
|
||||
> - config: 配置项目
|
||||
|
||||
config: 配置项目
|
||||
**Return**: 扁平化后的配置文件,但也包含原有的键值对
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
扁平化后的配置文件,但也包含原有的键值对
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def flat_config(config: dict[str, Any]) -> dict[str, Any]:
|
||||
@ -47,69 +39,80 @@ def flat_config(config: dict[str, Any]) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_yaml(file: str) -> dict[str, Any]`
|
||||
### *func* `load_from_yaml() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**Description**: Load config from yaml file
|
||||
|
||||
Load config from yaml file
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_yaml(file: str) -> dict[str, Any]:
|
||||
def load_from_yaml(file_: str) -> dict[str, Any]:
|
||||
"""
|
||||
Load config from yaml file
|
||||
|
||||
"""
|
||||
logger.debug(f'Loading YAML config from {file}')
|
||||
config = yaml.safe_load(open(file, 'r', encoding='utf-8'))
|
||||
logger.debug(f'Loading YAML config from {file_}')
|
||||
config = yaml.safe_load(open(file_, 'r', encoding='utf-8'))
|
||||
return flat_config(config if config is not None else {})
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_json(file: str) -> dict[str, Any]`
|
||||
### *func* `load_from_json() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**Description**: Load config from json file
|
||||
|
||||
Load config from json file
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_json(file: str) -> dict[str, Any]:
|
||||
def load_from_json(file_: str) -> dict[str, Any]:
|
||||
"""
|
||||
Load config from json file
|
||||
"""
|
||||
logger.debug(f'Loading JSON config from {file}')
|
||||
config = json.load(open(file, 'r', encoding='utf-8'))
|
||||
logger.debug(f'Loading JSON config from {file_}')
|
||||
config = json.load(open(file_, 'r', encoding='utf-8'))
|
||||
return flat_config(config if config is not None else {})
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_toml(file: str) -> dict[str, Any]`
|
||||
### *func* `load_from_toml() -> dict[str, Any]`
|
||||
|
||||
|
||||
|
||||
**Description**: Load config from toml file
|
||||
|
||||
Load config from toml file
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_toml(file: str) -> dict[str, Any]:
|
||||
def load_from_toml(file_: str) -> dict[str, Any]:
|
||||
"""
|
||||
Load config from toml file
|
||||
"""
|
||||
logger.debug(f'Loading TOML config from {file}')
|
||||
config = toml.load(open(file, 'r', encoding='utf-8'))
|
||||
logger.debug(f'Loading TOML config from {file_}')
|
||||
config = toml.load(open(file_, 'r', encoding='utf-8'))
|
||||
return flat_config(config if config is not None else {})
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_from_files() -> dict[str, Any]`
|
||||
### *func* `load_from_files(*, no_warning: bool = False) -> dict[str, Any]`
|
||||
|
||||
从指定文件加载配置项,会自动识别文件格式
|
||||
|
||||
|
||||
**Description**: 从指定文件加载配置项,会自动识别文件格式
|
||||
默认执行扁平化选项
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_from_files(*files: str, no_warning: bool=False) -> dict[str, Any]:
|
||||
@ -134,16 +137,17 @@ def load_from_files(*files: str, no_warning: bool=False) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_configs_from_dirs() -> dict[str, Any]`
|
||||
### *func* `load_configs_from_dirs(*, no_waring: bool = False) -> dict[str, Any]`
|
||||
|
||||
从目录下加载配置文件,不递归
|
||||
|
||||
|
||||
**Description**: 从目录下加载配置文件,不递归
|
||||
按照读取文件的优先级反向覆盖
|
||||
|
||||
默认执行扁平化选项
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_configs_from_dirs(*directories: str, no_waring: bool=False) -> dict[str, Any]:
|
||||
@ -165,16 +169,17 @@ def load_configs_from_dirs(*directories: str, no_waring: bool=False) -> dict[str
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_config_in_default(no_waring: bool) -> dict[str, Any]`
|
||||
### *func* `load_config_in_default(no_waring: bool = False) -> dict[str, Any]`
|
||||
|
||||
从一个标准的轻雪项目加载配置文件
|
||||
|
||||
|
||||
**Description**: 从一个标准的轻雪项目加载配置文件
|
||||
项目目录下的config.*和config目录下的所有配置文件
|
||||
|
||||
项目目录下的配置文件优先
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_config_in_default(no_waring: bool=False) -> dict[str, Any]:
|
||||
@ -189,43 +194,3 @@ def load_config_in_default(no_waring: bool=False) -> dict[str, Any]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `SatoriNodeConfig(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `SatoriConfig(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `BasicConfig(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `new_config = copy.deepcopy(config)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = yaml.safe_load(open(file, 'r', encoding='utf-8'))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = json.load(open(file, 'r', encoding='utf-8'))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = toml.load(open(file, 'r', encoding='utf-8'))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = {}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = {}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `config = load_configs_from_dirs('config', no_waring=no_waring)`
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.core
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,20 +1,12 @@
|
||||
---
|
||||
title: liteyuki.core.manager
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### **class** `ChannelDeliver`
|
||||
### *method* `__init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_active: Channel[Channel[Any]], channel_deliver_passive: Channel[tuple[str, dict]], publish: Channel[tuple[str, Any]])`
|
||||
|
||||
### ***class*** `ChannelDeliver`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_active: Channel[Channel[Any]], channel_deliver_passive: Channel[tuple[str, dict]], publish: Channel[tuple[str, Any]]) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_active: Channel[Channel[Any]], channel_deliver_passive: Channel[tuple[str, dict]], publish: Channel[tuple[str, Any]]):
|
||||
@ -26,16 +18,12 @@ def __init__(self, active: Channel[Any], passive: Channel[Any], channel_deliver_
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `ProcessManager`
|
||||
### **class** `ProcessManager`
|
||||
### *method* `__init__(self, lifespan: Lifespan)`
|
||||
|
||||
进程管理器
|
||||
|
||||
###   ***def*** `__init__(self, lifespan: 'Lifespan') -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, lifespan: 'Lifespan'):
|
||||
@ -45,18 +33,18 @@ def __init__(self, lifespan: 'Lifespan'):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `start(self, name: str) -> None`
|
||||
### *method* `start(self, name: str)`
|
||||
|
||||
 开启后自动监控进程,并添加到进程字典中
|
||||
|
||||
Args:
|
||||
|
||||
name:
|
||||
**Description**: 开启后自动监控进程,并添加到进程字典中
|
||||
|
||||
**Arguments**:
|
||||
> - name:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def start(self, name: str):
|
||||
@ -95,12 +83,15 @@ def start(self, name: str):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `start_all(self) -> None`
|
||||
### *method* `start_all(self)`
|
||||
|
||||
|
||||
|
||||
**Description**: 启动所有进程
|
||||
|
||||
 启动所有进程
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def start_all(self):
|
||||
@ -112,22 +103,21 @@ def start_all(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `add_target(self, name: str, target: TARGET_FUNC, args: tuple, kwargs: Any) -> None`
|
||||
### *method* `add_target(self, name: str, target: TARGET_FUNC, args: tuple = (), kwargs = None)`
|
||||
|
||||
 添加进程
|
||||
|
||||
Args:
|
||||
|
||||
name: 进程名,用于获取和唯一标识
|
||||
**Description**: 添加进程
|
||||
|
||||
target: 进程函数
|
||||
**Arguments**:
|
||||
> - name: 进程名,用于获取和唯一标识
|
||||
> - target: 进程函数
|
||||
> - args: 进程函数参数
|
||||
> - kwargs: 进程函数关键字参数,通常会默认传入chan_active和chan_passive
|
||||
|
||||
args: 进程函数参数
|
||||
|
||||
kwargs: 进程函数关键字参数,通常会默认传入chan_active和chan_passive
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def add_target(self, name: str, target: TARGET_FUNC, args: tuple=(), kwargs=None):
|
||||
@ -149,12 +139,11 @@ def add_target(self, name: str, target: TARGET_FUNC, args: tuple=(), kwargs=None
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `join_all(self) -> None`
|
||||
### *method* `join_all(self)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def join_all(self):
|
||||
@ -163,20 +152,18 @@ def join_all(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `terminate(self, name: str) -> None`
|
||||
|
||||
 终止进程并从进程字典中删除
|
||||
|
||||
Args:
|
||||
|
||||
name:
|
||||
### *method* `terminate(self, name: str)`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 终止进程并从进程字典中删除
|
||||
|
||||
**Arguments**:
|
||||
> - name:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def terminate(self, name: str):
|
||||
@ -200,12 +187,11 @@ def terminate(self, name: str):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `terminate_all(self) -> None`
|
||||
### *method* `terminate_all(self)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def terminate_all(self):
|
||||
@ -214,20 +200,18 @@ def terminate_all(self):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `is_process_alive(self, name: str) -> bool`
|
||||
|
||||
 检查进程是否存活
|
||||
|
||||
Args:
|
||||
|
||||
name:
|
||||
### *method* `is_process_alive(self, name: str) -> bool`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 检查进程是否存活
|
||||
|
||||
**Arguments**:
|
||||
> - name:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def is_process_alive(self, name: str) -> bool:
|
||||
@ -245,31 +229,7 @@ def is_process_alive(self, name: str) -> bool:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `TIMEOUT = 10`
|
||||
|
||||
|
||||
|
||||
### ***var*** `chan_active = get_channel(f'{name}-active')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `channel_deliver = ChannelDeliver(active=chan_active, passive=chan_passive, channel_deliver_active=channel_deliver_active_channel, channel_deliver_passive=channel_deliver_passive_channel, publish=publish_channel)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `process = self.processes[name]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `process = Process(target=self.targets[name][0], args=self.targets[name][1], kwargs=self.targets[name][2], daemon=True)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = chan_active.receive()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `kwargs = {}`
|
||||
|
||||
### ***var*** `TARGET_FUNC = Callable[..., Any]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.dev
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
---
|
||||
title: liteyuki.dev.observer
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `debounce()`
|
||||
|
||||
### ***def*** `debounce(wait: Any) -> None`
|
||||
|
||||
防抖函数
|
||||
|
||||
**Description**: 防抖函数
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def debounce(wait):
|
||||
@ -32,24 +31,22 @@ def debounce(wait):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `on_file_system_event(directories: tuple[str], recursive: bool, event_filter: FILTER_FUNC) -> Callable[[CALLBACK_FUNC], CALLBACK_FUNC]`
|
||||
### *func* `on_file_system_event(directories: tuple[str] = True, recursive: bool = None) -> Callable[[CALLBACK_FUNC], CALLBACK_FUNC]`
|
||||
|
||||
注册文件系统变化监听器
|
||||
|
||||
Args:
|
||||
|
||||
directories: 监听目录们
|
||||
**Description**: 注册文件系统变化监听器
|
||||
|
||||
recursive: 是否递归监听子目录
|
||||
**Arguments**:
|
||||
> - directories: 监听目录们
|
||||
> - recursive: 是否递归监听子目录
|
||||
> - event_filter: 事件过滤器, 返回True则执行回调函数
|
||||
|
||||
event_filter: 事件过滤器, 返回True则执行回调函数
|
||||
**Return**: 装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
Returns:
|
||||
|
||||
装饰器,装饰一个函数在接收到数据后执行
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_file_system_event(directories: tuple[str], recursive: bool=True, event_filter: FILTER_FUNC=None) -> Callable[[CALLBACK_FUNC], CALLBACK_FUNC]:
|
||||
@ -78,91 +75,13 @@ def on_file_system_event(directories: tuple[str], recursive: bool=True, event_fi
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: Any) -> None`
|
||||
|
||||
### **class** `CodeModifiedHandler(FileSystemEventHandler)`
|
||||
### `@debounce(1)`
|
||||
### *method* `on_modified(self, event)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def decorator(func):
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
nonlocal last_call_time
|
||||
current_time = time.time()
|
||||
if current_time - last_call_time > wait:
|
||||
last_call_time = current_time
|
||||
return func(*args, **kwargs)
|
||||
last_call_time = None
|
||||
return wrapper
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `decorator(func: CALLBACK_FUNC) -> CALLBACK_FUNC`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def decorator(func: CALLBACK_FUNC) -> CALLBACK_FUNC:
|
||||
|
||||
def wrapper(event: FileSystemEvent):
|
||||
if event_filter is not None and (not event_filter(event)):
|
||||
return
|
||||
func(event)
|
||||
code_modified_handler = CodeModifiedHandler()
|
||||
code_modified_handler.on_modified = wrapper
|
||||
for directory in directories:
|
||||
observer.schedule(code_modified_handler, directory, recursive=recursive)
|
||||
return func
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `wrapper() -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def wrapper(*args, **kwargs):
|
||||
nonlocal last_call_time
|
||||
current_time = time.time()
|
||||
if current_time - last_call_time > wait:
|
||||
last_call_time = current_time
|
||||
return func(*args, **kwargs)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `wrapper(event: FileSystemEvent) -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
def wrapper(event: FileSystemEvent):
|
||||
if event_filter is not None and (not event_filter(event)):
|
||||
return
|
||||
func(event)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `CodeModifiedHandler(FileSystemEventHandler)`
|
||||
|
||||
Handler for code file changes
|
||||
|
||||
###   ***def*** `on_modified(self, event: Any) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@debounce(1)
|
||||
@ -171,12 +90,11 @@ def on_modified(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_created(self, event: Any) -> None`
|
||||
### *method* `on_created(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_created(self, event):
|
||||
@ -184,12 +102,11 @@ def on_created(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_deleted(self, event: Any) -> None`
|
||||
### *method* `on_deleted(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_deleted(self, event):
|
||||
@ -197,12 +114,11 @@ def on_deleted(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_moved(self, event: Any) -> None`
|
||||
### *method* `on_moved(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_moved(self, event):
|
||||
@ -210,12 +126,11 @@ def on_moved(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `on_any_event(self, event: Any) -> None`
|
||||
### *method* `on_any_event(self, event)`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_any_event(self, event):
|
||||
@ -223,27 +138,15 @@ def on_any_event(self, event):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `liteyuki_bot = get_bot()`
|
||||
### ***var*** `CALLBACK_FUNC = Callable[[FileSystemEvent], None]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
- **Description**: 位置1为FileSystemEvent
|
||||
|
||||
### ***var*** `observer = Observer()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `last_call_time = None`
|
||||
|
||||
|
||||
|
||||
### ***var*** `code_modified_handler = CodeModifiedHandler()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `current_time = time.time()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `last_call_time = current_time`
|
||||
### ***var*** `FILTER_FUNC = Callable[[FileSystemEvent], bool]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
- **Description**: 位置1为FileSystemEvent
|
||||
|
||||
|
@ -1,20 +1,18 @@
|
||||
---
|
||||
title: liteyuki.dev.plugin
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `run_plugins()`
|
||||
|
||||
### ***def*** `run_plugins() -> None`
|
||||
|
||||
运行插件,无需手动初始化bot
|
||||
|
||||
Args:
|
||||
**Description**: 运行插件,无需手动初始化bot
|
||||
|
||||
**Arguments**:
|
||||
> - module_path: 插件路径,参考`liteyuki.load_plugin`的函数签名
|
||||
|
||||
module_path: 插件路径,参考`liteyuki.load_plugin`的函数签名
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def run_plugins(*module_path: str | Path):
|
||||
@ -32,15 +30,3 @@ def run_plugins(*module_path: str | Path):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `cfg = load_config_in_default()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `plugins = cfg.get('liteyuki.plugins', [])`
|
||||
|
||||
|
||||
|
||||
### ***var*** `bot = LiteyukiBot(**cfg)`
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +1,4 @@
|
||||
---
|
||||
title: liteyuki.exception
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `LiteyukiException(BaseException)`
|
||||
|
||||
Liteyuki的异常基类。
|
||||
|
||||
### **class** `LiteyukiException(BaseException)`
|
||||
|
@ -1,16 +1,11 @@
|
||||
---
|
||||
title: liteyuki.log
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `get_format(level: str) -> str`
|
||||
|
||||
### *func* `get_format() -> str`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_format(level: str) -> str:
|
||||
@ -21,14 +16,15 @@ def get_format(level: str) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `init_log(config: dict) -> None`
|
||||
### *func* `init_log()`
|
||||
|
||||
在语言加载完成后执行
|
||||
|
||||
Returns:
|
||||
|
||||
**Description**: 在语言加载完成后执行
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def init_log(config: dict):
|
||||
@ -48,11 +44,11 @@ def init_log(config: dict):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `logger = loguru.logger`
|
||||
### ***var*** `debug_format = '<c>{time:YYYY-MM-DD HH:mm:ss}</c> <lvl>[{level.icon}]</lvl> <c><{name}.{module}.{function}:{line}></c> {message}'`
|
||||
|
||||
- **Type**: `str`
|
||||
|
||||
### ***var*** `default_format = '<c>{time:MM-DD HH:mm:ss}</c> <lvl>[{level.icon}]</lvl> <c><{name}></c> {message}'`
|
||||
|
||||
### ***var*** `show_icon = config.get('log_icon', True)`
|
||||
|
||||
|
||||
- **Type**: `str`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.message
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,47 +1,19 @@
|
||||
---
|
||||
title: liteyuki.message.event
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `MessageEvent`
|
||||
### **class** `MessageEvent`
|
||||
### *method* `__init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, user_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]] = None)`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]]) -> None`
|
||||
**Description**: 轻雪抽象消息事件
|
||||
|
||||
 轻雪抽象消息事件
|
||||
|
||||
Args:
|
||||
|
||||
|
||||
|
||||
bot_id: 机器人ID
|
||||
|
||||
message: 消息,消息段数组[{type: str, data: dict[str, Any]}]
|
||||
|
||||
raw_message: 原始消息(通常为纯文本的格式)
|
||||
|
||||
message_type: 消息类型(private, group, other)
|
||||
|
||||
|
||||
|
||||
session_id: 会话ID(私聊通常为用户ID,群聊通常为群ID)
|
||||
|
||||
session_type: 会话类型(private, group)
|
||||
|
||||
receive_channel: 接收频道(用于回复消息)
|
||||
|
||||
|
||||
|
||||
data: 附加数据
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]]=None):
|
||||
def __init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_type: str, raw_message: str, session_id: str, user_id: str, session_type: str, receive_channel: str, data: Optional[dict[str, Any]]=None):
|
||||
"""
|
||||
轻雪抽象消息事件
|
||||
Args:
|
||||
@ -66,22 +38,23 @@ def __init__(self, bot_id: str, message: list[dict[str, Any]] | str, message_typ
|
||||
self.raw_message = raw_message
|
||||
self.session_id = session_id
|
||||
self.session_type = session_type
|
||||
self.user_id = user_id
|
||||
self.receive_channel = receive_channel
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `reply(self, message: str | dict[str, Any]) -> None`
|
||||
### *method* `reply(self, message: str | dict[str, Any])`
|
||||
|
||||
 回复消息
|
||||
|
||||
Args:
|
||||
|
||||
message:
|
||||
**Description**: 回复消息
|
||||
|
||||
**Arguments**:
|
||||
> - message:
|
||||
|
||||
Returns:
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def reply(self, message: str | dict[str, Any]):
|
||||
@ -96,11 +69,3 @@ def reply(self, message: str | dict[str, Any]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `reply_event = MessageEvent(message_type=self.session_type, message=message, raw_message='', data={'message': message}, bot_id=self.bot_id, session_id=self.session_id, session_type=self.session_type, receive_channel='_')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `data = {}`
|
||||
|
||||
|
||||
|
||||
|
@ -1,28 +1,21 @@
|
||||
---
|
||||
title: liteyuki.message.matcher
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `Matcher`
|
||||
### **class** `Matcher`
|
||||
### *method* `__init__(self, rule: Rule, priority: int, block: bool)`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, rule: Rule, priority: int, block: bool) -> None`
|
||||
**Description**: 匹配器
|
||||
|
||||
 匹配器
|
||||
**Arguments**:
|
||||
> - rule: 规则
|
||||
> - priority: 优先级 >= 0
|
||||
> - block: 是否阻断后续优先级更低的匹配器
|
||||
|
||||
Args:
|
||||
|
||||
rule: 规则
|
||||
|
||||
priority: 优先级 >= 0
|
||||
|
||||
block: 是否阻断后续优先级更低的匹配器
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, rule: Rule, priority: int, block: bool):
|
||||
@ -40,32 +33,65 @@ def __init__(self, rule: Rule, priority: int, block: bool):
|
||||
```
|
||||
</details>
|
||||
|
||||
###   ***def*** `handle(self, handler: EventHandler) -> EventHandler`
|
||||
### *method* `handle(self) -> Callable[[EventHandler], EventHandler]`
|
||||
|
||||
 添加处理函数,装饰器
|
||||
|
||||
Args:
|
||||
|
||||
handler:
|
||||
**Description**: 添加处理函数,装饰器
|
||||
|
||||
Returns:
|
||||
**Return**: 装饰器 handler
|
||||
|
||||
EventHandler
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def handle(self, handler: EventHandler) -> EventHandler:
|
||||
def handle(self) -> Callable[[EventHandler], EventHandler]:
|
||||
"""
|
||||
添加处理函数,装饰器
|
||||
Args:
|
||||
handler:
|
||||
Returns:
|
||||
EventHandler
|
||||
装饰器 handler
|
||||
"""
|
||||
self.handlers.append(handler)
|
||||
return handler
|
||||
|
||||
def decorator(handler: EventHandler) -> EventHandler:
|
||||
self.handlers.append(handler)
|
||||
return handler
|
||||
return decorator
|
||||
```
|
||||
</details>
|
||||
|
||||
### *async method* `run(self, event: MessageEvent) -> None`
|
||||
|
||||
|
||||
|
||||
**Description**: 运行处理函数
|
||||
|
||||
**Arguments**:
|
||||
> - event:
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
async def run(self, event: MessageEvent) -> None:
|
||||
"""
|
||||
运行处理函数
|
||||
Args:
|
||||
event:
|
||||
Returns:
|
||||
"""
|
||||
if not await self.rule(event):
|
||||
return
|
||||
for handler in self.handlers:
|
||||
try:
|
||||
await handler(event)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `EventHandler = Callable[[MessageEvent], Coroutine[None, None, Any]]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
|
@ -1,19 +1,14 @@
|
||||
---
|
||||
title: liteyuki.message.on
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `on_message(rule: Rule, priority: int, block: bool) -> Matcher`
|
||||
|
||||
### *func* `on_message(rule: Rule = empty_rule, priority: int = 0, block: bool = False) -> Matcher`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def on_message(rule: Rule=Rule(), priority: int=0, block: bool=True) -> Matcher:
|
||||
def on_message(rule: Rule=empty_rule, priority: int=0, block: bool=False) -> Matcher:
|
||||
matcher = Matcher(rule, priority, block)
|
||||
for i, m in enumerate(_matcher_list):
|
||||
if m.priority < matcher.priority:
|
||||
@ -25,15 +20,27 @@ def on_message(rule: Rule=Rule(), priority: int=0, block: bool=True) -> Matcher:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `current_priority = -1`
|
||||
### *func* `on_keywords(keywords: list[str] = empty_rule, rule = 0, priority: int = False) -> Matcher`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
### ***var*** `matcher = Matcher(rule, priority, block)`
|
||||
```python
|
||||
def on_keywords(keywords: list[str], rule=empty_rule, priority: int=0, block: bool=False) -> Matcher:
|
||||
|
||||
@Rule
|
||||
async def on_keywords_rule(event: MessageEvent):
|
||||
return any((keyword in event.raw_message for keyword in keywords))
|
||||
return on_message(on_keywords_rule & rule, priority, block)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `_matcher_list = []`
|
||||
|
||||
### ***var*** `current_priority = matcher.priority`
|
||||
- **Type**: `list[Matcher]`
|
||||
|
||||
### ***var*** `_queue = Queue()`
|
||||
|
||||
- **Type**: `Queue`
|
||||
|
||||
|
@ -1,24 +1,98 @@
|
||||
---
|
||||
title: liteyuki.message.rule
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### `@Rule`
|
||||
### *async func* `empty_rule() -> bool`
|
||||
|
||||
### ***class*** `Rule`
|
||||
|
||||
|
||||
|
||||
###   ***def*** `__init__(self, handler: Optional[RuleHandler]) -> None`
|
||||
|
||||
 
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, handler: Optional[RuleHandler]=None):
|
||||
@Rule
|
||||
async def empty_rule(event: MessageEvent) -> bool:
|
||||
return True
|
||||
```
|
||||
</details>
|
||||
|
||||
### `@Rule`
|
||||
### *async func* `is_su_rule() -> bool`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@Rule
|
||||
async def is_su_rule(event: MessageEvent) -> bool:
|
||||
return str(event.user_id) in _superusers
|
||||
```
|
||||
</details>
|
||||
|
||||
### **class** `Rule`
|
||||
### *method* `__init__(self, handler: RuleHandlerFunc)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __init__(self, handler: RuleHandlerFunc):
|
||||
self.handler = handler
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `__or__(self, other: Rule) -> Rule`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __or__(self, other: 'Rule') -> 'Rule':
|
||||
|
||||
async def combined_handler(event: MessageEvent) -> bool:
|
||||
return await self.handler(event) or await other.handler(event)
|
||||
return Rule(combined_handler)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *method* `__and__(self, other: Rule) -> Rule`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def __and__(self, other: 'Rule') -> 'Rule':
|
||||
|
||||
async def combined_handler(event: MessageEvent) -> bool:
|
||||
return await self.handler(event) and await other.handler(event)
|
||||
return Rule(combined_handler)
|
||||
```
|
||||
</details>
|
||||
|
||||
### *async method* `__call__(self, event: MessageEvent) -> bool`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
async def __call__(self, event: MessageEvent) -> bool:
|
||||
if self.handler is None:
|
||||
return True
|
||||
return await self.handler(event)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `_superusers = get_config('liteyuki.superusers', [])`
|
||||
|
||||
- **Type**: `list[str]`
|
||||
|
||||
### ***var*** `RuleHandlerFunc = Callable[[MessageEvent], Coroutine[None, None, bool]]`
|
||||
|
||||
- **Type**: `TypeAlias`
|
||||
|
||||
- **Description**: 规则函数签名
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.message.session
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,22 +1,19 @@
|
||||
---
|
||||
title: liteyuki.mkdoc
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `get_relative_path() -> str`
|
||||
|
||||
### ***def*** `get_relative_path(base_path: str, target_path: str) -> str`
|
||||
|
||||
获取相对路径
|
||||
|
||||
Args:
|
||||
**Description**: 获取相对路径
|
||||
|
||||
base_path: 基础路径
|
||||
**Arguments**:
|
||||
> - base_path: 基础路径
|
||||
> - target_path: 目标路径
|
||||
|
||||
target_path: 目标路径
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_relative_path(base_path: str, target_path: str) -> str:
|
||||
@ -30,16 +27,18 @@ def get_relative_path(base_path: str, target_path: str) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `write_to_files(file_data: dict[str, str]) -> None`
|
||||
### *func* `write_to_files()`
|
||||
|
||||
输出文件
|
||||
|
||||
Args:
|
||||
|
||||
file_data: 文件数据 相对路径
|
||||
**Description**: 输出文件
|
||||
|
||||
**Arguments**:
|
||||
> - file_data: 文件数据 相对路径
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def write_to_files(file_data: dict[str, str]):
|
||||
@ -56,12 +55,11 @@ def write_to_files(file_data: dict[str, str]):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_file_list(module_folder: str) -> None`
|
||||
|
||||
### *func* `get_file_list()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_file_list(module_folder: str):
|
||||
@ -74,22 +72,21 @@ def get_file_list(module_folder: str):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `get_module_info_normal(file_path: str, ignore_private: bool) -> ModuleInfo`
|
||||
### *func* `get_module_info_normal(file_path: str = True) -> ModuleInfo`
|
||||
|
||||
获取函数和类
|
||||
|
||||
Args:
|
||||
|
||||
file_path: Python 文件路径
|
||||
**Description**: 获取函数和类
|
||||
|
||||
ignore_private: 忽略私有函数和类
|
||||
**Arguments**:
|
||||
> - file_path: Python 文件路径
|
||||
> - ignore_private: 忽略私有函数和类
|
||||
|
||||
Returns:
|
||||
**Return**: 模块信息
|
||||
|
||||
模块信息
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_module_info_normal(file_path: str, ignore_private: bool=True) -> ModuleInfo:
|
||||
@ -149,33 +146,33 @@ def get_module_info_normal(file_path: str, ignore_private: bool=True) -> ModuleI
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `generate_markdown(module_info: ModuleInfo, front_matter: Any) -> str`
|
||||
### *func* `generate_markdown(module_info: ModuleInfo = None, front_matter = 'zh-CN') -> str`
|
||||
|
||||
生成模块的Markdown
|
||||
|
||||
|
||||
**Description**: 生成模块的Markdown
|
||||
你可在此自定义生成的Markdown格式
|
||||
|
||||
Args:
|
||||
**Arguments**:
|
||||
> - module_info: 模块信息
|
||||
> - front_matter: 自定义选项title, index, icon, category
|
||||
> - lang: 语言
|
||||
|
||||
module_info: 模块信息
|
||||
**Return**: Markdown 字符串
|
||||
|
||||
front_matter: 自定义选项title, index, icon, category
|
||||
|
||||
Returns:
|
||||
|
||||
Markdown 字符串
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def generate_markdown(module_info: ModuleInfo, front_matter=None) -> str:
|
||||
def generate_markdown(module_info: ModuleInfo, front_matter=None, lang: str='zh-CN') -> str:
|
||||
"""
|
||||
生成模块的Markdown
|
||||
你可在此自定义生成的Markdown格式
|
||||
Args:
|
||||
module_info: 模块信息
|
||||
front_matter: 自定义选项title, index, icon, category
|
||||
lang: 语言
|
||||
Returns:
|
||||
Markdown 字符串
|
||||
"""
|
||||
@ -205,7 +202,11 @@ def generate_markdown(module_info: ModuleInfo, front_matter=None) -> str:
|
||||
content += f"###   ***{('async ' if method.is_async else '')}def*** `{method.name}({', '.join(args_with_type)}) -> {method.return_type}`\n\n"
|
||||
method.docstring = method.docstring.replace('\n', '\n\n')
|
||||
content += f' {method.docstring}\n\n'
|
||||
content += f'<details>\n<summary>源代码</summary>\n\n```python\n{method.source_code}\n```\n</details>\n\n'
|
||||
if lang == 'zh-CN':
|
||||
TEXT_SOURCE_CODE = '源代码'
|
||||
else:
|
||||
TEXT_SOURCE_CODE = 'Source Code'
|
||||
content += f'<details>\n<summary>{TEXT_SOURCE_CODE}</summary>\n\n```python\n{method.source_code}\n```\n</details>\n\n'
|
||||
for attr in cls.attributes:
|
||||
content += f'###   ***attr*** `{attr.name}: {attr.type}`\n\n'
|
||||
for attr in module_info.attributes:
|
||||
@ -219,25 +220,25 @@ def generate_markdown(module_info: ModuleInfo, front_matter=None) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `generate_docs(module_folder: str, output_dir: str, with_top: bool, ignored_paths: Any) -> None`
|
||||
### *func* `generate_docs(module_folder: str = False, output_dir: str = 'zh-CN', with_top: bool = None)`
|
||||
|
||||
生成文档
|
||||
|
||||
Args:
|
||||
|
||||
module_folder: 模块文件夹
|
||||
**Description**: 生成文档
|
||||
|
||||
output_dir: 输出文件夹
|
||||
**Arguments**:
|
||||
> - module_folder: 模块文件夹
|
||||
> - output_dir: 输出文件夹
|
||||
> - with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md
|
||||
> - ignored_paths: 忽略的路径
|
||||
> - lang: 语言
|
||||
|
||||
with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md
|
||||
|
||||
ignored_paths: 忽略的路径
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, ignored_paths=None):
|
||||
def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, lang: str='zh-CN', ignored_paths=None):
|
||||
"""
|
||||
生成文档
|
||||
Args:
|
||||
@ -245,6 +246,7 @@ def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, ign
|
||||
output_dir: 输出文件夹
|
||||
with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md
|
||||
ignored_paths: 忽略的路径
|
||||
lang: 语言
|
||||
"""
|
||||
if ignored_paths is None:
|
||||
ignored_paths = []
|
||||
@ -273,201 +275,8 @@ def generate_docs(module_folder: str, output_dir: str, with_top: bool=False, ign
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***class*** `DefType(Enum)`
|
||||
|
||||
|
||||
|
||||
###   ***attr*** `FUNCTION: 'function'`
|
||||
|
||||
###   ***attr*** `METHOD: 'method'`
|
||||
|
||||
###   ***attr*** `STATIC_METHOD: 'staticmethod'`
|
||||
|
||||
###   ***attr*** `CLASS_METHOD: 'classmethod'`
|
||||
|
||||
###   ***attr*** `PROPERTY: 'property'`
|
||||
|
||||
### ***class*** `FunctionInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `AttributeInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `ClassInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***class*** `ModuleInfo(BaseModel)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `NO_TYPE_ANY = 'Any'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `NO_TYPE_HINT = 'NoTypeHint'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `FUNCTION = 'function'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `METHOD = 'method'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `STATIC_METHOD = 'staticmethod'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `CLASS_METHOD = 'classmethod'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `PROPERTY = 'property'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `file_list = []`
|
||||
|
||||
|
||||
|
||||
### ***var*** `dot_sep_module_path = file_path.replace(os.sep, '.').replace('.py', '').replace('.pyi', '')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_docstring = ast.get_docstring(tree)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_info = ModuleInfo(module_path=dot_sep_module_path, functions=[], classes=[], attributes=[], docstring=module_docstring if module_docstring else '')`
|
||||
|
||||
|
||||
|
||||
### ***var*** `content = ''`
|
||||
|
||||
|
||||
|
||||
### ***var*** `front_matter = '---\n' + '\n'.join([f'{k}: {v}' for k, v in front_matter.items()]) + '\n---\n\n'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `file_list = get_file_list(module_folder)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `replace_data = {'__init__': 'README', '.py': '.md'}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `file_content = file.read()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `tree = ast.parse(file_content)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args_with_type = [f'{arg[0]}: {arg[1]}' if arg[1] else arg[0] for arg in func.args]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `ignored_paths = []`
|
||||
|
||||
|
||||
|
||||
### ***var*** `no_module_name_pyfile_path = get_relative_path(module_folder, pyfile_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `rel_md_path = pyfile_path if with_top else no_module_name_pyfile_path`
|
||||
|
||||
|
||||
|
||||
### ***var*** `abs_md_path = os.path.join(output_dir, rel_md_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_info = get_module_info_normal(pyfile_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `md_content = generate_markdown(module_info, front_matter)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `inherit = f"({', '.join(cls.inherit)})" if cls.inherit else ''`
|
||||
|
||||
|
||||
|
||||
### ***var*** `rel_md_path = rel_md_path.replace(rk, rv)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `front_matter = {'title': module_info.module_path.replace('.__init__', '').replace('_', '\\n'), 'index': 'true', 'icon': 'laptop-code', 'category': 'API'}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `front_matter = {'title': module_info.module_path.replace('_', '\\n'), 'order': '1', 'icon': 'laptop-code', 'category': 'API'}`
|
||||
|
||||
|
||||
|
||||
### ***var*** `function_docstring = ast.get_docstring(node)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `func_info = FunctionInfo(name=node.name, args=[(arg.arg, ast.unparse(arg.annotation) if arg.annotation else NO_TYPE_ANY) for arg in node.args.args], return_type=ast.unparse(node.returns) if node.returns else 'None', docstring=function_docstring if function_docstring else '', type=DefType.FUNCTION, is_async=isinstance(node, ast.AsyncFunctionDef), source_code=ast.unparse(node))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `class_docstring = ast.get_docstring(node)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `class_info = ClassInfo(name=node.name, docstring=class_docstring if class_docstring else '', methods=[], attributes=[], inherit=[ast.unparse(base) for base in node.bases])`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args_with_type = [f'{arg[0]}: {arg[1]}' if arg[1] else arg[0] for arg in method.args]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `args_with_type = [f'{arg[0]}: {arg[1]}' if arg[1] and arg[0] != 'self' else arg[0] for arg in method.args]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `first_arg = node.args.args[0]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `method_docstring = ast.get_docstring(class_node)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.METHOD`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.STATIC_METHOD`
|
||||
|
||||
|
||||
|
||||
### ***var*** `attr_type = NO_TYPE_HINT`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.CLASS_METHOD`
|
||||
|
||||
|
||||
|
||||
### ***var*** `attr_type = ast.unparse(node.value.annotation)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `def_type = DefType.PROPERTY`
|
||||
|
||||
|
||||
|
||||
### **class** `DefType(Enum)`
|
||||
### **class** `FunctionInfo(BaseModel)`
|
||||
### **class** `AttributeInfo(BaseModel)`
|
||||
### **class** `ClassInfo(BaseModel)`
|
||||
### **class** `ModuleInfo(BaseModel)`
|
||||
|
@ -1,20 +1,17 @@
|
||||
---
|
||||
title: liteyuki.plugin
|
||||
index: true
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `get_loaded_plugins() -> dict[str, Plugin]`
|
||||
|
||||
### ***def*** `get_loaded_plugins() -> dict[str, Plugin]`
|
||||
|
||||
获取已加载的插件
|
||||
|
||||
Returns:
|
||||
**Description**: 获取已加载的插件
|
||||
|
||||
**Return**: dict[str, Plugin]: 插件字典
|
||||
|
||||
dict[str, Plugin]: 插件字典
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def get_loaded_plugins() -> dict[str, Plugin]:
|
||||
|
@ -1,24 +1,20 @@
|
||||
---
|
||||
title: liteyuki.plugin.load
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***def*** `load_plugin(module_path: str | Path) -> Optional[Plugin]`
|
||||
|
||||
加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
||||
### *func* `load_plugin() -> Optional[Plugin]`
|
||||
|
||||
|
||||
|
||||
参数:
|
||||
**Description**: 加载单个插件,可以是本地插件或是通过 `pip` 安装的插件。
|
||||
|
||||
module_path: 插件名称 `path.to.your.plugin`
|
||||
|
||||
或插件路径 `pathlib.Path(path/to/your/plugin)`
|
||||
**Arguments**:
|
||||
> - module_path: 插件名称 `path.to.your.plugin`
|
||||
> - 或插件路径 `pathlib.Path(path/to/your/plugin)`:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_plugin(module_path: str | Path) -> Optional[Plugin]:
|
||||
@ -31,11 +27,21 @@ def load_plugin(module_path: str | Path) -> Optional[Plugin]:
|
||||
module_path = path_to_module_name(Path(module_path)) if isinstance(module_path, Path) else module_path
|
||||
try:
|
||||
module = import_module(module_path)
|
||||
_plugins[module.__name__] = Plugin(name=module.__name__, module=module, module_name=module_path, metadata=module.__dict__.get('__plugin_metadata__', None))
|
||||
display_name = module.__name__.split('.')[-1]
|
||||
if module.__dict__.get('__plugin_meta__'):
|
||||
_plugins[module.__name__] = Plugin(name=module.__name__, module=module, module_name=module_path)
|
||||
if module.__dict__.get('__plugin_metadata__', None):
|
||||
metadata: 'PluginMetadata' = module.__dict__['__plugin_metadata__']
|
||||
display_name = module.__name__.split('.')[-1]
|
||||
elif module.__dict__.get('__liteyuki_plugin_meta__', None):
|
||||
metadata: 'PluginMetadata' = module.__dict__['__liteyuki_plugin_meta__']
|
||||
display_name = format_display_name(f"{metadata.name}({module.__name__.split('.')[-1]})", metadata.type)
|
||||
elif module.__dict__.get('__plugin_meta__', None):
|
||||
metadata: 'PluginMetadata' = module.__dict__['__plugin_meta__']
|
||||
display_name = format_display_name(f"{metadata.name}({module.__name__.split('.')[-1]})", metadata.type)
|
||||
else:
|
||||
logger.opt(colors=True).warning(f'The metadata of Liteyuki plugin "{module.__name__}" is not specified, use empty.')
|
||||
metadata = PluginMetadata(name=module.__name__)
|
||||
display_name = module.__name__.split('.')[-1]
|
||||
_plugins[module.__name__].metadata = metadata
|
||||
logger.opt(colors=True).success(f'Succeeded to load liteyuki plugin "{display_name}"')
|
||||
return _plugins[module.__name__]
|
||||
except Exception as e:
|
||||
@ -45,20 +51,20 @@ def load_plugin(module_path: str | Path) -> Optional[Plugin]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `load_plugins() -> set[Plugin]`
|
||||
|
||||
导入文件夹下多个插件
|
||||
### *func* `load_plugins(*, ignore_warning: bool = True) -> set[Plugin]`
|
||||
|
||||
|
||||
|
||||
参数:
|
||||
**Description**: 导入文件夹下多个插件
|
||||
|
||||
plugin_dir: 文件夹路径
|
||||
|
||||
ignore_warning: 是否忽略警告,通常是目录不存在或目录为空
|
||||
**Arguments**:
|
||||
> - plugin_dir: 文件夹路径
|
||||
> - ignore_warning: 是否忽略警告,通常是目录不存在或目录为空
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def load_plugins(*plugin_dir: str, ignore_warning: bool=True) -> set[Plugin]:
|
||||
@ -97,24 +103,21 @@ def load_plugins(*plugin_dir: str, ignore_warning: bool=True) -> set[Plugin]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `format_display_name(display_name: str, plugin_type: PluginType) -> str`
|
||||
|
||||
设置插件名称颜色,根据不同类型插件设置颜色
|
||||
|
||||
Args:
|
||||
|
||||
display_name: 插件名称
|
||||
|
||||
plugin_type: 插件类型
|
||||
### *func* `format_display_name() -> str`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 设置插件名称颜色,根据不同类型插件设置颜色
|
||||
|
||||
**Arguments**:
|
||||
> - display_name: 插件名称
|
||||
> - plugin_type: 插件类型
|
||||
|
||||
**Return**: str: 设置后的插件名称 <y>name</y>
|
||||
|
||||
str: 设置后的插件名称 <y>name</y>
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def format_display_name(display_name: str, plugin_type: PluginType) -> str:
|
||||
@ -141,59 +144,19 @@ def format_display_name(display_name: str, plugin_type: PluginType) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `module_path = path_to_module_name(Path(module_path)) if isinstance(module_path, Path) else module_path`
|
||||
### ***var*** `_plugins = {}`
|
||||
|
||||
- **Type**: `dict[str, Plugin]`
|
||||
|
||||
### ***var*** `metadata = module.__dict__['__plugin_metadata__']`
|
||||
|
||||
### ***var*** `plugins = set()`
|
||||
- **Type**: `'PluginMetadata'`
|
||||
|
||||
### ***var*** `metadata = module.__dict__['__liteyuki_plugin_meta__']`
|
||||
|
||||
- **Type**: `'PluginMetadata'`
|
||||
|
||||
### ***var*** `color = 'y'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module = import_module(module_path)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `display_name = module.__name__.split('.')[-1]`
|
||||
|
||||
|
||||
|
||||
### ***var*** `display_name = format_display_name(f"{metadata.name}({module.__name__.split('.')[-1]})", metadata.type)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `path = Path(os.path.join(dir_path, f))`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_name = None`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'm'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'g'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'e'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `color = 'c'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_name = f'{path_to_module_name(Path(dir_path))}.{f[:-3]}'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `module_name = path_to_module_name(path)`
|
||||
|
||||
### ***var*** `metadata = module.__dict__['__plugin_meta__']`
|
||||
|
||||
- **Type**: `'PluginMetadata'`
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
---
|
||||
title: liteyuki.plugin.manager
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
|
@ -1,89 +1,18 @@
|
||||
---
|
||||
title: liteyuki.plugin.model
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
|
||||
### ***class*** `PluginType(Enum)`
|
||||
|
||||
插件类型枚举值
|
||||
|
||||
###   ***attr*** `APPLICATION: 'application'`
|
||||
|
||||
###   ***attr*** `SERVICE: 'service'`
|
||||
|
||||
###   ***attr*** `MODULE: 'module'`
|
||||
|
||||
###   ***attr*** `UNCLASSIFIED: 'unclassified'`
|
||||
|
||||
###   ***attr*** `TEST: 'test'`
|
||||
|
||||
### ***class*** `PluginMetadata(BaseModel)`
|
||||
|
||||
轻雪插件元数据,由插件编写者提供,name为必填项
|
||||
|
||||
Attributes:
|
||||
|
||||
----------
|
||||
### **class** `PluginType(Enum)`
|
||||
### **class** `PluginMetadata(BaseModel)`
|
||||
### **class** `Plugin(BaseModel)`
|
||||
### *method* `__hash__(self)`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
name: str
|
||||
|
||||
插件名称
|
||||
|
||||
description: str
|
||||
|
||||
插件描述
|
||||
|
||||
usage: str
|
||||
|
||||
插件使用方法
|
||||
|
||||
type: str
|
||||
|
||||
插件类型
|
||||
|
||||
author: str
|
||||
|
||||
插件作者
|
||||
|
||||
homepage: str
|
||||
|
||||
插件主页
|
||||
|
||||
extra: dict[str, Any]
|
||||
|
||||
额外信息
|
||||
|
||||
### ***class*** `Plugin(BaseModel)`
|
||||
|
||||
存储插件信息
|
||||
|
||||
###   ***attr*** `model_config: {'arbitrary_types_allowed': True}`
|
||||
|
||||
### ***var*** `APPLICATION = 'application'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `SERVICE = 'service'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `MODULE = 'module'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `UNCLASSIFIED = 'unclassified'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `TEST = 'test'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `model_config = {'arbitrary_types_allowed': True}`
|
||||
|
||||
|
||||
```python
|
||||
def __hash__(self):
|
||||
return hash(self.module_name)
|
||||
```
|
||||
</details>
|
||||
|
||||
|
17
docs/en/dev/api/plugins/liteecho.md
Normal file
17
docs/en/dev/api/plugins/liteecho.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
title: liteyuki.plugins.liteecho
|
||||
---
|
||||
### `@on_startswith(['liteecho'], rule=is_su_rule).handle()`
|
||||
### *async func* `liteecho()`
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
@on_startswith(['liteecho'], rule=is_su_rule).handle()
|
||||
async def liteecho(event: MessageEvent):
|
||||
event.reply(event.raw_message.strip()[8:].strip())
|
||||
```
|
||||
</details>
|
||||
|
25
docs/en/dev/api/plugins/plugin_loader/README.md
Normal file
25
docs/en/dev/api/plugins/plugin_loader/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: liteyuki.plugins.plugin_loader
|
||||
---
|
||||
### *func* `default_plugins_loader()`
|
||||
|
||||
|
||||
|
||||
**Description**: 默认插件加载器,应在初始化时调用
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def default_plugins_loader():
|
||||
"""
|
||||
默认插件加载器,应在初始化时调用
|
||||
"""
|
||||
for plugin in get_config('liteyuki.plugins', []):
|
||||
load_plugin(plugin)
|
||||
for plugin_dir in get_config('liteyuki.plugin_dirs', ['src/liteyuki_plugins']):
|
||||
load_plugins(plugin_dir)
|
||||
```
|
||||
</details>
|
||||
|
@ -1,24 +1,20 @@
|
||||
---
|
||||
title: liteyuki.utils
|
||||
order: 1
|
||||
icon: laptop-code
|
||||
category: API
|
||||
---
|
||||
### *func* `is_coroutine_callable() -> bool`
|
||||
|
||||
### ***def*** `is_coroutine_callable(call: Callable[..., Any]) -> bool`
|
||||
|
||||
判断是否为协程可调用对象
|
||||
|
||||
Args:
|
||||
**Description**: 判断是否为协程可调用对象
|
||||
|
||||
call: 可调用对象
|
||||
**Arguments**:
|
||||
> - call: 可调用对象
|
||||
|
||||
Returns:
|
||||
**Return**: bool: 是否为协程可调用对象
|
||||
|
||||
bool: 是否为协程可调用对象
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def is_coroutine_callable(call: Callable[..., Any]) -> bool:
|
||||
@ -38,20 +34,18 @@ def is_coroutine_callable(call: Callable[..., Any]) -> bool:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `run_coroutine() -> None`
|
||||
|
||||
运行协程
|
||||
|
||||
Args:
|
||||
|
||||
coro:
|
||||
### *func* `run_coroutine()`
|
||||
|
||||
|
||||
|
||||
Returns:
|
||||
**Description**: 运行协程
|
||||
|
||||
**Arguments**:
|
||||
> - coro:
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def run_coroutine(*coro: Coroutine):
|
||||
@ -81,20 +75,47 @@ def run_coroutine(*coro: Coroutine):
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `path_to_module_name(path: Path) -> str`
|
||||
### *func* `run_coroutine_in_thread()`
|
||||
|
||||
转换路径为模块名
|
||||
|
||||
Args:
|
||||
|
||||
path: 路径a/b/c/d -> a.b.c.d
|
||||
**Description**: 在新线程中运行协程
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - coro:
|
||||
|
||||
str: 模块名
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def run_coroutine_in_thread(*coro: Coroutine):
|
||||
"""
|
||||
在新线程中运行协程
|
||||
Args:
|
||||
coro:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
threading.Thread(target=run_coroutine, args=coro, daemon=True).start()
|
||||
```
|
||||
</details>
|
||||
|
||||
### *func* `path_to_module_name() -> str`
|
||||
|
||||
|
||||
|
||||
**Description**: 转换路径为模块名
|
||||
|
||||
**Arguments**:
|
||||
> - path: 路径a/b/c/d -> a.b.c.d
|
||||
|
||||
**Return**: str: 模块名
|
||||
|
||||
|
||||
<details>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def path_to_module_name(path: Path) -> str:
|
||||
@ -113,20 +134,20 @@ def path_to_module_name(path: Path) -> str:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***def*** `async_wrapper(func: Callable[..., Any]) -> Callable[..., Coroutine]`
|
||||
### *func* `async_wrapper() -> Callable[..., Coroutine]`
|
||||
|
||||
异步包装器
|
||||
|
||||
Args:
|
||||
|
||||
func: Sync Callable
|
||||
**Description**: 异步包装器
|
||||
|
||||
Returns:
|
||||
**Arguments**:
|
||||
> - func: Sync Callable
|
||||
|
||||
**Return**: Coroutine: Asynchronous Callable
|
||||
|
||||
Coroutine: Asynchronous Callable
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
<summary> <b>Source code</b> </summary>
|
||||
|
||||
```python
|
||||
def async_wrapper(func: Callable[..., Any]) -> Callable[..., Coroutine]:
|
||||
@ -145,36 +166,3 @@ def async_wrapper(func: Callable[..., Any]) -> Callable[..., Coroutine]:
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***async def*** `wrapper() -> None`
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>源代码</summary>
|
||||
|
||||
```python
|
||||
async def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
```
|
||||
</details>
|
||||
|
||||
### ***var*** `IS_MAIN_PROCESS = multiprocessing.current_process().name == 'MainProcess'`
|
||||
|
||||
|
||||
|
||||
### ***var*** `func_ = getattr(call, '__call__', None)`
|
||||
|
||||
|
||||
|
||||
### ***var*** `rel_path = path.resolve().relative_to(Path.cwd().resolve())`
|
||||
|
||||
|
||||
|
||||
### ***var*** `loop = asyncio.get_event_loop()`
|
||||
|
||||
|
||||
|
||||
### ***var*** `loop = asyncio.new_event_loop()`
|
||||
|
||||
|
||||
|
||||
|
10
litedoc/__init__.py
Normal file
10
litedoc/__init__.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午12:52
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : __init__.py.py
|
||||
@Software: PyCharm
|
||||
"""
|
48
litedoc/__main__.py
Normal file
48
litedoc/__main__.py
Normal file
@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午4:08
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : __main__.py
|
||||
@Software: PyCharm
|
||||
"""
|
||||
# command line tool
|
||||
# args[0] path
|
||||
# -o|--output output path
|
||||
# -l|--lang zh-Hans en jp default zh-Hans
|
||||
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from litedoc.output import generate_from_module
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Generate documentation from Python modules.")
|
||||
parser.add_argument("path", type=str, help="Path to the Python module or package.")
|
||||
parser.add_argument("-o", "--output", default="doc-output", type=str, help="Output directory.")
|
||||
parser.add_argument("-c", "--contain-top", action="store_true", help="Whether to contain top-level dir in output dir.")
|
||||
parser.add_argument("-l", "--lang", default="zh_Hans", type=str, help="Languages of the document.")
|
||||
parser.add_argument("-t", "--theme", default="vitepress", type=str, help="Theme of the document.")
|
||||
parser.add_argument("-s", "--style", default="google", type=str, help="Style of the document.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.exists(args.path):
|
||||
print(f"Error: The path {args.path} does not exist.")
|
||||
sys.exit(1)
|
||||
|
||||
if not os.path.exists(args.output):
|
||||
os.makedirs(args.output)
|
||||
|
||||
lang = args.lang
|
||||
|
||||
generate_from_module(args.path, args.output, with_top=args.contain_top, lang=lang, theme=args.theme, style=args.style)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
10
litedoc/docstring/__init__.py
Normal file
10
litedoc/docstring/__init__.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午1:46
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : __init__.py.py
|
||||
@Software: PyCharm
|
||||
"""
|
157
litedoc/docstring/docstring.py
Normal file
157
litedoc/docstring/docstring.py
Normal file
@ -0,0 +1,157 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午1:46
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : docstring.py
|
||||
@Software: PyCharm
|
||||
"""
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from litedoc.i18n import get_text
|
||||
|
||||
|
||||
class Attr(BaseModel):
|
||||
name: str
|
||||
type: str = ""
|
||||
desc: str = ""
|
||||
|
||||
|
||||
class Args(BaseModel):
|
||||
name: str
|
||||
type: str = ""
|
||||
desc: str = ""
|
||||
|
||||
|
||||
class Return(BaseModel):
|
||||
desc: str = ""
|
||||
|
||||
|
||||
class Exception_(BaseModel):
|
||||
name: str
|
||||
desc: str = ""
|
||||
|
||||
|
||||
class Raise(BaseModel):
|
||||
exceptions: list[Exception_] = []
|
||||
|
||||
|
||||
class Example(BaseModel):
|
||||
desc: str = ""
|
||||
input: str = ""
|
||||
output: str = ""
|
||||
|
||||
|
||||
class Docstring(BaseModel):
|
||||
desc: str = ""
|
||||
args: list[Args] = []
|
||||
attrs: list[Attr] = []
|
||||
return_: Optional[Return] = None
|
||||
raise_: list[Exception_] = []
|
||||
example: list[Example] = []
|
||||
|
||||
def add_desc(self, desc: str):
|
||||
if self.desc == "":
|
||||
self.desc = desc
|
||||
else:
|
||||
self.desc += "\n" + desc
|
||||
|
||||
def add_arg(self, name: str, type_: str = "", desc: str = ""):
|
||||
self.args.append(Args(name=name, type=type_, desc=desc))
|
||||
|
||||
def add_attrs(self, name: str, type_: str = "", desc: str = ""):
|
||||
self.attrs.append(Attr(name=name, type=type_, desc=desc))
|
||||
|
||||
def add_return(self, desc: str = ""):
|
||||
self.return_ = Return(desc=desc)
|
||||
|
||||
def add_raise(self, name: str, desc: str = ""):
|
||||
self.raise_.append(Exception_(name=name, desc=desc))
|
||||
|
||||
def add_example(self, desc: str = "", input_: str = "", output: str = ""):
|
||||
self.example.append(Example(desc=desc, input=input_, output=output))
|
||||
|
||||
def reduction(self) -> str:
|
||||
"""
|
||||
通过解析结果还原docstring
|
||||
Args:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
ret = ""
|
||||
ret += self.desc + "\n"
|
||||
if self.args:
|
||||
ret += "Args:\n"
|
||||
for arg in self.args:
|
||||
ret += f" {arg.name}: {arg.type}\n {arg.desc}\n"
|
||||
if self.attrs:
|
||||
ret += "Attributes:\n"
|
||||
for attr in self.attrs:
|
||||
ret += f" {attr.name}: {attr.type}\n {attr.desc}\n"
|
||||
if self.return_:
|
||||
ret += "Returns:\n"
|
||||
ret += f" {self.return_.desc}\n"
|
||||
|
||||
if self.raise_:
|
||||
ret += "Raises:\n"
|
||||
for exception in self.raise_:
|
||||
ret += f" {exception.name}\n {exception.desc}\n"
|
||||
|
||||
if self.example:
|
||||
ret += "Examples:\n"
|
||||
for example in self.example:
|
||||
ret += f" {example.desc}\n Input: {example.input}\n Output: {example.output}\n"
|
||||
|
||||
return ret
|
||||
|
||||
def markdown(self, lang: str, indent: int = 4, is_classmethod: bool = False) -> str:
|
||||
"""
|
||||
生成markdown文档
|
||||
Args:
|
||||
is_classmethod:
|
||||
lang:
|
||||
indent:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
PREFIX = "" * indent
|
||||
ret = ""
|
||||
# ret += self.desc + "\n\n"
|
||||
# print(self.reduction())
|
||||
# print(self.desc, self.return_)
|
||||
# 单数属性
|
||||
if self.desc:
|
||||
ret += PREFIX + f"\n**{get_text(lang, 'desc')}**: {self.desc}\n"
|
||||
|
||||
# 复数属性
|
||||
if self.args:
|
||||
ret += PREFIX + f"\n**{get_text(lang, 'docstring.args')}**:\n"
|
||||
for arg in self.args:
|
||||
ret += PREFIX + f"> - {arg.name}: {arg.type} {arg.desc}\n"
|
||||
if self.attrs:
|
||||
ret += PREFIX + f"\n**{get_text(lang, 'docstring.attrs')}**:\n"
|
||||
for attr in self.attrs:
|
||||
ret += PREFIX + f"> - {attr.name}: {attr.type} {attr.desc}\n"
|
||||
|
||||
# 单数属性
|
||||
if self.return_ is not None:
|
||||
ret += PREFIX + f"\n**{get_text(lang, 'docstring.return')}**: {self.return_.desc}\n"
|
||||
# 复数属性
|
||||
if self.raise_:
|
||||
ret += PREFIX + f"\n**{get_text(lang, 'docstring.raises')}**:\n"
|
||||
for exception in self.raise_:
|
||||
ret += PREFIX + f"> - {exception.name} {exception.desc}\n"
|
||||
if self.example:
|
||||
ret += PREFIX + f"\n**{get_text(lang, 'docstring.example')}**:\n"
|
||||
for example in self.example:
|
||||
ret += PREFIX + f" - {example.desc}\n> **{get_text(lang, 'docs.input')}**: {example.input}\n> **{get_text(lang, 'docs.output')}**: {example.output}\n"
|
||||
return ret
|
||||
|
||||
def __str__(self):
|
||||
return self.desc
|
192
litedoc/docstring/parser.py
Normal file
192
litedoc/docstring/parser.py
Normal file
@ -0,0 +1,192 @@
|
||||
"""
|
||||
Google docstring parser for Python.
|
||||
"""
|
||||
from typing import Optional
|
||||
|
||||
from litedoc.docstring.docstring import Docstring
|
||||
|
||||
|
||||
class Parser:
|
||||
...
|
||||
|
||||
|
||||
class GoogleDocstringParser(Parser):
|
||||
_tokens = {
|
||||
"Args" : "args",
|
||||
"Arguments" : "args",
|
||||
"参数" : "args",
|
||||
|
||||
"Return" : "return",
|
||||
"Returns" : "return",
|
||||
"返回" : "return",
|
||||
|
||||
"Attribute" : "attribute",
|
||||
"Attributes" : "attribute",
|
||||
"属性" : "attribute",
|
||||
|
||||
"Raises" : "raises",
|
||||
"Raise" : "raises",
|
||||
"引发" : "raises",
|
||||
|
||||
"Example" : "example",
|
||||
"Examples" : "example",
|
||||
"示例" : "example",
|
||||
|
||||
"Yields" : "yields",
|
||||
"Yield" : "yields",
|
||||
"产出" : "yields",
|
||||
|
||||
"Requires" : "requires",
|
||||
"Require" : "requires",
|
||||
"需要" : "requires",
|
||||
|
||||
"FrontMatter": "front_matter",
|
||||
"前言" : "front_matter",
|
||||
}
|
||||
|
||||
def __init__(self, docstring: str, indent: int = 4):
|
||||
self.lines = docstring.splitlines()
|
||||
self.indent = indent
|
||||
self.lineno = 0 # Current line number
|
||||
self.char = 0 # Current character position
|
||||
|
||||
self.docstring = Docstring()
|
||||
|
||||
def read_line(self, move: bool = True) -> str:
|
||||
"""
|
||||
每次读取一行
|
||||
Args:
|
||||
move: 是否移动指针
|
||||
Returns:
|
||||
"""
|
||||
if self.lineno >= len(self.lines):
|
||||
return ""
|
||||
line = self.lines[self.lineno]
|
||||
if move:
|
||||
self.lineno += 1
|
||||
return line
|
||||
|
||||
def match_token(self) -> Optional[str]:
|
||||
"""
|
||||
解析下一行的token
|
||||
Returns:
|
||||
|
||||
"""
|
||||
for token in self._tokens:
|
||||
line = self.read_line(move=False)
|
||||
if line.strip().startswith(token):
|
||||
self.lineno += 1
|
||||
return self._tokens[token]
|
||||
return None
|
||||
|
||||
def parse_args(self):
|
||||
"""
|
||||
依次解析后面的参数行,直到缩进小于等于当前行的缩进
|
||||
"""
|
||||
while line := self.match_next_line():
|
||||
if ":" in line:
|
||||
name, desc = line.split(":", 1)
|
||||
self.docstring.add_arg(name.strip(), desc.strip())
|
||||
else:
|
||||
self.docstring.add_arg(line.strip())
|
||||
|
||||
def parse_return(self):
|
||||
"""
|
||||
解析返回值行
|
||||
"""
|
||||
if line := self.match_next_line():
|
||||
self.docstring.add_return(line.strip())
|
||||
|
||||
def parse_raises(self):
|
||||
"""
|
||||
解析异常行
|
||||
"""
|
||||
while line := self.match_next_line():
|
||||
if ":" in line:
|
||||
name, desc = line.split(":", 1)
|
||||
self.docstring.add_raise(name.strip(), desc.strip())
|
||||
else:
|
||||
self.docstring.add_raise(line.strip())
|
||||
|
||||
def parse_example(self):
|
||||
"""
|
||||
解析示例行
|
||||
"""
|
||||
while line := self.match_next_line():
|
||||
if ":" in line:
|
||||
name, desc = line.split(":", 1)
|
||||
self.docstring.add_example(name.strip(), desc.strip())
|
||||
else:
|
||||
self.docstring.add_example(line.strip())
|
||||
|
||||
def parse_attrs(self):
|
||||
"""
|
||||
解析属性行
|
||||
"""
|
||||
while line := self.match_next_line():
|
||||
if ":" in line:
|
||||
name, desc = line.split(":", 1)
|
||||
self.docstring.add_attrs(name.strip(), desc.strip())
|
||||
else:
|
||||
self.docstring.add_attrs(line.strip())
|
||||
|
||||
def match_next_line(self) -> Optional[str]:
|
||||
"""
|
||||
在一个子解析器中,解析下一行,直到缩进小于等于当前行的缩进
|
||||
Returns:
|
||||
"""
|
||||
line = self.read_line(move=False)
|
||||
if line.startswith(" " * self.indent):
|
||||
self.lineno += 1
|
||||
return line[self.indent:]
|
||||
else:
|
||||
return None
|
||||
|
||||
def parse(self) -> Docstring:
|
||||
"""
|
||||
逐行解析,直到遇到EOS
|
||||
|
||||
最开始未解析到的内容全部加入desc
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
add_desc = True
|
||||
while self.lineno < len(self.lines):
|
||||
token = self.match_token()
|
||||
if token is None and add_desc:
|
||||
self.docstring.add_desc(self.lines[self.lineno].strip())
|
||||
|
||||
if token is not None:
|
||||
add_desc = False
|
||||
|
||||
match token:
|
||||
case "args":
|
||||
self.parse_args()
|
||||
case "return":
|
||||
self.parse_return()
|
||||
case "attribute":
|
||||
self.parse_attrs()
|
||||
case "raises":
|
||||
self.parse_raises()
|
||||
case "example":
|
||||
self.parse_example()
|
||||
case _:
|
||||
self.lineno += 1
|
||||
|
||||
return self.docstring
|
||||
|
||||
|
||||
class NumpyDocstringParser(Parser):
|
||||
...
|
||||
|
||||
|
||||
class ReStructuredParser(Parser):
|
||||
...
|
||||
|
||||
|
||||
def parse(docstring: str, parser: str = "google", indent: int = 4) -> Docstring:
|
||||
if parser == "google":
|
||||
return GoogleDocstringParser(docstring, indent).parse()
|
||||
else:
|
||||
raise ValueError(f"Unknown parser: {parser}")
|
131
litedoc/i18n.py
Normal file
131
litedoc/i18n.py
Normal file
@ -0,0 +1,131 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Internationalization module.
|
||||
"""
|
||||
from typing import Optional, TypeAlias
|
||||
|
||||
NestedDict: TypeAlias = dict[str, 'str | NestedDict']
|
||||
|
||||
i18n_dict: dict[str, NestedDict] = {
|
||||
"en" : {
|
||||
"docstring": {
|
||||
"args" : "Arguments",
|
||||
"return" : "Return",
|
||||
"attribute": "Attribute",
|
||||
"raises" : "Raises",
|
||||
"example" : "Examples",
|
||||
"yields" : "Yields",
|
||||
},
|
||||
"src": "Source code",
|
||||
"desc": "Description",
|
||||
"type": "Type",
|
||||
},
|
||||
"zh-Hans": {
|
||||
"docstring": {
|
||||
"args" : "参数",
|
||||
"return" : "返回",
|
||||
"attribute": "属性",
|
||||
"raises" : "引发",
|
||||
"example" : "示例",
|
||||
"yields" : "产出",
|
||||
},
|
||||
"src": "源代码",
|
||||
"desc": "说明",
|
||||
"type": "类型",
|
||||
},
|
||||
"zh-Hant": {
|
||||
"docstring": {
|
||||
"args" : "變數説明",
|
||||
"return" : "返回",
|
||||
"attribute": "屬性",
|
||||
"raises" : "抛出",
|
||||
"example" : "範例",
|
||||
"yields" : "產出",
|
||||
},
|
||||
"src": "源碼",
|
||||
"desc": "説明",
|
||||
"type": "類型",
|
||||
},
|
||||
"ja" : {
|
||||
"docstring": {
|
||||
"args" : "引数",
|
||||
"return" : "戻り値",
|
||||
"attribute": "属性",
|
||||
"raises" : "例外",
|
||||
"example" : "例",
|
||||
"yields" : "生成",
|
||||
},
|
||||
"src": "ソースコード",
|
||||
"desc": "説明",
|
||||
"type": "タイプ",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def flat_i18n_dict(data: dict[str, NestedDict]) -> dict[str, dict[str, str]]:
|
||||
"""
|
||||
Flatten i18n_dict.
|
||||
Examples:
|
||||
```python
|
||||
{
|
||||
"en": {
|
||||
"docs": {
|
||||
"key1": "val1",
|
||||
"key2": "val2",
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```python
|
||||
{
|
||||
"en": {
|
||||
"docs.key1": "val1",
|
||||
"docs.key2": "val2",
|
||||
}
|
||||
}
|
||||
```
|
||||
Returns:
|
||||
"""
|
||||
ret: dict[str, dict[str, str]] = {}
|
||||
|
||||
def _flat(_lang_data: NestedDict) -> dict[str, str]:
|
||||
res = {}
|
||||
for k, v in _lang_data.items():
|
||||
if isinstance(v, dict):
|
||||
for kk, vv in _flat(v).items():
|
||||
res[f"{k}.{kk}"] = vv
|
||||
else:
|
||||
res[k] = v
|
||||
return res
|
||||
|
||||
for lang, lang_data in data.items():
|
||||
ret[lang] = _flat(lang_data)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
i18n_flat_dict = flat_i18n_dict(i18n_dict)
|
||||
|
||||
|
||||
def get_text(lang: str, key: str, default: Optional[str] = None, fallback: Optional[str] = "en") -> str:
|
||||
"""
|
||||
Get text from i18n_dict.
|
||||
Args:
|
||||
lang: language name
|
||||
key: text key
|
||||
default: default text, if None return fallback language or key
|
||||
fallback: fallback language, priority is higher than default
|
||||
Returns:
|
||||
str: text
|
||||
"""
|
||||
if lang in i18n_flat_dict:
|
||||
if key in i18n_flat_dict[lang]:
|
||||
return i18n_flat_dict[lang][key]
|
||||
|
||||
if fallback is not None:
|
||||
return i18n_flat_dict.get(fallback, {}).get(key, default or key)
|
||||
else:
|
||||
return default or key
|
116
litedoc/output.py
Normal file
116
litedoc/output.py
Normal file
@ -0,0 +1,116 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午3:59
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : output.py
|
||||
@Software: PyCharm
|
||||
"""
|
||||
import os.path
|
||||
|
||||
from litedoc.style.markdown import generate
|
||||
from litedoc.syntax.astparser import AstParser
|
||||
|
||||
|
||||
def write_to_file(content: str, output: str) -> None:
|
||||
"""
|
||||
Write content to file.
|
||||
|
||||
Args:
|
||||
content: str, content to write.
|
||||
output: str, path to output file.
|
||||
"""
|
||||
if not os.path.exists(os.path.dirname(output)):
|
||||
os.makedirs(os.path.dirname(output))
|
||||
|
||||
with open(output, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
|
||||
|
||||
def get_file_list(module_folder: str):
|
||||
file_list = []
|
||||
for root, dirs, files in os.walk(module_folder):
|
||||
for file in files:
|
||||
if file.endswith((".py", ".pyi")):
|
||||
file_list.append(os.path.join(root, file))
|
||||
return file_list
|
||||
|
||||
|
||||
def get_relative_path(base_path: str, target_path: str) -> str:
|
||||
"""
|
||||
获取相对路径
|
||||
Args:
|
||||
base_path: 基础路径
|
||||
target_path: 目标路径
|
||||
"""
|
||||
return os.path.relpath(target_path, base_path)
|
||||
|
||||
|
||||
def generate_from_module(module_folder: str,
|
||||
output_dir: str,
|
||||
with_top: bool = False,
|
||||
lang: str = "zh-Hans",
|
||||
ignored_paths=None,
|
||||
theme: str = "vitepress",
|
||||
style: str = "google"
|
||||
):
|
||||
"""
|
||||
生成文档
|
||||
Args:
|
||||
module_folder: 模块文件夹
|
||||
output_dir: 输出文件夹
|
||||
with_top: 是否包含顶层文件夹 False时例如docs/api/module_a, docs/api/module_b, True时例如docs/api/module/module_a.md, docs/api/module/module_b.md
|
||||
ignored_paths: 忽略的路径
|
||||
lang: 语言
|
||||
theme: 主题
|
||||
style: 样式
|
||||
"""
|
||||
if ignored_paths is None:
|
||||
ignored_paths = []
|
||||
file_data: dict[str, str] = {} # 路径 -> 字串
|
||||
|
||||
file_list = get_file_list(module_folder)
|
||||
|
||||
# 清理输出目录
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
replace_data = {
|
||||
"__init__": "index" if theme == "vitepress" else "README",
|
||||
".py" : ".md",
|
||||
}
|
||||
|
||||
for pyfile_path in file_list:
|
||||
if any(ignored_path.replace("\\", "/") in pyfile_path.replace("\\", "/") for ignored_path in ignored_paths):
|
||||
continue
|
||||
|
||||
no_module_name_pyfile_path = get_relative_path(module_folder, pyfile_path) # 去头路径
|
||||
|
||||
# markdown相对路径
|
||||
rel_md_path = pyfile_path if with_top else no_module_name_pyfile_path
|
||||
for rk, rv in replace_data.items():
|
||||
rel_md_path = rel_md_path.replace(rk, rv)
|
||||
|
||||
abs_md_path = os.path.join(output_dir, rel_md_path)
|
||||
|
||||
# 获取模块信息
|
||||
ast_parser = AstParser(open(pyfile_path, "r", encoding="utf-8").read())
|
||||
|
||||
# 生成markdown
|
||||
|
||||
front_matter = {
|
||||
"title": pyfile_path.replace("\\", "/").
|
||||
replace("/", ".").
|
||||
replace(".py", "").
|
||||
replace(".__init__", ""),
|
||||
|
||||
}
|
||||
|
||||
md_content = generate(ast_parser, lang=lang, frontmatter=front_matter)
|
||||
print(f"Generate {pyfile_path} -> {abs_md_path}")
|
||||
file_data[abs_md_path] = md_content
|
||||
|
||||
for fn, content in file_data.items():
|
||||
write_to_file(content, fn)
|
10
litedoc/style/__init__.py
Normal file
10
litedoc/style/__init__.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午3:39
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : __init__.py.py
|
||||
@Software: PyCharm
|
||||
"""
|
60
litedoc/style/markdown.py
Normal file
60
litedoc/style/markdown.py
Normal file
@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午3:39
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : markdown.py
|
||||
@Software: PyCharm
|
||||
"""
|
||||
from typing import Optional
|
||||
|
||||
from litedoc.syntax.astparser import AstParser
|
||||
from litedoc.syntax.node import *
|
||||
from litedoc.i18n import get_text
|
||||
|
||||
|
||||
def generate(parser: AstParser, lang: str, frontmatter: Optional[dict] = None, style: str = "google") -> str:
|
||||
"""
|
||||
Generate markdown style document from ast
|
||||
You can modify this function to generate markdown style that enjoys you
|
||||
Args:
|
||||
parser:
|
||||
lang: language
|
||||
frontmatter:
|
||||
style: style of docs
|
||||
Returns:
|
||||
markdown style document
|
||||
"""
|
||||
if frontmatter is not None:
|
||||
md = "---\n"
|
||||
for k, v in frontmatter.items():
|
||||
md += f"{k}: {v}\n"
|
||||
md += "---\n"
|
||||
else:
|
||||
md = ""
|
||||
|
||||
# var > func > class
|
||||
|
||||
"""遍历函数"""
|
||||
for func in parser.functions:
|
||||
if func.name.startswith("_"):
|
||||
continue
|
||||
md += func.markdown(lang)
|
||||
|
||||
"""遍历类"""
|
||||
|
||||
for cls in parser.classes:
|
||||
md += cls.markdown(lang)
|
||||
|
||||
"""遍历变量"""
|
||||
for var in parser.variables:
|
||||
md += f"### ***var*** `{var.name} = {var.value}`\n\n"
|
||||
if var.type != TypeHint.NO_TYPEHINT:
|
||||
md += f"- **{get_text(lang, 'type')}**: `{var.type}`\n\n"
|
||||
|
||||
if var.docs is not None:
|
||||
md += f"- **{get_text(lang, 'desc')}**: {var.docs}\n\n"
|
||||
|
||||
return md
|
300
litedoc/syntax/astparser.py
Normal file
300
litedoc/syntax/astparser.py
Normal file
@ -0,0 +1,300 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午2:13
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : astparser.py
|
||||
@Software: PyCharm
|
||||
"""
|
||||
import ast
|
||||
import inspect
|
||||
|
||||
from .node import *
|
||||
from ..docstring.parser import parse
|
||||
|
||||
class AstParser:
|
||||
def __init__(self, code: str, style: str = "google"):
|
||||
"""
|
||||
从代码解析AST
|
||||
Args:
|
||||
code: 代码
|
||||
style: 注释风格
|
||||
"""
|
||||
self.style = style
|
||||
self.code = code
|
||||
self.tree = ast.parse(code)
|
||||
|
||||
self.classes: list[ClassNode] = []
|
||||
self.functions: list[FunctionNode] = []
|
||||
self.variables: list[AssignNode] = []
|
||||
|
||||
self.parse()
|
||||
|
||||
@staticmethod
|
||||
def clear_quotes(s: str) -> str:
|
||||
"""
|
||||
去除类型注解中的引号
|
||||
Args:
|
||||
s:
|
||||
Returns:
|
||||
"""
|
||||
return s.replace("'", "").replace('"', "")
|
||||
|
||||
def get_line_content(self, lineno: int, ignore_index_out: bool = True) -> str:
|
||||
"""获取代码行内容
|
||||
Args:
|
||||
lineno: 行号
|
||||
ignore_index_out: 是否忽略索引越界
|
||||
Returns:
|
||||
代码行内容
|
||||
"""
|
||||
if ignore_index_out:
|
||||
if lineno < 1 or lineno > len(self.code.split("\n")):
|
||||
return ""
|
||||
return self.code.split("\n")[lineno - 1]
|
||||
|
||||
@staticmethod
|
||||
def match_line_docs(linecontent: str) -> str:
|
||||
"""匹配行内注释
|
||||
Args:
|
||||
linecontent: 行内容
|
||||
Returns:
|
||||
文档字符串
|
||||
"""
|
||||
in_string = False
|
||||
string_char = ''
|
||||
for i, char in enumerate(linecontent):
|
||||
if char in ('"', "'"):
|
||||
if in_string:
|
||||
if char == string_char:
|
||||
in_string = False
|
||||
else:
|
||||
in_string = True
|
||||
string_char = char
|
||||
elif char == '#' and not in_string:
|
||||
return linecontent[i + 1:].strip()
|
||||
return ""
|
||||
|
||||
def parse(self):
|
||||
for node in ast.walk(self.tree):
|
||||
if isinstance(node, ast.ClassDef):
|
||||
if not self._is_module_level_class(node):
|
||||
continue
|
||||
|
||||
class_node = ClassNode(
|
||||
name=node.name,
|
||||
docs=parse(ast.get_docstring(node), parser=self.style) if ast.get_docstring(node) else None,
|
||||
inherits=[ast.unparse(base) for base in node.bases]
|
||||
)
|
||||
self.classes.append(class_node)
|
||||
|
||||
# 继续遍历类内部的函数
|
||||
for sub_node in node.body:
|
||||
if isinstance(sub_node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
class_node.methods.append(FunctionNode(
|
||||
name=sub_node.name,
|
||||
docs=parse(ast.get_docstring(sub_node), parser=self.style) if ast.get_docstring(sub_node) else None,
|
||||
posonlyargs=[
|
||||
ArgNode(
|
||||
name=arg.arg,
|
||||
type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT,
|
||||
)
|
||||
for arg in sub_node.args.posonlyargs
|
||||
],
|
||||
args=[
|
||||
ArgNode(
|
||||
name=arg.arg,
|
||||
type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT,
|
||||
)
|
||||
for arg in sub_node.args.args
|
||||
],
|
||||
kwonlyargs=[
|
||||
ArgNode(
|
||||
name=arg.arg,
|
||||
type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT,
|
||||
)
|
||||
for arg in sub_node.args.kwonlyargs
|
||||
],
|
||||
kw_defaults=[
|
||||
ConstantNode(
|
||||
value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT
|
||||
)
|
||||
for default in sub_node.args.kw_defaults
|
||||
],
|
||||
defaults=[
|
||||
ConstantNode(
|
||||
value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT
|
||||
)
|
||||
for default in sub_node.args.defaults
|
||||
],
|
||||
return_=self.clear_quotes(ast.unparse(sub_node.returns).strip()) if sub_node.returns else TypeHint.NO_RETURN,
|
||||
decorators=[ast.unparse(decorator).strip() for decorator in sub_node.decorator_list],
|
||||
is_async=isinstance(sub_node, ast.AsyncFunctionDef),
|
||||
src=ast.unparse(sub_node).strip(),
|
||||
is_classmethod=True
|
||||
))
|
||||
# elif isinstance(sub_node, (ast.Assign, ast.AnnAssign)):
|
||||
# if isinstance(sub_node, ast.Assign):
|
||||
# class_node.attrs.append(AttrNode(
|
||||
# name=sub_node.targets[0].id, # type: ignore
|
||||
# type=TypeHint.NO_TYPEHINT,
|
||||
# value=ast.unparse(sub_node.value).strip()
|
||||
# ))
|
||||
# elif isinstance(sub_node, ast.AnnAssign):
|
||||
# class_node.attrs.append(AttrNode(
|
||||
# name=sub_node.target.id,
|
||||
# type=ast.unparse(sub_node.annotation).strip(),
|
||||
# value=ast.unparse(sub_node.value).strip() if sub_node.value else TypeHint.NO_DEFAULT
|
||||
# ))
|
||||
# else:
|
||||
# raise ValueError(f"Unsupported node type: {type(sub_node)}")
|
||||
|
||||
elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
# 仅打印模块级别的函数
|
||||
if not self._is_module_level_function(node):
|
||||
continue
|
||||
|
||||
self.functions.append(FunctionNode(
|
||||
name=node.name,
|
||||
docs=parse(ast.get_docstring(node), parser=self.style) if ast.get_docstring(node) else None,
|
||||
posonlyargs=[
|
||||
ArgNode(
|
||||
name=arg.arg,
|
||||
type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT,
|
||||
)
|
||||
for arg in node.args.posonlyargs
|
||||
],
|
||||
args=[
|
||||
ArgNode(
|
||||
name=arg.arg,
|
||||
type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT,
|
||||
)
|
||||
for arg, default in zip(node.args.args, node.args.defaults)
|
||||
],
|
||||
kwonlyargs=[
|
||||
ArgNode(
|
||||
name=arg.arg,
|
||||
type=self.clear_quotes(ast.unparse(arg.annotation).strip()) if arg.annotation else TypeHint.NO_TYPEHINT,
|
||||
)
|
||||
for arg in node.args.kwonlyargs
|
||||
],
|
||||
kw_defaults=[
|
||||
ConstantNode(
|
||||
value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT
|
||||
)
|
||||
for default in node.args.kw_defaults
|
||||
],
|
||||
defaults=[
|
||||
ConstantNode(
|
||||
value=ast.unparse(default).strip() if default else TypeHint.NO_DEFAULT
|
||||
)
|
||||
for default in node.args.defaults
|
||||
],
|
||||
return_=self.clear_quotes(ast.unparse(node.returns).strip()) if node.returns else TypeHint.NO_RETURN,
|
||||
decorators=[ast.unparse(decorator).strip() for decorator in node.decorator_list],
|
||||
is_async=isinstance(node, ast.AsyncFunctionDef),
|
||||
src=ast.unparse(node).strip()
|
||||
))
|
||||
|
||||
elif isinstance(node, (ast.Assign, ast.AnnAssign)):
|
||||
if not self._is_module_level_variable2(node):
|
||||
continue
|
||||
else:
|
||||
pass
|
||||
lineno = node.lineno
|
||||
prev_line = self.get_line_content(lineno - 1).strip()
|
||||
curr_line = self.get_line_content(lineno).strip()
|
||||
next_line = self.get_line_content(lineno + 1).strip()
|
||||
|
||||
# 获取文档字符串,优先检测下行"""
|
||||
if next_line.startswith('"""'):
|
||||
docs = next_line[3:-3]
|
||||
elif prev_line.startswith('"""'):
|
||||
docs = prev_line[3:-3]
|
||||
else:
|
||||
curr_docs = self.match_line_docs(curr_line)
|
||||
if curr_docs:
|
||||
docs = curr_docs
|
||||
else:
|
||||
docs = None
|
||||
|
||||
# if isinstance(node, ast.Assign):
|
||||
# for target in node.targets:
|
||||
# if isinstance(target, ast.Name):
|
||||
# self.variables.append(AssignNode(
|
||||
# name=target.id,
|
||||
# value=ast.unparse(node.value).strip(),
|
||||
# type=ast.unparse(node.annotation).strip() if isinstance(node, ast.AnnAssign) else TypeHint.NO_TYPEHINT
|
||||
# ))
|
||||
if isinstance(node, ast.AnnAssign):
|
||||
self.variables.append(AssignNode(
|
||||
name=node.target.id,
|
||||
value=ast.unparse(node.value).strip() if node.value else TypeHint.NO_DEFAULT,
|
||||
type=ast.unparse(node.annotation).strip(),
|
||||
docs=docs
|
||||
))
|
||||
|
||||
def _is_module_level_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef):
|
||||
for parent in ast.walk(self.tree):
|
||||
if isinstance(parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
if node in parent.body:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _is_module_level_class(self, node: ast.ClassDef):
|
||||
for parent in ast.walk(self.tree):
|
||||
if isinstance(parent, ast.ClassDef):
|
||||
if node in parent.body:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _is_module_level_variable(self, node: ast.Assign | ast.AnnAssign):
|
||||
"""在类方法或函数内部的变量不会被记录"""
|
||||
|
||||
# for parent in ast.walk(self.tree):
|
||||
# if isinstance(parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
# if node in parent.body:
|
||||
# return False
|
||||
# else:
|
||||
# for sub_node in parent.body:
|
||||
# if isinstance(sub_node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
# if node in sub_node.body:
|
||||
# return False
|
||||
# return True
|
||||
# 递归检查
|
||||
def _check(_node, _parent):
|
||||
if isinstance(_parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
if _node in _parent.body:
|
||||
return False
|
||||
else:
|
||||
for sub_node in _parent.body:
|
||||
if isinstance(sub_node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
return _check(_node, sub_node)
|
||||
return True
|
||||
|
||||
for parent in ast.walk(self.tree):
|
||||
if not _check(node, parent):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _is_module_level_variable2(self, node: ast.Assign | ast.AnnAssign) -> bool:
|
||||
"""
|
||||
检查变量是否在模块级别定义。
|
||||
"""
|
||||
for parent in ast.walk(self.tree):
|
||||
if isinstance(parent, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
if node in parent.body:
|
||||
return False
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
s = ""
|
||||
for cls in self.classes:
|
||||
s += f"class {cls.name}:\n"
|
||||
for func in self.functions:
|
||||
s += f"def {func.name}:\n"
|
||||
for var in self.variables:
|
||||
s += f"{var.name} = {var.value}\n"
|
||||
return s
|
314
litedoc/syntax/node.py
Normal file
314
litedoc/syntax/node.py
Normal file
@ -0,0 +1,314 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
|
||||
|
||||
@Time : 2024/8/28 下午2:14
|
||||
@Author : snowykami
|
||||
@Email : snowykami@outlook.com
|
||||
@File : node.py
|
||||
@Software: PyCharm
|
||||
"""
|
||||
from typing import Literal, Optional
|
||||
from enum import Enum
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from litedoc.docstring.docstring import Docstring
|
||||
from litedoc.i18n import get_text
|
||||
|
||||
|
||||
class TypeHint:
|
||||
NO_TYPEHINT = "NO_TYPE_HINT"
|
||||
NO_DEFAULT = "NO_DEFAULT"
|
||||
NO_RETURN = "NO_RETURN"
|
||||
|
||||
|
||||
class AssignNode(BaseModel):
|
||||
"""
|
||||
AssignNode is a pydantic model that represents an assignment.
|
||||
Attributes:
|
||||
name: str
|
||||
The name of the assignment.
|
||||
type: str = ""
|
||||
The type of the assignment.
|
||||
value: str
|
||||
The value of the assignment.
|
||||
"""
|
||||
name: str
|
||||
type: str = ""
|
||||
value: str
|
||||
docs: Optional[str] = ""
|
||||
|
||||
|
||||
class ArgNode(BaseModel):
|
||||
"""
|
||||
ArgNode is a pydantic model that represents an argument.
|
||||
Attributes:
|
||||
name: str
|
||||
The name of the argument.
|
||||
type: str = ""
|
||||
The type of the argument.
|
||||
default: str = ""
|
||||
The default value of the argument.
|
||||
"""
|
||||
name: str
|
||||
type: str = TypeHint.NO_TYPEHINT
|
||||
|
||||
|
||||
class AttrNode(BaseModel):
|
||||
"""
|
||||
AttrNode is a pydantic model that represents an attribute.
|
||||
Attributes:
|
||||
name: str
|
||||
The name of the attribute.
|
||||
type: str = ""
|
||||
The type of the attribute.
|
||||
value: str = ""
|
||||
The value of the attribute
|
||||
"""
|
||||
name: str
|
||||
type: str = ""
|
||||
value: str = ""
|
||||
|
||||
|
||||
class ImportNode(BaseModel):
|
||||
"""
|
||||
ImportNode is a pydantic model that represents an import statement.
|
||||
Attributes:
|
||||
name: str
|
||||
The name of the import statement.
|
||||
as_: str = ""
|
||||
The alias of the import
|
||||
"""
|
||||
name: str
|
||||
as_: str = ""
|
||||
|
||||
|
||||
class ConstantNode(BaseModel):
|
||||
"""
|
||||
ConstantNode is a pydantic model that represents a constant.
|
||||
Attributes:
|
||||
value: str
|
||||
The value of the constant.
|
||||
"""
|
||||
value: str
|
||||
|
||||
|
||||
class FunctionNode(BaseModel):
|
||||
"""
|
||||
FunctionNode is a pydantic model that represents a function.
|
||||
Attributes:
|
||||
name: str
|
||||
The name of the function.
|
||||
docs: str = ""
|
||||
The docstring of the function.
|
||||
args: list[ArgNode] = []
|
||||
The arguments of the function.
|
||||
return_: ReturnNode = None
|
||||
The return value of the function.
|
||||
decorators: list[str] = []
|
||||
The decorators of the function.
|
||||
is_async: bool = False
|
||||
Whether the function is asynchronous.
|
||||
"""
|
||||
name: str
|
||||
docs: Optional[Docstring] = None
|
||||
|
||||
posonlyargs: list[ArgNode] = []
|
||||
args: list[ArgNode] = []
|
||||
kwonlyargs: list[ArgNode] = []
|
||||
kw_defaults: list[ConstantNode] = []
|
||||
defaults: list[ConstantNode] = []
|
||||
|
||||
return_: str = TypeHint.NO_RETURN
|
||||
decorators: list[str] = []
|
||||
src: str
|
||||
is_async: bool = False
|
||||
is_classmethod: bool = False
|
||||
|
||||
magic_methods: dict[str, str] = {
|
||||
"__add__" : "+",
|
||||
"__radd__" : "+",
|
||||
"__sub__" : "-",
|
||||
"__rsub__" : "-",
|
||||
"__mul__" : "*",
|
||||
"__rmul__" : "*",
|
||||
"__matmul__" : "@",
|
||||
"__rmatmul__": "@",
|
||||
"__mod__" : "%",
|
||||
"__truediv__": "/",
|
||||
"__rtruediv__": "/",
|
||||
"__neg__" : "-",
|
||||
} # 魔术方法, 例如运算符
|
||||
|
||||
def is_private(self):
|
||||
"""
|
||||
Check if the function or method is private.
|
||||
Returns:
|
||||
bool: True if the function or method is private, False otherwise.
|
||||
"""
|
||||
return self.name.startswith("_")
|
||||
|
||||
def is_builtin(self):
|
||||
"""
|
||||
Check if the function or method is a builtin function or method.
|
||||
Returns:
|
||||
bool: True if the function or method is a builtin function or method, False otherwise.
|
||||
"""
|
||||
return self.name.startswith("__") and self.name.endswith("__")
|
||||
|
||||
def markdown(self, lang: str, indent: int = 0) -> str:
|
||||
"""
|
||||
Args:
|
||||
indent: int
|
||||
The number of spaces to indent the markdown.
|
||||
lang: str
|
||||
The language of the
|
||||
Returns:
|
||||
markdown style document
|
||||
"""
|
||||
self.complete_default_args()
|
||||
PREFIX = "" * indent
|
||||
# if is_classmethod:
|
||||
# PREFIX = "- #"
|
||||
func_type = "func" if not self.is_classmethod else "method"
|
||||
|
||||
md = ""
|
||||
# 装饰器部分
|
||||
if len(self.decorators) > 0:
|
||||
for decorator in self.decorators:
|
||||
md += PREFIX + f"### `@{decorator}`\n"
|
||||
|
||||
if self.is_async:
|
||||
md += PREFIX + f"### *async {func_type}* "
|
||||
else:
|
||||
md += PREFIX + f"### *{func_type}* "
|
||||
|
||||
# code start
|
||||
# 配对位置参数和位置参数默认值,无默认值用TypeHint.NO_DEFAULT
|
||||
args: list[str] = [] # 可直接", ".join(args)得到位置参数部分
|
||||
arg_i = 0
|
||||
|
||||
if len(self.posonlyargs) > 0:
|
||||
for arg in self.posonlyargs:
|
||||
arg_text = f"{arg.name}"
|
||||
if arg.type != TypeHint.NO_TYPEHINT:
|
||||
arg_text += f": {arg.type}"
|
||||
arg_default = self.defaults[arg_i].value
|
||||
if arg_default != TypeHint.NO_DEFAULT:
|
||||
arg_text += f" = {arg_default}"
|
||||
args.append(arg_text)
|
||||
arg_i += 1
|
||||
# 加位置参数分割符 /
|
||||
args.append("/")
|
||||
|
||||
for arg in self.args:
|
||||
arg_text = f"{arg.name}"
|
||||
if arg.type != TypeHint.NO_TYPEHINT:
|
||||
arg_text += f": {arg.type}"
|
||||
arg_default = self.defaults[arg_i].value
|
||||
if arg_default != TypeHint.NO_DEFAULT:
|
||||
arg_text += f" = {arg_default}"
|
||||
args.append(arg_text)
|
||||
arg_i += 1
|
||||
|
||||
if len(self.kwonlyargs) > 0:
|
||||
# 加关键字参数分割符 *
|
||||
args.append("*")
|
||||
for arg, kw_default in zip(self.kwonlyargs, self.kw_defaults):
|
||||
arg_text = f"{arg.name}"
|
||||
if arg.type != TypeHint.NO_TYPEHINT:
|
||||
arg_text += f": {arg.type}"
|
||||
if kw_default.value != TypeHint.NO_DEFAULT:
|
||||
arg_text += f" = {kw_default.value}"
|
||||
args.append(arg_text)
|
||||
|
||||
"""魔法方法"""
|
||||
if self.name in self.magic_methods:
|
||||
if len(args) == 2:
|
||||
md += f"`{args[0]} {self.magic_methods[self.name]} {args[1]}"
|
||||
elif len(args) == 1:
|
||||
md += f"`{self.magic_methods[self.name]} {args[0]}"
|
||||
if self.return_ != TypeHint.NO_RETURN:
|
||||
md += f" => {self.return_}"
|
||||
else:
|
||||
md += f"`{self.name}(" # code start
|
||||
md += ", ".join(args) + ")"
|
||||
if self.return_ != TypeHint.NO_RETURN:
|
||||
md += f" -> {self.return_}"
|
||||
|
||||
md += "`\n\n" # code end
|
||||
|
||||
"""此处预留docstring"""
|
||||
if self.docs is not None:
|
||||
md += f"\n{self.docs.markdown(lang, indent)}\n"
|
||||
else:
|
||||
pass
|
||||
# 源码展示
|
||||
md += PREFIX + f"\n<details>\n<summary> <b>{get_text(lang, 'src')}</b> </summary>\n\n```python\n{self.src}\n```\n</details>\n\n"
|
||||
|
||||
return md
|
||||
|
||||
def complete_default_args(self):
|
||||
"""
|
||||
补全位置参数默认值,用无默认值插入
|
||||
Returns:
|
||||
|
||||
"""
|
||||
num = len(self.args) + len(self.posonlyargs) - len(self.defaults)
|
||||
self.defaults = [ConstantNode(value=TypeHint.NO_DEFAULT) for _ in range(num)] + self.defaults
|
||||
|
||||
def __str__(self):
|
||||
return f"def {self.name}({', '.join([f'{arg.name}: {arg.type} = {arg.default}' for arg in self.args])}) -> {self.return_}"
|
||||
|
||||
|
||||
class ClassNode(BaseModel):
|
||||
"""
|
||||
ClassNode is a pydantic model that represents a class.
|
||||
Attributes:
|
||||
name: str
|
||||
The name of the class.
|
||||
docs: str = ""
|
||||
The docstring of the class.
|
||||
attrs: list[AttrNode] = []
|
||||
The attributes of the class.
|
||||
methods: list[MethodNode] = []
|
||||
The methods of the class.
|
||||
inherits: list["ClassNode"] = []
|
||||
The classes that the class inherits from
|
||||
"""
|
||||
name: str
|
||||
docs: Optional[Docstring] = None
|
||||
attrs: list[AttrNode] = []
|
||||
methods: list[FunctionNode] = []
|
||||
inherits: list[str] = []
|
||||
|
||||
def markdown(self, lang: str) -> str:
|
||||
"""
|
||||
返回类的markdown文档
|
||||
Args:
|
||||
lang: str
|
||||
The language of the
|
||||
Returns:
|
||||
markdown style document
|
||||
"""
|
||||
hidden_methods = [
|
||||
"__str__",
|
||||
"__repr__",
|
||||
]
|
||||
md = ""
|
||||
md += f"### **class** `{self.name}"
|
||||
if len(self.inherits) > 0:
|
||||
md += f"({', '.join([cls for cls in self.inherits])})"
|
||||
md += "`\n"
|
||||
for method in self.methods:
|
||||
if method.name in hidden_methods:
|
||||
continue
|
||||
md += method.markdown(lang, 2)
|
||||
for attr in self.attrs:
|
||||
if attr.type == TypeHint.NO_TYPEHINT:
|
||||
md += f"#### ***attr*** `{attr.name} = {attr.value}`\n\n"
|
||||
else:
|
||||
md += f"#### ***attr*** `{attr.name}: {attr.type} = {attr.value}`\n\n"
|
||||
|
||||
return md
|
Loading…
Reference in New Issue
Block a user