pz-cli 5.0.0__py3-none-any.whl
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.
- pz_cli-5.0.0.dist-info/METADATA +51 -0
- pz_cli-5.0.0.dist-info/RECORD +399 -0
- pz_cli-5.0.0.dist-info/WHEEL +4 -0
- pz_cli-5.0.0.dist-info/entry_points.txt +5 -0
- pz_core/__init__.py +64 -0
- pz_core/__main__.py +7 -0
- pz_core/app.py +45 -0
- pz_core/assembly/__init__.py +17 -0
- pz_core/assembly/app_discovery.py +1240 -0
- pz_core/assembly/apps/__init__.py +25 -0
- pz_core/assembly/apps/compiler.py +824 -0
- pz_core/assembly/apps/providers.py +188 -0
- pz_core/assembly/cli/__init__.py +9 -0
- pz_core/assembly/cli/compiler.py +166 -0
- pz_core/assembly/diagnostics/__init__.py +21 -0
- pz_core/assembly/diagnostics/checks.py +257 -0
- pz_core/assembly/diagnostics/dev_sources.py +569 -0
- pz_core/assembly/events/__init__.py +5 -0
- pz_core/assembly/events/compiler.py +219 -0
- pz_core/assembly/extensions/__init__.py +5 -0
- pz_core/assembly/extensions/compiler.py +696 -0
- pz_core/assembly/infra/__init__.py +6 -0
- pz_core/assembly/infra/compiler.py +272 -0
- pz_core/assembly/lifecycle/__init__.py +5 -0
- pz_core/assembly/lifecycle/compiler.py +95 -0
- pz_core/assembly/middlewares/__init__.py +19 -0
- pz_core/assembly/middlewares/compiler.py +508 -0
- pz_core/assembly/project/__init__.py +7 -0
- pz_core/assembly/project/compiler.py +9 -0
- pz_core/assembly/project/context.py +17 -0
- pz_core/assembly/project/discovery.py +227 -0
- pz_core/assembly/resources/__init__.py +19 -0
- pz_core/assembly/resources/compiler.py +310 -0
- pz_core/assembly/resources/settings.py +129 -0
- pz_core/assembly/routes/__init__.py +7 -0
- pz_core/assembly/routes/compiler.py +400 -0
- pz_core/assembly/runtime_manifests/__init__.py +13 -0
- pz_core/assembly/runtime_manifests/compiler.py +159 -0
- pz_core/assembly/settings/__init__.py +17 -0
- pz_core/assembly/settings/compiler.py +786 -0
- pz_core/assembly/settings/host_project_overrides.py +82 -0
- pz_core/assembly/settings/host_runtime_endpoint.py +207 -0
- pz_core/authoring/__init__.py +79 -0
- pz_core/authoring/app_init_service.py +946 -0
- pz_core/authoring/app_versions.py +814 -0
- pz_core/authoring/cli.py +192 -0
- pz_core/authoring/commands.py +1810 -0
- pz_core/authoring/conflicts.py +180 -0
- pz_core/authoring/dev_bindings.py +916 -0
- pz_core/authoring/dev_git.py +1087 -0
- pz_core/authoring/dev_import.py +1061 -0
- pz_core/authoring/dev_manifest.py +522 -0
- pz_core/authoring/dev_sources.py +1638 -0
- pz_core/authoring/env_cli.py +454 -0
- pz_core/authoring/files.py +109 -0
- pz_core/authoring/ide_projection.py +1129 -0
- pz_core/authoring/naming.py +58 -0
- pz_core/authoring/official_dev_sources.py +432 -0
- pz_core/authoring/official_sources.json +156 -0
- pz_core/authoring/orchestration_service.py +558 -0
- pz_core/authoring/project_default.jsonc +53 -0
- pz_core/authoring/project_defaults.py +88 -0
- pz_core/authoring/project_metadata_service.py +199 -0
- pz_core/authoring/project_settings_checks.py +51 -0
- pz_core/authoring/project_settings_cli.py +299 -0
- pz_core/authoring/project_settings_service.py +1700 -0
- pz_core/authoring/project_state.py +399 -0
- pz_core/authoring/publish_git.py +423 -0
- pz_core/authoring/publish_lock.py +188 -0
- pz_core/authoring/publish_source.py +195 -0
- pz_core/authoring/release.py +1382 -0
- pz_core/authoring/repo_keys.py +29 -0
- pz_core/authoring/root_cli.py +28 -0
- pz_core/authoring/scaffold_service.py +325 -0
- pz_core/authoring/sync_service.py +787 -0
- pz_core/authoring/templates/app/__init__.py +1 -0
- pz_core/authoring/templates/app/api.py +25 -0
- pz_core/authoring/templates/app/apps.py +31 -0
- pz_core/authoring/templates/app/auth_package_init.py +14 -0
- pz_core/authoring/templates/app/auth_readme.py +29 -0
- pz_core/authoring/templates/app/configs_package_init.py +14 -0
- pz_core/authoring/templates/app/default_env.py +18 -0
- pz_core/authoring/templates/app/default_jsonc.py +25 -0
- pz_core/authoring/templates/app/locales_readme.py +25 -0
- pz_core/authoring/templates/app/migrations_readme.py +19 -0
- pz_core/authoring/templates/app/models.py +14 -0
- pz_core/authoring/templates/app/package_init.py +8 -0
- pz_core/authoring/templates/app/pages_base.py +161 -0
- pz_core/authoring/templates/app/pages_readme.py +25 -0
- pz_core/authoring/templates/app/public.py +31 -0
- pz_core/authoring/templates/app/pyproject.py +77 -0
- pz_core/authoring/templates/app/readme.py +74 -0
- pz_core/authoring/templates/app/settings.py +46 -0
- pz_core/authoring/templates/app/static_app_js.py +24 -0
- pz_core/authoring/templates/app/static_readme.py +31 -0
- pz_core/authoring/templates/app/template_config_page.py +23 -0
- pz_core/authoring/templates/app/template_index_html.py +28 -0
- pz_core/authoring/templates/app/templates_readme.py +32 -0
- pz_core/authoring/templates/app/urls.py +36 -0
- pz_core/authoring/templates/app/views.py +36 -0
- pz_core/authoring/templates/project/__init__.py +1 -0
- pz_core/authoring/templates/project/agents.py +51 -0
- pz_core/authoring/templates/project/apps_container_readme.py +37 -0
- pz_core/authoring/templates/project/main_py.py +59 -0
- pz_core/authoring/templates/project/project_env.py +19 -0
- pz_core/authoring/templates/project/pyproject.py +26 -0
- pz_core/authoring/templates/project/pz_env_env.py +65 -0
- pz_core/authoring/templates/project/pz_env_jsonc.py +69 -0
- pz_core/authoring/templates/project/pz_jsonc.py +12 -0
- pz_core/authoring/templates/project/readme.py +94 -0
- pz_core/authoring/templates/project/root_gitkeep.py +8 -0
- pz_core/authoring/templates/shared/__init__.py +5 -0
- pz_core/authoring/templates/shared/text.py +10 -0
- pz_core/authoring/venv_service.py +87 -0
- pz_core/authoring/workspace.py +167 -0
- pz_core/cli.py +291 -0
- pz_core/cli_options.py +74 -0
- pz_core/core/__init__.py +3 -0
- pz_core/core/errors/__init__.py +5 -0
- pz_core/core/errors/models.py +117 -0
- pz_core/core/events/__init__.py +5 -0
- pz_core/core/events/registry.py +54 -0
- pz_core/core/extensions/__init__.py +51 -0
- pz_core/core/extensions/registry.py +790 -0
- pz_core/core/health/__init__.py +6 -0
- pz_core/core/health/contracts.py +10 -0
- pz_core/core/middlewares/__init__.py +6 -0
- pz_core/core/middlewares/models.py +24 -0
- pz_core/core/routing/__init__.py +5 -0
- pz_core/core/routing/models.py +21 -0
- pz_core/core/settings_contracts.py +25 -0
- pz_core/docs/README.md +20 -0
- pz_core/docs/distribution-README.md +438 -0
- pz_core/docs/pz/345/221/275/344/273/244/346/200/273/350/247/210.md +1011 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/00-pz/346/236/266/346/236/204/346/200/273/347/272/262.md +240 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/01-/347/233/256/345/275/225/344/270/216/345/210/206/345/261/202/350/247/204/350/214/203.md +216 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/02-/345/214/205/344/270/216/345/210/206/345/217/221/350/247/204/350/214/203.md +403 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/03-App/346/234/200/345/260/217/345/255/220/345/214/205/350/247/204/350/214/203.md +571 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/04-Settings/344/270/216/351/205/215/347/275/256/350/247/204/350/214/203.md +1177 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/05-/350/265/204/346/272/220/344/270/216/350/277/220/350/241/214/347/233/256/345/275/225/350/247/204/350/214/203.md +575 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/06-/346/225/260/346/215/256/345/272/223/344/270/216/345/217/257/351/200/211/345/237/272/347/241/200/350/256/276/346/226/275/350/247/204/350/214/203.md +499 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/07-App/346/233/277/346/215/242/350/247/204/350/214/203.md +206 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/08-/345/271/263/345/217/260/347/272/247App/344/270/216/350/277/220/350/241/214/346/227/266/345/215/225/344/276/213/350/247/204/350/214/203.md +445 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/09-CLI/344/270/216Worker/345/205/245/345/217/243/350/247/204/350/214/203.md +950 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/10-/346/265/213/350/257/225/344/270/216/345/245/221/347/272/246/350/247/204/350/214/203.md +1001 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/11-/344/273/223/345/272/223/347/234/237/347/233/270/346/272/220/345/234/260/345/233/276.md +102 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/12-/346/236/204/345/273/272/344/270/216/345/217/221/345/270/203/346/243/200/346/237/245/346/270/205/345/215/225.md +171 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/13-/346/255/243/345/274/217Facade/346/200/273/350/241/250.md +402 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/14-/345/210/206/345/261/202/344/270/216/346/211/251/345/261/225/350/247/204/350/214/203.md +550 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/15-/345/255/220/345/214/205/345/274/200/345/217/221/344/275/277/347/224/250/346/211/213/345/206/214.md +1004 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/16-/346/211/251/345/261/225/347/202/271/346/255/243/345/274/217/345/215/217/350/256/256/346/270/205/345/215/225.md +352 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/17-pz.protocols.v1/346/255/243/345/274/217/345/215/217/350/256/256.md +266 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/18-/346/211/251/345/261/225/347/202/271/345/206/262/347/252/201/350/243/201/345/206/263/346/200/273/350/241/250.md +131 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/19-/351/224/231/350/257/257/347/240/201/344/270/216/350/257/212/346/226/255/345/215/217/350/256/256.md +176 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/20-/347/247/201/346/234/211/345/214/205/344/273/223/344/270/216/347/273/237/344/270/200/350/256/244/350/257/201/351/203/250/347/275/262/350/247/204/350/214/203.md +243 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/21-contrib/347/272/246/345/256/232/344/270/216Provider/346/216/245/345/205/245/350/247/204/350/214/203.md +365 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/22-/345/244/232/345/233/275/350/257/255/350/250/200/350/265/204/346/272/220/346/262/273/347/220/206/344/270/216/346/214/211/351/234/200/345/212/240/350/275/275/350/247/204/350/214/203.md +912 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/23-/351/246/226/345/261/217/345/261/225/347/244/272/344/270/216/351/246/226/345/270/247/347/250/263/345/256/232/350/247/204/350/214/203.md +269 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/24-pz/345/220/257/345/212/250/344/270/216/350/277/220/350/241/214/346/227/266/347/274/226/350/257/221/346/265/201/347/250/213.md +245 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/25-/351/235/242/345/220/221/345/257/271/350/261/241/345/274/200/345/217/221/350/247/204/350/214/203.md +300 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/README.md +98 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/00-legacy_core/346/240/207/345/207/206pip/345/214/205/345/214/226/351/207/215/346/236/204/346/200/273/347/272/262.md +1073 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/01-/347/233/256/345/275/225/344/270/216/345/210/206/345/261/202/351/207/215/346/236/204/346/211/247/350/241/214/346/226/271/346/241/210.md +224 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/02-/345/214/205/344/270/216/345/210/206/345/217/221/350/247/204/350/214/203-/345/220/253/345/216/206/345/217/262/345/217/243/345/276/204.md +671 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/13-/344/270/200/346/254/241/346/200/247/345/256/236/346/226/275/346/270/205/345/215/225.md +387 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/14-/345/255/220/345/214/205/351/200/202/351/205/215/346/224/271/351/200/240/346/270/205/345/215/225.md +592 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/15-infra/350/243/201/345/211/252/344/270/216/350/220/275/344/275/215/346/270/205/345/215/225.md +81 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/19-core/345/215/225/344/270/200/346/255/243/345/274/217/346/226/271/346/241/210/346/224/266/346/225/233/346/211/247/350/241/214/346/270/205/345/215/225.md +161 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/25-/345/215/217/350/256/256/345/210/260/346/272/220/347/240/201/345/267/256/350/267/235/346/270/205/345/215/225.md +377 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/26-cutover/345/256/214/345/267/245/346/243/200/346/237/245/346/270/205/345/215/225.md +117 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/29-/345/244/232/345/233/275/350/257/255/350/250/200/350/265/204/346/272/220/346/262/273/347/220/206/344/270/216/346/214/211/351/234/200/345/212/240/350/275/275/350/247/204/350/214/203-/345/220/253/350/277/201/347/247/273/347/255/226/347/225/245.md +956 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/99-/350/265/204/346/272/220/346/224/266/345/217/243/345/220/216/347/273/255TODO.md +84 -0
- pz_core/docs//345/217/221/347/211/210/345/211/215/346/270/205/345/215/225-4.0.11.md +84 -0
- pz_core/docs//346/226/260/346/211/213/346/214/207/345/215/227.md +422 -0
- pz_core/infra/__init__.py +17 -0
- pz_core/infra/db/__init__.py +23 -0
- pz_core/infra/db/contracts.py +73 -0
- pz_core/infra/health/__init__.py +5 -0
- pz_core/infra/health/contracts.py +8 -0
- pz_core/infra/kv/__init__.py +5 -0
- pz_core/infra/kv/contracts.py +17 -0
- pz_core/infra/observability/__init__.py +23 -0
- pz_core/infra/observability/contracts.py +142 -0
- pz_core/infra/resilience/__init__.py +5 -0
- pz_core/infra/resilience/contracts.py +17 -0
- pz_core/infra/resources/__init__.py +5 -0
- pz_core/infra/resources/contracts.py +16 -0
- pz_core/infra/settings/__init__.py +17 -0
- pz_core/infra/settings/models.py +81 -0
- pz_core/infra/storage/__init__.py +5 -0
- pz_core/infra/storage/ports.py +27 -0
- pz_core/project_root_commands.py +282 -0
- pz_core/project_runtime_cli.py +344 -0
- pz_core/project_sources.py +253 -0
- pz_core/pz_launcher.py +209 -0
- pz_core/root_cli.py +70 -0
- pz_core/runtime/__init__.py +229 -0
- pz_core/runtime/access.py +86 -0
- pz_core/runtime/adapters/__init__.py +5 -0
- pz_core/runtime/adapters/base.py +18 -0
- pz_core/runtime/asyncio_bridge.py +18 -0
- pz_core/runtime/bindings/__init__.py +5 -0
- pz_core/runtime/bindings/container.py +50 -0
- pz_core/runtime/cli/__init__.py +5 -0
- pz_core/runtime/cli/_args.py +67 -0
- pz_core/runtime/cli/app_commands.py +417 -0
- pz_core/runtime/cli/check.py +214 -0
- pz_core/runtime/cli/db.py +297 -0
- pz_core/runtime/cli/main.py +89 -0
- pz_core/runtime/cli/resources.py +280 -0
- pz_core/runtime/discovery.py +23 -0
- pz_core/runtime/environment_integrity.py +157 -0
- pz_core/runtime/errors.py +5 -0
- pz_core/runtime/events.py +87 -0
- pz_core/runtime/facades/__init__.py +38 -0
- pz_core/runtime/facades/_capabilities.py +46 -0
- pz_core/runtime/facades/cache.py +103 -0
- pz_core/runtime/facades/database.py +71 -0
- pz_core/runtime/facades/events.py +380 -0
- pz_core/runtime/facades/health.py +101 -0
- pz_core/runtime/facades/mail.py +121 -0
- pz_core/runtime/facades/observability.py +102 -0
- pz_core/runtime/facades/providers.py +75 -0
- pz_core/runtime/facades/resources.py +52 -0
- pz_core/runtime/facades/storage.py +296 -0
- pz_core/runtime/health/__init__.py +5 -0
- pz_core/runtime/health/service.py +102 -0
- pz_core/runtime/host.py +188 -0
- pz_core/runtime/host_runner.py +282 -0
- pz_core/runtime/http/__init__.py +20 -0
- pz_core/runtime/http/app.py +576 -0
- pz_core/runtime/http_timing.py +173 -0
- pz_core/runtime/invocation.py +29 -0
- pz_core/runtime/json_safe.py +47 -0
- pz_core/runtime/lifecycle/__init__.py +25 -0
- pz_core/runtime/lifecycle/manager.py +533 -0
- pz_core/runtime/plan.py +214 -0
- pz_core/runtime/plan_context.py +33 -0
- pz_core/runtime/plan_snapshot.py +177 -0
- pz_core/runtime/registries/__init__.py +27 -0
- pz_core/runtime/registries/capabilities.py +101 -0
- pz_core/runtime/registries/providers.py +396 -0
- pz_core/runtime/resource_assets.py +344 -0
- pz_core/runtime/run_cli.py +211 -0
- pz_core/runtime/settings.py +888 -0
- pz_core/runtime/worker/__init__.py +21 -0
- pz_core/runtime/worker/engine.py +921 -0
- pz_core/runtime/worker/runtime.py +25 -0
- pz_core/testing/__init__.py +15 -0
- pz_core/testing/doc_route_contracts.py +305 -0
- pz_core/utils/__init__.py +44 -0
- pz_core/utils/env.py +65 -0
- pz_core/utils/project_jsonc/__init__.py +29 -0
- pz_core/utils/project_jsonc/document.py +420 -0
- pz_core/utils/project_settings.py +99 -0
- pz_foundation/__init__.py +50 -0
- pz_foundation/_contracts.py +81 -0
- pz_foundation/_errors.py +34 -0
- pz_foundation/api.py +14 -0
- pz_foundation/apps.py +127 -0
- pz_foundation/auth/__init__.py +1 -0
- pz_foundation/cache_control.py +233 -0
- pz_foundation/cli/__init__.py +2 -0
- pz_foundation/cli/workers.py +565 -0
- pz_foundation/configs/__init__.py +0 -0
- pz_foundation/configs/default.env +15 -0
- pz_foundation/configs/default.jsonc +452 -0
- pz_foundation/db/__init__.py +94 -0
- pz_foundation/db/aerich_executor.py +664 -0
- pz_foundation/db/config.py +358 -0
- pz_foundation/db/connection_manager.py +689 -0
- pz_foundation/db/connection_probe.py +204 -0
- pz_foundation/db/database.py +1291 -0
- pz_foundation/db/deps.py +47 -0
- pz_foundation/db/lifecycle_status.py +85 -0
- pz_foundation/db/migrations.py +477 -0
- pz_foundation/db/mysql.py +57 -0
- pz_foundation/db/postgresql.py +409 -0
- pz_foundation/db/production_pool_fallback.py +143 -0
- pz_foundation/db/public.py +45 -0
- pz_foundation/db/session.py +369 -0
- pz_foundation/db/sqlite.py +15 -0
- pz_foundation/db/tortoise_manager.py +724 -0
- pz_foundation/db/tortoise_psycopg.py +148 -0
- pz_foundation/docs/README.md +18 -0
- pz_foundation/docs/distribution-README.md +319 -0
- pz_foundation/docs/infra/350/243/201/345/211/252/344/270/216/350/220/275/344/275/215/350/257/264/346/230/216.md +39 -0
- pz_foundation/docs//345/205/254/345/274/200/345/205/215/350/264/271/346/216/245/345/217/243/351/230/262/346/273/245/347/224/250/344/270/216/344/272/272/346/234/272/346/240/241/351/252/214.md +680 -0
- pz_foundation/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +288 -0
- pz_foundation/docs//350/267/257/347/224/261/344/270/216URL/345/244/204/347/220/206/350/247/204/350/214/203.md +119 -0
- pz_foundation/health.py +105 -0
- pz_foundation/host/__init__.py +11 -0
- pz_foundation/host/builder.py +34 -0
- pz_foundation/host/cache_runtime.py +44 -0
- pz_foundation/host/db/__init__.py +17 -0
- pz_foundation/host/db/aerich_config.py +36 -0
- pz_foundation/host/db/config.py +106 -0
- pz_foundation/host/db/connection_manager.py +48 -0
- pz_foundation/host/db/deps.py +5 -0
- pz_foundation/host/db/orm_retry_patch.py +566 -0
- pz_foundation/host/db/request_adapter.py +325 -0
- pz_foundation/host/db/router.py +28 -0
- pz_foundation/host/db/session.py +284 -0
- pz_foundation/host/db/tortoise_manager.py +10 -0
- pz_foundation/host/idempotency.py +132 -0
- pz_foundation/host/lifespan.py +247 -0
- pz_foundation/host/redis_runtime.py +100 -0
- pz_foundation/host/web.py +790 -0
- pz_foundation/infra_provider.py +236 -0
- pz_foundation/kv/__init__.py +25 -0
- pz_foundation/kv/cache.py +1166 -0
- pz_foundation/kv/deps.py +84 -0
- pz_foundation/kv/public.py +25 -0
- pz_foundation/kv/redis_manager.py +1531 -0
- pz_foundation/lazy_exports.py +43 -0
- pz_foundation/lazy_imports.py +124 -0
- pz_foundation/lifecycle.py +392 -0
- pz_foundation/managed_workers.py +1117 -0
- pz_foundation/middlewares/__init__.py +26 -0
- pz_foundation/middlewares/_settings.py +250 -0
- pz_foundation/middlewares/analytics.py +124 -0
- pz_foundation/middlewares/cache_control.py +156 -0
- pz_foundation/middlewares/compression.py +202 -0
- pz_foundation/middlewares/cors.py +62 -0
- pz_foundation/middlewares/geo_country.py +44 -0
- pz_foundation/middlewares/inner_router.py +50 -0
- pz_foundation/middlewares/rate_limited/__init__.py +3 -0
- pz_foundation/middlewares/rate_limited/key_limiter.py +115 -0
- pz_foundation/middlewares/request_logging.py +104 -0
- pz_foundation/middlewares/route_owner.py +309 -0
- pz_foundation/middlewares/security_csrf.py +44 -0
- pz_foundation/middlewares/security_headers/__init__.py +4 -0
- pz_foundation/middlewares/security_headers/conflicts.py +44 -0
- pz_foundation/middlewares/security_headers/csp_nonce.py +200 -0
- pz_foundation/middlewares/security_headers/security_headers.py +44 -0
- pz_foundation/migrations/__init__.py +1 -0
- pz_foundation/migrations/pz_foundation/__init__.py +1 -0
- pz_foundation/models.py +22 -0
- pz_foundation/notifications/__init__.py +23 -0
- pz_foundation/notifications/email.py +542 -0
- pz_foundation/notifications/public.py +31 -0
- pz_foundation/observability/__init__.py +71 -0
- pz_foundation/observability/http.py +34 -0
- pz_foundation/observability/logger/__init__.py +49 -0
- pz_foundation/observability/logger/_bot_settings.py +126 -0
- pz_foundation/observability/logger/bot_message.py +592 -0
- pz_foundation/observability/logger/core.py +385 -0
- pz_foundation/observability/logger/delivery_audit.py +84 -0
- pz_foundation/observability/logger/feishu_bot.py +199 -0
- pz_foundation/observability/logger/telegram_bot.py +194 -0
- pz_foundation/observability/metrics.py +365 -0
- pz_foundation/observability/runtime.py +68 -0
- pz_foundation/public.py +405 -0
- pz_foundation/resources/__init__.py +12 -0
- pz_foundation/resources/builder.py +900 -0
- pz_foundation/resources/images.py +363 -0
- pz_foundation/root_cli.py +20 -0
- pz_foundation/routing/__init__.py +203 -0
- pz_foundation/routing/canonical.py +486 -0
- pz_foundation/routing/convertors.py +82 -0
- pz_foundation/routing/declarations.py +843 -0
- pz_foundation/routing/exports.py +148 -0
- pz_foundation/routing/loaders.py +138 -0
- pz_foundation/routing/manifest.py +215 -0
- pz_foundation/routing/manifest_provider.py +47 -0
- pz_foundation/routing/mounts.py +101 -0
- pz_foundation/routing/ordering.py +172 -0
- pz_foundation/routing/registry.py +133 -0
- pz_foundation/routing/utils.py +28 -0
- pz_foundation/runtime.py +234 -0
- pz_foundation/settings.py +253 -0
- pz_foundation/settings_normalization.py +130 -0
- pz_foundation/storage/__init__.py +25 -0
- pz_foundation/storage/local.py +209 -0
- pz_foundation/storage/public.py +106 -0
- pz_foundation/storage/s3.py +116 -0
- pz_foundation/storage/service.py +234 -0
- pz_foundation/urls.py +19 -0
- pz_foundation/utils/__init__.py +6 -0
- pz_foundation/utils/merge.py +160 -0
- pz_foundation/worker_replicas.py +55 -0
- pz_settings_center/__init__.py +5 -0
- pz_settings_center/api/__init__.py +5 -0
- pz_settings_center/api/runtime_overrides.py +360 -0
- pz_settings_center/apps.py +28 -0
- pz_settings_center/configs/__init__.py +0 -0
- pz_settings_center/configs/default.env +2 -0
- pz_settings_center/configs/default.jsonc +1 -0
- pz_settings_center/docs/01-settings_center/350/203/275/345/212/233/350/276/271/347/225/214.md +124 -0
- pz_settings_center/docs/README.md +12 -0
- pz_settings_center/docs/distribution-README.md +150 -0
- pz_settings_center/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +48 -0
- pz_settings_center/integration_payload.py +18 -0
- pz_settings_center/project_helpers.py +405 -0
- pz_settings_center/public.py +139 -0
- pz_settings_center/routing_helpers.py +73 -0
- pz_settings_center/runtime_override_provider.py +61 -0
- pz_settings_center/typed_settings.py +324 -0
- pz_settings_center/urls.py +9 -0
|
@@ -0,0 +1,696 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from importlib import import_module
|
|
5
|
+
import inspect
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from pz_core.assembly.apps import AppRegistry, load_app_object_from_decl
|
|
9
|
+
from pz_core.assembly.project import active_project_import_root
|
|
10
|
+
from pz_core.assembly.settings import SettingsSnapshot
|
|
11
|
+
from pz_core.core.errors import PzError
|
|
12
|
+
from pz_core.core.extensions import (
|
|
13
|
+
CliToolSpec,
|
|
14
|
+
ExtensionRegistry,
|
|
15
|
+
ExtensionSpec,
|
|
16
|
+
FormalExtensionSpec,
|
|
17
|
+
HostBuilderSpec,
|
|
18
|
+
InfraProviderSpec,
|
|
19
|
+
LifecycleContributionSpec,
|
|
20
|
+
PageProfileProviderSpec,
|
|
21
|
+
ResourceContributionSpec,
|
|
22
|
+
RuntimeManifestContributionSpec,
|
|
23
|
+
ProtocolExtensionSpec,
|
|
24
|
+
ProtocolRegistrationSpec,
|
|
25
|
+
SettingsProviderSpec,
|
|
26
|
+
WorkerRoleSpec,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
_MISSING = object()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _payload_field(payload: Any, name: str, *, default: Any = None) -> Any:
|
|
34
|
+
if isinstance(payload, Mapping):
|
|
35
|
+
return payload.get(name, default)
|
|
36
|
+
value = getattr(payload, name, _MISSING)
|
|
37
|
+
if value is _MISSING:
|
|
38
|
+
return default
|
|
39
|
+
return value
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _resolve_dotted(target: str) -> Any:
|
|
43
|
+
module_name, attr_name = str(target or "").rsplit(".", 1)
|
|
44
|
+
module = import_module(module_name)
|
|
45
|
+
return getattr(module, attr_name)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _instantiate_page_profile_provider(provider: Any) -> Any:
|
|
49
|
+
if isinstance(provider, str):
|
|
50
|
+
provider = _resolve_dotted(provider)
|
|
51
|
+
if inspect.isclass(provider):
|
|
52
|
+
return provider()
|
|
53
|
+
return provider
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _validate_page_profile_provider_spec(spec: PageProfileProviderSpec) -> PageProfileProviderSpec:
|
|
57
|
+
try:
|
|
58
|
+
provider = _instantiate_page_profile_provider(spec.provider)
|
|
59
|
+
except PzError:
|
|
60
|
+
raise
|
|
61
|
+
except Exception as exc:
|
|
62
|
+
raise PzError(
|
|
63
|
+
code="PZ_PAGE_PROFILE_PROVIDER_IMPORT_FAILED",
|
|
64
|
+
message=f"Page-profile provider '{spec.id}' failed to load during extension compilation: {exc}",
|
|
65
|
+
stage="extensions",
|
|
66
|
+
owner=spec.owner_app,
|
|
67
|
+
action="compile_extension_registry",
|
|
68
|
+
) from exc
|
|
69
|
+
resolver = getattr(provider, "resolve_page_profile", None)
|
|
70
|
+
if not callable(resolver):
|
|
71
|
+
raise PzError(
|
|
72
|
+
code="PZ_PAGE_PROFILE_PROVIDER_INVALID",
|
|
73
|
+
message=f"Page-profile provider '{spec.id}' must expose resolve_page_profile(...).",
|
|
74
|
+
stage="extensions",
|
|
75
|
+
owner=spec.owner_app,
|
|
76
|
+
action="compile_extension_registry",
|
|
77
|
+
)
|
|
78
|
+
return spec
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _lifecycle_handlers_match(left: Any, right: Any) -> bool:
|
|
82
|
+
if left is right:
|
|
83
|
+
return True
|
|
84
|
+
left_func = getattr(left, "__func__", None)
|
|
85
|
+
right_func = getattr(right, "__func__", None)
|
|
86
|
+
if left_func is None or right_func is None:
|
|
87
|
+
return False
|
|
88
|
+
return left_func is right_func and getattr(left, "__self__", None) is getattr(right, "__self__", None)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _declares_matching_lifecycle_hook(
|
|
92
|
+
declared: tuple[FormalExtensionSpec, ...],
|
|
93
|
+
*,
|
|
94
|
+
owner_app: str,
|
|
95
|
+
phase: str,
|
|
96
|
+
handler: Any,
|
|
97
|
+
) -> bool:
|
|
98
|
+
for item in declared:
|
|
99
|
+
if not isinstance(item, LifecycleContributionSpec):
|
|
100
|
+
continue
|
|
101
|
+
if item.owner_app != owner_app or item.phase != phase:
|
|
102
|
+
continue
|
|
103
|
+
if _lifecycle_handlers_match(item.handler, handler):
|
|
104
|
+
return True
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _synthesized_lifecycle_contributions(
|
|
109
|
+
app_decl: Any,
|
|
110
|
+
app_obj: Any,
|
|
111
|
+
*,
|
|
112
|
+
declared: tuple[FormalExtensionSpec, ...],
|
|
113
|
+
) -> tuple[LifecycleContributionSpec, ...]:
|
|
114
|
+
out: list[LifecycleContributionSpec] = []
|
|
115
|
+
for phase in ("startup", "shutdown"):
|
|
116
|
+
hook = getattr(app_obj, phase, None)
|
|
117
|
+
if hook is None:
|
|
118
|
+
continue
|
|
119
|
+
if not callable(hook):
|
|
120
|
+
raise PzError(
|
|
121
|
+
code="PZ_APP_LIFECYCLE_HOOK_INVALID",
|
|
122
|
+
message=f"App '{app_decl.app_id}' exposes non-callable hook '{phase}'.",
|
|
123
|
+
stage="extensions",
|
|
124
|
+
owner=app_decl.app_id,
|
|
125
|
+
action="compile_extension_registry",
|
|
126
|
+
)
|
|
127
|
+
if _declares_matching_lifecycle_hook(
|
|
128
|
+
declared,
|
|
129
|
+
owner_app=app_decl.app_id,
|
|
130
|
+
phase=phase,
|
|
131
|
+
handler=hook,
|
|
132
|
+
):
|
|
133
|
+
continue
|
|
134
|
+
out.append(
|
|
135
|
+
LifecycleContributionSpec(
|
|
136
|
+
id=f"{app_decl.app_id}.app_hook.{phase}",
|
|
137
|
+
owner_app=app_decl.app_id,
|
|
138
|
+
phase=phase,
|
|
139
|
+
handler=hook,
|
|
140
|
+
)
|
|
141
|
+
)
|
|
142
|
+
return tuple(out)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _coerce_extension_spec(payload: Any, *, owner_hint: str) -> ExtensionSpec | None:
|
|
146
|
+
raw_kind = _payload_field(payload, "kind")
|
|
147
|
+
raw_id = _payload_field(payload, "id")
|
|
148
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
149
|
+
if not isinstance(raw_kind, str) or not raw_kind.strip():
|
|
150
|
+
return None
|
|
151
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
152
|
+
return None
|
|
153
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
154
|
+
return None
|
|
155
|
+
return ExtensionSpec(
|
|
156
|
+
id=raw_id,
|
|
157
|
+
kind=raw_kind,
|
|
158
|
+
owner_app=raw_owner,
|
|
159
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
160
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
161
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
162
|
+
payload=dict(_payload_field(payload, "payload", default=None) or {}),
|
|
163
|
+
source=str(_payload_field(payload, "source", default="") or ""),
|
|
164
|
+
provides=tuple(_payload_field(payload, "provides", default=()) or ()),
|
|
165
|
+
conflicts=tuple(_payload_field(payload, "conflicts", default=()) or ()),
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _coerce_host_builder_spec(payload: Any, *, owner_hint: str) -> HostBuilderSpec | None:
|
|
170
|
+
builder = _payload_field(payload, "builder")
|
|
171
|
+
if builder is None:
|
|
172
|
+
return None
|
|
173
|
+
raw_id = _payload_field(payload, "id")
|
|
174
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
175
|
+
raw_kind = _payload_field(payload, "kind", default="host.builder")
|
|
176
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
177
|
+
return None
|
|
178
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
179
|
+
return None
|
|
180
|
+
if str(raw_kind or "").strip() != "host.builder":
|
|
181
|
+
return None
|
|
182
|
+
return HostBuilderSpec(
|
|
183
|
+
id=raw_id,
|
|
184
|
+
owner_app=raw_owner,
|
|
185
|
+
builder=builder,
|
|
186
|
+
kind="host.builder",
|
|
187
|
+
runtime_kind=str(_payload_field(payload, "runtime_kind", default="web") or "web"),
|
|
188
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
189
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
190
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _coerce_settings_provider_spec(payload: Any, *, owner_hint: str) -> SettingsProviderSpec | None:
|
|
195
|
+
provider = _payload_field(payload, "provider")
|
|
196
|
+
if provider is None:
|
|
197
|
+
return None
|
|
198
|
+
raw_id = _payload_field(payload, "id")
|
|
199
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
200
|
+
raw_kind = _payload_field(payload, "kind", default="settings.provider")
|
|
201
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
202
|
+
return None
|
|
203
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
204
|
+
return None
|
|
205
|
+
if str(raw_kind or "").strip() != "settings.provider":
|
|
206
|
+
return None
|
|
207
|
+
return SettingsProviderSpec(
|
|
208
|
+
id=raw_id,
|
|
209
|
+
owner_app=raw_owner,
|
|
210
|
+
provider=provider,
|
|
211
|
+
kind="settings.provider",
|
|
212
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
213
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def _coerce_infra_provider_spec(payload: Any, *, owner_hint: str) -> InfraProviderSpec | None:
|
|
218
|
+
provider = _payload_field(payload, "provider")
|
|
219
|
+
if provider is None:
|
|
220
|
+
return None
|
|
221
|
+
raw_id = _payload_field(payload, "id")
|
|
222
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
223
|
+
raw_kind = _payload_field(payload, "kind", default="infra.provider")
|
|
224
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
225
|
+
return None
|
|
226
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
227
|
+
return None
|
|
228
|
+
if str(raw_kind or "").strip() != "infra.provider":
|
|
229
|
+
return None
|
|
230
|
+
return InfraProviderSpec(
|
|
231
|
+
id=raw_id,
|
|
232
|
+
owner_app=raw_owner,
|
|
233
|
+
provider=provider,
|
|
234
|
+
kind="infra.provider",
|
|
235
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
236
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
237
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _coerce_runtime_manifest_contribution_spec(
|
|
242
|
+
payload: Any,
|
|
243
|
+
*,
|
|
244
|
+
owner_hint: str,
|
|
245
|
+
) -> RuntimeManifestContributionSpec | None:
|
|
246
|
+
provider = _payload_field(payload, "provider")
|
|
247
|
+
if provider is None:
|
|
248
|
+
return None
|
|
249
|
+
raw_id = _payload_field(payload, "id")
|
|
250
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
251
|
+
raw_kind = _payload_field(payload, "kind", default="runtime.manifest_contribution")
|
|
252
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
253
|
+
return None
|
|
254
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
255
|
+
return None
|
|
256
|
+
if str(raw_kind or "").strip() != "runtime.manifest_contribution":
|
|
257
|
+
return None
|
|
258
|
+
return RuntimeManifestContributionSpec(
|
|
259
|
+
id=raw_id,
|
|
260
|
+
owner_app=raw_owner,
|
|
261
|
+
provider=provider,
|
|
262
|
+
kind="runtime.manifest_contribution",
|
|
263
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
264
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
265
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def _coerce_lifecycle_contribution_spec(payload: Any, *, owner_hint: str) -> LifecycleContributionSpec | None:
|
|
270
|
+
handler = _payload_field(payload, "handler")
|
|
271
|
+
phase = _payload_field(payload, "phase")
|
|
272
|
+
raw_id = _payload_field(payload, "id")
|
|
273
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
274
|
+
raw_kind = _payload_field(payload, "kind", default="lifecycle.contribution")
|
|
275
|
+
if handler is None:
|
|
276
|
+
return None
|
|
277
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
278
|
+
return None
|
|
279
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
280
|
+
return None
|
|
281
|
+
if not isinstance(phase, str) or not phase.strip():
|
|
282
|
+
return None
|
|
283
|
+
if str(raw_kind or "").strip() != "lifecycle.contribution":
|
|
284
|
+
return None
|
|
285
|
+
return LifecycleContributionSpec(
|
|
286
|
+
id=raw_id,
|
|
287
|
+
owner_app=raw_owner,
|
|
288
|
+
handler=handler,
|
|
289
|
+
phase=phase.strip(),
|
|
290
|
+
kind="lifecycle.contribution",
|
|
291
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
292
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def _coerce_worker_role_spec(payload: Any, *, owner_hint: str) -> WorkerRoleSpec | None:
|
|
297
|
+
tool_name = _payload_field(payload, "tool_name")
|
|
298
|
+
raw_id = _payload_field(payload, "id")
|
|
299
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
300
|
+
raw_kind = _payload_field(payload, "kind", default="worker.role")
|
|
301
|
+
if not isinstance(tool_name, str) or not tool_name.strip():
|
|
302
|
+
return None
|
|
303
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
304
|
+
return None
|
|
305
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
306
|
+
return None
|
|
307
|
+
if str(raw_kind or "").strip() != "worker.role":
|
|
308
|
+
return None
|
|
309
|
+
return WorkerRoleSpec(
|
|
310
|
+
id=raw_id,
|
|
311
|
+
owner_app=raw_owner,
|
|
312
|
+
tool_name=tool_name.strip(),
|
|
313
|
+
kind="worker.role",
|
|
314
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
315
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
316
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
317
|
+
name=str(_payload_field(payload, "name", default="") or "").strip(),
|
|
318
|
+
auto_start=bool(_payload_field(payload, "auto_start", default=False)),
|
|
319
|
+
auto_start_setting=str(_payload_field(payload, "auto_start_setting", default="") or "").strip(),
|
|
320
|
+
restart=str(_payload_field(payload, "restart", default="always") or "always").strip() or "always",
|
|
321
|
+
worker_kind=(
|
|
322
|
+
str(
|
|
323
|
+
_payload_field(payload, "worker_kind", default="infrastructure_worker")
|
|
324
|
+
or "infrastructure_worker"
|
|
325
|
+
)
|
|
326
|
+
.strip()
|
|
327
|
+
or "infrastructure_worker"
|
|
328
|
+
),
|
|
329
|
+
replica_count_setting=str(_payload_field(payload, "replica_count_setting", default="") or "").strip(),
|
|
330
|
+
description=str(_payload_field(payload, "description", default="") or "").strip(),
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def _coerce_cli_tool_spec(payload: Any, *, owner_hint: str) -> CliToolSpec | None:
|
|
335
|
+
tool = _payload_field(payload, "tool")
|
|
336
|
+
command = _payload_field(payload, "command")
|
|
337
|
+
summary = _payload_field(payload, "summary")
|
|
338
|
+
raw_id = _payload_field(payload, "id")
|
|
339
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
340
|
+
raw_kind = _payload_field(payload, "kind", default="cli.tool")
|
|
341
|
+
if tool is None:
|
|
342
|
+
return None
|
|
343
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
344
|
+
return None
|
|
345
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
346
|
+
return None
|
|
347
|
+
if str(raw_kind or "").strip() != "cli.tool":
|
|
348
|
+
return None
|
|
349
|
+
if isinstance(command, str):
|
|
350
|
+
command_parts = (command.strip(),) if command.strip() else ()
|
|
351
|
+
else:
|
|
352
|
+
command_parts = tuple(str(item).strip() for item in tuple(command or ()) if str(item).strip())
|
|
353
|
+
if not command_parts:
|
|
354
|
+
return None
|
|
355
|
+
return CliToolSpec(
|
|
356
|
+
id=raw_id,
|
|
357
|
+
owner_app=raw_owner,
|
|
358
|
+
command=command_parts,
|
|
359
|
+
summary=str(summary or "").strip(),
|
|
360
|
+
tool=tool,
|
|
361
|
+
kind="cli.tool",
|
|
362
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
363
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
364
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def _coerce_page_profile_provider_spec(payload: Any, *, owner_hint: str) -> PageProfileProviderSpec | None:
|
|
369
|
+
provider = _payload_field(payload, "provider")
|
|
370
|
+
if provider is None:
|
|
371
|
+
return None
|
|
372
|
+
raw_id = _payload_field(payload, "id")
|
|
373
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
374
|
+
raw_kind = _payload_field(payload, "kind", default="page.profile_provider")
|
|
375
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
376
|
+
return None
|
|
377
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
378
|
+
return None
|
|
379
|
+
if str(raw_kind or "").strip() != "page.profile_provider":
|
|
380
|
+
return None
|
|
381
|
+
return PageProfileProviderSpec(
|
|
382
|
+
id=raw_id,
|
|
383
|
+
owner_app=raw_owner,
|
|
384
|
+
provider=provider,
|
|
385
|
+
kind="page.profile_provider",
|
|
386
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
387
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
388
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def _coerce_resource_contribution_spec(payload: Any, *, owner_hint: str) -> ResourceContributionSpec | None:
|
|
393
|
+
raw_kind = _payload_field(payload, "kind", default="resource.contribution")
|
|
394
|
+
if str(raw_kind or "").strip() != "resource.contribution":
|
|
395
|
+
return None
|
|
396
|
+
raw_id = _payload_field(payload, "id")
|
|
397
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
398
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
399
|
+
return None
|
|
400
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
401
|
+
return None
|
|
402
|
+
|
|
403
|
+
def _read_tuple(field_name: str) -> tuple[Any, ...]:
|
|
404
|
+
value = _payload_field(payload, field_name, default=())
|
|
405
|
+
if value in (None, ()):
|
|
406
|
+
return ()
|
|
407
|
+
if isinstance(value, tuple):
|
|
408
|
+
return value
|
|
409
|
+
if isinstance(value, list):
|
|
410
|
+
return tuple(value)
|
|
411
|
+
return ()
|
|
412
|
+
|
|
413
|
+
def _read_locale_allowlist(field_name: str) -> tuple[str, ...]:
|
|
414
|
+
items = _read_tuple(field_name)
|
|
415
|
+
out: list[str] = []
|
|
416
|
+
for item in items:
|
|
417
|
+
if not isinstance(item, str) or not item.strip():
|
|
418
|
+
return ()
|
|
419
|
+
out.append(item.strip())
|
|
420
|
+
return tuple(out)
|
|
421
|
+
|
|
422
|
+
return ResourceContributionSpec(
|
|
423
|
+
id=raw_id,
|
|
424
|
+
owner_app=raw_owner,
|
|
425
|
+
templates_dir=str(_payload_field(payload, "templates_dir", default="templates") or "templates"),
|
|
426
|
+
static_dir=str(_payload_field(payload, "static_dir", default="static") or "static"),
|
|
427
|
+
locales_dir=str(_payload_field(payload, "locales_dir", default="locales") or "locales"),
|
|
428
|
+
migrations_dir=str(_payload_field(payload, "migrations_dir", default="migrations") or "migrations"),
|
|
429
|
+
kind="resource.contribution",
|
|
430
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
431
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
432
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
433
|
+
locale_bundles=tuple(dict(item) for item in _read_tuple("locale_bundles") if isinstance(item, dict)),
|
|
434
|
+
locale_dependencies=tuple(
|
|
435
|
+
dict(item) for item in _read_tuple("locale_dependencies") if isinstance(item, dict)
|
|
436
|
+
),
|
|
437
|
+
locale_consumer_bindings=tuple(
|
|
438
|
+
dict(item) for item in _read_tuple("locale_consumer_bindings") if isinstance(item, dict)
|
|
439
|
+
),
|
|
440
|
+
locale_profiles=tuple(dict(item) for item in _read_tuple("locale_profiles") if isinstance(item, dict)),
|
|
441
|
+
locale_overrides=tuple(dict(item) for item in _read_tuple("locale_overrides") if isinstance(item, dict)),
|
|
442
|
+
locale_allowlist=_read_locale_allowlist("locale_allowlist"),
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def _coerce_protocol_registration_spec(payload: Any, *, owner_hint: str) -> ProtocolRegistrationSpec | None:
|
|
447
|
+
raw_kind = _payload_field(payload, "kind", default="protocol.registration")
|
|
448
|
+
if str(raw_kind or "").strip() != "protocol.registration":
|
|
449
|
+
return None
|
|
450
|
+
protocol_kind = _payload_field(payload, "protocol_kind")
|
|
451
|
+
spec_name = _payload_field(payload, "spec_name")
|
|
452
|
+
runtime_owner = _payload_field(payload, "runtime_owner")
|
|
453
|
+
raw_id = _payload_field(payload, "id")
|
|
454
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
455
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
456
|
+
return None
|
|
457
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
458
|
+
return None
|
|
459
|
+
if not isinstance(protocol_kind, str) or not protocol_kind.strip():
|
|
460
|
+
return None
|
|
461
|
+
if not isinstance(spec_name, str) or not spec_name.strip():
|
|
462
|
+
return None
|
|
463
|
+
if not isinstance(runtime_owner, str) or not runtime_owner.strip():
|
|
464
|
+
return None
|
|
465
|
+
return ProtocolRegistrationSpec(
|
|
466
|
+
id=raw_id,
|
|
467
|
+
owner_app=raw_owner,
|
|
468
|
+
protocol_kind=protocol_kind.strip(),
|
|
469
|
+
spec_name=spec_name.strip(),
|
|
470
|
+
runtime_owner=runtime_owner.strip(),
|
|
471
|
+
required_fields=tuple(_payload_field(payload, "required_fields", default=()) or ()),
|
|
472
|
+
string_fields=tuple(_payload_field(payload, "string_fields", default=()) or ()),
|
|
473
|
+
import_fields=tuple(_payload_field(payload, "import_fields", default=()) or ()),
|
|
474
|
+
callable_fields=tuple(_payload_field(payload, "callable_fields", default=()) or ()),
|
|
475
|
+
validator=_payload_field(payload, "validator", default=None),
|
|
476
|
+
kind="protocol.registration",
|
|
477
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
478
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
479
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def _coerce_protocol_extension_spec(payload: Any, *, owner_hint: str) -> ProtocolExtensionSpec | None:
|
|
484
|
+
raw_kind = _payload_field(payload, "kind")
|
|
485
|
+
if not isinstance(raw_kind, str) or not raw_kind.strip():
|
|
486
|
+
return None
|
|
487
|
+
if raw_kind.strip() in {
|
|
488
|
+
"host.builder",
|
|
489
|
+
"settings.provider",
|
|
490
|
+
"infra.provider",
|
|
491
|
+
"runtime.manifest_contribution",
|
|
492
|
+
"lifecycle.contribution",
|
|
493
|
+
"worker.role",
|
|
494
|
+
"cli.tool",
|
|
495
|
+
"page.profile_provider",
|
|
496
|
+
"resource.contribution",
|
|
497
|
+
"protocol.registration",
|
|
498
|
+
}:
|
|
499
|
+
return None
|
|
500
|
+
raw_id = _payload_field(payload, "id")
|
|
501
|
+
raw_owner = _payload_field(payload, "owner_app", default=owner_hint)
|
|
502
|
+
fields = _payload_field(payload, "fields", default=None)
|
|
503
|
+
if not isinstance(raw_id, str) or not raw_id.strip():
|
|
504
|
+
return None
|
|
505
|
+
if not isinstance(raw_owner, str) or not raw_owner.strip():
|
|
506
|
+
return None
|
|
507
|
+
if not isinstance(fields, Mapping):
|
|
508
|
+
return None
|
|
509
|
+
return ProtocolExtensionSpec(
|
|
510
|
+
id=raw_id,
|
|
511
|
+
owner_app=raw_owner,
|
|
512
|
+
kind=raw_kind.strip(),
|
|
513
|
+
fields={str(key): value for key, value in dict(fields).items()},
|
|
514
|
+
optional=bool(_payload_field(payload, "optional", default=False)),
|
|
515
|
+
api_version=str(_payload_field(payload, "api_version", default="v1") or "v1"),
|
|
516
|
+
priority=int(_payload_field(payload, "priority", default=100) or 100),
|
|
517
|
+
title=str(_payload_field(payload, "title", default="") or ""),
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def _normalize_decl(payload: Any, *, owner_hint: str) -> FormalExtensionSpec:
|
|
522
|
+
if isinstance(payload, HostBuilderSpec):
|
|
523
|
+
return payload
|
|
524
|
+
if isinstance(payload, SettingsProviderSpec):
|
|
525
|
+
return payload
|
|
526
|
+
if isinstance(payload, InfraProviderSpec):
|
|
527
|
+
return payload
|
|
528
|
+
if isinstance(payload, RuntimeManifestContributionSpec):
|
|
529
|
+
return payload
|
|
530
|
+
if isinstance(payload, LifecycleContributionSpec):
|
|
531
|
+
return payload
|
|
532
|
+
if isinstance(payload, WorkerRoleSpec):
|
|
533
|
+
return payload
|
|
534
|
+
if isinstance(payload, CliToolSpec):
|
|
535
|
+
return payload
|
|
536
|
+
if isinstance(payload, PageProfileProviderSpec):
|
|
537
|
+
return _validate_page_profile_provider_spec(payload)
|
|
538
|
+
if isinstance(payload, ProtocolRegistrationSpec):
|
|
539
|
+
return payload
|
|
540
|
+
if isinstance(payload, ProtocolExtensionSpec):
|
|
541
|
+
return payload
|
|
542
|
+
if isinstance(payload, ExtensionSpec):
|
|
543
|
+
if payload.kind in {
|
|
544
|
+
"host.builder",
|
|
545
|
+
"settings.provider",
|
|
546
|
+
"infra.provider",
|
|
547
|
+
"runtime.manifest_contribution",
|
|
548
|
+
"lifecycle.contribution",
|
|
549
|
+
"worker.role",
|
|
550
|
+
"cli.tool",
|
|
551
|
+
"page.profile_provider",
|
|
552
|
+
"protocol.registration",
|
|
553
|
+
}:
|
|
554
|
+
raise PzError(
|
|
555
|
+
code="PZ_EXTENSION_DECL_INVALID",
|
|
556
|
+
message=(
|
|
557
|
+
f"App '{owner_hint}' must declare '{payload.kind}' via the dedicated formal spec "
|
|
558
|
+
"instead of generic ExtensionSpec."
|
|
559
|
+
),
|
|
560
|
+
stage="extensions",
|
|
561
|
+
owner=owner_hint,
|
|
562
|
+
action="compile_extension_registry",
|
|
563
|
+
)
|
|
564
|
+
return payload
|
|
565
|
+
shaped_host_builder = _coerce_host_builder_spec(payload, owner_hint=owner_hint)
|
|
566
|
+
if shaped_host_builder is not None:
|
|
567
|
+
return shaped_host_builder
|
|
568
|
+
shaped_settings_provider = _coerce_settings_provider_spec(payload, owner_hint=owner_hint)
|
|
569
|
+
if shaped_settings_provider is not None:
|
|
570
|
+
return shaped_settings_provider
|
|
571
|
+
shaped_infra_provider = _coerce_infra_provider_spec(payload, owner_hint=owner_hint)
|
|
572
|
+
if shaped_infra_provider is not None:
|
|
573
|
+
return shaped_infra_provider
|
|
574
|
+
shaped_runtime_manifest_contribution = _coerce_runtime_manifest_contribution_spec(
|
|
575
|
+
payload,
|
|
576
|
+
owner_hint=owner_hint,
|
|
577
|
+
)
|
|
578
|
+
if shaped_runtime_manifest_contribution is not None:
|
|
579
|
+
return shaped_runtime_manifest_contribution
|
|
580
|
+
shaped_lifecycle_contribution = _coerce_lifecycle_contribution_spec(payload, owner_hint=owner_hint)
|
|
581
|
+
if shaped_lifecycle_contribution is not None:
|
|
582
|
+
return shaped_lifecycle_contribution
|
|
583
|
+
shaped_worker_role = _coerce_worker_role_spec(payload, owner_hint=owner_hint)
|
|
584
|
+
if shaped_worker_role is not None:
|
|
585
|
+
return shaped_worker_role
|
|
586
|
+
shaped_cli_tool = _coerce_cli_tool_spec(payload, owner_hint=owner_hint)
|
|
587
|
+
if shaped_cli_tool is not None:
|
|
588
|
+
return shaped_cli_tool
|
|
589
|
+
shaped_page_profile_provider = _coerce_page_profile_provider_spec(payload, owner_hint=owner_hint)
|
|
590
|
+
if shaped_page_profile_provider is not None:
|
|
591
|
+
return _validate_page_profile_provider_spec(shaped_page_profile_provider)
|
|
592
|
+
shaped_resource_contribution = _coerce_resource_contribution_spec(payload, owner_hint=owner_hint)
|
|
593
|
+
if shaped_resource_contribution is not None:
|
|
594
|
+
return shaped_resource_contribution
|
|
595
|
+
shaped_protocol_registration = _coerce_protocol_registration_spec(payload, owner_hint=owner_hint)
|
|
596
|
+
if shaped_protocol_registration is not None:
|
|
597
|
+
return shaped_protocol_registration
|
|
598
|
+
shaped_protocol_extension = _coerce_protocol_extension_spec(payload, owner_hint=owner_hint)
|
|
599
|
+
if shaped_protocol_extension is not None:
|
|
600
|
+
return shaped_protocol_extension
|
|
601
|
+
shaped_extension = _coerce_extension_spec(payload, owner_hint=owner_hint)
|
|
602
|
+
if shaped_extension is not None:
|
|
603
|
+
if shaped_extension.kind in {
|
|
604
|
+
"host.builder",
|
|
605
|
+
"settings.provider",
|
|
606
|
+
"infra.provider",
|
|
607
|
+
"runtime.manifest_contribution",
|
|
608
|
+
"lifecycle.contribution",
|
|
609
|
+
"worker.role",
|
|
610
|
+
"cli.tool",
|
|
611
|
+
"page.profile_provider",
|
|
612
|
+
"resource.contribution",
|
|
613
|
+
"protocol.registration",
|
|
614
|
+
}:
|
|
615
|
+
raise PzError(
|
|
616
|
+
code="PZ_EXTENSION_DECL_INVALID",
|
|
617
|
+
message=(
|
|
618
|
+
f"App '{owner_hint}' must declare '{shaped_extension.kind}' via the dedicated formal spec "
|
|
619
|
+
"instead of generic ExtensionSpec."
|
|
620
|
+
),
|
|
621
|
+
stage="extensions",
|
|
622
|
+
owner=owner_hint,
|
|
623
|
+
action="compile_extension_registry",
|
|
624
|
+
)
|
|
625
|
+
return shaped_extension
|
|
626
|
+
raise PzError(
|
|
627
|
+
code="PZ_EXTENSION_DECL_INVALID",
|
|
628
|
+
message=(
|
|
629
|
+
f"Extension declaration from '{owner_hint}' must be a formal protocol object "
|
|
630
|
+
"ExtensionSpec, HostBuilderSpec, SettingsProviderSpec, InfraProviderSpec, "
|
|
631
|
+
"RuntimeManifestContributionSpec, LifecycleContributionSpec, WorkerRoleSpec, "
|
|
632
|
+
"CliToolSpec, PageProfileProviderSpec, "
|
|
633
|
+
"ResourceContributionSpec, "
|
|
634
|
+
"ProtocolRegistrationSpec, or ProtocolExtensionSpec."
|
|
635
|
+
),
|
|
636
|
+
stage="extensions",
|
|
637
|
+
owner=owner_hint,
|
|
638
|
+
action="compile_extension_registry",
|
|
639
|
+
)
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def _load_app_declared_extensions(app_registry: AppRegistry) -> tuple[FormalExtensionSpec, ...]:
|
|
643
|
+
out: list[FormalExtensionSpec] = []
|
|
644
|
+
for app in app_registry.apps:
|
|
645
|
+
app_obj = load_app_object_from_decl(app)
|
|
646
|
+
normalized: list[FormalExtensionSpec] = []
|
|
647
|
+
extensions_factory = getattr(app_obj, "extensions", None)
|
|
648
|
+
if extensions_factory is None:
|
|
649
|
+
declared = ()
|
|
650
|
+
else:
|
|
651
|
+
if not callable(extensions_factory):
|
|
652
|
+
raise PzError(
|
|
653
|
+
code="PZ_APP_EXTENSIONS_INVALID",
|
|
654
|
+
message=f"App '{app.app_id}' exposes non-callable extensions().",
|
|
655
|
+
stage="extensions",
|
|
656
|
+
owner=app.app_id,
|
|
657
|
+
action="compile_extension_registry",
|
|
658
|
+
)
|
|
659
|
+
declared = extensions_factory()
|
|
660
|
+
if declared not in (None, (), []):
|
|
661
|
+
if not isinstance(declared, (list, tuple)):
|
|
662
|
+
raise PzError(
|
|
663
|
+
code="PZ_APP_EXTENSIONS_INVALID",
|
|
664
|
+
message=f"App '{app.app_id}' extensions() must return a list or tuple.",
|
|
665
|
+
stage="extensions",
|
|
666
|
+
owner=app.app_id,
|
|
667
|
+
action="compile_extension_registry",
|
|
668
|
+
)
|
|
669
|
+
normalized.extend(_normalize_decl(payload, owner_hint=app.app_id) for payload in declared)
|
|
670
|
+
normalized.extend(
|
|
671
|
+
_synthesized_lifecycle_contributions(
|
|
672
|
+
app,
|
|
673
|
+
app_obj,
|
|
674
|
+
declared=tuple(normalized),
|
|
675
|
+
)
|
|
676
|
+
)
|
|
677
|
+
out.extend(normalized)
|
|
678
|
+
return tuple(out)
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
def compile_extension_registry(
|
|
682
|
+
settings: SettingsSnapshot,
|
|
683
|
+
app_registry: AppRegistry,
|
|
684
|
+
) -> ExtensionRegistry:
|
|
685
|
+
project_dir = getattr(settings, "project_dir", None)
|
|
686
|
+
import_roots = getattr(settings, "import_roots", ())
|
|
687
|
+
with active_project_import_root(
|
|
688
|
+
project_dir,
|
|
689
|
+
extra_import_roots=import_roots,
|
|
690
|
+
):
|
|
691
|
+
registry = ExtensionRegistry(extensions=_load_app_declared_extensions(app_registry))
|
|
692
|
+
registry.validate()
|
|
693
|
+
return registry
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
__all__ = ["compile_extension_registry"]
|