Developer Guide¶
This guide is for ChatArch packages that want to use ChatEnv. ChatEnv owns typed env/profile mechanics; leaf packages own their service variables, connectivity tests, and runtime token semantics.
Responsibilities¶
ChatEnv provides:
EnvFieldfor environment variable metadata.BaseEnvConfigfor typed schemas and automatic registry.EnvStorefor active.envand named profile files.TokenStorefortokens/<Service>/<profile>.jsonruntime state with safe metadata.chatenvCLI commands for env profiles and runtime tokens.chatenv.configsdiscovery for schema providers.chatenv.token_refreshersdiscovery for service-owned refresh hooks.
Leaf packages provide:
- Their own
BaseEnvConfigsubclasses. _aliasesand_storage_dir.chatenv.configsentry points.- Optional login/refresh functions registered through
chatenv.token_refreshers. - Service-specific
test()implementations.
Integrating a package¶
Depend on ChatEnv:
[project]
dependencies = [
"chatenv>=0.2.8,<0.3.0",
]
Define a schema:
from chatenv import BaseEnvConfig, EnvField
class FooConfig(BaseEnvConfig):
_title = "Foo Configuration"
_aliases = ["foo", "chatfoo"]
_storage_dir = "Foo"
FOO_API_BASE = EnvField("FOO_API_BASE", desc="Foo API base URL")
FOO_API_KEY = EnvField("FOO_API_KEY", desc="Foo API key", is_sensitive=True)
Register the provider:
[project.entry-points."chatenv.configs"]
chatfoo = "chatfoo.config"
Runtime token refresh providers¶
If a package needs access tokens, web sessions, cookies, or CSRF state, stable env/profile values should contain only re-authentication inputs. The runtime values should be generated by a service-owned refresh function:
[project.entry-points."chatenv.token_refreshers"]
Foo = "chatfoo.tokens:refresh_chatenv_token"
from chatenv import TokenRefreshResult
def refresh_chatenv_token(*, service, profile, home, env_store, token_store):
return TokenRefreshResult(
values={"access_token": "[REDACTED]"},
token_type="oauth_access_token",
summary={"account": "operator", "base_url": "https://foo.example"},
expires_at="2026-08-11T23:00:00Z",
)
chatenv token refresh Foo work invokes the hook and writes the token-store file. token import is only an explicit migration or external-refresh handoff path.
Local development¶
python -m pip install -e /path/to/ChatEnv
python -m pip install -e /path/to/chatfoo
chatenv status --detail
chatenv list
chatenv init -t foo -i
chatenv cat -t foo
chatenv test -t foo
chatenv test -t foo work
chatenv test -t foo --profile work
Reusable profile loading for future commands is available through EnvStore.load_config(config_cls, profile=None), which returns the loaded path. Active mode preserves legacy load_from_sources(env_values=...) overrides. Named mode uses BaseEnvConfig.load_from_profile(values) to assign literal file values and schema defaults, bypassing legacy source loaders that do not accept new keywords. A missing named profile raises FileNotFoundError. No arguments are added to provider test() methods.
test() receives the loaded target configuration. chatenv test -t foo work loads a named profile without activating it or filling missing fields from process environment or active values. Providers should inspect the loaded fields rather than reload default configuration inside test(). The shared load_from_sources(..., include_process_env=False) API supports the same isolated loading; omitting the option preserves process environment fallback.