Skip to main content

一个强大的对象控制工具, 覆盖了配置管理、状态管理、上下文管理和生命周期管理。

Project description

Mapgraph

mapgraph 提供了强大的对象控制工具, 覆盖了配置管理、状态管理、上下文管理和生命周期管理。

一阴一阳之谓道

CodeFactor GitHub CodeQL

功能

  • 配置管理
    • 基于类型声明的配置
    • 支持实时变更
  • 上下文管理
    • 基于描述器的依赖注入
    • 优雅的上下文切换
  • 生命周期管理
    • 服务编排
  • 状态管理

安装

pip install mapgraph

Or

pdm add mapgraph

入门指南

上下文管理

from mapgraph.context import InstanceContext

InstanceContext 实例上下文, 顾名思义是管理 对象 的抽象, 它通过两个维度对 对象 进行管理, 即 名义类型

  • 名义类型 可以理解为 变量名 或者是 变量类型, 总之它在当前实例上下文是唯一的 KEY
  • 很好理解,即是某个被管理的 对象
from mapgraph.globals import GLOBAL_INSTANCE_CONTEXT

GLOBAL_INSTANCE_CONTEXT 全局实例上下文, 即最顶层的命名空间, 本质也是一个 InstanceContext

基本使用

from typing import NewType

from mapgraph.globals import GLOBAL_INSTANCE_CONTEXT
from mapgraph.instance_of import get_instance

MYINT = NewType("MYINT", int)

GLOBAL_INSTANCE_CONTEXT.store(123, "test")
# GLOBAL_INSTANCE_CONTEXT.store({int: 123, str: "test"}) 
GLOBAL_INSTANCE_CONTEXT.store({list[int]: [1,2,3]})
GLOBAL_INSTANCE_CONTEXT.store({MYINT: -123})

print(get_instance(int)) # 123
print(get_instance(MYINT)) # 123
print(get_instance(MYINT, is_key=True)) # -123
print(get_instance(str)) # test
print(get_instance(list[int])) # [1,2,3]
  • get_instance 可以通过类型获取 InstanceContext 中的值, 当 is_key=True名义类型 匹配, 反之为 匹配
  • .store 拥有可变位置参数 collection_or_targets 类型为 Mapping[type, Any] | Any
  • .store(123, "test") 等价于 .store({int: 123, str: "test"})

因为运行时类型检查器拥有的局限性,所以分别引入了 名义类型,它们相互补充

多级实例上下文

from mapgraph.context import InstanceContext
from mapgraph.globals import GLOBAL_INSTANCE_CONTEXT
from mapgraph.instance_of import get_instance

loacl_context = InstanceContext()

GLOBAL_INSTANCE_CONTEXT.store(123, {list[int]: [1,2,3]})
loacl_context.store("test", -123)

print(get_instance(int)) # 123
# print(get_instance(str)) # ValueError: <class 'str'>

with loacl_context.scope():
    print(get_instance(str)) # test
    print(get_instance(int)) # -123
    print(get_instance(list[int])) # [1,2,3]

with loacl_context.scope(inherit=False):
    print(get_instance(str)) # test
    print(get_instance(int)) # -123
    print(get_instance(list[int])) # ValueError: <class 'list[int]'>

.scope 拥有关键字参数 inherit, 表示是否继承上一级 InstanceContext

描述器支持

from typing import NewType

from httpx import AsyncClient
from mapgraph.globals import GLOBAL_INSTANCE_CONTEXT
from mapgraph.instance_of import get_instance, InstanceOf, InstanceOfK, InstanceOfV

OPENAI_API_KEY = NewType("OPENAI_API_KEY", str)

class Test:
    client: InstanceOfV[AsyncClient] = InstanceOf(AsyncClient)
    openai_api_key: InstanceOfK[OPENAI_API_KEY] = InstanceOf(OPENAI_API_KEY, is_key=True)

GLOBAL_INSTANCE_CONTEXT.store({OPENAI_API_KEY: "test"}, AsyncClient())

test = Test()

print(test.client) # <httpx.AsyncClient object at 0x7f7f7f7f7f7f>
print(test.openai_api_key) # test

InstanceOf 是一个函数会返两种描述器 InstanceOfV[T]InstanceOfK[T], 很好理解 前者被声明为通过 匹配, 后者被声明通过 名义类型 匹配。

描述器读取

from typing import NewType

from httpx import AsyncClient
from mapgraph.context import InstanceContext
from mapgraph.globals import GLOBAL_INSTANCE_CONTEXT
from mapgraph.instance_of import get_instance, InstanceOf, InstanceOfK, InstanceOfV

OPENAI_API_KEY = NewType("OPENAI_API_KEY", str)
BASE_URL = NewType("BASE_URL", str)

loacl_context = InstanceContext()

class Test:
    client: InstanceOfV[AsyncClient] = InstanceOf(AsyncClient)
    openai_api_key: InstanceOfK[OPENAI_API_KEY] = InstanceOf(OPENAI_API_KEY, is_key=True)
    base_url: InstanceOfK[BASE_URL] = InstanceOf(BASE_URL, is_key=True)

GLOBAL_INSTANCE_CONTEXT.store({OPENAI_API_KEY: "sk-proj-xxx", BASE_URL: "https://api.openai.com"}, AsyncClient())
loacl_context.store({BASE_URL: "https://api.xxxmy.com"})

test = Test()

print(test.client) # <httpx.AsyncClient object at 0x7f7f7f7f7f7f>
print(test.openai_api_key) # sk-proj-xxx
print(test.base_url) # https://api.openai.com

with loacl_context.scope():
    print(test.base_url) # https://api.xxxmy.com

描述器写入

from typing import NewType

from httpx import AsyncClient
from mapgraph.context import InstanceContext
from mapgraph.globals import GLOBAL_INSTANCE_CONTEXT
from mapgraph.instance_of import get_instance, InstanceOf, InstanceOfK, InstanceOfV

OPENAI_API_KEY = NewType("OPENAI_API_KEY", str)
BASE_URL = NewType("BASE_URL", str)

loacl_context = InstanceContext()

class Test:
    client: InstanceOfV[AsyncClient] = InstanceOf(AsyncClient)
    base_url: InstanceOfK[BASE_URL] = InstanceOf(BASE_URL, is_key=True)


GLOBAL_INSTANCE_CONTEXT.store(
    {BASE_URL: "https://api.openai.com"}, AsyncClient()
)
loacl_context.store({BASE_URL: "https://api.xxxmy.com"})

test = Test()

print(id(test.client))  # 139921911645712
print(test.base_url)  # https://api.openai.com

with loacl_context.scope():
    print(test.base_url)  # https://api.xxxmy.com
    print(id(test.client))  # 139921911645712
    test.base_url = {BASE_URL: BASE_URL("https://api.yyymy.com")}
    test.client = AsyncClient()
    print(test.base_url)  # https://api.yyymy.com
    print(id(test.client))  # 140043844997072

print(test.base_url)  # https://api.openai.com
print(id(test.client))  # 139921911645712
  • 当描述器为 InstanceOfK[T] 时, 设置值需要一个 Mapping[Type[T], T]
  • 当描述器为 InstanceOfV[T] 时, 设置值需要为 T

配置管理

.env

OPENAI_API_KEY = "sk-proj-xxx"
BASE_URL = "https://api.openai.com"
MYINT = 123
MYDICT = {"a": 1}
MYLIST = [1, 2, 3]
from typing import NewType

from mapgraph.config import load_env
from mapgraph.instance_of import InstanceOf

OPENAI_API_KEY = NewType("OPENAI_API_KEY", str)
BASE_URL = NewType("BASE_URL", str)
MYINT = NewType("MYINT", int)
MYLIST = NewType("MYLIST", list[int])
MYDICT = NewType("MYDICT", dict[str, int])
MYBOOL = NewType("MYBOOL", bool)

class ConfigData:
    a = InstanceOf(MYINT, is_key=True)
    b = InstanceOf(MYLIST, is_key=True)
    c = InstanceOf(MYDICT, is_key=True)
    d = InstanceOf(MYBOOL, is_key=True)

class Config:
    api_key = InstanceOf(OPENAI_API_KEY, is_key=True)
    base_url = InstanceOf(BASE_URL, is_key=True)
    data = ConfigData()


load_env(
    envs=(OPENAI_API_KEY, BASE_URL, MYINT, MYLIST, MYDICT), 
    envs_kv={MYBOOL: False}, # 设置默认值
    dotenv_path=".env"
)

config = Config()

print(config.api_key) # sk-proj-xxx
print(config.base_url) # https://api.openai.com
print(config.data.a) # 123
print(config.data.b) # [1, 2, 3]
print(config.data.c) # {'a': 1}
print(config.data.d) # False

最佳实践是控制所需的最细的粒度, 当配置较为复杂可以进行嵌套

状态管理

依赖于 statv 文档

生命周期管理

目前可以使用两种实现

  • mapgraph.lifecycle 提供了 launch_services 服务自动编排
  • 依赖于 launart 文档

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mapgraph-0.2.4.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

mapgraph-0.2.4-py3-none-any.whl (15.3 kB view details)

Uploaded Python 3

File details

Details for the file mapgraph-0.2.4.tar.gz.

File metadata

  • Download URL: mapgraph-0.2.4.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: pdm/2.20.0.post1 CPython/3.10.12 Linux/6.5.0-1025-azure

File hashes

Hashes for mapgraph-0.2.4.tar.gz
Algorithm Hash digest
SHA256 3b212e69496ddbec30b9a209c6a427f4894b7ea1a729feb797df6fec40d365fe
MD5 43bf60886a49096e8db68152dc874267
BLAKE2b-256 ac981846ba5212c0b9318d6d3607bb38e2dd9efbedf881dcb1bbb42231beb7fa

See more details on using hashes here.

File details

Details for the file mapgraph-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: mapgraph-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 15.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: pdm/2.20.0.post1 CPython/3.10.12 Linux/6.5.0-1025-azure

File hashes

Hashes for mapgraph-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 2fed8fd37179c312f4828bee1df40579ce8fd6db8ec1e4f350db5eb7e66485a2
MD5 508a006ee9aaa2e5184ac8e05021be0b
BLAKE2b-256 e3411c3e74acc9789eef28a09291fa93794ff556dd1ef49fd37e1d2dca8fdc53

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page