模块化
我现在是这样的
Bot:
└─config
└─db
└─modules
└─utils
config内包含所有模块用到的配置项db内是实体类和业务语句的集合utils内是一些公共工具
现在问题是,config与db非常难维护,一打开就是几百行语句,找起来都麻烦,数据库和配置项有一点不对整个bot就无法启动
依照模块化的思想,所有与具体module有关的类都应在它自己的文件夹下,做到方便维护,Bot主体可以实现扩展并管理配置文件和database,甚至做到overload(很难),这些是一开始写时没有想到的。
实体类与pydantic重复
写db相关经常会构建两个差不多的类,一个数据库实体类,一个装载它的pydantic模型类,其实可以直接使用sqlmodel这个依赖进行一次性构建
pip install sqlmodel
from typing import Optional
from sqlmodel import Field, SQLModel
class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
secret_name: str
age: Optional[int] = None
非常方便
生命周期管理
很多模块有争对用户的功能,那就要做到基本的用户增删改查,以及给管理员的增删改查,不要想着偷懒,后面出问题会非常难受
有些单例有初始化方法,初始化的位置与是否async要考虑好,常用的类可以交给launart管理
from launart import ExportInterface, Launchable
class TestService(Launchable):
id: str = "test/init"
@property
def required(self) -> set[str | type[ExportInterface]]:
return set()
@property
def stages(self) -> set[str]:
return {"preparing", "cleanup"}
async def launch(self, _):
print("before preparing")
async with self.stage("preparing"):
print("preparing")
print("before cleanup")
async with self.stage("cleanup"):
print("cleanup")
print("after cleanup")
交给launart就不用担心sync与async的冲突问题,还可以方便的获得具体的Service实例
统一Session
bot作为工具的集成,许多功能是需要发送get/post请求获取信息的,统一的Session可以节省一些开支,但是会区分用户以及cookies的功能需要注意,不然单例的Session在async的使用上会出现不可预知的错误,包括用户对不上等等
依赖过重
一些基本的功能可以写个request就可以替代,却非得拉个库来实现,例如为了bilibili的视频解析而引入了biliapi,就导致了aiohttp的依赖冲突问题