orchestrator-core 4.6.0rc1__py3-none-any.whl → 4.6.0rc2__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.
orchestrator/__init__.py CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  """This is the orchestrator workflow engine."""
15
15
 
16
- __version__ = "4.6.0rc1"
16
+ __version__ = "4.6.0rc2"
17
17
 
18
18
 
19
19
  from structlog import get_logger
@@ -12,26 +12,23 @@
12
12
  # limitations under the License.
13
13
 
14
14
 
15
- import logging
16
15
  import time
17
16
 
18
17
  import typer
19
18
 
20
19
  from orchestrator.schedules.scheduler import (
21
- get_paused_scheduler,
20
+ get_all_scheduler_tasks,
21
+ get_scheduler,
22
+ get_scheduler_task,
22
23
  )
23
24
 
24
- log = logging.getLogger(__name__)
25
-
26
25
  app: typer.Typer = typer.Typer()
27
26
 
28
27
 
29
28
  @app.command()
30
29
  def run() -> None:
31
30
  """Start scheduler and loop eternally to keep thread alive."""
32
- with get_paused_scheduler() as scheduler:
33
- scheduler.resume()
34
-
31
+ with get_scheduler():
35
32
  while True:
36
33
  time.sleep(1)
37
34
 
@@ -42,27 +39,23 @@ def show_schedule() -> None:
42
39
 
43
40
  in cli underscore is replaced by a dash `show-schedule`
44
41
  """
45
- with get_paused_scheduler() as scheduler:
46
- jobs = scheduler.get_jobs()
47
-
48
- for job in jobs:
49
- typer.echo(f"[{job.id}] Next run: {job.next_run_time} | Trigger: {job.trigger}")
42
+ for task in get_all_scheduler_tasks():
43
+ typer.echo(f"[{task.id}] Next run: {task.next_run_time} | Trigger: {task.trigger}")
50
44
 
51
45
 
52
46
  @app.command()
53
- def force(job_id: str) -> None:
54
- """Force the execution of (a) scheduler(s) based on a job_id."""
55
- with get_paused_scheduler() as scheduler:
56
- job = scheduler.get_job(job_id)
47
+ def force(task_id: str) -> None:
48
+ """Force the execution of (a) scheduler(s) based on a task_id."""
49
+ task = get_scheduler_task(task_id)
57
50
 
58
- if not job:
59
- typer.echo(f"Job '{job_id}' not found.")
51
+ if not task:
52
+ typer.echo(f"Task '{task_id}' not found.")
60
53
  raise typer.Exit(code=1)
61
54
 
62
- typer.echo(f"Running job [{job.id}] now...")
55
+ typer.echo(f"Running Task [{task.id}] now...")
63
56
  try:
64
- job.func(*job.args or (), **job.kwargs or {})
65
- typer.echo("Job executed successfully.")
57
+ task.func(*task.args or (), **task.kwargs or {})
58
+ typer.echo("Task executed successfully.")
66
59
  except Exception as e:
67
- typer.echo(f"Job execution failed: {e}")
60
+ typer.echo(f"Task execution failed: {e}")
68
61
  raise typer.Exit(code=1)
@@ -17,16 +17,16 @@ from datetime import datetime
17
17
  from typing import Any, Generator
18
18
 
19
19
  from apscheduler.executors.pool import ThreadPoolExecutor
20
- from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
20
+ from apscheduler.jobstores.sqlalchemy import Job, SQLAlchemyJobStore
21
21
  from apscheduler.schedulers.background import BackgroundScheduler
22
22
  from more_itertools import partition
23
23
  from pydantic import BaseModel
24
24
 
25
+ from orchestrator.db import db
25
26
  from orchestrator.db.filters import Filter
26
27
  from orchestrator.db.filters.filters import CallableErrorHandler
27
28
  from orchestrator.db.sorting import Sort
28
29
  from orchestrator.db.sorting.sorting import SortOrder
29
- from orchestrator.settings import app_settings
30
30
  from orchestrator.utils.helpers import camel_to_snake, to_camel
31
31
 
32
32
  executors = {
@@ -40,18 +40,37 @@ scheduler = BackgroundScheduler(executors=executors, job_defaults=job_defaults)
40
40
 
41
41
 
42
42
  @contextmanager
43
- def get_paused_scheduler() -> Generator[BackgroundScheduler, Any, None]:
43
+ def get_scheduler_store() -> Generator[SQLAlchemyJobStore, Any, None]:
44
+ store = SQLAlchemyJobStore(engine=db.engine)
44
45
  try:
45
- scheduler.add_jobstore(SQLAlchemyJobStore(url=str(app_settings.DATABASE_URI)))
46
- except ValueError:
47
- pass
48
- scheduler.start(paused=True)
49
-
50
- try:
51
- yield scheduler
46
+ yield store
52
47
  finally:
53
- scheduler.shutdown()
54
- scheduler._jobstores["default"].engine.dispose()
48
+ store.shutdown()
49
+
50
+
51
+ def get_all_scheduler_tasks() -> list[Job]:
52
+ with get_scheduler_store() as scheduler_store:
53
+ return scheduler_store.get_all_jobs()
54
+
55
+
56
+ def get_scheduler_task(job_id: str) -> Job | None:
57
+ with get_scheduler_store() as scheduler_store:
58
+ return scheduler_store.lookup_job(job_id)
59
+
60
+
61
+ @contextmanager
62
+ def get_scheduler(paused: bool = False) -> Generator[BackgroundScheduler, Any, None]:
63
+ with get_scheduler_store() as store:
64
+ try:
65
+ scheduler.add_jobstore(store)
66
+ except ValueError:
67
+ pass
68
+ scheduler.start(paused=paused)
69
+
70
+ try:
71
+ yield scheduler
72
+ finally:
73
+ scheduler.shutdown()
55
74
 
56
75
 
57
76
  class ScheduledTask(BaseModel):
@@ -149,9 +168,7 @@ def get_scheduler_tasks(
149
168
  sort_by: list[Sort] | None = None,
150
169
  error_handler: CallableErrorHandler = default_error_handler,
151
170
  ) -> tuple[list[ScheduledTask], int]:
152
- with get_paused_scheduler() as pauzed_scheduler:
153
- scheduled_tasks = pauzed_scheduler.get_jobs()
154
-
171
+ scheduled_tasks = get_all_scheduler_tasks()
155
172
  scheduled_tasks = filter_scheduled_tasks(scheduled_tasks, error_handler, filter_by)
156
173
  scheduled_tasks = sort_scheduled_tasks(scheduled_tasks, error_handler, sort_by)
157
174
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orchestrator-core
3
- Version: 4.6.0rc1
3
+ Version: 4.6.0rc2
4
4
  Summary: This is the orchestrator workflow engine.
5
5
  Author-email: SURF <automation-beheer@surf.nl>
6
6
  Requires-Python: >=3.11,<3.14
@@ -1,4 +1,4 @@
1
- orchestrator/__init__.py,sha256=5_01EzLm3qIBb4g-j2hknYC1bKKR4yvTNcVx3hpF98Y,1450
1
+ orchestrator/__init__.py,sha256=5uPIbvZOqPTKQJ_tm9IcleuirD5gawR8uclr2-asW9Q,1450
2
2
  orchestrator/agentic_app.py,sha256=6C_-pbw4xLJah8--CPcopz6dym4V7AfX2DtAYIGljmk,3020
3
3
  orchestrator/app.py,sha256=UPKQuDpg8MWNC6r3SRRbp6l9RBzwb00IMIaGRk-jbCU,13203
4
4
  orchestrator/exception_handlers.py,sha256=UsW3dw8q0QQlNLcV359bIotah8DYjMsj2Ts1LfX4ClY,1268
@@ -40,7 +40,7 @@ orchestrator/cli/migrate_domain_models.py,sha256=WRXy_1OnziQwpsCFZXvjB30nDJtjj0i
40
40
  orchestrator/cli/migrate_tasks.py,sha256=bju8XColjSZD0v3rS4kl-24dLr8En_H4-6enBmqd494,7255
41
41
  orchestrator/cli/migrate_workflows.py,sha256=nxUpx0vgEIc_8aJrjAyrw3E9Dt8JmaamTts8oiQ4vHY,8923
42
42
  orchestrator/cli/migration_helpers.py,sha256=C5tpkP5WEBr7G9S-1k1hgSI8ili6xd9Z5ygc9notaK0,4110
43
- orchestrator/cli/scheduler.py,sha256=2q6xT_XVOodY3e_qzIV98MWNvKvrbFpOJajWesj1fcs,1911
43
+ orchestrator/cli/scheduler.py,sha256=4jWpgxx0j0UFoba4Kw0nOEM6slr5XffDYBkm6hzK_C0,1766
44
44
  orchestrator/cli/domain_gen_helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  orchestrator/cli/domain_gen_helpers/fixed_input_helpers.py,sha256=uzpwsaau81hHSxNMOS9-o7kF-9_78R0f_UE0AvWooZQ,6775
46
46
  orchestrator/cli/domain_gen_helpers/helpers.py,sha256=tIPxn8ezED_xYZxH7ZAtQLwkDc6RNmLZVxWAoJ3a9lw,4203
@@ -258,7 +258,7 @@ orchestrator/migrations/versions/schema/2025-07-04_4b58e336d1bf_deprecating_work
258
258
  orchestrator/migrations/versions/schema/2025-07-28_850dccac3b02_update_description_of_resume_workflows_.py,sha256=R6Qoga83DJ1IL0WYPu0u5u2ZvAmqGlDmUMv_KtJyOhQ,812
259
259
  orchestrator/schedules/__init__.py,sha256=Zy0fTOBMGIRFoh5iVFDLF9_PRAFaONYDThGK9EsysWo,981
260
260
  orchestrator/schedules/resume_workflows.py,sha256=jRnVRWDy687pQu-gtk80ecwiLSdrvtL15tG3U2zWA6I,891
261
- orchestrator/schedules/scheduler.py,sha256=nnuehZnBbtC90MsFP_Q6kqcD1ihsq08vr1ALJ6jHF_s,5833
261
+ orchestrator/schedules/scheduler.py,sha256=9d6n-J2_GB6crOoVSCK29IfaktfUyzQYcTZl7gRTZ5c,6250
262
262
  orchestrator/schedules/scheduling.py,sha256=_mbpHMhijey8Y56ebtJ4wVkrp_kPVRm8hoByzlQF4SE,2821
263
263
  orchestrator/schedules/task_vacuum.py,sha256=mxb7fsy1GphRwvUWi_lvwNaj51YAXUdIDlkOJd90AFI,874
264
264
  orchestrator/schedules/validate_products.py,sha256=_ucUG9HecskG2eN3tcDSiMzJK9gN3kZB1dXjrtxcApY,1324
@@ -373,7 +373,7 @@ orchestrator/workflows/tasks/resume_workflows.py,sha256=T3iobSJjVgiupe0rClD34kUZ
373
373
  orchestrator/workflows/tasks/validate_product_type.py,sha256=lo2TX_MZOfcOmYFjLyD82FrJ5AAN3HOsE6BhDVFuy9Q,3210
374
374
  orchestrator/workflows/tasks/validate_products.py,sha256=GZJBoFF-WMphS7ghMs2-gqvV2iL1F0POhk0uSNt93n0,8510
375
375
  orchestrator/workflows/translations/en-GB.json,sha256=ST53HxkphFLTMjFHonykDBOZ7-P_KxksktZU3GbxLt0,846
376
- orchestrator_core-4.6.0rc1.dist-info/licenses/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
377
- orchestrator_core-4.6.0rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
378
- orchestrator_core-4.6.0rc1.dist-info/METADATA,sha256=C0vrYdm7AO0XDhb5lJ8JplynhdKsB-tu0tRWF9tyuB8,6253
379
- orchestrator_core-4.6.0rc1.dist-info/RECORD,,
376
+ orchestrator_core-4.6.0rc2.dist-info/licenses/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
377
+ orchestrator_core-4.6.0rc2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
378
+ orchestrator_core-4.6.0rc2.dist-info/METADATA,sha256=otV2lyDTZ_ytfz5miako0btSnzsGdxbMZRxkSEDBtIs,6253
379
+ orchestrator_core-4.6.0rc2.dist-info/RECORD,,