Py-Tools 是一个面向 Python 开发者的实用工具集和可复用组件库,重点解决项目初始化和日常开发里高频、重复、容易写散的基础问题。
适合需要统一配置、日志、HTTP 调用和数据库 CRUD 基础封装的 Python 项目。
设计细节可参考掘金专栏:https://juejin.cn/column/7131286129713610766
- Python 版本:
>= 3.9 - 发布包名:
huidevkit - 历史版本记录:https://pypi.org/project/huidevkit/#history
从
0.6.0开始,包名由hui-tools调整为huidevkit。历史包名仍可安装,但不再推荐继续使用。
默认安装:
pip install huidevkit按需安装:
pip install huidevkit[db-orm, db-redis, excel-tools]全部能力:
pip install huidevkit[all]py_tools.logging:基于loguru的日志初始化与默认配置py_tools.utils.ConfigUtil:统一读取环境变量、.env、YAML 和 Settingspy_tools.connections.http:同步 / 异步 HTTP 客户端、上传文件、流式读取py_tools.connections.db.mysql:基于 SQLAlchemy 的数据库管理与常见 CRUD 封装py_tools.utils.AsyncUtil:同步异步互转、后台任务执行py_tools.utils:时间、文件、JWT、编码、序列化、树结构等通用工具
顶层 py_tools 包默认不聚合所有子模块,请从对应子模块导入。
README 只保留最常用、最能体现封装价值的示例。
from py_tools.constants import BASE_DIR
from py_tools.logging import logger, setup_logging
setup_logging(log_dir=BASE_DIR / "logs")
logger.info("service started")
logger.error("something happened")对应示例:demo/logging/logging_demo.py
from pydantic_settings import SettingsConfigDict
from py_tools.utils import BaseConfigSettings, ConfigUtil
class AppSettings(BaseConfigSettings):
app_name: str = "py-tools-demo"
app_port: int = 8000
debug: bool = False
model_config = SettingsConfigDict(env_prefix="", env_file=".env", extra="ignore")
settings = ConfigUtil.load_merged_settings(
AppSettings,
yaml_file="config.yaml",
env_file=".env",
app_name="runtime-app",
)
print(settings.model_dump())默认优先级:
显式传参(kwargs) > 环境变量 > .env > yaml > 默认值
对应示例:demo/utils/config_util_demo.py
import asyncio
from py_tools.connections.http import AsyncHttpClient
async def main():
url = "https://juejin.cn/"
resp = await AsyncHttpClient().get(url).execute()
text_data = await AsyncHttpClient().get(url, params={"test": "hui"}).text()
json_data = await AsyncHttpClient().post(url, data={"test": "hui"}).json()
byte_data = await AsyncHttpClient().get(url).bytes()
print(text_data)
print(resp.status)
print(json_data)
print(byte_data[:10])
async for chunk in AsyncHttpClient().get(url).stream(chunk_size=512):
print(chunk)
break
asyncio.run(main())对应示例:demo/connections/http_client_demo.py
上传文件:
import asyncio
from py_tools.connections.http import AsyncHttpClient
async def main():
upload_file_ret = await AsyncHttpClient().upload_file(
"https://httpbin.org/post",
file="test.txt",
).json()
print(upload_file_ret)
asyncio.run(main())import asyncio
from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column
from py_tools.connections.db.mysql import BaseOrmTable, DBManager, SQLAlchemyManager
class UserFileTable(BaseOrmTable):
__tablename__ = "user_file"
filename: Mapped[str] = mapped_column(String(100), default="")
oss_key: Mapped[str] = mapped_column(String(100), default="")
class UserFileManager(DBManager):
orm_table = UserFileTable
db_client = SQLAlchemyManager(
host="127.0.0.1",
port=3306,
user="root",
password="123456",
db_name="db_demo",
)
async def main():
db_client.init_mysql_engine()
DBManager.init_db_client(db_client)
file_id = await UserFileManager().add({"filename": "demo.txt", "oss_key": "demo-key"})
file_obj = await UserFileManager().query_by_id(file_id)
file_list = await UserFileManager().query_all(cols=["id", "filename", "oss_key"])
await UserFileManager().update(
values={"filename": "demo-updated.txt"},
conds=[UserFileTable.id == file_id],
)
await UserFileManager().delete_by_id(file_id)
print(file_obj)
print(file_list)
asyncio.run(main())对应示例:
- demo/connections/sqlalchemy_demo/demo.py
- demo/connections/sqlalchemy_demo/manager.py
- demo/connections/sqlalchemy_demo/table.py
示例统一放在 demo/ 目录,避免文档示例与代码示例重复维护。
- 示例索引:demo/README.md
- Async 工具:demo/utils/async_util_demo.py
- WebSocket:demo/connections/websocket_demo.py
- FastAPI WebSocket:demo/connections/fastapi_websocket_demo.py
- 编码工具:demo/utils/encode_util_demo.py
pip install -e .[test]
python -m pytest -q
ruff check .- Fork 并克隆仓库
- 安装依赖
- 运行测试与静态检查
- 提交 Pull Request