🏷️ 完善 typing 及注释

This commit is contained in:
Artin 2020-12-03 12:08:04 +08:00
parent f1a0ac099b
commit e718f25c3f
7 changed files with 58 additions and 45 deletions

View File

@ -0,0 +1,12 @@
---
contentSidebar: true
sidebarDepth: 0
---
NoneBot.adapters.ding 模块
============================
.. automodule:: nonebot.adapters.ding
:members:
:private-members:
:show-inheritance:

View File

@ -140,7 +140,7 @@ class BaseBot(abc.ABC):
T = TypeVar("T", bound=BaseModel) T = TypeVar("T", bound=BaseModel)
class BaseEvent(Generic[T], abc.ABC): class BaseEvent(abc.ABC, Generic[T]):
""" """
Event 基类提供上报信息的关键信息其余信息可从原始上报消息获取 Event 基类提供上报信息的关键信息其余信息可从原始上报消息获取
""" """
@ -149,7 +149,7 @@ class BaseEvent(Generic[T], abc.ABC):
""" """
:参数: :参数:
* ``raw_event: T``: 原始上报消息 * ``raw_event: Union[dict, T]``: 原始上报消息
""" """
self._raw_event = raw_event self._raw_event = raw_event

View File

@ -12,4 +12,4 @@
from .bot import Bot from .bot import Bot
from .event import Event from .event import Event
from .message import Message, MessageSegment from .message import Message, MessageSegment
from .exception import ApiError, SessionExpired, AdapterException from .exception import ApiError, SessionExpired, DingAdapterException

View File

@ -4,7 +4,7 @@ import httpx
from nonebot.log import logger from nonebot.log import logger
from nonebot.config import Config from nonebot.config import Config
from nonebot.message import handle_event from nonebot.message import handle_event
from nonebot.typing import Driver, WebSocket, NoReturn from nonebot.typing import Driver, NoReturn
from nonebot.typing import Any, Union, Optional from nonebot.typing import Any, Union, Optional
from nonebot.adapters import BaseBot from nonebot.adapters import BaseBot
from nonebot.exception import NetworkError, RequestDenied, ApiNotAvailable from nonebot.exception import NetworkError, RequestDenied, ApiNotAvailable
@ -20,19 +20,10 @@ class Bot(BaseBot):
钉钉 协议 Bot 适配继承属性参考 `BaseBot <./#class-basebot>`_ 。 钉钉 协议 Bot 适配继承属性参考 `BaseBot <./#class-basebot>`_ 。
""" """
def __init__(self, def __init__(self, driver: Driver, connection_type: str, config: Config,
driver: Driver, self_id: str, **kwargs):
connection_type: str,
config: Config,
self_id: str,
*,
websocket: Optional[WebSocket] = None):
super().__init__(driver, super().__init__(driver, connection_type, config, self_id, **kwargs)
connection_type,
config,
self_id,
websocket=websocket)
@property @property
def type(self) -> str: def type(self) -> str:
@ -56,26 +47,19 @@ class Bot(BaseBot):
# 检查 timestamp # 检查 timestamp
if not timestamp: if not timestamp:
log("WARNING", "Missing `timestamp` Header")
raise RequestDenied(400, "Missing `timestamp` Header") raise RequestDenied(400, "Missing `timestamp` Header")
# 检查 sign # 检查 sign
if not sign: if not sign:
log("WARNING", "Missing `sign` Header")
raise RequestDenied(400, "Missing `sign` Header") raise RequestDenied(400, "Missing `sign` Header")
# 校验 sign 和 timestamp判断是否是来自钉钉的合法请求 # 校验 sign 和 timestamp判断是否是来自钉钉的合法请求
if not check_legal(timestamp, sign, driver): if not check_legal(timestamp, sign, driver):
log("WARNING", "Signature Header is invalid")
raise RequestDenied(403, "Signature is invalid") raise RequestDenied(403, "Signature is invalid")
# 检查连接方式 # 检查连接方式
if connection_type not in ["http"]: if connection_type not in ["http"]:
log("WARNING", "Unsupported connection type")
raise RequestDenied(405, "Unsupported connection type") raise RequestDenied(405, "Unsupported connection type")
access_token = driver.config.access_token access_token = driver.config.access_token
if access_token and access_token != access_token: if access_token and access_token != access_token:
log(
"WARNING", "Authorization Header is invalid"
if access_token else "Missing Authorization Header")
raise RequestDenied( raise RequestDenied(
403, "Authorization Header is invalid" 403, "Authorization Header is invalid"
if access_token else "Missing Authorization Header") if access_token else "Missing Authorization Header")
@ -116,6 +100,9 @@ class Bot(BaseBot):
- ``NetworkError``: 网络错误 - ``NetworkError``: 网络错误
- ``ActionFailed``: API 调用失败 - ``ActionFailed``: API 调用失败
""" """
if self.connection_type != "http":
log("ERROR", "Only support http connection.")
return
if "self_id" in data: if "self_id" in data:
self_id = data.pop("self_id") self_id = data.pop("self_id")
if self_id: if self_id:
@ -125,9 +112,9 @@ class Bot(BaseBot):
log("DEBUG", f"Calling API <y>{api}</y>") log("DEBUG", f"Calling API <y>{api}</y>")
log("DEBUG", f"Calling data <y>{data}</y>") log("DEBUG", f"Calling data <y>{data}</y>")
if self.connection_type == "http" and api == "post_webhook": if api == "send_message":
raw_event: MessageModel = data["raw_event"] raw_event: MessageModel = data["raw_event"]
# 确保 sessionWebhook 没有过期
if int(datetime.now().timestamp()) > int( if int(datetime.now().timestamp()) > int(
raw_event.sessionWebhookExpiredTime / 1000): raw_event.sessionWebhookExpiredTime / 1000):
raise SessionExpired raise SessionExpired
@ -202,4 +189,4 @@ class Bot(BaseBot):
params["message"] = msg params["message"] = msg
log("DEBUG", f"send -> params: {params}") log("DEBUG", f"send -> params: {params}")
return await self.call_api("post_webhook", **params) return await self.call_api("send_message", **params)

View File

@ -1,9 +1,7 @@
from typing import Literal from typing import Literal, Union, Optional
from nonebot.adapters import BaseEvent from nonebot.adapters import BaseEvent
from nonebot.typing import Optional
from .utils import log
from .message import Message from .message import Message
from .model import MessageModel, ConversationType, TextMessage from .model import MessageModel, ConversationType, TextMessage
@ -15,9 +13,7 @@ class Event(BaseEvent):
def __init__(self, message: MessageModel): def __init__(self, message: MessageModel):
super().__init__(message) super().__init__(message)
if not message.msgtype: # 其实目前钉钉机器人只能接收到 text 类型的消息
log("ERROR", "message has no msgtype")
# 目前钉钉机器人只能接收到 text 类型的消息
self._message = Message(getattr(message, message.msgtype or "text")) self._message = Message(getattr(message, message.msgtype or "text"))
@property @property
@ -37,12 +33,9 @@ class Event(BaseEvent):
def name(self) -> str: def name(self) -> str:
""" """
- 类型: ``str`` - 类型: ``str``
- 说明: 事件名称类型与 ``.`` 组合而成 - 说明: 事件名称 `type`.`detail_type` 组合而成
""" """
n = self.type + "." + self.detail_type return self.type + "." + self.detail_type
if self.sub_type:
n += "." + self.sub_type
return n
@property @property
def self_id(self) -> str: def self_id(self) -> str:
@ -89,12 +82,12 @@ class Event(BaseEvent):
self.raw_event.conversationType = ConversationType.group self.raw_event.conversationType = ConversationType.group
@property @property
def sub_type(self) -> Optional[str]: def sub_type(self) -> None:
""" """
- 类型: ``Optional[str]`` - 类型: ``None``
- 说明: 事件子类型 - 说明: 钉钉适配器无事件子类型
""" """
return "" return None
@sub_type.setter @sub_type.setter
def sub_type(self, value) -> None: def sub_type(self, value) -> None:
@ -134,7 +127,7 @@ class Event(BaseEvent):
@to_me.setter @to_me.setter
def to_me(self, value) -> None: def to_me(self, value) -> None:
self.raw_event.isInAtList = value pass
@property @property
def message(self) -> Optional["Message"]: def message(self) -> Optional["Message"]:
@ -157,7 +150,7 @@ class Event(BaseEvent):
raise ValueError("暂不支持 reply") raise ValueError("暂不支持 reply")
@property @property
def raw_message(self) -> Optional[TextMessage]: def raw_message(self) -> Optional[Union[TextMessage]]:
""" """
- 类型: ``Optional[str]`` - 类型: ``Optional[str]``
- 说明: 原始消息 - 说明: 原始消息

View File

@ -2,6 +2,12 @@ from nonebot.exception import AdapterException
class DingAdapterException(AdapterException): class DingAdapterException(AdapterException):
"""
:说明:
钉钉 Adapter 错误基类
"""
def __init__(self) -> None: def __init__(self) -> None:
super.__init__("DING") super.__init__("DING")
@ -11,7 +17,7 @@ class ApiError(DingAdapterException):
""" """
:说明: :说明:
API 请求成功返回数据 API 操作失败 API 请求返回错误信息
""" """
@ -24,6 +30,12 @@ class ApiError(DingAdapterException):
class SessionExpired(DingAdapterException): class SessionExpired(DingAdapterException):
"""
:说明:
发消息的 session 已经过期
"""
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<sessionWebhook is Expired>" return f"<sessionWebhook is Expired>"

View File

@ -148,6 +148,15 @@ class ActionFailed(Exception):
class AdapterException(Exception): class AdapterException(Exception):
"""
:说明:
def __init__(self, adapter_name) -> None: 代表 Adapter 抛出的异常所有的 Adapter 都要在内部继承自这个 `Exception`
:参数:
* ``adapter_name: str``: 标识 adapter
"""
def __init__(self, adapter_name: str) -> None:
self.adapter_name = adapter_name self.adapter_name = adapter_name