autoboot


Nameautoboot JSON
Version 0.12.2 PyPI version JSON
download
home_pagehttps://github.com/yizzuide/autoboot
SummaryIoC with auto config framework
upload_time2024-08-12 13:34:26
maintainerNone
docs_urlNone
authoryizzuide
requires_python>=3.8
licenseMIT
keywords ioc event auto config
VCS
bugtrack_url
requirements python-dotenv filetype loguru pyyaml wrapt pydantic result whenever tzlocal jmespath more-itertools cytoolz
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # autoboot
一个Python语言的仿SpringBoot开发方式,支持IoC组件容器、注解式注册、配置驱动开发、事件通知、插件扩展的快速开发框架。
<p>
  <a href="https://pypi.org/project/autoboot">
      <img src="https://img.shields.io/pypi/v/autoboot?color=%2334D058&label=pypi%20package" alt="Version">
  </a>
  <a href="https://pypi.org/project/autoboot">
        <img src="https://img.shields.io/pypi/pyversions/autoboot.svg?color=%2334D058" alt="Python">
  </a>
  <a href="https://pepy.tech/project/autoboot">
      <img src="https://static.pepy.tech/personalized-badge/autoboot?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads" alt="Downloads">
  </a>
  <a href="https://github.com/yizzuide/autoboot/blob/main/LICENSE">
      <img src="https://img.shields.io/github/license/yizzuide/autoboot" alt="License">
  </a>
</p>

## Purpose
在使用Python开发AI应用服务时遇到以下问题:

- 在`.env`里添加配置的方式,在获取配置参数时很容易写错,且调用没有代码提示。
- 配置参数较多时会让查找起来比较混乱,无法分类进行管理。
- 各种对象创建在各个函数和方法里,但多时候只需要创建一个单例。
- 很多代码和函数写在全局执行文件,创建的上下文数据在调用其它函数时需要层层传递。


## autoboot vs SpringBoot
由于Python有自身的语法特性,开发时也得到了天然的优化支持,以下是对比的测试环境:

| 开发语言 | 框架 | server |
| :----: | :----: | :----: |
| Python 3.11 | autoboot 0.10 | 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
```bash
pip install autoboot
```

### Usage

#### 配置
* 启动配置文件`./config/.env`

```ini
# 环境名称(默认值:dev,框架根据这个配置项来加载当前的环境配置)
ENV_NAME=dev

# 应用名
APPLICATION_NAME=demo
```

* 环境配置文件`./config/.env.dev`

```ini
APPLICATION_NAME=demo-dev
```

* 主配置文件`./config/autoboot.yaml`

```yml
autoboot:
  application:
    # !env 引用 .env 里的配置参数 
    name: !env $APPLICATION_NAME
    # 微服务模块名
    module: api
    # 日志
    log:
      dir: logs
      # !!str 明确定义为字符串类型
      max_size: !!str 100 MB
      retention: !!str 30 days
```

#### 创建并启动容器
```python
from autoboot import AutoBoot, AutoBootConfig

context = Autoboot(AutoBootConfig(config_dir="./config"))
context.run()

# 或者直接使用 loguru.logger,日志的配置同样生效
Autoboot.logger.info("Context run succeed!")
```

## Advanced Features

### 自定义配置

#### 主配置文件
```yml
api:
  # 在环境配置文件.env添加:API_SECRET_KEY=xxx
  secret: !env $API_SECRET_KEY
```

#### 创建配置类`api_properties.py`
```python
from autoboot.annotation import static_property

class ApiProperties:

  @static_property("api.secret")
  def secret() -> str:
    # 返回的值作为默认的配置值
    return ""
```

#### 创建并启动容器
```python
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`文件:

```python
from autoboot.annotation import component

@component()
class HelloService(object):
  def __init__(self):
    pass

  def hello(self):
    return "Hello World!"
```

#### 函数式注册组件

如果注册的类来自第三方库,无法采用继承Component的方式,那么可以通过下面方式来注册:

```python
from autoboot.annotation import component
from .hello_service import HelloService


@component(name='HelloService')
def hello_service():
  return HelloService()
```

#### 调用组件
```python
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())
```


### 监听容器事件

#### 主配置文件
```yml
autoboot:
  application:
    # 扫描监听器包
    scan_listener_packages:
      - listener
```      

#### 项目下创建目录`listener`

* 在该目录创建`__init__.py`

```python
from .app_listener import AppListener

__all__ = ["AppListener"]
```

* 在该目录创建`app_listener.py`

```python
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的事件发送与监听
```python
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"))
```

#### 基于事件类型自动匹配的发送与监听
```python
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`
```python
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!")
```

#### 安装插件
```python
from autoboot import AutoBoot, AutoBootConfig
from .my_plugin import MyPlugin

context = Autoboot(AutoBootConfig(config_dir="./config"))
context.apply(MyPlugin())
context.run()
```

## Ecosystem
* [autoboot-web](https://github.com/yizzuide/autoboot-web)
* [autoboot-data](https://github.com/yizzuide/autoboot-data)

## Contributors
有问题可以在issues开话题讨论,如果你有新的想法,创建新的`feat`或`pref`分支并提交PR。

## License
[MIT License](https://github.com/yizzuide/autoboot/blob/main/LICENSE.txt)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/yizzuide/autoboot",
    "name": "autoboot",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "IoC, event, auto config",
    "author": "yizzuide",
    "author_email": "fu837014586@163.com",
    "download_url": "https://files.pythonhosted.org/packages/54/25/8962d628734cfa1b06f0a7335d5ad91605dbd7a25bf95fc2f55ccb596aaa/autoboot-0.12.2.tar.gz",
    "platform": null,
    "description": "# autoboot\n\u4e00\u4e2aPython\u8bed\u8a00\u7684\u4effSpringBoot\u5f00\u53d1\u65b9\u5f0f\uff0c\u652f\u6301IoC\u7ec4\u4ef6\u5bb9\u5668\u3001\u6ce8\u89e3\u5f0f\u6ce8\u518c\u3001\u914d\u7f6e\u9a71\u52a8\u5f00\u53d1\u3001\u4e8b\u4ef6\u901a\u77e5\u3001\u63d2\u4ef6\u6269\u5c55\u7684\u5feb\u901f\u5f00\u53d1\u6846\u67b6\u3002\n<p>\n  <a href=\"https://pypi.org/project/autoboot\">\n      <img src=\"https://img.shields.io/pypi/v/autoboot?color=%2334D058&label=pypi%20package\" alt=\"Version\">\n  </a>\n  <a href=\"https://pypi.org/project/autoboot\">\n        <img src=\"https://img.shields.io/pypi/pyversions/autoboot.svg?color=%2334D058\" alt=\"Python\">\n  </a>\n  <a href=\"https://pepy.tech/project/autoboot\">\n      <img src=\"https://static.pepy.tech/personalized-badge/autoboot?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads\" alt=\"Downloads\">\n  </a>\n  <a href=\"https://github.com/yizzuide/autoboot/blob/main/LICENSE\">\n      <img src=\"https://img.shields.io/github/license/yizzuide/autoboot\" alt=\"License\">\n  </a>\n</p>\n\n## Purpose\n\u5728\u4f7f\u7528Python\u5f00\u53d1AI\u5e94\u7528\u670d\u52a1\u65f6\u9047\u5230\u4ee5\u4e0b\u95ee\u9898\uff1a\n\n- \u5728`.env`\u91cc\u6dfb\u52a0\u914d\u7f6e\u7684\u65b9\u5f0f\uff0c\u5728\u83b7\u53d6\u914d\u7f6e\u53c2\u6570\u65f6\u5f88\u5bb9\u6613\u5199\u9519\uff0c\u4e14\u8c03\u7528\u6ca1\u6709\u4ee3\u7801\u63d0\u793a\u3002\n- \u914d\u7f6e\u53c2\u6570\u8f83\u591a\u65f6\u4f1a\u8ba9\u67e5\u627e\u8d77\u6765\u6bd4\u8f83\u6df7\u4e71\uff0c\u65e0\u6cd5\u5206\u7c7b\u8fdb\u884c\u7ba1\u7406\u3002\n- \u5404\u79cd\u5bf9\u8c61\u521b\u5efa\u5728\u5404\u4e2a\u51fd\u6570\u548c\u65b9\u6cd5\u91cc\uff0c\u4f46\u591a\u65f6\u5019\u53ea\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u5355\u4f8b\u3002\n- \u5f88\u591a\u4ee3\u7801\u548c\u51fd\u6570\u5199\u5728\u5168\u5c40\u6267\u884c\u6587\u4ef6\uff0c\u521b\u5efa\u7684\u4e0a\u4e0b\u6587\u6570\u636e\u5728\u8c03\u7528\u5176\u5b83\u51fd\u6570\u65f6\u9700\u8981\u5c42\u5c42\u4f20\u9012\u3002\n\n\n## autoboot vs SpringBoot\n\u7531\u4e8ePython\u6709\u81ea\u8eab\u7684\u8bed\u6cd5\u7279\u6027\uff0c\u5f00\u53d1\u65f6\u4e5f\u5f97\u5230\u4e86\u5929\u7136\u7684\u4f18\u5316\u652f\u6301\uff0c\u4ee5\u4e0b\u662f\u5bf9\u6bd4\u7684\u6d4b\u8bd5\u73af\u5883\uff1a\n\n| \u5f00\u53d1\u8bed\u8a00 | \u6846\u67b6 | server |\n| :----: | :----: | :----: |\n| Python 3.11 | autoboot 0.10 | uvicorn\n| Java 1.8 | SpringBoot 2.7 | Tomcat\n\n- \u57fa\u4e8e\u5355\u5bb9\u5668\u8bbe\u8ba1\uff0c\u4f7f\u7528\u7b80\u5355\uff0c\u5b66\u4e60\u6210\u672c\u4f4e\u3002\n- \u4e0d\u9700\u8981\u626b\u63cf\u7ec4\u4ef6\u6240\u5728\u7684\u5305\uff0c\u6240\u6709\u7ec4\u4ef6\u53ea\u9700\u8981\u58f0\u660e\u5373\u53ef\uff08\u9664Listener\u7279\u6b8a\u7ec4\u4ef6\u9700\u8981\u914d\u7f6e\u626b\u63cf\u5916\uff09\u3002\n- \u6240\u6709\u58f0\u660e\u7684\u7ec4\u4ef6\u53ea\u6709\u5728\u8c03\u7528\u65f6\u624d\u4f1a\u521b\u5efa\u5e76\u7f13\u5b58\uff0c\u5b9e\u73b0\u4e86SpringBoot\u63a8\u8350\u7684\u61d2\u52a0\u8f7d\u521b\u5efa\u65b9\u5f0f\u3002\n- \u914d\u7f6e\u91c7\u7528`.env + yaml`\u7ec4\u5408\uff0c`.env`\u7528\u4e8e\u652f\u6301\u591a\u73af\u5883\u914d\u7f6e\u9879\uff0c\u4e3b\u914d\u7f6e\u4f7f\u7528`autoboot.yaml`\uff0c\u6846\u67b6\u6269\u5c55\u4e86yaml\u81ea\u5b9a\u4e49\u6307\u4ee4`!env`\u7528\u4e8e\u4ece`.env`\u4e2d\u83b7\u53d6\u914d\u7f6e\u53c2\u6570\u3002\n- \u6ca1\u6709\u5386\u53f2\u9057\u7559\u5305\u88b1\uff0c\u542f\u52a8\u521b\u5efa\u7684\u5bf9\u8c61\u5c11\uff0c\u5360\u7528\u5185\u5b58\u4f4e\u3002\n- \u5fae\u670d\u52a1\u9879\u76ee\u7684\u542f\u52a8\u901f\u5ea6\u5feb\u5230\u53ef\u4ee5\u57281-2\u79d2\u5185\u542f\u52a8\u5b8c\u6210\uff0c\u76f8\u6bd4SpringBoot\u768410\u51e0\u79d2\uff0c\u5feb\u4e86\u81f3\u5c1110\u500d\u3002\n\n## Quick Start\n\n### Install\n```bash\npip install autoboot\n```\n\n### Usage\n\n#### \u914d\u7f6e\n* \u542f\u52a8\u914d\u7f6e\u6587\u4ef6`./config/.env`\n\n```ini\n# \u73af\u5883\u540d\u79f0\uff08\u9ed8\u8ba4\u503c\uff1adev\uff0c\u6846\u67b6\u6839\u636e\u8fd9\u4e2a\u914d\u7f6e\u9879\u6765\u52a0\u8f7d\u5f53\u524d\u7684\u73af\u5883\u914d\u7f6e\uff09\nENV_NAME=dev\n\n# \u5e94\u7528\u540d\nAPPLICATION_NAME=demo\n```\n\n* \u73af\u5883\u914d\u7f6e\u6587\u4ef6`./config/.env.dev`\n\n```ini\nAPPLICATION_NAME=demo-dev\n```\n\n* \u4e3b\u914d\u7f6e\u6587\u4ef6`./config/autoboot.yaml`\n\n```yml\nautoboot:\n  application:\n    # !env \u5f15\u7528 .env \u91cc\u7684\u914d\u7f6e\u53c2\u6570 \n    name: !env $APPLICATION_NAME\n    # \u5fae\u670d\u52a1\u6a21\u5757\u540d\n    module: api\n    # \u65e5\u5fd7\n    log:\n      dir: logs\n      # !!str \u660e\u786e\u5b9a\u4e49\u4e3a\u5b57\u7b26\u4e32\u7c7b\u578b\n      max_size: !!str 100 MB\n      retention: !!str 30 days\n```\n\n#### \u521b\u5efa\u5e76\u542f\u52a8\u5bb9\u5668\n```python\nfrom autoboot import AutoBoot, AutoBootConfig\n\ncontext = Autoboot(AutoBootConfig(config_dir=\"./config\"))\ncontext.run()\n\n# \u6216\u8005\u76f4\u63a5\u4f7f\u7528 loguru.logger\uff0c\u65e5\u5fd7\u7684\u914d\u7f6e\u540c\u6837\u751f\u6548\nAutoboot.logger.info(\"Context run succeed!\")\n```\n\n## Advanced Features\n\n### \u81ea\u5b9a\u4e49\u914d\u7f6e\n\n#### \u4e3b\u914d\u7f6e\u6587\u4ef6\n```yml\napi:\n  # \u5728\u73af\u5883\u914d\u7f6e\u6587\u4ef6.env\u6dfb\u52a0\uff1aAPI_SECRET_KEY=xxx\n  secret: !env $API_SECRET_KEY\n```\n\n#### \u521b\u5efa\u914d\u7f6e\u7c7b`api_properties.py`\n```python\nfrom autoboot.annotation import static_property\n\nclass ApiProperties:\n\n  @static_property(\"api.secret\")\n  def secret() -> str:\n    # \u8fd4\u56de\u7684\u503c\u4f5c\u4e3a\u9ed8\u8ba4\u7684\u914d\u7f6e\u503c\n    return \"\"\n```\n\n#### \u521b\u5efa\u5e76\u542f\u52a8\u5bb9\u5668\n```python\nfrom autoboot import AutoBoot, AutoBootConfig\nfrom .api_properties import ApiProperties\n\ncontext = Autoboot(AutoBootConfig(config_dir=\"./config\"))\ncontext.run()\n\n# \u5728\u5bb9\u5668\u542f\u52a8\u5b8c\u6210\u540e\u83b7\u53d6\nAutoboot.logger.info(\"api.secret: {}\", ApiProperties.secret())\n```\n\n### \u6ce8\u518c\u7ec4\u4ef6\n#### \u7c7b\u5f0f\u6ce8\u518c\u7ec4\u4ef6\n\n\u521b\u5efa\u7ec4\u4ef6`hello_service.py`\u6587\u4ef6\uff1a\n\n```python\nfrom autoboot.annotation import component\n\n@component()\nclass HelloService(object):\n  def __init__(self):\n    pass\n\n  def hello(self):\n    return \"Hello World!\"\n```\n\n#### \u51fd\u6570\u5f0f\u6ce8\u518c\u7ec4\u4ef6\n\n\u5982\u679c\u6ce8\u518c\u7684\u7c7b\u6765\u81ea\u7b2c\u4e09\u65b9\u5e93\uff0c\u65e0\u6cd5\u91c7\u7528\u7ee7\u627fComponent\u7684\u65b9\u5f0f\uff0c\u90a3\u4e48\u53ef\u4ee5\u901a\u8fc7\u4e0b\u9762\u65b9\u5f0f\u6765\u6ce8\u518c\uff1a\n\n```python\nfrom autoboot.annotation import component\nfrom .hello_service import HelloService\n\n\n@component(name='HelloService')\ndef hello_service():\n  return HelloService()\n```\n\n#### \u8c03\u7528\u7ec4\u4ef6\n```python\nfrom autoboot import AutoBoot, AutoBootConfig\nfrom .hello_service import HelloService\n\ncontext = Autoboot(AutoBootConfig(config_dir=\"./config\"))\ncontext.run()\n\n# \u5728\u5bb9\u5668\u542f\u52a8\u5b8c\u6210\u540e\u8c03\u7528\n# HelloService() \u4f1a\u5728\u521b\u5efa\u5bf9\u8c61\u540e\u81ea\u52a8\u6ce8\u518c\u5230\u5bb9\u5668\uff0c\u4e14\u591a\u6b21\u8c03\u7528\u8fd4\u56de\u540c\u4e00\u4e2a\u5b9e\u4f8b\nassert id(HelloService()) == id(HelloService())\nAutoboot.logger.info(\"HelloService.hello: {}\", HelloService().hello())\n```\n\n\n### \u76d1\u542c\u5bb9\u5668\u4e8b\u4ef6\n\n#### \u4e3b\u914d\u7f6e\u6587\u4ef6\n```yml\nautoboot:\n  application:\n    # \u626b\u63cf\u76d1\u542c\u5668\u5305\n    scan_listener_packages:\n      - listener\n```      \n\n#### \u9879\u76ee\u4e0b\u521b\u5efa\u76ee\u5f55`listener`\n\n* \u5728\u8be5\u76ee\u5f55\u521b\u5efa`__init__.py`\n\n```python\nfrom .app_listener import AppListener\n\n__all__ = [\"AppListener\"]\n```\n\n* \u5728\u8be5\u76ee\u5f55\u521b\u5efa`app_listener.py`\n\n```python\nfrom autoboot import AutoBoot\nfrom autoboot.event import ApplicationListener\nfrom autoboot.meta import Listener\n\n@Listener\nclass AppListener(ApplicationListener):\n\n  def on_env_prepared(self, config: dict[str, Any]):\n    AutoBoot.logger.info(\"listen: env prepared!\")\n  \n  def on_started(self):\n    AutoBoot.logger.info(\"listen: app started!\")\n\n```\n\n### \u53d1\u9001\u4e8b\u4ef6\n\n#### \u57fa\u4e8eAction\u7684\u4e8b\u4ef6\u53d1\u9001\u4e0e\u76d1\u542c\n```python\nfrom dataclasses import dataclass\nfrom autoboot.event import emitter, Event\nfrom loguru import logger\n\n@dataclass(slots=True)\nclass PayOrder:\n  no: str\n\n@emitter.on(\"pay_action\")\ndef received_payment(event: Event[str]):\n  logger.info(\"received_payment\")\n  assert(event.data == \"pay order: 1001\")\n\n\nemitter.emit(action=\"pay_action\", event=Event(\"pay order: 1001\"))\n```\n\n#### \u57fa\u4e8e\u4e8b\u4ef6\u7c7b\u578b\u81ea\u52a8\u5339\u914d\u7684\u53d1\u9001\u4e0e\u76d1\u542c\n```python\nfrom dataclasses import dataclass\nfrom autoboot.event import emitter, Event\nfrom loguru import logger\n\n@dataclass(slots=True)\nclass PayOrder:\n  no: str\n\n@emitter.on_event\ndef received_pay(event: Event[PayOrder]):\n  logger.info(\"received_pay\")\n  assert(event.data == PayOrder(\"1001\"))\n\nemitter.emit(event=Event(PayOrder(\"1001\")))\n```\n\n### \u6269\u5c55\u63d2\u4ef6\n#### \u521b\u5efa\u63d2\u4ef6`my_plugin.py`\n```python\nfrom autoboot.plugin import AppPlugin\n\nclass MyPlugin(AppPlugin):\n  def install(self):\n    AutoBoot.logger.info(\"plugin: installed!\")\n\n  def on_env_prepared(self, config: dict[str, Any]):\n    AutoBoot.logger.info(\"plugin: env prepared!\")\n\n  def on_started(self):\n    AutoBoot.logger.info(\"plugin: started!\")\n```\n\n#### \u5b89\u88c5\u63d2\u4ef6\n```python\nfrom autoboot import AutoBoot, AutoBootConfig\nfrom .my_plugin import MyPlugin\n\ncontext = Autoboot(AutoBootConfig(config_dir=\"./config\"))\ncontext.apply(MyPlugin())\ncontext.run()\n```\n\n## Ecosystem\n* [autoboot-web](https://github.com/yizzuide/autoboot-web)\n* [autoboot-data](https://github.com/yizzuide/autoboot-data)\n\n## Contributors\n\u6709\u95ee\u9898\u53ef\u4ee5\u5728issues\u5f00\u8bdd\u9898\u8ba8\u8bba\uff0c\u5982\u679c\u4f60\u6709\u65b0\u7684\u60f3\u6cd5\uff0c\u521b\u5efa\u65b0\u7684`feat`\u6216`pref`\u5206\u652f\u5e76\u63d0\u4ea4PR\u3002\n\n## License\n[MIT License](https://github.com/yizzuide/autoboot/blob/main/LICENSE.txt)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "IoC with auto config framework",
    "version": "0.12.2",
    "project_urls": {
        "Homepage": "https://github.com/yizzuide/autoboot"
    },
    "split_keywords": [
        "ioc",
        " event",
        " auto config"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6ea0939649b3a3e43f8d237c9e53956978bf038ad37d565bcd5d3da9621a3ff6",
                "md5": "eac9ff043c708269658325ae0e7144ae",
                "sha256": "dc509d12ae6bb1f2bf4674b8e018d20498664de92ed0e378bbd90edaaea02f9e"
            },
            "downloads": -1,
            "filename": "autoboot-0.12.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "eac9ff043c708269658325ae0e7144ae",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 24427,
            "upload_time": "2024-08-12T13:34:24",
            "upload_time_iso_8601": "2024-08-12T13:34:24.407498Z",
            "url": "https://files.pythonhosted.org/packages/6e/a0/939649b3a3e43f8d237c9e53956978bf038ad37d565bcd5d3da9621a3ff6/autoboot-0.12.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "54258962d628734cfa1b06f0a7335d5ad91605dbd7a25bf95fc2f55ccb596aaa",
                "md5": "8bfc9a48ca2c44e66defd9aede40c443",
                "sha256": "190bb613131261e9e92a9e250b2b5207df36db9c4bda463575ff3b9da6021d21"
            },
            "downloads": -1,
            "filename": "autoboot-0.12.2.tar.gz",
            "has_sig": false,
            "md5_digest": "8bfc9a48ca2c44e66defd9aede40c443",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 22847,
            "upload_time": "2024-08-12T13:34:26",
            "upload_time_iso_8601": "2024-08-12T13:34:26.369435Z",
            "url": "https://files.pythonhosted.org/packages/54/25/8962d628734cfa1b06f0a7335d5ad91605dbd7a25bf95fc2f55ccb596aaa/autoboot-0.12.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-12 13:34:26",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "yizzuide",
    "github_project": "autoboot",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "python-dotenv",
            "specs": [
                [
                    ">=",
                    "1.0.0"
                ],
                [
                    "<",
                    "2.0"
                ]
            ]
        },
        {
            "name": "filetype",
            "specs": [
                [
                    "<",
                    "2.0"
                ],
                [
                    ">=",
                    "1.2.0"
                ]
            ]
        },
        {
            "name": "loguru",
            "specs": [
                [
                    ">=",
                    "0.7.0"
                ],
                [
                    "<",
                    "1.0"
                ]
            ]
        },
        {
            "name": "pyyaml",
            "specs": [
                [
                    "<",
                    "7.0"
                ],
                [
                    ">=",
                    "6.0.1"
                ]
            ]
        },
        {
            "name": "wrapt",
            "specs": [
                [
                    "<",
                    "2.0"
                ],
                [
                    ">=",
                    "1.14.1"
                ]
            ]
        },
        {
            "name": "pydantic",
            "specs": [
                [
                    ">=",
                    "2.6.4"
                ],
                [
                    "<",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "result",
            "specs": [
                [
                    ">=",
                    "0.14.0"
                ],
                [
                    "<",
                    "1.0"
                ]
            ]
        },
        {
            "name": "whenever",
            "specs": [
                [
                    "<",
                    "1.0"
                ],
                [
                    ">=",
                    "0.6.0"
                ]
            ]
        },
        {
            "name": "tzlocal",
            "specs": [
                [
                    ">=",
                    "5.1.0"
                ],
                [
                    "<",
                    "6.0"
                ]
            ]
        },
        {
            "name": "jmespath",
            "specs": [
                [
                    "<",
                    "2.0"
                ],
                [
                    ">=",
                    "1.0.1"
                ]
            ]
        },
        {
            "name": "more-itertools",
            "specs": [
                [
                    "<",
                    "11.0"
                ],
                [
                    ">=",
                    "10.1.0"
                ]
            ]
        },
        {
            "name": "cytoolz",
            "specs": [
                [
                    ">=",
                    "0.12.3"
                ],
                [
                    "<",
                    "1.0"
                ]
            ]
        }
    ],
    "lcname": "autoboot"
}
        
Elapsed time: 1.39975s