Asyncio插件、组件、依赖注入和配置
项目描述
该项目受到Pyramid的启发,并满足我快速创建和维护类似微服务应用的日常需求。
插件机制
插件可能依赖于其他插件
插件产生要运行的任务
上下文注册表充当插件创建的应用组件的存储库
依赖注入创建中间组件
配置源映射到插件特定配置,并且可能被环境变量完全覆盖
structlog用于json/tty日志的样板代码
分叉进程并共享绑定套接字
pytest插件以减少测试样板代码
您可以通过以下方式启动
from buvar import plugin
plugin.stage("some.module.with.prepare")
# some.module.with.prepare
from buvar import context, plugin
class Foo:
...
async def task():
asyncio.sleep(1)
async def server():
my_component = context.get(Foo)
await asyncio.Future()
# there is also plugin.Teardown and plugin.Cancel
async def prepare(load: plugin.Loader):
await load('.another.plugin')
# create some long lasting components
my_component = context.add(Foo())
# you may run simple tasks
yield task()
# you may run server tasks
yield server()
组件和依赖注入解决方案
依赖注入依赖于注册的适配器,这些适配器可能是一个函数、一个方法、一个类、一个类方法或一个通用类方法。
依赖关系在组件中查找,或可能通过kwargs提供。
from buvar import di
class Bar:
pass
class Foo:
def __init__(self, bar: Bar = None):
self.bar = bar
@classmethod
async def adapt(cls, baz: str) -> Foo:
return Foo()
async def adapt(bar: Bar) -> Foo
foo = Foo(bar)
return foo
async def task():
foo = await di.nject(Foo, baz="baz")
assert foo.bar is None
bar = Bar()
foo = await di.nject(Foo, bar=bar)
assert foo.bar is bar
async def prepare():
di.register(Foo.adapt)
di.register(adapt)
yield task()
配置源
buvar.config.ConfigSource
只是一个dict
,它将任意dict合并为一个。它作为应用变异性唯一真相来源。
您可以将配置值的部分加载到您自定义的attrs类实例中。如果存在,ConfigSource将覆盖环境变量中的值。
config.toml
log_level = "DEBUG"
show_warnings = "yes"
[foobar]
some = "value"
export APP_FOOBAR_SOME=thing
import attr
import toml
from buvar import config
@attr.s(auto_attribs=True)
class GeneralConfig:
log_level: str = "INFO"
show_warnings: bool = config.bool_var(False)
@attr.s(auto_attribs=True)
class FoobarConfig:
some: str
source = config.ConfigSource(toml.load('config.toml'), env_prefix="APP")
general_config = source.load(GeneralConfig)
assert general_config == GeneralConfig(log_level="DEBUG", show_warnings=True)
foobar_config = source.load(FoobarConfig, 'foobar')
assert foobar_config.some == "thing"
由buvar.config.Config
提供了一种上述方法的快捷方式,需要从它派生出一个具有不同section
属性的子类。如果添加了一个buvar.config.ConfigSource
组件,他将在一次调用中收到映射的配置。
from buvar import config, plugin
@attr.s(auto_attribs=True)
class GeneralConfig(config.Config):
log_level: str = "INFO"
show_warnings: bool = config.bool_var(False)
@attr.s(auto_attribs=True)
class FoobarConfig(config.Config, section="foobar"):
some: str
async def prepare(load: plugin.Loader):
# this would by typically placed in the main CLI entry point
source = context.add(config.ConfigSource(toml.load('config.toml'), env_prefix="APP"))
# to provide the adapter to di, which could also be done in the main entry point
await load(config)
foobar_config = await di.nject(FoobarConfig)
a structlog
只是structlog的基本模板。
import sys
from buvar import log
log_config = log.LogConfig(tty=sys.stdout.isatty(), level="DEBUG")
log_config.setup()
pytest
提供了一些pytest fixture,以便将您的上下文置于合理的状态
buvar_config_source
一个包含任意应用程序设置的
dict
。buvar_context
基本上下文分阶段操作。
buvar_stage
处理所有插件的实际阶段。
buvar_load
将插件添加到阶段的加载器。
buvar_plugin_context
当插件准备就绪时,所有插件共享的上下文。
以下标记可以应用于测试
buvar_plugins(plugin, ...)
将所有插件加载到插件上下文中。
import pytest
async def prepare():
from buvar import context
context.add("foobar")
@pytest.mark.asyncio
@pytest.mark.buvar_plugins("tests.test_testing")
async def test_wrapped_stage_context():
from buvar import context, plugin
assert context.get(str) == "foobar"
assert context.get(plugin.Cancel)
@pytest.mark.asyncio
@pytest.mark.buvar_plugins()
async def test_wrapped_stage_context_load(buvar_load):
from buvar import context, plugin
await buvar_load(prepare)
assert context.get(str) == "foobar"
assert context.get(plugin.Cancel)
项目详情
关闭
buvar-0.43.10.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 3ef639784f14688647398cf8b70a33bd8890ba651bb84bd03efdcdef99a6d370 |
|
MD5 | 4cf1601ea6f1a4e38685794f2150a14d |
|
BLAKE2b-256 | 350510659dd91ba071ce5ee90de002a15c453d6a31bbd8086e5af5004d8141bb |
关闭
buvar-0.43.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | cd382c38dfcd7096c77e29abae81bd47b39d09c869bc5dd0a12b5ba3ccaf5a20 |
|
MD5 | 8ead49c24fa425017ba3691ba221e9f3 |
|
BLAKE2b-256 | 51e7b21b17f72c7c056159689a0093f0264e17bfbd114e7229ff7ca62bde8f61 |
关闭
buvar-0.43.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 5cb3def0193be876230a70119e32d1a36dca9a38280d0b6c8366f2c35ca00e01 |
|
MD5 | 8c56dd1142304d5cb76d036e44803bf9 |
|
BLAKE2b-256 | c2780bf6a339f8aee76663b390eba321d30faa589efd328b0d6fa9bbd6609db1 |
关闭
buvar-0.43.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | a45c783bb2dbe43f6d3c87f5e4c78c25729e6f10d3f0bdabb8dd61583ef306cd |
|
MD5 | 396f39c712848ad5f62222cdea088a98 |
|
BLAKE2b-256 | 0058f4f684ec3d81e5e8e40843be4836b9b793ed7c066f360b97020ec3daa5e7 |