simple-module-settings 0.0.1__tar.gz → 0.0.2__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.
Files changed (57) hide show
  1. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/PKG-INFO +5 -4
  2. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/pyproject.toml +7 -6
  3. simple_module_settings-0.0.2/settings/cli.py +61 -0
  4. simple_module_settings-0.0.1/settings/cli.py +0 -78
  5. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/.gitignore +0 -0
  6. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/LICENSE +0 -0
  7. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/README.md +0 -0
  8. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/package.json +0 -0
  9. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/__init__.py +0 -0
  10. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/_module_settings.py +0 -0
  11. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/constants.py +0 -0
  12. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/contracts/__init__.py +0 -0
  13. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/contracts/accessor.py +0 -0
  14. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/contracts/events.py +0 -0
  15. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/contracts/registry.py +0 -0
  16. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/contracts/schemas.py +0 -0
  17. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/deps.py +0 -0
  18. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/endpoints/__init__.py +0 -0
  19. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/endpoints/api.py +0 -0
  20. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/endpoints/module_api.py +0 -0
  21. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/endpoints/views.py +0 -0
  22. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/env_vars.py +0 -0
  23. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/hydrate.py +0 -0
  24. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/locales/en.json +0 -0
  25. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/models.py +0 -0
  26. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/module.py +0 -0
  27. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/module_registry.py +0 -0
  28. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/Browse.tsx +0 -0
  29. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/Create.tsx +0 -0
  30. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/Edit.tsx +0 -0
  31. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/ModulesEdit.tsx +0 -0
  32. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/components/FieldInput.tsx +0 -0
  33. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/components/ModuleForm.tsx +0 -0
  34. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/components/ValueInput.tsx +0 -0
  35. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/pages/routes.ts +0 -0
  36. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/py.typed +0 -0
  37. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/registration.py +0 -0
  38. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/reload.py +0 -0
  39. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/service.py +0 -0
  40. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/services.py +0 -0
  41. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/settings.py +0 -0
  42. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/settings/store.py +0 -0
  43. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_cli_import.py +0 -0
  44. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_hydrate.py +0 -0
  45. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_module_api.py +0 -0
  46. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_module_registry.py +0 -0
  47. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_module_settings.py +0 -0
  48. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_registration.py +0 -0
  49. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_reload.py +0 -0
  50. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_settings_accessor.py +0 -0
  51. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_settings_api.py +0 -0
  52. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_settings_events.py +0 -0
  53. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_settings_module.py +0 -0
  54. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_settings_schemas.py +0 -0
  55. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_settings_service.py +0 -0
  56. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tests/test_store.py +0 -0
  57. {simple_module_settings-0.0.1 → simple_module_settings-0.0.2}/tsconfig.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simple_module_settings
3
- Version: 0.0.1
3
+ Version: 0.0.2
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.1
25
- Requires-Dist: simple-module-db==0.0.1
26
- Requires-Dist: simple-module-hosting==0.0.1
24
+ Requires-Dist: simple-module-core==0.0.2
25
+ Requires-Dist: simple-module-db==0.0.2
26
+ Requires-Dist: simple-module-hosting==0.0.2
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.1"
3
+ version = "0.0.2"
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.1",
25
- "simple_module_db==0.0.1",
26
- "simple_module_hosting==0.0.1",
24
+ "simple_module_core==0.0.2",
25
+ "simple_module_db==0.0.2",
26
+ "simple_module_hosting==0.0.2",
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.scripts]
33
- sm-settings = "settings.cli:main"
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())