ErisPulse 2.5.2.dev4__tar.gz → 2.5.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/PKG-INFO +2 -2
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/pyproject.toml +5 -2
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/create.py +39 -27
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/adapter.py +113 -57
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/adapter.pyi +31 -29
- erispulse-2.5.3/src/ErisPulse/Core/Bases/module.py +216 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/module.pyi +46 -1
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/wrapper.py +96 -15
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/wrapper.pyi +50 -21
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/constants.py +37 -39
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/constants.pyi +2 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/en.py +3 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/ja.py +3 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/ru.py +3 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/zh_cn.py +3 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/zh_tw.py +3 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/module.py +3 -0
- erispulse-2.5.3/src/ErisPulse/py.typed +4 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/__init__.py +8 -2
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/__init__.pyi +1 -1
- erispulse-2.5.3/src/ErisPulse/runtime/config_schema.py +624 -0
- erispulse-2.5.3/src/ErisPulse/runtime/config_schema.pyi +287 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/exceptions.py +14 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/exceptions.pyi +1 -1
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/hints.py +36 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/hints.pyi +26 -0
- erispulse-2.5.2.dev4/src/ErisPulse/Core/Bases/module.py +0 -118
- erispulse-2.5.2.dev4/src/ErisPulse/runtime/config_schema.py +0 -344
- erispulse-2.5.2.dev4/src/ErisPulse/runtime/config_schema.pyi +0 -136
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/.gitignore +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/LICENSE +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/README.md +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/base.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/base.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/cli.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/cli.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/create.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/init.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/init.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/install.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/install.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/language.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/language.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/list.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/list.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/list_remote.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/run.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/run.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/self_update.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/self_update.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/uninstall.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/commands/upgrade.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/console.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/console.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/en.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/en.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/ja.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/ja.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/ru.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/ru.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/zh_cn.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/zh_cn.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/zh_tw.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/i18n/locales/zh_tw.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/registry.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/registry.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/display.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/display.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/file_watcher.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/file_watcher.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/package_manager.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/CLI/utils/package_manager.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/client.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/client.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/errors.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/errors.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/kv_builder.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/kv_builder.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/manager.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/manager.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/router.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/router.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/storage.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/storage.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/websocket.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Bases/websocket.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/base.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/base.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/command.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/command.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/message.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/message.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/message_builder.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/message_builder.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/meta.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/meta.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/notice.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/notice.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/request.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/request.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/session_type.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/Event/session_type.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/adapter.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/adapter.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/client.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/client.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/config.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/config.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/constants.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/constants.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/en.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/ja.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/ru.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/zh_cn.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/i18n/locales/zh_tw.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/lifecycle.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/lifecycle.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/logger.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/logger.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/module.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/router.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/router.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/storage.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/Core/storage.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/__main__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/__main__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/adapter.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/adapter.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/bases/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/bases/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/bases/finder.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/bases/finder.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/module.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/finders/module.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/adapter.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/adapter.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/bases/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/bases/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/bases/loader.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/bases/loader.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/module.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/module.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/strategy.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/strategy.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/strict.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/loaders/strict.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/context.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/context.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/frame_config.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/runtime/frame_config.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/sdk.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/sdk.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/web_status/4xx.png +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/web_status/5xx.png +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/web_status/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/web_status/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.3}/src/ErisPulse/web_status/unknow.png +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 2.5.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 2.5.3
|
|
4
|
+
Summary: Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署
|
|
5
5
|
Project-URL: Homepage, https://github.com/ErisPulse/ErisPulse
|
|
6
6
|
Project-URL: Documentation, https://www.erisdev.com#docs
|
|
7
7
|
Project-URL: Repository, https://github.com/ErisPulse/ErisPulse
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ErisPulse"
|
|
7
|
-
version = "2.5.
|
|
8
|
-
description = "
|
|
7
|
+
version = "2.5.3"
|
|
8
|
+
description = "Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = { file = "LICENSE" }
|
|
@@ -105,6 +105,9 @@ project.root = "src"
|
|
|
105
105
|
[tool.hatch.build.targets.wheel]
|
|
106
106
|
packages = ["src/ErisPulse"]
|
|
107
107
|
|
|
108
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
109
|
+
"src/ErisPulse/py.typed" = "ErisPulse/py.typed"
|
|
110
|
+
|
|
108
111
|
[tool.hatch.build.targets.sdist]
|
|
109
112
|
include = [
|
|
110
113
|
"/src/ErisPulse",
|
|
@@ -62,8 +62,21 @@ dependencies = [
|
|
|
62
62
|
_MODULE_INIT = """from .Core import Main
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
|
-
_MODULE_CORE = """from
|
|
65
|
+
_MODULE_CORE = """from dataclasses import dataclass, field
|
|
66
|
+
from ErisPulse.Core.Bases import BaseModule
|
|
66
67
|
from ErisPulse.Core.Event import command, message, notice
|
|
68
|
+
from ErisPulse.runtime.config_schema import BaseConfig
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class {name}Config(BaseConfig):
|
|
73
|
+
\"\"\"{name} 模块配置\"\"\"
|
|
74
|
+
enabled: bool = field(
|
|
75
|
+
default=True,
|
|
76
|
+
metadata={{
|
|
77
|
+
\"description\": \"是否启用模块\",
|
|
78
|
+
}},
|
|
79
|
+
)
|
|
67
80
|
|
|
68
81
|
|
|
69
82
|
class Main(BaseModule):
|
|
@@ -73,16 +86,17 @@ class Main(BaseModule):
|
|
|
73
86
|
继承自BaseModule基类,实现了标准化的模块生命周期管理和事件处理
|
|
74
87
|
\"\"\"
|
|
75
88
|
|
|
89
|
+
ConfigClass = {name}Config
|
|
90
|
+
|
|
76
91
|
def __init__(self, sdk=None):
|
|
77
92
|
from ErisPulse import sdk as _sdk
|
|
78
93
|
self.sdk = _sdk if sdk is None else sdk
|
|
79
|
-
self.logger = self.sdk.logger.get_child("{name}")
|
|
94
|
+
self.logger = self.sdk.logger.get_child(\"{name}\")
|
|
80
95
|
self.storage = self.sdk.storage
|
|
81
96
|
self.adapter = self.sdk.adapter
|
|
82
97
|
self.client = self.sdk.client
|
|
83
98
|
|
|
84
|
-
self.logger.info("{name}
|
|
85
|
-
self.config = self._load_config()
|
|
99
|
+
self.logger.info(\"{name} 初始化完成\")
|
|
86
100
|
|
|
87
101
|
@staticmethod
|
|
88
102
|
def get_load_strategy():
|
|
@@ -101,7 +115,7 @@ class Main(BaseModule):
|
|
|
101
115
|
\"\"\"
|
|
102
116
|
await self._register_commands()
|
|
103
117
|
await self._register_message_handlers()
|
|
104
|
-
self.logger.info(f"模块已加载: {{event}}")
|
|
118
|
+
self.logger.info(f\"模块已加载: {{event}}\")
|
|
105
119
|
return True
|
|
106
120
|
|
|
107
121
|
async def on_unload(self, event: dict) -> bool:
|
|
@@ -111,29 +125,18 @@ class Main(BaseModule):
|
|
|
111
125
|
:param event: 事件内容
|
|
112
126
|
:return: 处理结果
|
|
113
127
|
\"\"\"
|
|
114
|
-
self.logger.info(f"模块已卸载: {{event}}")
|
|
128
|
+
self.logger.info(f\"模块已卸载: {{event}}\")
|
|
115
129
|
return True
|
|
116
130
|
|
|
117
|
-
def _load_config(self):
|
|
118
|
-
config = self.sdk.config.getConfig("{name}")
|
|
119
|
-
if not config:
|
|
120
|
-
default_config = {{
|
|
121
|
-
"enabled": True,
|
|
122
|
-
}}
|
|
123
|
-
self.sdk.config.setConfig("{name}", default_config)
|
|
124
|
-
self.logger.warning("未找到模块配置, 已创建默认配置到config.toml")
|
|
125
|
-
return default_config
|
|
126
|
-
return config
|
|
127
|
-
|
|
128
131
|
async def _register_commands(self):
|
|
129
|
-
@command("hello", help
|
|
132
|
+
@command(\"hello\", help=\"发送问候消息\")
|
|
130
133
|
async def hello_command(event):
|
|
131
|
-
await event.reply("Hello from {name}
|
|
134
|
+
await event.reply(\"Hello from {name}!\")
|
|
132
135
|
|
|
133
136
|
async def _register_message_handlers(self):
|
|
134
137
|
@message.on_private_message()
|
|
135
138
|
async def private_message_handler(event):
|
|
136
|
-
self.logger.info(f"收到私聊消息: {{event.get_text()}}")
|
|
139
|
+
self.logger.info(f\"收到私聊消息: {{event.get_text()}}\")
|
|
137
140
|
|
|
138
141
|
@message.on_group_message()
|
|
139
142
|
async def group_message_handler(event):
|
|
@@ -141,7 +144,7 @@ class Main(BaseModule):
|
|
|
141
144
|
|
|
142
145
|
@notice.on_friend_add()
|
|
143
146
|
async def friend_add_handler(event):
|
|
144
|
-
self.logger.info(f"新好友添加: {{event.get_user_nickname()}}")
|
|
147
|
+
self.logger.info(f\"新好友添加: {{event.get_user_nickname()}}\")
|
|
145
148
|
"""
|
|
146
149
|
|
|
147
150
|
_ADAPTER_PYPROJECT = """[project]
|
|
@@ -176,20 +179,29 @@ _ADAPTER_CORE = """import asyncio
|
|
|
176
179
|
import json
|
|
177
180
|
from dataclasses import dataclass, field
|
|
178
181
|
from ErisPulse.Core import BaseAdapter
|
|
179
|
-
from ErisPulse.runtime.config_schema import
|
|
182
|
+
from ErisPulse.runtime.config_schema import BaseConfig
|
|
180
183
|
from ErisPulse.Core import router
|
|
181
184
|
|
|
182
185
|
|
|
183
186
|
@dataclass
|
|
184
|
-
class {name}Config(
|
|
187
|
+
class {name}Config(BaseConfig):
|
|
185
188
|
\"\"\"{name} 适配器配置\"\"\"
|
|
186
189
|
endpoint: str = field(
|
|
187
190
|
default="https://api.example.com",
|
|
188
|
-
metadata={{
|
|
191
|
+
metadata={{
|
|
192
|
+
"description": {{"i18n": "adapter.{name}.endpoint", "default": "平台 API 地址"}},
|
|
193
|
+
"required": False,
|
|
194
|
+
"ui": {{"widget": "text", "group": "connection", "order": 1}},
|
|
195
|
+
}},
|
|
189
196
|
)
|
|
190
197
|
token: str = field(
|
|
191
198
|
default="",
|
|
192
|
-
metadata={{
|
|
199
|
+
metadata={{
|
|
200
|
+
"description": {{"i18n": "adapter.{name}.token", "default": "平台 Token"}},
|
|
201
|
+
"required": True,
|
|
202
|
+
"secret": True,
|
|
203
|
+
"ui": {{"widget": "password", "group": "basic", "order": 2}},
|
|
204
|
+
}},
|
|
193
205
|
)
|
|
194
206
|
|
|
195
207
|
|
|
@@ -284,7 +296,7 @@ class {name}(BaseAdapter):
|
|
|
284
296
|
|
|
285
297
|
async def start(self):
|
|
286
298
|
\"\"\"启动适配器\"\"\"
|
|
287
|
-
cfg = self.
|
|
299
|
+
cfg = self.cfg
|
|
288
300
|
self.logger.info(f"启动 {{cfg.endpoint}} 适配器")
|
|
289
301
|
|
|
290
302
|
router.register_websocket(
|
|
@@ -322,7 +334,7 @@ class {name}(BaseAdapter):
|
|
|
322
334
|
\"\"\"调用平台 API\"\"\"
|
|
323
335
|
from ErisPulse.Core import client
|
|
324
336
|
|
|
325
|
-
cfg = self.
|
|
337
|
+
cfg = self.cfg
|
|
326
338
|
headers = {{"Authorization": "Bearer " + cfg.token}}
|
|
327
339
|
url = cfg.endpoint + endpoint
|
|
328
340
|
|
|
@@ -532,7 +532,7 @@ class BaseAdapter(ABC):
|
|
|
532
532
|
4. 通过on装饰器注册事件处理器
|
|
533
533
|
5. 支持OneBot12协议的事件处理
|
|
534
534
|
6. 通过 ConfigClass / AccountConfigClass 声明配置类,框架自动管理配置
|
|
535
|
-
7. 通过 self.
|
|
535
|
+
7. 通过 self.cfg / self.accounts 访问类型安全的配置对象(实时读取)
|
|
536
536
|
8. 通过 self.emit_meta() 发送 meta 事件
|
|
537
537
|
9. 通过 self.make_response() / self.make_error() 构造标准化响应
|
|
538
538
|
{!--< /tips >!--}
|
|
@@ -672,10 +672,13 @@ class BaseAdapter(ABC):
|
|
|
672
672
|
self._config_instance = None
|
|
673
673
|
self._accounts_data = None
|
|
674
674
|
|
|
675
|
+
# 初始化时确保配置模板存在
|
|
675
676
|
if self.ConfigClass is not None:
|
|
676
|
-
self.
|
|
677
|
+
self._ensure_config_exists()
|
|
677
678
|
if self.AccountConfigClass is not None:
|
|
678
|
-
self.
|
|
679
|
+
self._ensure_accounts_exist()
|
|
680
|
+
# 填充 _accounts_data 以保持向后兼容(适配器可能覆写 _load_accounts)
|
|
681
|
+
self._accounts_data = self.accounts
|
|
679
682
|
|
|
680
683
|
@abstractmethod
|
|
681
684
|
async def call_api(self, endpoint: str, **params: Any) -> Any:
|
|
@@ -708,40 +711,115 @@ class BaseAdapter(ABC):
|
|
|
708
711
|
raise NotImplementedError("适配器必须实现shutdown方法")
|
|
709
712
|
|
|
710
713
|
@property
|
|
711
|
-
def
|
|
714
|
+
def cfg(self):
|
|
712
715
|
"""
|
|
713
|
-
|
|
716
|
+
类型安全的配置对象(实时读取)
|
|
717
|
+
|
|
718
|
+
每次访问都从配置存储读取最新值,确保用户修改配置后立即生效。
|
|
719
|
+
返回的 dataclass 实例是只读快照,修改它不会回写存储。
|
|
714
720
|
|
|
715
|
-
:return: AdapterConfig 实例
|
|
721
|
+
:return: AdapterConfig / BaseConfig 实例
|
|
716
722
|
:raises AttributeError: 未声明 ConfigClass 时抛出
|
|
723
|
+
|
|
724
|
+
{!--< tips >!--}
|
|
725
|
+
推荐使用 ``self.cfg`` 而非 ``self.config``,
|
|
726
|
+
后者已弃用且可能被子类属性覆盖产生冲突。
|
|
727
|
+
{!--< /tips >!--}
|
|
717
728
|
"""
|
|
718
|
-
if self.
|
|
729
|
+
if self.ConfigClass is None:
|
|
719
730
|
raise AttributeError(
|
|
720
731
|
"未声明 ConfigClass,请设置 MyAdapter.ConfigClass = MyConfig"
|
|
721
732
|
)
|
|
722
|
-
|
|
733
|
+
from ...runtime.config_schema import dict_to_dataclass
|
|
734
|
+
from ..config import config as config_mgr
|
|
735
|
+
|
|
736
|
+
data = config_mgr.getConfig(self._get_config_key())
|
|
737
|
+
if data is None:
|
|
738
|
+
# 配置不存在时生成默认模板后重试
|
|
739
|
+
self._ensure_config_exists()
|
|
740
|
+
data = config_mgr.getConfig(self._get_config_key()) or {}
|
|
741
|
+
return dict_to_dataclass(self.ConfigClass, data)
|
|
742
|
+
|
|
743
|
+
@cfg.setter
|
|
744
|
+
def cfg(self, value):
|
|
745
|
+
"""设置配置实例,同时同步写入配置存储(保证实时性)"""
|
|
746
|
+
self._config_instance = value
|
|
747
|
+
if value is not None:
|
|
748
|
+
from dataclasses import asdict
|
|
749
|
+
from ..config import config as config_mgr
|
|
750
|
+
|
|
751
|
+
try:
|
|
752
|
+
config_mgr.setConfig(self._get_config_key(), asdict(value))
|
|
753
|
+
except Exception:
|
|
754
|
+
pass
|
|
755
|
+
|
|
756
|
+
@property
|
|
757
|
+
def config(self):
|
|
758
|
+
"""
|
|
759
|
+
``self.cfg`` 的兼容别名
|
|
760
|
+
|
|
761
|
+
功能与 ``self.cfg`` 完全一致,推荐新代码使用 ``self.cfg``。
|
|
762
|
+
"""
|
|
763
|
+
return self.cfg
|
|
723
764
|
|
|
724
765
|
@config.setter
|
|
725
766
|
def config(self, value):
|
|
726
|
-
self.
|
|
767
|
+
self.cfg = value
|
|
727
768
|
|
|
728
769
|
@property
|
|
729
770
|
def accounts(self) -> dict:
|
|
730
771
|
"""
|
|
731
|
-
|
|
772
|
+
类型安全的账户配置字典(实时读取)
|
|
773
|
+
|
|
774
|
+
每次访问都从配置存储读取最新值,确保用户修改账户配置后立即生效。
|
|
732
775
|
|
|
733
|
-
:return: 账户配置字典
|
|
776
|
+
:return: 账户配置字典 {name: config_instance}
|
|
734
777
|
:raises AttributeError: 未声明 AccountConfigClass 时抛出
|
|
735
778
|
"""
|
|
736
|
-
if self.
|
|
779
|
+
if self.AccountConfigClass is None:
|
|
737
780
|
raise AttributeError(
|
|
738
781
|
"未声明 AccountConfigClass,请设置 MyAdapter.AccountConfigClass = MyBotConfig"
|
|
739
782
|
)
|
|
740
|
-
|
|
783
|
+
from ...runtime.config_schema import dict_to_dataclass, validate_config
|
|
784
|
+
from ..config import config as config_mgr
|
|
785
|
+
|
|
786
|
+
key = f"{self._get_config_key()}.accounts"
|
|
787
|
+
data = config_mgr.getConfig(key)
|
|
788
|
+
if data is None:
|
|
789
|
+
# 配置不存在时生成默认账户模板后重试
|
|
790
|
+
self._ensure_accounts_exist()
|
|
791
|
+
data = config_mgr.getConfig(key) or {}
|
|
792
|
+
|
|
793
|
+
accounts = {}
|
|
794
|
+
for name, account_data in data.items():
|
|
795
|
+
if not isinstance(account_data, dict):
|
|
796
|
+
continue
|
|
797
|
+
instance = dict_to_dataclass(self.AccountConfigClass, account_data)
|
|
798
|
+
errors = validate_config(instance)
|
|
799
|
+
if errors:
|
|
800
|
+
self._get_logger().error(
|
|
801
|
+
f"账户 {name} 配置校验失败: {', '.join(errors)}"
|
|
802
|
+
)
|
|
803
|
+
continue
|
|
804
|
+
accounts[name] = instance
|
|
805
|
+
|
|
806
|
+
return accounts
|
|
741
807
|
|
|
742
808
|
@accounts.setter
|
|
743
809
|
def accounts(self, value):
|
|
810
|
+
"""设置账户配置字典,同时同步写入配置存储"""
|
|
744
811
|
self._accounts_data = value
|
|
812
|
+
if value is not None:
|
|
813
|
+
from dataclasses import asdict
|
|
814
|
+
from ..config import config as config_mgr
|
|
815
|
+
|
|
816
|
+
key = f"{self._get_config_key()}.accounts"
|
|
817
|
+
try:
|
|
818
|
+
config_mgr.setConfig(
|
|
819
|
+
key, {name: asdict(cfg) for name, cfg in value.items()}
|
|
820
|
+
)
|
|
821
|
+
except Exception:
|
|
822
|
+
pass
|
|
745
823
|
|
|
746
824
|
@property
|
|
747
825
|
def enabled_accounts(self) -> dict:
|
|
@@ -782,20 +860,18 @@ class BaseAdapter(ABC):
|
|
|
782
860
|
|
|
783
861
|
return logging.getLogger(self.__class__.__name__)
|
|
784
862
|
|
|
785
|
-
def
|
|
863
|
+
def _ensure_config_exists(self):
|
|
786
864
|
"""
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
1. 读取 {ConfigKey} 键
|
|
790
|
-
2. 如果不存在,用 dataclass 默认值生成模板并写入
|
|
791
|
-
3. 用 dict_to_dataclass() 转为类型安全的实例
|
|
865
|
+
确保全局配置模板存在,不存在则生成默认配置
|
|
792
866
|
|
|
793
|
-
|
|
867
|
+
{!--< internal-use >!--}
|
|
868
|
+
{!--< /internal-use >!--}
|
|
794
869
|
"""
|
|
870
|
+
if self.ConfigClass is None:
|
|
871
|
+
return
|
|
795
872
|
from ...runtime.config_schema import (
|
|
796
873
|
dataclass_to_defaults_dict,
|
|
797
874
|
dataclass_to_toml_with_comments,
|
|
798
|
-
dict_to_dataclass,
|
|
799
875
|
)
|
|
800
876
|
from ..config import config as config_mgr
|
|
801
877
|
|
|
@@ -808,24 +884,16 @@ class BaseAdapter(ABC):
|
|
|
808
884
|
config_mgr.setConfig(key, data, immediate=True)
|
|
809
885
|
self._get_logger().info(f"已生成 {key} 默认配置模板:\n{toml_str}")
|
|
810
886
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
def _load_accounts(self) -> dict:
|
|
887
|
+
def _ensure_accounts_exist(self):
|
|
814
888
|
"""
|
|
815
|
-
|
|
889
|
+
确保多账户配置模板存在,不存在则生成默认账户配置
|
|
816
890
|
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
3. 对每个账户做 validate_config() 校验
|
|
820
|
-
4. 跳过校验失败的账户并记录错误
|
|
821
|
-
|
|
822
|
-
:return: 账户配置字典 {name: config_instance}
|
|
891
|
+
{!--< internal-use >!--}
|
|
892
|
+
{!--< /internal-use >!--}
|
|
823
893
|
"""
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
validate_config,
|
|
828
|
-
)
|
|
894
|
+
if self.AccountConfigClass is None:
|
|
895
|
+
return
|
|
896
|
+
from ...runtime.config_schema import dataclass_to_defaults_dict
|
|
829
897
|
from ..config import config as config_mgr
|
|
830
898
|
|
|
831
899
|
key = f"{self._get_config_key()}.accounts"
|
|
@@ -837,21 +905,6 @@ class BaseAdapter(ABC):
|
|
|
837
905
|
config_mgr.setConfig(key, data, immediate=True)
|
|
838
906
|
self._get_logger().info(f"已生成 {key} 默认账户配置")
|
|
839
907
|
|
|
840
|
-
accounts = {}
|
|
841
|
-
for name, account_data in data.items():
|
|
842
|
-
if not isinstance(account_data, dict):
|
|
843
|
-
continue
|
|
844
|
-
instance = dict_to_dataclass(self.AccountConfigClass, account_data)
|
|
845
|
-
errors = validate_config(instance)
|
|
846
|
-
if errors:
|
|
847
|
-
self._get_logger().error(
|
|
848
|
-
f"账户 {name} 配置校验失败: {', '.join(errors)}"
|
|
849
|
-
)
|
|
850
|
-
continue
|
|
851
|
-
accounts[name] = instance
|
|
852
|
-
|
|
853
|
-
return accounts
|
|
854
|
-
|
|
855
908
|
def _resolve_account(self, account_id: str | None = None) -> tuple:
|
|
856
909
|
"""
|
|
857
910
|
解析目标账户
|
|
@@ -869,18 +922,21 @@ class BaseAdapter(ABC):
|
|
|
869
922
|
"""
|
|
870
923
|
from dataclasses import fields as dc_fields
|
|
871
924
|
|
|
925
|
+
# 单账户适配器(未声明 AccountConfigClass 或未填充 _accounts_data)
|
|
872
926
|
if self._accounts_data is None:
|
|
873
|
-
|
|
927
|
+
return None, None
|
|
928
|
+
|
|
929
|
+
accounts = self._accounts_data
|
|
874
930
|
|
|
875
931
|
if account_id is not None:
|
|
876
|
-
if account_id in
|
|
877
|
-
return account_id,
|
|
932
|
+
if account_id in accounts:
|
|
933
|
+
return account_id, accounts[account_id]
|
|
878
934
|
|
|
879
|
-
for name, cfg in
|
|
935
|
+
for name, cfg in accounts.items():
|
|
880
936
|
if hasattr(cfg, "bot_id") and cfg.bot_id == account_id:
|
|
881
937
|
return name, cfg
|
|
882
938
|
|
|
883
|
-
for name, cfg in
|
|
939
|
+
for name, cfg in accounts.items():
|
|
884
940
|
for f in dc_fields(cfg):
|
|
885
941
|
if f.name in ("enabled", "name"):
|
|
886
942
|
continue
|
|
@@ -888,7 +944,7 @@ class BaseAdapter(ABC):
|
|
|
888
944
|
if isinstance(val, str) and val == account_id:
|
|
889
945
|
return name, cfg
|
|
890
946
|
|
|
891
|
-
for name, cfg in
|
|
947
|
+
for name, cfg in accounts.items():
|
|
892
948
|
if cfg.enabled:
|
|
893
949
|
return name, cfg
|
|
894
950
|
|
|
@@ -315,7 +315,7 @@ class BaseAdapter(ABC):
|
|
|
315
315
|
4. 通过on装饰器注册事件处理器
|
|
316
316
|
5. 支持OneBot12协议的事件处理
|
|
317
317
|
6. 通过 ConfigClass / AccountConfigClass 声明配置类,框架自动管理配置
|
|
318
|
-
7. 通过 self.
|
|
318
|
+
7. 通过 self.cfg / self.accounts 访问类型安全的配置对象(实时读取)
|
|
319
319
|
8. 通过 self.emit_meta() 发送 meta 事件
|
|
320
320
|
9. 通过 self.make_response() / self.make_error() 构造标准化响应
|
|
321
321
|
{!--< /tips >!--}
|
|
@@ -350,25 +350,50 @@ class BaseAdapter(ABC):
|
|
|
350
350
|
:raises NotImplementedError: 必须由子类实现
|
|
351
351
|
"""
|
|
352
352
|
...
|
|
353
|
-
def
|
|
353
|
+
def cfg(self: object) -> ...:
|
|
354
354
|
"""
|
|
355
|
-
|
|
355
|
+
类型安全的配置对象(实时读取)
|
|
356
|
+
|
|
357
|
+
每次访问都从配置存储读取最新值,确保用户修改配置后立即生效。
|
|
358
|
+
返回的 dataclass 实例是只读快照,修改它不会回写存储。
|
|
356
359
|
|
|
357
|
-
:return: AdapterConfig 实例
|
|
360
|
+
:return: AdapterConfig / BaseConfig 实例
|
|
358
361
|
:raises AttributeError: 未声明 ConfigClass 时抛出
|
|
362
|
+
|
|
363
|
+
{!--< tips >!--}
|
|
364
|
+
推荐使用 ``self.cfg`` 而非 ``self.config``,
|
|
365
|
+
后者已弃用且可能被子类属性覆盖产生冲突。
|
|
366
|
+
{!--< /tips >!--}
|
|
367
|
+
"""
|
|
368
|
+
...
|
|
369
|
+
def cfg(self: object, value: ...) -> ...:
|
|
370
|
+
"""
|
|
371
|
+
设置配置实例,同时同步写入配置存储(保证实时性)
|
|
372
|
+
"""
|
|
373
|
+
...
|
|
374
|
+
def config(self: object) -> ...:
|
|
375
|
+
"""
|
|
376
|
+
``self.cfg`` 的兼容别名
|
|
377
|
+
|
|
378
|
+
功能与 ``self.cfg`` 完全一致,推荐新代码使用 ``self.cfg``。
|
|
359
379
|
"""
|
|
360
380
|
...
|
|
361
381
|
def config(self: object, value: ...) -> ...:
|
|
362
382
|
...
|
|
363
383
|
def accounts(self: object) -> dict:
|
|
364
384
|
"""
|
|
365
|
-
|
|
385
|
+
类型安全的账户配置字典(实时读取)
|
|
386
|
+
|
|
387
|
+
每次访问都从配置存储读取最新值,确保用户修改账户配置后立即生效。
|
|
366
388
|
|
|
367
|
-
:return: 账户配置字典
|
|
389
|
+
:return: 账户配置字典 {name: config_instance}
|
|
368
390
|
:raises AttributeError: 未声明 AccountConfigClass 时抛出
|
|
369
391
|
"""
|
|
370
392
|
...
|
|
371
393
|
def accounts(self: object, value: ...) -> ...:
|
|
394
|
+
"""
|
|
395
|
+
设置账户配置字典,同时同步写入配置存储
|
|
396
|
+
"""
|
|
372
397
|
...
|
|
373
398
|
def enabled_accounts(self: object) -> dict:
|
|
374
399
|
"""
|
|
@@ -396,29 +421,6 @@ class BaseAdapter(ABC):
|
|
|
396
421
|
获取 logger,兼容 sdk 未注入的场景
|
|
397
422
|
"""
|
|
398
423
|
...
|
|
399
|
-
def _load_config(self: object) -> ...:
|
|
400
|
-
"""
|
|
401
|
-
从 TOML 加载全局配置
|
|
402
|
-
|
|
403
|
-
1. 读取 {ConfigKey} 键
|
|
404
|
-
2. 如果不存在,用 dataclass 默认值生成模板并写入
|
|
405
|
-
3. 用 dict_to_dataclass() 转为类型安全的实例
|
|
406
|
-
|
|
407
|
-
:return: AdapterConfig 实例
|
|
408
|
-
"""
|
|
409
|
-
...
|
|
410
|
-
def _load_accounts(self: object) -> dict:
|
|
411
|
-
"""
|
|
412
|
-
从 TOML 加载多账户配置
|
|
413
|
-
|
|
414
|
-
1. 读取 {ConfigKey}.accounts 键
|
|
415
|
-
2. 如果不存在,创建包含一个 default 账户的模板
|
|
416
|
-
3. 对每个账户做 validate_config() 校验
|
|
417
|
-
4. 跳过校验失败的账户并记录错误
|
|
418
|
-
|
|
419
|
-
:return: 账户配置字典 {name: config_instance}
|
|
420
|
-
"""
|
|
421
|
-
...
|
|
422
424
|
def _resolve_account(self: object, account_id: str | None = ...) -> tuple:
|
|
423
425
|
"""
|
|
424
426
|
解析目标账户
|