orionis 0.518.0__py3-none-any.whl → 0.520.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.
@@ -1,3 +1,4 @@
1
+ from typing import Dict, List
1
2
  from rich.console import Console
2
3
  from rich.panel import Panel
3
4
  from rich.table import Table
@@ -71,7 +72,7 @@ class ScheduleListCommand(BaseCommand):
71
72
  await scheduler.tasks(schedule_service)
72
73
 
73
74
  # Retrieve the list of scheduled jobs/events
74
- list_tasks = schedule_service.events()
75
+ list_tasks: List[Dict] = schedule_service.events()
75
76
 
76
77
  # Display a message if no scheduled jobs are found
77
78
  if not list_tasks:
@@ -85,20 +86,20 @@ class ScheduleListCommand(BaseCommand):
85
86
  table.add_column("Signature", style="cyan", no_wrap=True)
86
87
  table.add_column("Arguments", style="magenta")
87
88
  table.add_column("Purpose", style="green")
88
- table.add_column("Random Delay (calculated result)", style="yellow")
89
+ table.add_column("Random Delay (Calculated Result)", style="yellow")
89
90
  table.add_column("Start Date", style="white")
90
91
  table.add_column("End Date", style="white")
91
92
  table.add_column("Details", style="dim")
92
93
 
93
94
  # Populate the table with job details
94
95
  for job in list_tasks:
95
- signature = str(job.get("signature", ""))
96
- args = ", ".join(map(str, job.get("args", [])))
97
- purpose = str(job.get("purpose", ""))
98
- random_delay = str(job.get("random_delay", ""))
99
- start_date = str(job.get("start_date", "")) if job.get("start_date") else "-"
100
- end_date = str(job.get("end_date", "")) if job.get("end_date") else "-"
101
- details = str(job.get("details", ""))
96
+ signature = str(job.get("signature"))
97
+ args = str(job.get("args", []))
98
+ purpose = str(job.get("purpose"))
99
+ random_delay = str(job.get("random_delay"))
100
+ start_date = str(job.get("start_date"))
101
+ end_date = str(job.get("end_date"))
102
+ details = str(job.get("details"))
102
103
 
103
104
  table.add_row(signature, args, purpose, random_delay, start_date, end_date, details)
104
105
 
@@ -289,7 +289,7 @@ class Scheduler(ISchedule):
289
289
  # Return the Event instance for further scheduling configuration
290
290
  return self.__events[signature]
291
291
 
292
- def __suscribeListeners(
292
+ def __subscribeListeners(
293
293
  self
294
294
  ) -> None:
295
295
  """
@@ -367,12 +367,31 @@ class Scheduler(ISchedule):
367
367
 
368
368
  # Ensure the listener is callable before invoking it
369
369
  if callable(listener):
370
- # If the listener is a coroutine, schedule it as an asyncio task
371
- if asyncio.iscoroutinefunction(listener):
372
- asyncio.create_task(listener(event_data, self))
373
- # Otherwise, invoke the listener directly as a regular function
374
- else:
375
- listener(event_data, self)
370
+
371
+ try:
372
+
373
+ # If the listener is a coroutine, schedule it as an asyncio task
374
+ if asyncio.iscoroutinefunction(listener):
375
+ try:
376
+ # Try to get the running event loop
377
+ loop = asyncio.get_running_loop()
378
+ loop.create_task(listener(event_data, self))
379
+ except RuntimeError:
380
+ # If no event loop is running, create a new one
381
+ asyncio.run(listener(event_data, self))
382
+ # Otherwise, invoke the listener directly as a regular function
383
+ else:
384
+ listener(event_data, self)
385
+
386
+ except Exception as e:
387
+
388
+ # Log any exceptions that occur during listener invocation
389
+ self.__logger.error(f"Error invoking global listener for event '{scheduler_event}': {str(e)}")
390
+
391
+ # Raise a runtime error if listener invocation fails
392
+ raise CLIOrionisRuntimeError(
393
+ f"An error occurred while invoking the listener for event '{scheduler_event}': {str(e)}"
394
+ )
376
395
 
377
396
  def __taskCallableListener(
378
397
  self,
@@ -412,6 +431,10 @@ class Scheduler(ISchedule):
412
431
  if not isinstance(listening_vent, ListeningEvent):
413
432
  raise CLIOrionisValueError("The event must be an instance of ListeningEvent.")
414
433
 
434
+ # Validate that event_data is not None and has a job_id attribute
435
+ if event_data is None or not hasattr(event_data, 'job_id'):
436
+ return
437
+
415
438
  # Retrieve the global identifier for the event from the ListeningEvent enum
416
439
  scheduler_event = listening_vent.value
417
440
 
@@ -428,13 +451,17 @@ class Scheduler(ISchedule):
428
451
  if hasattr(listener, scheduler_event) and callable(getattr(listener, scheduler_event)):
429
452
  listener_method = getattr(listener, scheduler_event)
430
453
 
431
- # Invoke the listener method, handling both coroutine and regular functions
432
- if asyncio.iscoroutinefunction(listener_method):
433
- # Schedule the coroutine listener method as an asyncio task
434
- asyncio.create_task(listener_method(event_data, self))
435
- else:
436
- # Call the regular listener method directly
437
- listener_method(event_data, self)
454
+ try:
455
+ # Invoke the listener method, handling both coroutine and regular functions
456
+ if asyncio.iscoroutinefunction(listener_method):
457
+ # Schedule the coroutine listener method as an asyncio task
458
+ asyncio.create_task(listener_method(event_data, self))
459
+ else:
460
+ # Call the regular listener method directly
461
+ listener_method(event_data, self)
462
+ except Exception as e:
463
+ # Log any exceptions that occur during listener invocation
464
+ self.__logger.error(f"Error invoking listener method '{scheduler_event}' for job '{event_data.job_id}': {str(e)}")
438
465
 
439
466
  def __startedListener(
440
467
  self,
@@ -525,7 +552,7 @@ class Scheduler(ISchedule):
525
552
  # Log an informational message indicating that the scheduler has been paused
526
553
  self.__logger.info(message)
527
554
 
528
- # Check if a listener is registered for the scheduler started event
555
+ # Check if a listener is registered for the scheduler paused event
529
556
  self.__globalCallableListener(event, ListeningEvent.SCHEDULER_PAUSED)
530
557
 
531
558
  def __resumedListener(
@@ -562,7 +589,7 @@ class Scheduler(ISchedule):
562
589
  # Log an informational message indicating that the scheduler has resumed
563
590
  self.__logger.info(message)
564
591
 
565
- # Check if a listener is registered for the scheduler started event
592
+ # Check if a listener is registered for the scheduler resumed event
566
593
  self.__globalCallableListener(event, ListeningEvent.SCHEDULER_RESUMED)
567
594
 
568
595
  def __shutdownListener(
@@ -599,7 +626,7 @@ class Scheduler(ISchedule):
599
626
  # Log an informational message indicating that the scheduler has shut down
600
627
  self.__logger.info(message)
601
628
 
602
- # Check if a listener is registered for the scheduler started event
629
+ # Check if a listener is registered for the scheduler shutdown event
603
630
  self.__globalCallableListener(event, ListeningEvent.SCHEDULER_SHUTDOWN)
604
631
 
605
632
  def __errorListener(
@@ -879,11 +906,11 @@ class Scheduler(ISchedule):
879
906
  self.__jobs.append(entity)
880
907
 
881
908
  # Create a unique key for the job based on its signature
909
+ def create_job_func(cmd, args_list):
910
+ return lambda: self.__reactor.call(cmd, args_list)
911
+
882
912
  self.__scheduler.add_job(
883
- func= lambda command=signature, args=list(entity.args): self.__reactor.call(
884
- command,
885
- args
886
- ),
913
+ func=create_job_func(signature, list(entity.args)),
887
914
  trigger=entity.trigger,
888
915
  id=signature,
889
916
  name=signature,
@@ -981,8 +1008,8 @@ class Scheduler(ISchedule):
981
1008
  self.__scheduler.add_job(
982
1009
  func=self.__scheduler.pause, # Function to pause the scheduler
983
1010
  trigger=DateTrigger(run_date=at), # Trigger type is 'date' for one-time execution
984
- id=f"pause_scheduler_at_{at.isoformat()}", # Unique job ID based on the datetime
985
- name=f"Pause Scheduler at {at.isoformat()}", # Descriptive name for the job
1011
+ id=ListeningEvent.SCHEDULER_PAUSED.value, # Unique job ID for pausing the scheduler
1012
+ name=ListeningEvent.SCHEDULER_PAUSED.value, # Descriptive name for the job
986
1013
  replace_existing=True # Replace any existing job with the same ID
987
1014
  )
988
1015
 
@@ -1023,8 +1050,8 @@ class Scheduler(ISchedule):
1023
1050
  self.__scheduler.add_job(
1024
1051
  func=self.__scheduler.resume, # Function to resume the scheduler
1025
1052
  trigger=DateTrigger(run_date=at), # Trigger type is 'date' for one-time execution
1026
- id=f"resume_scheduler_at_{at.isoformat()}", # Unique job ID based on the datetime
1027
- name=f"Resume Scheduler at {at.isoformat()}", # Descriptive name for the job
1053
+ id=ListeningEvent.SCHEDULER_RESUMED.value, # Unique job ID for resuming the scheduler
1054
+ name=ListeningEvent.SCHEDULER_RESUMED.value, # Descriptive name for the job
1028
1055
  replace_existing=True # Replace any existing job with the same ID
1029
1056
  )
1030
1057
 
@@ -1065,8 +1092,8 @@ class Scheduler(ISchedule):
1065
1092
  self.__scheduler.add_job(
1066
1093
  func=self.__scheduler.shutdown, # Function to shut down the scheduler
1067
1094
  trigger=DateTrigger(run_date=at), # Trigger type is 'date' for one-time execution
1068
- id=f"shutdown_scheduler_at_{at.isoformat()}", # Unique job ID based on the datetime
1069
- name=f"Shutdown Scheduler at {at.isoformat()}", # Descriptive name for the job
1095
+ id=ListeningEvent.SCHEDULER_SHUTDOWN.value, # Unique job ID for shutting down the scheduler
1096
+ name=ListeningEvent.SCHEDULER_SHUTDOWN.value, # Descriptive name for the job
1070
1097
  replace_existing=True # Replace any existing job with the same ID
1071
1098
  )
1072
1099
 
@@ -1087,14 +1114,14 @@ class Scheduler(ISchedule):
1087
1114
  # Start the AsyncIOScheduler to handle asynchronous jobs.
1088
1115
  try:
1089
1116
 
1117
+ # Ensure we're in an asyncio context
1118
+ asyncio.get_running_loop()
1119
+
1090
1120
  # Ensure all events are loaded into the internal jobs list
1091
1121
  self.__loadEvents()
1092
1122
 
1093
- # Subscribe to scheduler events for monitoring and handling
1094
- self.__suscribeListeners()
1095
-
1096
- # Ensure we're in an asyncio context
1097
- asyncio.get_running_loop()
1123
+ # Subscribe to scheduler events
1124
+ self.__subscribeListeners()
1098
1125
 
1099
1126
  # Start the scheduler
1100
1127
  if not self.__scheduler.running:
@@ -1340,15 +1367,24 @@ class Scheduler(ISchedule):
1340
1367
 
1341
1368
  # Iterate over each job in the internal jobs list
1342
1369
  for job in self.__jobs:
1370
+
1371
+ signature = job.signature
1372
+ args = job.args
1373
+ purpose = job.purpose
1374
+ random_delay = job.random_delay if job.random_delay else 0
1375
+ start_date = job.start_date.strftime('%Y-%m-%d %H:%M:%S') if job.start_date else 'Not Applicable'
1376
+ end_date = job.end_date.strftime('%Y-%m-%d %H:%M:%S') if job.end_date else 'Not Applicable'
1377
+ details = job.details if job.details else 'Not Available'
1378
+
1343
1379
  # Append a dictionary with relevant job details to the events list
1344
1380
  events.append({
1345
- 'signature': job.signature,
1346
- 'args': job.args,
1347
- 'purpose': job.purpose,
1348
- 'random_delay': job.random_delay,
1349
- 'start_date': job.start_date.strftime('%Y-%m-%d %H:%M:%S') if job.start_date else None,
1350
- 'end_date': job.end_date.strftime('%Y-%m-%d %H:%M:%S') if job.end_date else None,
1351
- 'details': job.details
1381
+ 'signature': signature,
1382
+ 'args': args,
1383
+ 'purpose': purpose,
1384
+ 'random_delay': random_delay,
1385
+ 'start_date': start_date,
1386
+ 'end_date': end_date,
1387
+ 'details': details
1352
1388
  })
1353
1389
 
1354
1390
  # Return the list of scheduled job details
@@ -5,7 +5,7 @@
5
5
  NAME = "orionis"
6
6
 
7
7
  # Current version of the framework
8
- VERSION = "0.518.0"
8
+ VERSION = "0.520.0"
9
9
 
10
10
  # Full name of the author or maintainer of the project
11
11
  AUTHOR = "Raul Mauricio Uñate Castro"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orionis
3
- Version: 0.518.0
3
+ Version: 0.520.0
4
4
  Summary: Orionis Framework – Elegant, Fast, and Powerful.
5
5
  Home-page: https://github.com/orionis-framework/framework
6
6
  Author: Raul Mauricio Uñate Castro
@@ -14,7 +14,7 @@ orionis/console/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
14
14
  orionis/console/commands/cache.py,sha256=8DsYoRzSBLn0P9qkGVItRbo0R6snWBDBg0_Xa7tmVhs,2322
15
15
  orionis/console/commands/help.py,sha256=zfSw0pYaOnFN-_Ozdn4veBQDYMgSSDY10nPDCi-7tTY,3199
16
16
  orionis/console/commands/publisher.py,sha256=FUg-EUzK7LLXsla10ZUZro8V0Z5S-KjmsaSdRHSSGbA,21381
17
- orionis/console/commands/scheduler_list.py,sha256=iPO-tc5qj-Q17lL_1MRSCaRov_o4GoQcnWTATLKPeLE,4826
17
+ orionis/console/commands/scheduler_list.py,sha256=A2N_mEXEJDHO8DX2TDrL1ROeeRhFSkWD3rCw64Hrf0o,4763
18
18
  orionis/console/commands/scheduler_work.py,sha256=yHTbnDH1frAmyvPaUgn0a5q34Eym9QYMXdqYZWwodFs,6336
19
19
  orionis/console/commands/test.py,sha256=-EmQwFwMBuby3OI9HwqMIwuJzd2CGbWbOqmwrR25sOE,2402
20
20
  orionis/console/commands/version.py,sha256=SUuNDJ40f2uq69OQUmPQXJKaa9Bm_iVRDPmBd7zc1Yc,3658
@@ -81,7 +81,7 @@ orionis/console/request/cli_request.py,sha256=7-sgYmNUCipuHLVAwWLJiHv0cJCDmsM1Lu
81
81
  orionis/console/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
82
  orionis/console/tasks/event.py,sha256=l4J-HEPaj1mxB_PYQMgG9dRHUe01wUag8fKLLnR2N2M,164395
83
83
  orionis/console/tasks/listener.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
- orionis/console/tasks/schedule.py,sha256=kKRqjy5IVRnVtFH_M1j_CXiRRP5GWlAtm6OFkMVuq5w,56567
84
+ orionis/console/tasks/schedule.py,sha256=y6fnvxofKw_sd-Br2ICzsvinCyV5HDLygLJtDlyTCLw,58292
85
85
  orionis/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
86
  orionis/container/container.py,sha256=aF_b6lTUpG4YCo9yFJEzsntTdIzgMMXFW5LyWqAJVBQ,87987
87
87
  orionis/container/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -239,7 +239,7 @@ orionis/foundation/providers/scheduler_provider.py,sha256=72SoixFog9IOE9Ve9Xcfw6
239
239
  orionis/foundation/providers/testing_provider.py,sha256=SrJRpdvcblx9WvX7x9Y3zc7OQfiTf7la0HAJrm2ESlE,3725
240
240
  orionis/foundation/providers/workers_provider.py,sha256=oa_2NIDH6UxZrtuGkkoo_zEoNIMGgJ46vg5CCgAm7wI,3926
241
241
  orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
242
- orionis/metadata/framework.py,sha256=wug5g4rr99G557BnwMHazwC0CR8MPOjrfZhcyhWmfWo,4109
242
+ orionis/metadata/framework.py,sha256=9ERo-wA31Fhf-QLk4fPAYjSxTyE4FM6xHG0dXUxPL_0,4109
243
243
  orionis/metadata/package.py,sha256=k7Yriyp5aUcR-iR8SK2ec_lf0_Cyc-C7JczgXa-I67w,16039
244
244
  orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
245
245
  orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -415,7 +415,7 @@ orionis/test/validators/web_report.py,sha256=n9BfzOZz6aEiNTypXcwuWbFRG0OdHNSmCNu
415
415
  orionis/test/validators/workers.py,sha256=rWcdRexINNEmGaO7mnc1MKUxkHKxrTsVuHgbnIfJYgc,1206
416
416
  orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
417
417
  orionis/test/view/render.py,sha256=f-zNhtKSg9R5Njqujbg2l2amAs2-mRVESneLIkWOZjU,4082
418
- orionis-0.518.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
418
+ orionis-0.520.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
419
419
  tests/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
420
420
  tests/container/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
421
421
  tests/container/context/test_manager.py,sha256=wOwXpl9rHNfTTexa9GBKYMwK0_-KSQPbI-AEyGNkmAE,1356
@@ -561,8 +561,8 @@ tests/testing/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
561
561
  tests/testing/validators/test_testing_validators.py,sha256=WPo5GxTP6xE-Dw3X1vZoqOMpb6HhokjNSbgDsDRDvy4,16588
562
562
  tests/testing/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
563
563
  tests/testing/view/test_render.py,sha256=tnnMBwS0iKUIbogLvu-7Rii50G6Koddp3XT4wgdFEYM,1050
564
- orionis-0.518.0.dist-info/METADATA,sha256=57ipFsdsX4YY8wMWB_LqFKG5Y6eBUj8MkjFdM4WERuo,4801
565
- orionis-0.518.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
566
- orionis-0.518.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
567
- orionis-0.518.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
568
- orionis-0.518.0.dist-info/RECORD,,
564
+ orionis-0.520.0.dist-info/METADATA,sha256=UAhnPWMKxyQiTmmFb6zL_34hsjfhmzdPIjOrXhmJDYM,4801
565
+ orionis-0.520.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
566
+ orionis-0.520.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
567
+ orionis-0.520.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
568
+ orionis-0.520.0.dist-info/RECORD,,