simple-module-settings 0.0.1__tar.gz → 0.0.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.
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/.gitignore +4 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/PKG-INFO +5 -4
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/pyproject.toml +7 -6
- simple_module_settings-0.0.3/settings/cli.py +61 -0
- simple_module_settings-0.0.1/settings/cli.py +0 -78
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/LICENSE +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/README.md +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/package.json +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/__init__.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/_module_settings.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/constants.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/__init__.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/accessor.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/events.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/registry.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/schemas.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/deps.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/endpoints/__init__.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/endpoints/api.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/endpoints/module_api.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/endpoints/views.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/env_vars.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/hydrate.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/locales/en.json +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/models.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/module.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/module_registry.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/Browse.tsx +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/Create.tsx +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/Edit.tsx +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/ModulesEdit.tsx +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/components/FieldInput.tsx +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/components/ModuleForm.tsx +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/components/ValueInput.tsx +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/routes.ts +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/py.typed +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/registration.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/reload.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/service.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/services.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/settings.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/store.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_cli_import.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_hydrate.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_module_api.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_module_registry.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_module_settings.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_registration.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_reload.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_accessor.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_api.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_events.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_module.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_schemas.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_service.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_store.py +0 -0
- {simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tsconfig.json +0 -0
|
@@ -36,6 +36,10 @@ uploads/
|
|
|
36
36
|
# Vite
|
|
37
37
|
host/static/dist/
|
|
38
38
|
|
|
39
|
+
# VitePress (docs)
|
|
40
|
+
docs/.vitepress/cache/
|
|
41
|
+
docs/.vitepress/dist/
|
|
42
|
+
|
|
39
43
|
# Auto-generated frontend module manifest (regenerated by the host at boot
|
|
40
44
|
# or via `make gen-pages`).
|
|
41
45
|
host/client_app/modules.manifest.json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simple_module_settings
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Runtime settings UI — modules plug their own settings panels into a shared admin view
|
|
5
5
|
Project-URL: Homepage, https://github.com/antosubash/simple_module_python
|
|
6
6
|
Project-URL: Repository, https://github.com/antosubash/simple_module_python
|
|
@@ -21,9 +21,10 @@ Classifier: Topic :: Internet :: WWW/HTTP
|
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
22
22
|
Classifier: Typing :: Typed
|
|
23
23
|
Requires-Python: >=3.12
|
|
24
|
-
Requires-Dist: simple-module-core==0.0.
|
|
25
|
-
Requires-Dist: simple-module-db==0.0.
|
|
26
|
-
Requires-Dist: simple-module-hosting==0.0.
|
|
24
|
+
Requires-Dist: simple-module-core==0.0.3
|
|
25
|
+
Requires-Dist: simple-module-db==0.0.3
|
|
26
|
+
Requires-Dist: simple-module-hosting==0.0.3
|
|
27
|
+
Requires-Dist: typer>=0.12
|
|
27
28
|
Description-Content-Type: text/markdown
|
|
28
29
|
|
|
29
30
|
# simple_module_settings
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "simple_module_settings"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.3"
|
|
4
4
|
description = "Runtime settings UI — modules plug their own settings panels into a shared admin view"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -21,16 +21,17 @@ classifiers = [
|
|
|
21
21
|
"Typing :: Typed",
|
|
22
22
|
]
|
|
23
23
|
dependencies = [
|
|
24
|
-
"simple_module_core==0.0.
|
|
25
|
-
"simple_module_db==0.0.
|
|
26
|
-
"simple_module_hosting==0.0.
|
|
24
|
+
"simple_module_core==0.0.3",
|
|
25
|
+
"simple_module_db==0.0.3",
|
|
26
|
+
"simple_module_hosting==0.0.3",
|
|
27
|
+
"typer>=0.12",
|
|
27
28
|
]
|
|
28
29
|
|
|
29
30
|
[project.entry-points.simple_module]
|
|
30
31
|
settings = "settings.module:SettingsModule"
|
|
31
32
|
|
|
32
|
-
[project.
|
|
33
|
-
|
|
33
|
+
[project.entry-points."simple_module_cli.cli_plugins"]
|
|
34
|
+
settings = "settings.cli:app"
|
|
34
35
|
|
|
35
36
|
[project.urls]
|
|
36
37
|
Homepage = "https://github.com/antosubash/simple_module_python"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""``sm settings`` plugin — currently only ``import-from-env``.
|
|
2
|
+
|
|
3
|
+
One-shot migration: walks every registered module's BaseSettings and
|
|
4
|
+
writes a SYSTEM-scoped override for each ``SM_<PREFIX>_<FIELD>`` env
|
|
5
|
+
var that is set.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
import typer
|
|
14
|
+
from fastapi import FastAPI
|
|
15
|
+
|
|
16
|
+
from settings.constants import MODULE_PACKAGE
|
|
17
|
+
from settings.env_vars import env_prefix_for
|
|
18
|
+
from settings.hydrate import value_type_for_field
|
|
19
|
+
from settings.store import SettingsStore
|
|
20
|
+
|
|
21
|
+
app = typer.Typer(help="Settings module administration.", no_args_is_help=True)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
async def import_from_env_impl(app_inst: FastAPI, store: SettingsStore) -> int:
|
|
25
|
+
"""Write a SYSTEM override for every ``SM_<PREFIX>_<FIELD>`` env var set."""
|
|
26
|
+
registry = getattr(app_inst.state, MODULE_PACKAGE).module_registry
|
|
27
|
+
count = 0
|
|
28
|
+
for package, cls in registry.items():
|
|
29
|
+
prefix = env_prefix_for(package)
|
|
30
|
+
for field_name in cls.model_fields:
|
|
31
|
+
raw = os.environ.get(f"{prefix}{field_name.upper()}")
|
|
32
|
+
if raw is None:
|
|
33
|
+
continue
|
|
34
|
+
vtype = value_type_for_field(cls, field_name)
|
|
35
|
+
await store.set_override(package, field_name, raw, vtype)
|
|
36
|
+
count += 1
|
|
37
|
+
return count
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@app.command("import-from-env")
|
|
41
|
+
def import_from_env() -> None:
|
|
42
|
+
"""Write SYSTEM overrides for every SM_<PREFIX>_<FIELD> env var set."""
|
|
43
|
+
from simple_module_hosting.app_builder import create_app
|
|
44
|
+
from simple_module_hosting.settings import Settings
|
|
45
|
+
|
|
46
|
+
from settings.service import SettingService
|
|
47
|
+
|
|
48
|
+
fastapi_app = create_app(Settings())
|
|
49
|
+
|
|
50
|
+
async def run() -> int:
|
|
51
|
+
async with (
|
|
52
|
+
fastapi_app.router.lifespan_context(fastapi_app),
|
|
53
|
+
fastapi_app.state.sm.db.session_factory() as session,
|
|
54
|
+
):
|
|
55
|
+
store = SettingsStore(SettingService(session))
|
|
56
|
+
n = await import_from_env_impl(fastapi_app, store)
|
|
57
|
+
await session.commit()
|
|
58
|
+
typer.echo(f"Imported {n} override(s) from environment.")
|
|
59
|
+
return 0
|
|
60
|
+
|
|
61
|
+
raise typer.Exit(code=asyncio.run(run()))
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"""``sm-settings`` CLI — currently only ``import-from-env``.
|
|
2
|
-
|
|
3
|
-
One-shot migration: walks every registered module's ``BaseSettings`` and,
|
|
4
|
-
for each field whose legacy ``SM_<PREFIX>_<FIELD>`` env var is set, writes
|
|
5
|
-
a SYSTEM-scoped override into the Settings store.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import asyncio
|
|
11
|
-
import os
|
|
12
|
-
import sys
|
|
13
|
-
|
|
14
|
-
from fastapi import FastAPI
|
|
15
|
-
|
|
16
|
-
from settings.constants import MODULE_PACKAGE
|
|
17
|
-
from settings.env_vars import env_prefix_for
|
|
18
|
-
from settings.hydrate import value_type_for_field
|
|
19
|
-
from settings.store import SettingsStore
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
async def import_from_env_impl(app: FastAPI, store: SettingsStore) -> int:
|
|
23
|
-
"""Write a SYSTEM override for every ``SM_<PREFIX>_<FIELD>`` env var set.
|
|
24
|
-
|
|
25
|
-
Returns the count of overrides written. Env vars that don't match a
|
|
26
|
-
registered field are ignored.
|
|
27
|
-
"""
|
|
28
|
-
registry = getattr(app.state, MODULE_PACKAGE).module_registry
|
|
29
|
-
count = 0
|
|
30
|
-
for package, cls in registry.items():
|
|
31
|
-
prefix = env_prefix_for(package)
|
|
32
|
-
for field_name in cls.model_fields:
|
|
33
|
-
raw = os.environ.get(f"{prefix}{field_name.upper()}")
|
|
34
|
-
if raw is None:
|
|
35
|
-
continue
|
|
36
|
-
vtype = value_type_for_field(cls, field_name)
|
|
37
|
-
await store.set_override(package, field_name, raw, vtype)
|
|
38
|
-
count += 1
|
|
39
|
-
return count
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def main() -> int:
|
|
43
|
-
"""Console-script entry point for ``sm-settings``.
|
|
44
|
-
|
|
45
|
-
Supports a single subcommand: ``import-from-env``.
|
|
46
|
-
"""
|
|
47
|
-
argv = sys.argv[1:]
|
|
48
|
-
if not argv or argv[0] in ("-h", "--help"):
|
|
49
|
-
print("Usage: sm-settings import-from-env")
|
|
50
|
-
return 0 if argv else 1
|
|
51
|
-
if argv[0] != "import-from-env":
|
|
52
|
-
print(f"Unknown command: {argv[0]}", file=sys.stderr)
|
|
53
|
-
print("Usage: sm-settings import-from-env", file=sys.stderr)
|
|
54
|
-
return 2
|
|
55
|
-
|
|
56
|
-
from simple_module_hosting.app_builder import create_app
|
|
57
|
-
from simple_module_hosting.settings import Settings
|
|
58
|
-
|
|
59
|
-
from settings.service import SettingService
|
|
60
|
-
|
|
61
|
-
app = create_app(Settings())
|
|
62
|
-
|
|
63
|
-
async def run() -> int:
|
|
64
|
-
async with (
|
|
65
|
-
app.router.lifespan_context(app),
|
|
66
|
-
app.state.sm.db.session_factory() as session,
|
|
67
|
-
):
|
|
68
|
-
store = SettingsStore(SettingService(session))
|
|
69
|
-
n = await import_from_env_impl(app, store)
|
|
70
|
-
await session.commit()
|
|
71
|
-
print(f"Imported {n} override(s) from environment.")
|
|
72
|
-
return 0
|
|
73
|
-
|
|
74
|
-
return asyncio.run(run())
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if __name__ == "__main__":
|
|
78
|
-
sys.exit(main())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/__init__.py
RENAMED
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/accessor.py
RENAMED
|
File without changes
|
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/contracts/registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/endpoints/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/endpoints/module_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/settings/pages/ModulesEdit.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_accessor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_schemas.py
RENAMED
|
File without changes
|
{simple_module_settings-0.0.1 → simple_module_settings-0.0.3}/tests/test_settings_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|