# 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"
}