pulse-engine 0.2.22__tar.gz → 0.2.23__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/PKG-INFO +1 -1
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/pyproject.toml +1 -1
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/pipeline_sync.py +9 -2
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/middleware/tenant.py +13 -1
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/config_parser.py +39 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/router_pipelines.py +62 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/schemas.py +10 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/service.py +4 -1
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/README.md +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/audio_transcription.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/batcher.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/digital_news.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/digital_news_metadata.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/document_event_campaign_mapper.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/exceptions.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/mart_export.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/models.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/opensearch_sql.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/opensearch_storage.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/prompts.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/report_generator.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/speech_content.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/speech_metadata.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/base.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/config.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/factory.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/providers/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/providers/deepgram.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/providers/openai_whisper.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/providers/selfhosted_job.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/providers/youtube_captions.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/service.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/source.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/twitter.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/youtube_downloader.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/youtube_metadata.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/api/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/api/v1/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/api/v1/auth.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/api/v1/health.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/api/v1/router.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/main.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/cookiecutter.json +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/.gitignore +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/Dockerfile +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/pipeline.yaml +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/pyproject.toml +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/src/pulse_{{cookiecutter.product_slug}}/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/tests/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/tests/unit/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/pulse-{{cookiecutter.product_name}}/tests/unit/test_manifest.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/client.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/config.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/core/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/core/error_handlers.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/core/exceptions.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/core/job_token.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/core/logging.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/core/scope.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/core/security.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/models.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/repository.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/router.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/runner.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/schemas.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/service.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/tasks.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cron/translator.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/database.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/dependencies.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/deployment/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/deployment/infra_provisioner.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/evolution/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/evolution/adapter.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/evolution/client.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/evolution/models.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/evolution/router.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/evolution/service.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/extractor/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/extractor/adapters/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/extractor/base.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/main.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/mcp/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/mcp/__main__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/mcp/server.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/mcp/tools_kb.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/mcp/tools_modules.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/mcp/tools_pipelines.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/mcp/tools_processor.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/middleware/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/middleware/rate_limit.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/middleware/request_id.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/middleware/security_headers.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/notifications/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/notifications/apprise_notifier.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/expression.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/models.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/repositories.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/router_modules.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/airflow_status.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/airflow_translator.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/base.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/prefect_status.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/prefect_translator.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/base.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/core/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/core/analysis.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/core/chunking.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/core/prompts.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/core/topic_splitter.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/defaults/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/defaults/core_processor.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/defaults/postprocessor.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/defaults/preprocessor.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/llm/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/llm/provider.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/ocr/gemini.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/pipeline.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/postprocessor/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/postprocessor/embeddings.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/postprocessor/tasks.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/preprocessor/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/preprocessor/tasks.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/router.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/schemas.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/registry.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/agent.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/fixtures.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/models.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/prompts.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/service.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/tools.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/reporting/wiring.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/runners/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/runners/lambda_runner.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/runners/pipeline_runner.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/runners/prefect_pipeline_flow.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/runners/prefect_runner.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/s3.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/backend.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/lambda_microvm.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/microvm_agent/Dockerfile +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/microvm_agent/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/microvm_agent/server.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/session.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/secrets.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/services/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/services/bootstrap.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/services/opensearch.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/catalog.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/models.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/repo.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/seed.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/seed_data/skill_files.json +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/seed_data/skills.json +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/sync.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/tools.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/connectors/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/connectors/athena.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/connectors/base.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/connectors/opensearch.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/knowledge_base.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/router.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/schemas.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/testing/__init__.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/testing/fixtures.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/testing/mocks.py +0 -0
- {pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/worker.py +0 -0
|
@@ -76,16 +76,23 @@ async def sync_pipeline_schedules(session: AsyncSession, settings: Settings) ->
|
|
|
76
76
|
continue
|
|
77
77
|
|
|
78
78
|
name = config.deployment_name
|
|
79
|
+
# Internal trigger endpoint: authenticated by the shared cron-internal
|
|
80
|
+
# token (not a tenant Bearer token) and accepts a JSON body, so the
|
|
81
|
+
# generic cron_job_flow can fire it without Cognito creds or multipart.
|
|
79
82
|
trigger_url = (
|
|
80
|
-
f"{settings.pulse_engine_url.rstrip('/')}
|
|
83
|
+
f"{settings.pulse_engine_url.rstrip('/')}"
|
|
84
|
+
"/api/v1/pipelines/trigger-internal"
|
|
81
85
|
if settings.pulse_engine_url
|
|
82
|
-
else "/api/v1/pipelines/trigger"
|
|
86
|
+
else "/api/v1/pipelines/trigger-internal"
|
|
83
87
|
)
|
|
84
88
|
|
|
85
89
|
await repo.upsert(
|
|
86
90
|
tenant_id=tenant_id,
|
|
87
91
|
name=name,
|
|
88
92
|
webhook_url=trigger_url,
|
|
93
|
+
webhook_headers={
|
|
94
|
+
"X-Cron-Internal-Token": settings.pulse_cron_internal_token
|
|
95
|
+
},
|
|
89
96
|
schedule=config.infra.schedule,
|
|
90
97
|
payload={"pipeline_name": config.name, "yaml_path": str(yaml_path)},
|
|
91
98
|
job_type="pipeline",
|
|
@@ -30,6 +30,13 @@ PUBLIC_PATHS = {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
# Paths authenticated by the shared X-Cron-Internal-Token (verified in-endpoint)
|
|
34
|
+
# rather than a tenant Bearer token — must bypass TenantMiddleware resolution.
|
|
35
|
+
INTERNAL_TOKEN_PATHS = {
|
|
36
|
+
"/api/v1/pipelines/trigger-internal",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
33
40
|
def _is_cron_internal_path(path: str) -> bool:
|
|
34
41
|
"""True for cron callback endpoints authenticated via X-Cron-Internal-Token."""
|
|
35
42
|
# /api/v1/cron-jobs/{job_id}/runs/init
|
|
@@ -54,7 +61,12 @@ class TenantMiddleware(BaseHTTPMiddleware):
|
|
|
54
61
|
async def dispatch(
|
|
55
62
|
self, request: Request, call_next: RequestResponseEndpoint
|
|
56
63
|
) -> Response:
|
|
57
|
-
|
|
64
|
+
path = request.url.path
|
|
65
|
+
if (
|
|
66
|
+
path in PUBLIC_PATHS
|
|
67
|
+
or path in INTERNAL_TOKEN_PATHS
|
|
68
|
+
or _is_cron_internal_path(path)
|
|
69
|
+
):
|
|
58
70
|
return await call_next(request)
|
|
59
71
|
|
|
60
72
|
try:
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterator
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
3
6
|
import yaml # type: ignore[import-untyped]
|
|
4
7
|
from pydantic import ValidationError
|
|
5
8
|
|
|
@@ -35,6 +38,42 @@ def parse_pipeline_config(yaml_content: str) -> PipelineConfig:
|
|
|
35
38
|
return config
|
|
36
39
|
|
|
37
40
|
|
|
41
|
+
def iter_pipeline_configs(pipeline_dirs: str) -> Iterator[tuple[Path, PipelineConfig]]:
|
|
42
|
+
"""Yield ``(path, config)`` for every valid ``*.yaml`` across the dirs.
|
|
43
|
+
|
|
44
|
+
``pipeline_dirs`` is a colon-separated list (same format as
|
|
45
|
+
``Settings.pulse_pipeline_dirs``). Missing dirs and files that fail
|
|
46
|
+
validation are skipped silently — callers that care log their own context.
|
|
47
|
+
"""
|
|
48
|
+
for raw in pipeline_dirs.split(":"):
|
|
49
|
+
entry = raw.strip()
|
|
50
|
+
if not entry:
|
|
51
|
+
continue
|
|
52
|
+
directory = Path(entry)
|
|
53
|
+
if not directory.is_dir():
|
|
54
|
+
continue
|
|
55
|
+
for yaml_path in sorted(directory.glob("*.yaml")):
|
|
56
|
+
try:
|
|
57
|
+
config = parse_pipeline_config(yaml_path.read_text())
|
|
58
|
+
except PipelineConfigError:
|
|
59
|
+
continue
|
|
60
|
+
yield yaml_path, config
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def find_pipeline_config(
|
|
64
|
+
pipeline_dirs: str, pipeline_name: str
|
|
65
|
+
) -> PipelineConfig | None:
|
|
66
|
+
"""Return the first pipeline config whose ``name`` matches, else ``None``.
|
|
67
|
+
|
|
68
|
+
Names are assumed unique across the configured dirs; if two configs share a
|
|
69
|
+
name the first (sorted, per-dir) match wins.
|
|
70
|
+
"""
|
|
71
|
+
for _path, config in iter_pipeline_configs(pipeline_dirs):
|
|
72
|
+
if config.name == pipeline_name:
|
|
73
|
+
return config
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
|
|
38
77
|
def validate_dag(config: PipelineConfig) -> None:
|
|
39
78
|
"""Validate DAG structure for v2 pipelines."""
|
|
40
79
|
errors: list[str] = []
|
|
@@ -8,6 +8,7 @@ from fastapi import (
|
|
|
8
8
|
Depends,
|
|
9
9
|
File,
|
|
10
10
|
Form,
|
|
11
|
+
Header,
|
|
11
12
|
HTTPException,
|
|
12
13
|
Request,
|
|
13
14
|
UploadFile,
|
|
@@ -19,11 +20,13 @@ from pulse_engine.dependencies import get_db_session
|
|
|
19
20
|
from pulse_engine.middleware.tenant import get_tenant_id
|
|
20
21
|
from pulse_engine.pipeline.config_parser import (
|
|
21
22
|
PipelineConfigError,
|
|
23
|
+
find_pipeline_config,
|
|
22
24
|
parse_pipeline_config,
|
|
23
25
|
)
|
|
24
26
|
from pulse_engine.pipeline.schemas import (
|
|
25
27
|
InitRunRequest,
|
|
26
28
|
InitRunResponse,
|
|
29
|
+
InternalTriggerRequest,
|
|
27
30
|
PipelineRunListResponse,
|
|
28
31
|
PipelineRunStatus,
|
|
29
32
|
PipelineStatusResponse,
|
|
@@ -109,6 +112,65 @@ async def trigger_pipeline(
|
|
|
109
112
|
return TriggerResponse(run_id=run_id)
|
|
110
113
|
|
|
111
114
|
|
|
115
|
+
def _verify_cron_internal_token(
|
|
116
|
+
request: Request,
|
|
117
|
+
x_cron_internal_token: Annotated[str | None, Header()] = None,
|
|
118
|
+
) -> None:
|
|
119
|
+
"""Authorize internal callers via the shared cron-internal token."""
|
|
120
|
+
settings = request.app.state.settings
|
|
121
|
+
expected = getattr(settings, "pulse_cron_internal_token", "")
|
|
122
|
+
if not expected or x_cron_internal_token != expected:
|
|
123
|
+
raise HTTPException(
|
|
124
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
125
|
+
detail="Invalid or missing internal token",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@router.post(
|
|
130
|
+
"/trigger-internal",
|
|
131
|
+
status_code=status.HTTP_202_ACCEPTED,
|
|
132
|
+
response_model=TriggerResponse,
|
|
133
|
+
)
|
|
134
|
+
async def trigger_pipeline_internal(
|
|
135
|
+
body: InternalTriggerRequest,
|
|
136
|
+
request: Request,
|
|
137
|
+
service: Annotated[PipelineService, Depends(get_pipeline_service)] = None, # type: ignore[assignment]
|
|
138
|
+
_: None = Depends(_verify_cron_internal_token),
|
|
139
|
+
) -> TriggerResponse:
|
|
140
|
+
"""Trigger a scheduled pipeline by name, authenticated by cron-internal token.
|
|
141
|
+
|
|
142
|
+
Used by ``cron_job_flow`` for ``type=pipeline`` crons: resolves the pipeline
|
|
143
|
+
config from ``pulse_pipeline_dirs`` server-side (no multipart upload, no
|
|
144
|
+
tenant Bearer token needed). Tenant is taken from the config, mirroring
|
|
145
|
+
``sync_pipeline_schedules``.
|
|
146
|
+
"""
|
|
147
|
+
settings = request.app.state.settings
|
|
148
|
+
config = find_pipeline_config(
|
|
149
|
+
getattr(settings, "pulse_pipeline_dirs", "") or "", body.pipeline_name
|
|
150
|
+
)
|
|
151
|
+
if config is None:
|
|
152
|
+
raise HTTPException(
|
|
153
|
+
status_code=404,
|
|
154
|
+
detail=f"Pipeline '{body.pipeline_name}' not found in configured dirs",
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
tenant_id = config.config.get("tenant_id") or "default"
|
|
158
|
+
try:
|
|
159
|
+
run_id = await service.trigger(
|
|
160
|
+
tenant_id=tenant_id,
|
|
161
|
+
product=config.name,
|
|
162
|
+
orchestrator=config.infra.orchestrator,
|
|
163
|
+
config=config,
|
|
164
|
+
global_config=config.config,
|
|
165
|
+
)
|
|
166
|
+
except PipelineSubmissionError as e:
|
|
167
|
+
raise HTTPException(status_code=502, detail=str(e))
|
|
168
|
+
except PipelineServiceError as e:
|
|
169
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
170
|
+
|
|
171
|
+
return TriggerResponse(run_id=run_id)
|
|
172
|
+
|
|
173
|
+
|
|
112
174
|
@router.post(
|
|
113
175
|
"/runs/init",
|
|
114
176
|
status_code=status.HTTP_201_CREATED,
|
|
@@ -172,6 +172,16 @@ class TriggerPayload(BaseModel):
|
|
|
172
172
|
orchestrator: Literal["prefect"] | None = None
|
|
173
173
|
|
|
174
174
|
|
|
175
|
+
class InternalTriggerRequest(BaseModel):
|
|
176
|
+
"""Body for the internal cron-token pipeline trigger.
|
|
177
|
+
|
|
178
|
+
Extra fields (e.g. ``yaml_path``, ``cron_run_id``) sent by ``cron_job_flow``
|
|
179
|
+
are ignored.
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
pipeline_name: str
|
|
183
|
+
|
|
184
|
+
|
|
175
185
|
class PipelineRunStatus(str, Enum):
|
|
176
186
|
pending = "pending"
|
|
177
187
|
running = "running"
|
|
@@ -332,10 +332,13 @@ class PipelineService:
|
|
|
332
332
|
now = datetime.now(tz=UTC)
|
|
333
333
|
await self._run_repo.update_status(run.id, "running", started_at=now)
|
|
334
334
|
|
|
335
|
+
# Cron/scheduled per-execution runs may retry or run for days after the
|
|
336
|
+
# token is minted; use the same 90-day TTL as the scheduled trigger path
|
|
337
|
+
# so step-status callbacks don't 401 on an expired token.
|
|
335
338
|
token = self._token_issuer.issue_token(
|
|
336
339
|
pipeline_run_id=run.id,
|
|
337
340
|
tenant_id=tenant_id,
|
|
338
|
-
ttl_seconds=
|
|
341
|
+
ttl_seconds=7_776_000, # 90 days
|
|
339
342
|
)
|
|
340
343
|
return run.id, token
|
|
341
344
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/audio_transcription.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/digital_news_metadata.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/config.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/factory.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/service.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/adapters/transcription/source.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/cli/templates/cookiecutter.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/deployment/infra_provisioner.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/notifications/apprise_notifier.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/__init__.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/airflow_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/pipeline/translators/prefect_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/core/topic_splitter.py
RENAMED
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/defaults/core_processor.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/defaults/postprocessor.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/defaults/preprocessor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/postprocessor/__init__.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/postprocessor/embeddings.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/postprocessor/tasks.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/preprocessor/__init__.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/processor/preprocessor/tasks.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/runners/prefect_pipeline_flow.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/microvm_agent/Dockerfile
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/microvm_agent/__init__.py
RENAMED
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/sandbox/microvm_agent/server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/skills/seed_data/skill_files.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pulse_engine-0.2.22 → pulse_engine-0.2.23}/src/pulse_engine/storage/connectors/opensearch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|