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,558 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable, Sequence
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from dataclasses import dataclass, replace
|
|
6
|
+
from importlib import invalidate_caches
|
|
7
|
+
import json
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import site
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from pz_core.runtime.errors import PzError, as_pz_error
|
|
15
|
+
|
|
16
|
+
from .app_init_service import (
|
|
17
|
+
AppInitSourcePlan,
|
|
18
|
+
AppInitSourcesResult,
|
|
19
|
+
SourcePackageInstallResult,
|
|
20
|
+
build_app_init_source_plan,
|
|
21
|
+
init_project_source_apps,
|
|
22
|
+
)
|
|
23
|
+
from .app_versions import (
|
|
24
|
+
declare_app_version,
|
|
25
|
+
query_app_versions,
|
|
26
|
+
reconcile_project_environment,
|
|
27
|
+
resolve_app_version,
|
|
28
|
+
)
|
|
29
|
+
from .dev_git import BaseBranch
|
|
30
|
+
from .dev_import import cache_git_source, import_cached_apps
|
|
31
|
+
from .dev_sources import (
|
|
32
|
+
DevTransactionResult,
|
|
33
|
+
InitDevSourcesRequest,
|
|
34
|
+
initialize_dev_sources,
|
|
35
|
+
)
|
|
36
|
+
from .project_settings_service import update_settings_file
|
|
37
|
+
from .ide_projection import sync_ide_projections
|
|
38
|
+
from .project_metadata_service import update_project_uv_sources
|
|
39
|
+
from .project_state import ensure_business_app_identity, ensure_project_state
|
|
40
|
+
from pz_core.project_sources import load_official_source_catalog
|
|
41
|
+
from .release import PublishResult, publish_app
|
|
42
|
+
from .scaffold_service import ensure_default_local_app, ensure_project_scaffold
|
|
43
|
+
from .sync_service import sync_project_targets
|
|
44
|
+
from .venv_service import (
|
|
45
|
+
ProjectVirtualenvResult,
|
|
46
|
+
ensure_project_virtualenv,
|
|
47
|
+
resolve_virtualenv_python,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
ProgressReporter = Callable[[str], None]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@contextmanager
|
|
55
|
+
def _source_plan_import_paths(
|
|
56
|
+
plan: AppInitSourcePlan,
|
|
57
|
+
*,
|
|
58
|
+
project_venv: Path | None,
|
|
59
|
+
action: str,
|
|
60
|
+
):
|
|
61
|
+
original = tuple(sys.path)
|
|
62
|
+
try:
|
|
63
|
+
if project_venv is not None:
|
|
64
|
+
for site_packages in _project_venv_site_packages(
|
|
65
|
+
project_venv,
|
|
66
|
+
action=action,
|
|
67
|
+
):
|
|
68
|
+
site.addsitedir(str(site_packages))
|
|
69
|
+
if project_venv is None:
|
|
70
|
+
source_roots: list[str] = []
|
|
71
|
+
for package in plan.packages:
|
|
72
|
+
root = str(package.package_root)
|
|
73
|
+
if root not in source_roots:
|
|
74
|
+
source_roots.append(root)
|
|
75
|
+
for root in reversed(source_roots):
|
|
76
|
+
while root in sys.path:
|
|
77
|
+
sys.path.remove(root)
|
|
78
|
+
sys.path.insert(0, root)
|
|
79
|
+
invalidate_caches()
|
|
80
|
+
yield
|
|
81
|
+
finally:
|
|
82
|
+
sys.path[:] = original
|
|
83
|
+
invalidate_caches()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _project_venv_site_packages(
|
|
87
|
+
project_venv: Path,
|
|
88
|
+
*,
|
|
89
|
+
action: str,
|
|
90
|
+
) -> tuple[Path, ...]:
|
|
91
|
+
python = resolve_virtualenv_python(project_venv, action=action)
|
|
92
|
+
completed = subprocess.run(
|
|
93
|
+
(
|
|
94
|
+
str(python),
|
|
95
|
+
"-c",
|
|
96
|
+
"import json, site; print(json.dumps(site.getsitepackages()))",
|
|
97
|
+
),
|
|
98
|
+
check=False,
|
|
99
|
+
capture_output=True,
|
|
100
|
+
text=True,
|
|
101
|
+
)
|
|
102
|
+
if completed.returncode != 0:
|
|
103
|
+
raise PzError(
|
|
104
|
+
code="PZ_APP_INIT_VENV_INSPECTION_FAILED",
|
|
105
|
+
message="failed to inspect project virtualenv import paths.",
|
|
106
|
+
stage="app_init",
|
|
107
|
+
owner="pz_core.authoring.orchestration_service",
|
|
108
|
+
action=action,
|
|
109
|
+
detail=(completed.stderr or completed.stdout or "site inspection failed").strip(),
|
|
110
|
+
)
|
|
111
|
+
try:
|
|
112
|
+
payload = json.loads(completed.stdout)
|
|
113
|
+
except json.JSONDecodeError as exc:
|
|
114
|
+
raise PzError(
|
|
115
|
+
code="PZ_APP_INIT_VENV_INSPECTION_FAILED",
|
|
116
|
+
message="project virtualenv returned invalid import path metadata.",
|
|
117
|
+
stage="app_init",
|
|
118
|
+
owner="pz_core.authoring.orchestration_service",
|
|
119
|
+
action=action,
|
|
120
|
+
detail=str(exc),
|
|
121
|
+
) from exc
|
|
122
|
+
if not isinstance(payload, list) or not all(
|
|
123
|
+
isinstance(item, str) and item.strip() for item in payload
|
|
124
|
+
):
|
|
125
|
+
raise PzError(
|
|
126
|
+
code="PZ_APP_INIT_VENV_INSPECTION_FAILED",
|
|
127
|
+
message="project virtualenv returned invalid import path metadata.",
|
|
128
|
+
stage="app_init",
|
|
129
|
+
owner="pz_core.authoring.orchestration_service",
|
|
130
|
+
action=action,
|
|
131
|
+
)
|
|
132
|
+
return tuple(Path(item).resolve() for item in payload)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@dataclass(frozen=True, slots=True)
|
|
136
|
+
class DevInitPreparationResult:
|
|
137
|
+
business_app_id: str
|
|
138
|
+
scaffold_created: bool
|
|
139
|
+
default_app_id: str | None
|
|
140
|
+
default_app_created: bool
|
|
141
|
+
project_venv: ProjectVirtualenvResult | None
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@dataclass(frozen=True, slots=True)
|
|
145
|
+
class EnvInstallExecutionResult:
|
|
146
|
+
project_venv: ProjectVirtualenvResult
|
|
147
|
+
synced_targets: tuple[Any, ...]
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@dataclass(frozen=True, slots=True)
|
|
151
|
+
class EnvInitExecutionResult:
|
|
152
|
+
initialized_project: bool
|
|
153
|
+
project_venv: ProjectVirtualenvResult | None
|
|
154
|
+
synced_targets: tuple[Any, ...]
|
|
155
|
+
settings_path: Path
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass(frozen=True, slots=True)
|
|
159
|
+
class EnvSyncExecutionResult:
|
|
160
|
+
synced_targets: tuple[Any, ...]
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@dataclass(frozen=True, slots=True)
|
|
164
|
+
class AppInitExecutionResult:
|
|
165
|
+
source_apps: AppInitSourcesResult
|
|
166
|
+
project_venv: ProjectVirtualenvResult | None
|
|
167
|
+
source_install: SourcePackageInstallResult
|
|
168
|
+
synced_targets: tuple[Any, ...]
|
|
169
|
+
settings_path: Path | None = None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@dataclass(frozen=True, slots=True)
|
|
173
|
+
class PublishBatchExecutionResult:
|
|
174
|
+
results: tuple[PublishResult, ...]
|
|
175
|
+
summary_message: str
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def prepare_dev_init_project(
|
|
179
|
+
project_dir: Path,
|
|
180
|
+
*,
|
|
181
|
+
app_name: str | None,
|
|
182
|
+
action: str,
|
|
183
|
+
) -> DevInitPreparationResult:
|
|
184
|
+
identity = ensure_business_app_identity(
|
|
185
|
+
project_dir,
|
|
186
|
+
app_name=app_name,
|
|
187
|
+
action=action,
|
|
188
|
+
)
|
|
189
|
+
scaffold_result = ensure_project_scaffold(project_dir)
|
|
190
|
+
ensure_project_state(project_dir, action=action)
|
|
191
|
+
default_app_result = ensure_default_local_app(
|
|
192
|
+
project_dir,
|
|
193
|
+
app_name=identity.business_app_id,
|
|
194
|
+
scaffold_created=scaffold_result.created,
|
|
195
|
+
action=action,
|
|
196
|
+
)
|
|
197
|
+
return DevInitPreparationResult(
|
|
198
|
+
business_app_id=identity.business_app_id,
|
|
199
|
+
scaffold_created=scaffold_result.created,
|
|
200
|
+
default_app_id=default_app_result.app_id,
|
|
201
|
+
default_app_created=default_app_result.created,
|
|
202
|
+
project_venv=None,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def execute_env_install(
|
|
207
|
+
project_dir: Path,
|
|
208
|
+
*,
|
|
209
|
+
action: str,
|
|
210
|
+
groups: Sequence[str] = (),
|
|
211
|
+
extras: Sequence[str] = (),
|
|
212
|
+
reinstall_packages: Sequence[str] = (),
|
|
213
|
+
project_only: bool = False,
|
|
214
|
+
existing_project_venv: ProjectVirtualenvResult | None = None,
|
|
215
|
+
sync_targets: Callable[..., tuple[Any, ...]] | None = None,
|
|
216
|
+
) -> EnvInstallExecutionResult:
|
|
217
|
+
project_venv = existing_project_venv or ensure_project_virtualenv(
|
|
218
|
+
project_dir, action=action
|
|
219
|
+
)
|
|
220
|
+
synced_targets = (
|
|
221
|
+
sync_targets
|
|
222
|
+
if sync_targets is not None
|
|
223
|
+
else lambda path, **kwargs: sync_project_targets(path, action=action, **kwargs)
|
|
224
|
+
)(
|
|
225
|
+
project_dir,
|
|
226
|
+
groups=tuple(groups),
|
|
227
|
+
extras=tuple(extras),
|
|
228
|
+
reinstall_packages=tuple(reinstall_packages),
|
|
229
|
+
project_only=project_only,
|
|
230
|
+
)
|
|
231
|
+
return EnvInstallExecutionResult(
|
|
232
|
+
project_venv=project_venv,
|
|
233
|
+
synced_targets=synced_targets,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def execute_dev_init(
|
|
238
|
+
project_dir: Path,
|
|
239
|
+
*,
|
|
240
|
+
app_name: str | None,
|
|
241
|
+
base_branch: BaseBranch,
|
|
242
|
+
clone_sources: bool,
|
|
243
|
+
link: bool = False,
|
|
244
|
+
source_dir: str | None = None,
|
|
245
|
+
no_sync: bool,
|
|
246
|
+
action: str,
|
|
247
|
+
progress_reporter: ProgressReporter | None = None,
|
|
248
|
+
) -> tuple[DevInitPreparationResult, DevTransactionResult]:
|
|
249
|
+
if progress_reporter is not None:
|
|
250
|
+
progress_reporter(f"Preparing project scaffold in {project_dir}.")
|
|
251
|
+
preparation = prepare_dev_init_project(
|
|
252
|
+
project_dir, app_name=app_name, action=action
|
|
253
|
+
)
|
|
254
|
+
if progress_reporter is not None:
|
|
255
|
+
if preparation.scaffold_created:
|
|
256
|
+
progress_reporter("Project scaffold is ready.")
|
|
257
|
+
if preparation.default_app_created and preparation.default_app_id is not None:
|
|
258
|
+
progress_reporter(
|
|
259
|
+
f"Default local app `{preparation.default_app_id}` is ready."
|
|
260
|
+
)
|
|
261
|
+
if link and clone_sources == (source_dir is not None):
|
|
262
|
+
raise PzError(
|
|
263
|
+
code="PZ_DEV_INIT_SOURCE_SELECTOR_INVALID",
|
|
264
|
+
message="pz dev init --link 必须且只能指定 --clone-sources 或 --source-dir。",
|
|
265
|
+
stage="dev",
|
|
266
|
+
owner="pz_core.authoring.orchestration_service",
|
|
267
|
+
action=action,
|
|
268
|
+
)
|
|
269
|
+
if not link and (clone_sources or source_dir is not None):
|
|
270
|
+
raise PzError(
|
|
271
|
+
code="PZ_DEV_INIT_SOURCE_SELECTOR_INVALID",
|
|
272
|
+
message="--clone-sources 和 --source-dir 只能与 --link 一起使用。",
|
|
273
|
+
stage="dev",
|
|
274
|
+
owner="pz_core.authoring.orchestration_service",
|
|
275
|
+
action=action,
|
|
276
|
+
)
|
|
277
|
+
if link:
|
|
278
|
+
if progress_reporter is not None:
|
|
279
|
+
progress_reporter("Binding the official pz bootstrap repository.")
|
|
280
|
+
shared_entry: Path | None = None
|
|
281
|
+
shared_entry_created = False
|
|
282
|
+
if source_dir is not None:
|
|
283
|
+
external = Path(source_dir).expanduser().resolve(strict=True)
|
|
284
|
+
if not external.is_dir() or not (external / ".git").exists():
|
|
285
|
+
raise PzError(
|
|
286
|
+
code="PZ_DEV_INIT_SOURCE_DIR_INVALID",
|
|
287
|
+
message="--source-dir 必须指向本地 pz Git checkout。",
|
|
288
|
+
stage="dev",
|
|
289
|
+
owner="pz_core.authoring.orchestration_service",
|
|
290
|
+
action=action,
|
|
291
|
+
)
|
|
292
|
+
shared_entry = project_dir / "apps" / ".sources" / "pz"
|
|
293
|
+
shared_entry.parent.mkdir(parents=True, exist_ok=True)
|
|
294
|
+
if shared_entry.is_symlink():
|
|
295
|
+
if shared_entry.resolve(strict=True) != external:
|
|
296
|
+
raise PzError(
|
|
297
|
+
code="PZ_DEV_SOURCE_CONFLICT",
|
|
298
|
+
message="apps/.sources/pz 已指向另一个共享 checkout。",
|
|
299
|
+
stage="dev",
|
|
300
|
+
owner="pz_core.authoring.orchestration_service",
|
|
301
|
+
action=action,
|
|
302
|
+
)
|
|
303
|
+
elif shared_entry.exists():
|
|
304
|
+
raise PzError(
|
|
305
|
+
code="PZ_DEV_SOURCE_CONFLICT",
|
|
306
|
+
message="apps/.sources/pz 已被现有路径占用。",
|
|
307
|
+
stage="dev",
|
|
308
|
+
owner="pz_core.authoring.orchestration_service",
|
|
309
|
+
action=action,
|
|
310
|
+
)
|
|
311
|
+
else:
|
|
312
|
+
shared_entry.symlink_to(external, target_is_directory=True)
|
|
313
|
+
shared_entry_created = True
|
|
314
|
+
try:
|
|
315
|
+
dev_sources = initialize_dev_sources(
|
|
316
|
+
InitDevSourcesRequest(
|
|
317
|
+
project_dir=project_dir,
|
|
318
|
+
app_name=preparation.business_app_id,
|
|
319
|
+
locators=("pz", "pz_settings_center", "pz_foundation"),
|
|
320
|
+
base_branch=base_branch,
|
|
321
|
+
)
|
|
322
|
+
)
|
|
323
|
+
except Exception:
|
|
324
|
+
if shared_entry_created and shared_entry is not None:
|
|
325
|
+
shared_entry.unlink(missing_ok=True)
|
|
326
|
+
raise
|
|
327
|
+
metadata = update_project_uv_sources(project_dir, action=action)
|
|
328
|
+
init_project_source_apps(project_dir, action=action, plan=metadata.plan)
|
|
329
|
+
else:
|
|
330
|
+
if progress_reporter is not None:
|
|
331
|
+
progress_reporter("Caching and importing official pz_apps source.")
|
|
332
|
+
root = load_official_source_catalog()["pz_apps"]
|
|
333
|
+
cache = cache_git_source(
|
|
334
|
+
repo_key=root.repo_key,
|
|
335
|
+
source=root.source,
|
|
336
|
+
branch="develop",
|
|
337
|
+
action=action,
|
|
338
|
+
)
|
|
339
|
+
app_specs = tuple(
|
|
340
|
+
(child.expected_app_id, child.subpath)
|
|
341
|
+
for child in root.children.values()
|
|
342
|
+
if child.kind == "app" and child.expected_app_id is not None
|
|
343
|
+
)
|
|
344
|
+
imported = import_cached_apps(
|
|
345
|
+
cache,
|
|
346
|
+
project_dir=project_dir,
|
|
347
|
+
apps=app_specs,
|
|
348
|
+
action=action,
|
|
349
|
+
)
|
|
350
|
+
dev_sources = DevTransactionResult(
|
|
351
|
+
operation="init",
|
|
352
|
+
project_dir=project_dir,
|
|
353
|
+
business_branch=preparation.business_app_id,
|
|
354
|
+
base_branch=base_branch,
|
|
355
|
+
repo_keys=(),
|
|
356
|
+
checkouts=(),
|
|
357
|
+
bindings=tuple(item.app_id for item in imported),
|
|
358
|
+
links=tuple(item.destination for item in imported),
|
|
359
|
+
)
|
|
360
|
+
settings_result = update_settings_file(project_dir)
|
|
361
|
+
if not no_sync:
|
|
362
|
+
if progress_reporter is not None:
|
|
363
|
+
progress_reporter("Running initial environment install.")
|
|
364
|
+
install_result = execute_env_install(
|
|
365
|
+
project_dir,
|
|
366
|
+
action=action,
|
|
367
|
+
existing_project_venv=preparation.project_venv,
|
|
368
|
+
)
|
|
369
|
+
preparation = replace(preparation, project_venv=install_result.project_venv)
|
|
370
|
+
if progress_reporter is not None:
|
|
371
|
+
progress_reporter(
|
|
372
|
+
f"Initial environment install finished for {len(install_result.synced_targets)} target(s)."
|
|
373
|
+
)
|
|
374
|
+
if progress_reporter is not None:
|
|
375
|
+
progress_reporter(f"Managed settings are ready at {settings_result.path}.")
|
|
376
|
+
sync_ide_projections(project_dir)
|
|
377
|
+
return preparation, dev_sources
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def execute_env_init(
|
|
381
|
+
project_dir: Path,
|
|
382
|
+
*,
|
|
383
|
+
action: str,
|
|
384
|
+
no_sync: bool,
|
|
385
|
+
) -> EnvInitExecutionResult:
|
|
386
|
+
scaffold_result = ensure_project_scaffold(project_dir)
|
|
387
|
+
settings_result = update_settings_file(project_dir)
|
|
388
|
+
install_result: EnvInstallExecutionResult | None = None
|
|
389
|
+
if not no_sync:
|
|
390
|
+
install_result = execute_env_install(project_dir, action=action)
|
|
391
|
+
return EnvInitExecutionResult(
|
|
392
|
+
initialized_project=scaffold_result.created,
|
|
393
|
+
project_venv=None if install_result is None else install_result.project_venv,
|
|
394
|
+
synced_targets=() if install_result is None else install_result.synced_targets,
|
|
395
|
+
settings_path=settings_result.path,
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def execute_env_sync(
|
|
400
|
+
project_dir: Path,
|
|
401
|
+
*,
|
|
402
|
+
groups: Sequence[str],
|
|
403
|
+
extras: Sequence[str],
|
|
404
|
+
reinstall_packages: Sequence[str],
|
|
405
|
+
project_only: bool,
|
|
406
|
+
sync_targets: Callable[..., tuple[Any, ...]],
|
|
407
|
+
) -> EnvSyncExecutionResult:
|
|
408
|
+
synced_targets = sync_targets(
|
|
409
|
+
project_dir,
|
|
410
|
+
groups=tuple(groups),
|
|
411
|
+
extras=tuple(extras),
|
|
412
|
+
reinstall_packages=tuple(reinstall_packages),
|
|
413
|
+
project_only=project_only,
|
|
414
|
+
)
|
|
415
|
+
return EnvSyncExecutionResult(synced_targets=synced_targets)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def execute_app_init(
|
|
419
|
+
project_dir: Path,
|
|
420
|
+
*,
|
|
421
|
+
no_sync: bool,
|
|
422
|
+
action: str,
|
|
423
|
+
) -> AppInitExecutionResult:
|
|
424
|
+
ensure_project_scaffold(project_dir)
|
|
425
|
+
ensure_project_state(project_dir, action=action)
|
|
426
|
+
plan = build_app_init_source_plan(project_dir, action=action)
|
|
427
|
+
exact_versions: dict[str, str] = {}
|
|
428
|
+
for package in plan.app_packages:
|
|
429
|
+
state = query_app_versions(
|
|
430
|
+
package.app_id,
|
|
431
|
+
project_dir=project_dir,
|
|
432
|
+
action=action,
|
|
433
|
+
)
|
|
434
|
+
exact_versions[package.app_id] = resolve_app_version(
|
|
435
|
+
state,
|
|
436
|
+
None,
|
|
437
|
+
project_dir=project_dir,
|
|
438
|
+
action=action,
|
|
439
|
+
)
|
|
440
|
+
source_apps = init_project_source_apps(
|
|
441
|
+
project_dir,
|
|
442
|
+
action=action,
|
|
443
|
+
plan=plan,
|
|
444
|
+
)
|
|
445
|
+
for package in plan.app_packages:
|
|
446
|
+
declare_app_version(
|
|
447
|
+
package.app_id,
|
|
448
|
+
exact_versions[package.app_id],
|
|
449
|
+
project_dir=project_dir,
|
|
450
|
+
action=action,
|
|
451
|
+
)
|
|
452
|
+
project_venv: ProjectVirtualenvResult | None = None
|
|
453
|
+
source_install = SourcePackageInstallResult(
|
|
454
|
+
distributions=(),
|
|
455
|
+
install_target=None,
|
|
456
|
+
install_targets=(),
|
|
457
|
+
python=None,
|
|
458
|
+
command=(),
|
|
459
|
+
)
|
|
460
|
+
synced_targets: tuple[Any, ...] = ()
|
|
461
|
+
if not no_sync:
|
|
462
|
+
project_venv = ensure_project_virtualenv(project_dir, action=action)
|
|
463
|
+
if plan.app_packages:
|
|
464
|
+
first = plan.app_packages[0]
|
|
465
|
+
reconcile_project_environment(
|
|
466
|
+
first.app_id,
|
|
467
|
+
project_dir=project_dir,
|
|
468
|
+
action=action,
|
|
469
|
+
)
|
|
470
|
+
for package in plan.app_packages:
|
|
471
|
+
expected = exact_versions[package.app_id]
|
|
472
|
+
state = query_app_versions(
|
|
473
|
+
package.app_id,
|
|
474
|
+
project_dir=project_dir,
|
|
475
|
+
action=action,
|
|
476
|
+
)
|
|
477
|
+
if state.locked != expected or state.installed != expected:
|
|
478
|
+
raise PzError(
|
|
479
|
+
code="PZ_APP_VERSION_STATE_MISMATCH",
|
|
480
|
+
message=f"{package.distribution} did not converge to {expected}.",
|
|
481
|
+
stage="app_init",
|
|
482
|
+
owner="pz_core.authoring.orchestration_service",
|
|
483
|
+
action=action,
|
|
484
|
+
detail=f"locked={state.locked!r}; installed={state.installed!r}",
|
|
485
|
+
)
|
|
486
|
+
source_install = SourcePackageInstallResult(
|
|
487
|
+
distributions=tuple(
|
|
488
|
+
f"{package.distribution}=={exact_versions[package.app_id]}"
|
|
489
|
+
for package in plan.app_packages
|
|
490
|
+
),
|
|
491
|
+
install_target=None,
|
|
492
|
+
install_targets=(),
|
|
493
|
+
python=resolve_virtualenv_python(project_venv.path, action=action),
|
|
494
|
+
command=("uv", "sync", "--active"),
|
|
495
|
+
)
|
|
496
|
+
with _source_plan_import_paths(
|
|
497
|
+
plan,
|
|
498
|
+
project_venv=None if project_venv is None else project_venv.path,
|
|
499
|
+
action=action,
|
|
500
|
+
):
|
|
501
|
+
settings_path = update_settings_file(project_dir).path
|
|
502
|
+
return AppInitExecutionResult(
|
|
503
|
+
source_apps=source_apps,
|
|
504
|
+
project_venv=project_venv,
|
|
505
|
+
source_install=source_install,
|
|
506
|
+
synced_targets=synced_targets,
|
|
507
|
+
settings_path=settings_path,
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def execute_publish_batch(
|
|
512
|
+
app_ids: Sequence[str],
|
|
513
|
+
*,
|
|
514
|
+
project_dir: Path,
|
|
515
|
+
target_name: str | None,
|
|
516
|
+
dry_run: bool,
|
|
517
|
+
action: str,
|
|
518
|
+
) -> PublishBatchExecutionResult:
|
|
519
|
+
results: list[PublishResult] = []
|
|
520
|
+
for raw_app_id in app_ids:
|
|
521
|
+
try:
|
|
522
|
+
result = publish_app(
|
|
523
|
+
raw_app_id,
|
|
524
|
+
project_dir=project_dir,
|
|
525
|
+
target_name=target_name,
|
|
526
|
+
dry_run=dry_run,
|
|
527
|
+
action=action,
|
|
528
|
+
)
|
|
529
|
+
except Exception as exc:
|
|
530
|
+
if not results:
|
|
531
|
+
raise
|
|
532
|
+
root_error = as_pz_error(
|
|
533
|
+
exc, owner="pz_core.authoring", action=action, stage="cli"
|
|
534
|
+
)
|
|
535
|
+
completed = ", ".join(result.app_id for result in results)
|
|
536
|
+
raise PzError(
|
|
537
|
+
code="PZ_SCAFFOLD_PUBLISH_BATCH_FAILED",
|
|
538
|
+
message=(
|
|
539
|
+
f"batch publish stopped at `{raw_app_id}` after "
|
|
540
|
+
f"{len(results)} successful publish(es)."
|
|
541
|
+
),
|
|
542
|
+
stage="cli",
|
|
543
|
+
owner="pz_core.authoring",
|
|
544
|
+
action=action,
|
|
545
|
+
detail=(
|
|
546
|
+
f"completed: {completed}; "
|
|
547
|
+
f"failed: {root_error.code}: {root_error.message}"
|
|
548
|
+
),
|
|
549
|
+
) from exc
|
|
550
|
+
results.append(result)
|
|
551
|
+
summary_message = (
|
|
552
|
+
f"Completed batch publish for {len(results)} package(s) using target "
|
|
553
|
+
f"{results[0].target.name if results else (target_name or 'default')}: "
|
|
554
|
+
f"{', '.join(result.app_id for result in results)}."
|
|
555
|
+
)
|
|
556
|
+
return PublishBatchExecutionResult(
|
|
557
|
+
results=tuple(results), summary_message=summary_message
|
|
558
|
+
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"installed_apps": [],
|
|
3
|
+
"commands": {
|
|
4
|
+
// npm-like project root command extension point.
|
|
5
|
+
// string -> shell command
|
|
6
|
+
// array -> argv execution
|
|
7
|
+
// object -> {"command": "..."} or {"argv": ["..."], "description": "..."}
|
|
8
|
+
},
|
|
9
|
+
"project": {
|
|
10
|
+
"name": "PZ Project",
|
|
11
|
+
"default_module": "base",
|
|
12
|
+
"site_theme": "default",
|
|
13
|
+
// Single service base URL. Local/IP URLs may be adjusted by explicit
|
|
14
|
+
// APP_HOST or APP_PORT runtime overrides; domain URLs stay canonical.
|
|
15
|
+
"base_url": "http://127.0.0.1:8000",
|
|
16
|
+
"app_host": "0.0.0.0",
|
|
17
|
+
"api_v1_str": "/api/v1",
|
|
18
|
+
"static_version": 1,
|
|
19
|
+
"settings_backup_keep_count": 15,
|
|
20
|
+
"app_port": 8000,
|
|
21
|
+
"app_workers": 1,
|
|
22
|
+
"app_reload": false,
|
|
23
|
+
"static_target_path": "",
|
|
24
|
+
"static_target_owner": "",
|
|
25
|
+
"asset_dir": ".assets"
|
|
26
|
+
},
|
|
27
|
+
"resources": {
|
|
28
|
+
// Formal resource items that pz will discover inside each app package
|
|
29
|
+
// and merge in installed_apps order during startup compilation.
|
|
30
|
+
"items": [
|
|
31
|
+
{ "name": "templates" },
|
|
32
|
+
{ "name": "static" },
|
|
33
|
+
{ "name": "locales" },
|
|
34
|
+
{ "name": "pages" },
|
|
35
|
+
{ "name": "template_config" },
|
|
36
|
+
{ "name": "migrations" }
|
|
37
|
+
],
|
|
38
|
+
// Root directory under cache_dir that stores merged resource artifacts.
|
|
39
|
+
"output_root": "resources",
|
|
40
|
+
// Manifest file name written under output_root.
|
|
41
|
+
"manifest_name": "manifest.json",
|
|
42
|
+
// Temporary staging directory name under output_root used before atomic swap/publish.
|
|
43
|
+
"staging_dir": "staging",
|
|
44
|
+
// Lock file name written under runtime_dir/locks for resource compilation.
|
|
45
|
+
"lock_name": "resources.lock"
|
|
46
|
+
},
|
|
47
|
+
"routing": {},
|
|
48
|
+
"events": {
|
|
49
|
+
"declared": {}
|
|
50
|
+
},
|
|
51
|
+
"app_replacements": {},
|
|
52
|
+
"apps": {}
|
|
53
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pz_core.utils.project_jsonc import load_jsonc_file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
PROJECT_DEFAULT_JSONC_NAME = "project_default.jsonc"
|
|
10
|
+
_MANAGED_ROOT_KEYS = frozenset({"installed_apps", "middlewares"})
|
|
11
|
+
_OMIT = object()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def project_default_jsonc_path() -> Path:
|
|
15
|
+
return Path(__file__).resolve().with_name(PROJECT_DEFAULT_JSONC_NAME)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def load_project_default_jsonc_payload() -> dict[str, Any]:
|
|
19
|
+
payload = load_jsonc_file(
|
|
20
|
+
project_default_jsonc_path(),
|
|
21
|
+
code="PZ_PROJECT_DEFAULTS_INVALID",
|
|
22
|
+
owner="pz_core.authoring",
|
|
23
|
+
action="load_project_defaults",
|
|
24
|
+
)
|
|
25
|
+
if not isinstance(payload, dict):
|
|
26
|
+
return {}
|
|
27
|
+
return dict(payload)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def build_project_scaffold_payload(*, installed_apps: list[str] | None = None) -> dict[str, Any]:
|
|
31
|
+
return {
|
|
32
|
+
"installed_apps": list(installed_apps or []),
|
|
33
|
+
"commands": {},
|
|
34
|
+
"project": {
|
|
35
|
+
"static_version": 1,
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def compact_project_payload(payload: dict[str, Any]) -> dict[str, Any]:
|
|
41
|
+
defaults = load_project_default_jsonc_payload()
|
|
42
|
+
compacted = _compact_value(payload, defaults, at_root=True)
|
|
43
|
+
if not isinstance(compacted, dict):
|
|
44
|
+
return {}
|
|
45
|
+
return dict(compacted)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _compact_value(value: Any, default: Any, *, at_root: bool = False) -> Any:
|
|
49
|
+
if at_root and isinstance(value, dict):
|
|
50
|
+
compacted_root: dict[str, Any] = {}
|
|
51
|
+
default_mapping = default if isinstance(default, dict) else {}
|
|
52
|
+
for key, item in value.items():
|
|
53
|
+
if key in _MANAGED_ROOT_KEYS:
|
|
54
|
+
compacted_root[key] = item
|
|
55
|
+
continue
|
|
56
|
+
compacted = _compact_value(item, default_mapping.get(key, _OMIT))
|
|
57
|
+
if compacted is _OMIT:
|
|
58
|
+
continue
|
|
59
|
+
compacted_root[key] = compacted
|
|
60
|
+
return compacted_root
|
|
61
|
+
|
|
62
|
+
if isinstance(value, dict):
|
|
63
|
+
default_mapping = default if isinstance(default, dict) else None
|
|
64
|
+
compacted_mapping: dict[str, Any] = {}
|
|
65
|
+
for key, item in value.items():
|
|
66
|
+
next_default = default_mapping.get(key, _OMIT) if isinstance(default_mapping, dict) else _OMIT
|
|
67
|
+
compacted = _compact_value(item, next_default)
|
|
68
|
+
if compacted is _OMIT:
|
|
69
|
+
continue
|
|
70
|
+
compacted_mapping[key] = compacted
|
|
71
|
+
if compacted_mapping:
|
|
72
|
+
return compacted_mapping
|
|
73
|
+
if isinstance(default_mapping, dict):
|
|
74
|
+
return _OMIT
|
|
75
|
+
return value
|
|
76
|
+
|
|
77
|
+
if default is not _OMIT and value == default:
|
|
78
|
+
return _OMIT
|
|
79
|
+
return value
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
__all__ = [
|
|
83
|
+
"PROJECT_DEFAULT_JSONC_NAME",
|
|
84
|
+
"build_project_scaffold_payload",
|
|
85
|
+
"compact_project_payload",
|
|
86
|
+
"load_project_default_jsonc_payload",
|
|
87
|
+
"project_default_jsonc_path",
|
|
88
|
+
]
|