IoC with auto config framework
Project description
autoboot
一个Python语言的仿SpringBoot开发方式,支持IoC组件容器、注解式注册、配置驱动开发、事件通知、插件扩展的快速开发框架。
Purpose
在使用Python开发AI应用服务时遇到以下问题:
- 在
.env
里添加配置的方式,在获取配置参数时很容易写错,且调用没有代码提示。 - 配置参数较多时会让查找起来比较混乱,无法分类进行管理。
- 各种对象创建在各个函数和方法里,但多时候只需要创建一个单例。
- 很多代码和函数写在全局执行文件,创建的上下文数据在调用其它函数时需要层层传递。
autoboot vs SpringBoot
由于Python有自身的语法特性,开发时也得到了天然的优化支持,以下是对比的测试环境:
开发语言 | 框架 | server |
---|---|---|
Python 3.11 | autoboot 0.7 | uvicorn |
Java 1.8 | SpringBoot 2.7 | Tomcat |
- 基于单容器设计,使用简单,学习成本低。
- 不需要扫描组件所在的包,所有组件只需要声明即可(除Listener特殊组件需要配置扫描外)。
- 所有声明的组件只有在调用时才会创建并缓存,实现了SpringBoot推荐的懒加载创建方式。
- 配置采用
.env + yaml
组合,.env
用于支持多环境配置项,主配置使用autoboot.yaml
,框架扩展了yaml自定义指令!env
用于从.env
中获取配置参数。 - 没有历史遗留包袱,启动创建的对象少,占用内存低。
- 微服务项目的启动速度快到可以在1-2秒内启动完成,相比SpringBoot的10几秒,快了至少10倍。
Quick Start
Install
pip install autoboot
Usage
配置
- 启动配置文件
./config/.env
# 环境名称(默认值:dev,框架根据这个配置项来加载当前的环境配置)
ENV_NAME=dev
# 应用名
APPLICATION_NAME=demo
- 环境配置文件
./config/.env.dev
APPLICATION_NAME=demo-dev
- 主配置文件
./config/autoboot.yaml
autoboot:
application:
# !env 引用 .env 里的配置参数
name: !env APPLICATION_NAME
# 微服务模块名
module: api
# 日志
log:
dir: logs
# !!str 明确定义为字符串类型
max_size: !!str 100 MB
retention: !!str 30 days
创建并启动容器
from autoboot import AutoBoot, AutoBootConfig
context = Autoboot(AutoBootConfig(config_dir="./config"))
context.run()
# 或者直接使用 loguru.logger,日志的配置同样生效
Autoboot.logger.info("Context run succeed!")
Advanced Features
自定义配置
主配置文件
api:
# 在环境配置文件.env添加:API_SECRET_KEY=xxx
secret: !env API_SECRET_KEY
创建配置类api_properties.py
from autoboot.annotation.env import static_property
class ApiProperties:
@static_property("api.secret")
def secret() -> str:
# 返回的值作为默认的配置值
return ""
创建并启动容器
from autoboot import AutoBoot, AutoBootConfig
from .api_properties import ApiProperties
context = Autoboot(AutoBootConfig(config_dir="./config"))
context.run()
# 在容器启动完成后获取
Autoboot.logger.info("api.secret: {}", ApiProperties.secret())
注册组件
创建组件hello_service.py
通过继承Component实现自注册,如果自己项目中的类,推荐采用这种方式。
from autoboot.meta import Component
class HelloService(Component):
def __init__(self):
pass
def hello(self):
return "Hello World!"
非继承式注册组件
如果注册的类来自第三方库,无法采用继承Component的方式,那么可以通过下面方式来注册:
from autoboot.annotation import component
from .hello_service import HelloService
@component("HelloService")
def hello_service():
return HelloService()
调用组件
from autoboot import AutoBoot, AutoBootConfig
from .hello_service import HelloService
context = Autoboot(AutoBootConfig(config_dir="./config"))
context.run()
# 在容器启动完成后调用
# HelloService() 会在创建对象后自动注册到容器,且多次调用返回同一个实例
assert id(HelloService()) == id(HelloService())
Autoboot.logger.info("HelloService.hello: {}", HelloService().hello())
监听容器事件
主配置文件
autoboot:
application:
# 扫描监听器包
scan_listener_packages:
- listener
项目下创建目录listener
- 在该目录创建
__init__.py
from .app_listener import AppListener
__all__ = ["AppListener"]
- 在该目录创建
app_listener.py
from autoboot import AutoBoot
from autoboot.event import ApplicationListener
from autoboot.meta import Listener
@Listener
class AppListener(ApplicationListener):
def on_env_prepared(self, config: dict[str, Any]):
AutoBoot.logger.info("listen: env prepared!")
def on_started(self):
AutoBoot.logger.info("listen: app started!")
发送事件
基于Action的事件发送与监听
from dataclasses import dataclass
from autoboot.event import emitter, Event
from loguru import logger
@dataclass(slots=True)
class PayOrder:
no: str
@emitter.on("pay_action")
def received_payment(event: Event[str]):
logger.info("received_payment")
assert(event.data == "pay order: 1001")
emitter.emit(action="pay_action", event=Event("pay order: 1001"))
基于事件类型自动匹配的发送与监听
from dataclasses import dataclass
from autoboot.event import emitter, Event
from loguru import logger
@dataclass(slots=True)
class PayOrder:
no: str
@emitter.on_event
def received_pay(event: Event[PayOrder]):
logger.info("received_pay")
assert(event.data == PayOrder("1001"))
emitter.emit(event=Event(PayOrder("1001")))
扩展插件
创建插件my_plugin.py
from autoboot.plugin import AppPlugin
class MyPlugin(AppPlugin):
def install(self):
AutoBoot.logger.info("plugin: installed!")
def on_env_prepared(self, config: dict[str, Any]):
AutoBoot.logger.info("plugin: env prepared!")
def on_started(self):
AutoBoot.logger.info("plugin: started!")
安装插件
from autoboot import AutoBoot, AutoBootConfig
from .my_plugin import MyPlugin
context = Autoboot(AutoBootConfig(config_dir="./config"))
context.apply(MyPlugin())
context.run()
Ecosystem
Contributors
有问题可以在issues开话题讨论,如果你有新的想法,创建新的feat
或pref
分支并提交PR。
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
autoboot-0.10.0.tar.gz
(21.8 kB
view details)
Built Distribution
autoboot-0.10.0-py3-none-any.whl
(23.2 kB
view details)
File details
Details for the file autoboot-0.10.0.tar.gz
.
File metadata
- Download URL: autoboot-0.10.0.tar.gz
- Upload date:
- Size: 21.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/40.0 requests/2.31.0 requests-toolbelt/1.0.0 urllib3/1.26.16 tqdm/4.65.0 importlib-metadata/6.8.0 keyring/24.2.0 rfc3986/1.5.0 colorama/0.4.6 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1b7ce618b46fc6f7bb3c2b58b459483146938d9fda4c00ae5c3a0720680bf351 |
|
MD5 | 07bd73cf0c1295099facee4ec103cdf4 |
|
BLAKE2b-256 | 189acc2b7e0616bbf1bb3c4725870fba15e8c7cb4c47c60a299ab4a81fcb11eb |
File details
Details for the file autoboot-0.10.0-py3-none-any.whl
.
File metadata
- Download URL: autoboot-0.10.0-py3-none-any.whl
- Upload date:
- Size: 23.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.9.6 readme-renderer/40.0 requests/2.31.0 requests-toolbelt/1.0.0 urllib3/1.26.16 tqdm/4.65.0 importlib-metadata/6.8.0 keyring/24.2.0 rfc3986/1.5.0 colorama/0.4.6 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b64e1958005cfcb21f308654a62bef2cce70ba5a87595fa8849b62b564593e9f |
|
MD5 | a36ef89840547dbb2d53774a8ff65c8a |
|
BLAKE2b-256 | 31c02403e95319b62529c7cae08b2cfa8ca3449016be5d296a96e7c646c24db7 |