scalable-pypeline 2.1.18__py2.py3-none-any.whl → 2.1.19__py2.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.
pypeline/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.1.18"
1
+ __version__ = "2.1.19"
pypeline/dramatiq.py CHANGED
@@ -45,7 +45,7 @@ from pypeline.pipelines.middleware.parallel_pipeline_middleware import ParallelP
45
45
  from pypeline.pipelines.middleware.pypeline_middleware import PypelineMiddleware
46
46
  from pypeline.utils.config_utils import (
47
47
  retrieve_latest_schedule_config,
48
- get_service_config_for_worker,
48
+ get_service_config_for_worker, retrieve_executable_job_config,
49
49
  )
50
50
  from pypeline.utils.dramatiq_utils import (
51
51
  guess_code_directory,
@@ -107,6 +107,7 @@ def configure_default_broker(broker: Broker = None):
107
107
  def register_actors_for_workers(broker: Broker):
108
108
  service = get_service_config_for_worker(pypeline_config)
109
109
  scheduled_jobs_config = retrieve_latest_schedule_config()
110
+ executable_jobs_config = retrieve_executable_job_config()
110
111
 
111
112
  if not service:
112
113
  return
@@ -155,6 +156,19 @@ def register_actors_for_workers(broker: Broker):
155
156
  except Exception as e:
156
157
  logger.exception(f"Unable to add a task to dramatiq: {e}")
157
158
 
159
+ for job in executable_jobs_config or []:
160
+ config = job["config"]
161
+ if config["task"] in worker_registered_tasks:
162
+ pipeline_meta = {"queue": config.get("queue", "default")}
163
+ try:
164
+ tmp_handler = get_callable(config["task"])
165
+ if pipeline_meta and pipeline_meta.get("maxRetry", 0) >= 0:
166
+ pipeline_meta["store_results"] = True
167
+ _ = register_lazy_actor(broker, tmp_handler, pipeline_meta, None)
168
+ except Exception as e:
169
+ logger.exception(f"Unable to add a task to dramatiq: {e}")
170
+
171
+
158
172
 
159
173
  class Dramatiq:
160
174
  """Flask extension bridging Dramatiq broker and Flask app.
@@ -0,0 +1,35 @@
1
+ from marshmallow import Schema, EXCLUDE, fields
2
+
3
+ class ExecutableJobConfigSchema(Schema):
4
+ queue = fields.String(
5
+ required=True,
6
+ description="Name of queue on which to place task.",
7
+ example="my-default-queue",
8
+ )
9
+ task = fields.String(
10
+ required=True,
11
+ description="Path to task to invoke.",
12
+ example="my_app.module.method",
13
+ )
14
+
15
+ class ExecutableJobSchema(Schema):
16
+ """Definition of a single schedule entry"""
17
+ class Meta:
18
+ unknown = EXCLUDE
19
+
20
+ name = fields.String(
21
+ required=True,
22
+ description="Name of schedule entry.",
23
+ example="My Scheduled Task",
24
+ )
25
+ schemaVersion = fields.Integer(required=True)
26
+ config = fields.Dict(required=True)
27
+ enabled = fields.Boolean(
28
+ required=True, description="Whether entry is enabled.", example=True
29
+ )
30
+ config = fields.Nested(
31
+ ExecutableJobConfigSchema,
32
+ required=True,
33
+ description="Configuration information for this job.",
34
+ )
35
+
pypeline/pypeline_yaml.py CHANGED
@@ -54,6 +54,8 @@ import yaml
54
54
  from yaml.loader import SafeLoader
55
55
  from marshmallow import Schema, fields, pre_load, EXCLUDE, INCLUDE, validates_schema
56
56
  from marshmallow.exceptions import ValidationError
57
+
58
+ from pypeline.executable_job_config_schema import ExecutableJobSchema
57
59
  from pypeline.utils.module_utils import PypelineModuleLoader, normalized_pkg_name
58
60
  from pypeline.constants import PYPELINE_YAML_PATH, PYPELINE_CLIENT_PKG_NAME
59
61
  from pypeline.pipeline_config_schema import BasePipelineSchema
@@ -165,6 +167,14 @@ class PypelineYamlSchema(ExcludeUnknownSchema):
165
167
  required=False,
166
168
  )
167
169
 
170
+ executableJobs = fields.Dict(
171
+ keys=fields.String(),
172
+ values=fields.Nested(ExecutableJobSchema),
173
+ description="List of executable jobs",
174
+ required=False,
175
+ allow_none=True,
176
+ )
177
+
168
178
  def validate_errors(self, schema: Schema, value: dict):
169
179
  """Run Marshmallow validate() and raise if any errors"""
170
180
  schema = schema()
@@ -41,6 +41,16 @@ def retrieve_latest_schedule_config():
41
41
  return None
42
42
 
43
43
 
44
+ def retrieve_executable_job_config():
45
+ pypeline_config = load_pypeline_config()
46
+ if "executableJobs" in pypeline_config:
47
+ tasks = []
48
+ for task_id, config in pypeline_config["executableJobs"].items():
49
+ tasks.append(config)
50
+ return tasks
51
+ return None
52
+
53
+
44
54
  def get_service_config_for_worker(
45
55
  pypeline_config: dict, worker_name: str = None
46
56
  ) -> Union[dict, None]:
@@ -0,0 +1,35 @@
1
+ from dramatiq.broker import get_broker
2
+
3
+ from pypeline.utils.config_utils import retrieve_executable_job_config
4
+ from pypeline.utils.dramatiq_utils import register_lazy_actor, LazyActor
5
+ from pypeline.utils.module_utils import get_callable
6
+
7
+
8
+ def execute_job(fn, *args, **kwargs):
9
+ executable_jobs_config = retrieve_executable_job_config()
10
+
11
+ module_path = kwargs.get("module_path", None)
12
+
13
+ job = None
14
+
15
+ for j in executable_jobs_config or []:
16
+ if module_path and module_path == j["config"]["task"]:
17
+ job = j
18
+ break
19
+ elif fn.__name__ in j["config"]["task"]:
20
+ if job:
21
+ raise ValueError(
22
+ f"Multiple matches found in yaml for {fn.__name__}, "
23
+ f"Consider passing module_path as a kwarg to avoid ambiguity."
24
+ )
25
+ job = j
26
+
27
+ if job is None:
28
+ raise ValueError(f"No match found in yaml for {fn.__name__} function.")
29
+
30
+ pipeline_meta = {"queue": job["config"].get("queue", "default")}
31
+ tmp_handler = get_callable(job["config"]["task"])
32
+
33
+ actor: LazyActor = register_lazy_actor(get_broker(), tmp_handler, pipeline_meta, None)
34
+
35
+ return actor.send(*args, **kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scalable-pypeline
3
- Version: 2.1.18
3
+ Version: 2.1.19
4
4
  Summary: PypeLine - Python pipelines for the Real World
5
5
  Home-page: https://gitlab.com/bravos2/pypeline
6
6
  Author: Bravos Power Corporation
@@ -1,11 +1,12 @@
1
- pypeline/__init__.py,sha256=Hc95NdHPIFrDSqp8_iblHu8tL5yscXH7JDPIvIVi8oI,23
1
+ pypeline/__init__.py,sha256=ORNtksaL65IiKUhkJEaS3s0gzZq5HMSHSwIKtUEfCBA,23
2
2
  pypeline/barrier.py,sha256=oO964l9qOCOibweOHyNivmAvufdXOke9nz2tdgclouo,1172
3
3
  pypeline/constants.py,sha256=EGSuLq4KhZ4bxrbtnUgKclELRyya5ipvv0WeybCzNAs,3049
4
- pypeline/dramatiq.py,sha256=D-E6_oJc9he-F2rvze-DCq4eBVY3Hq7V0pSC5crHrrU,13703
4
+ pypeline/dramatiq.py,sha256=S_rZMpGgE-VAmx9YjDBkHpSjFdhwp7mz4uuuKBUx4iQ,14405
5
+ pypeline/executable_job_config_schema.py,sha256=P2Z8SO057Jgyt4I5oZxcbEi1iaZkLoAh7qp8PtuqcqU,1010
5
6
  pypeline/extensions.py,sha256=BzOTnXhNxap3N7uIUUh_hO6dDwx08Vc_RJDE93_K0Lo,610
6
7
  pypeline/pipeline_config_schema.py,sha256=kprvmfPfmNVP5MOqtWzDm4ON5NJWIKQC8GWbIy5EIuk,11183
7
8
  pypeline/pipeline_settings_schema.py,sha256=B_Jzh4rUKLYBRSBT2vYgeXMYdFiYRdt3_sX6t125Hkk,20899
8
- pypeline/pypeline_yaml.py,sha256=Og08sUKwOjq7JYPnkg-NIcGbHravYCkC5Arz22rZEtA,16981
9
+ pypeline/pypeline_yaml.py,sha256=hbOdwKDUg10wsZnwVaBt46FbpS3iuB3bLwVuYyXh4OY,17270
9
10
  pypeline/schedule_config_schema.py,sha256=vtZV-5wpGcAiYcXxdBPRkrjsbR6x_9E-1PC2elrKKbE,3611
10
11
  pypeline/flask/__init__.py,sha256=AdljRh0lMiS8ExgDmgzObwVs8jW7hqQuf83Ml8kn8GQ,491
11
12
  pypeline/flask/decorators.py,sha256=ki6jkjZwbDbCWuj7ET7N-ncZwrASp4Fy7257WIYiAAQ,1102
@@ -24,16 +25,17 @@ pypeline/pipelines/middleware/graceful_shutdown_middleware.py,sha256=k37zmFk9dOy
24
25
  pypeline/pipelines/middleware/parallel_pipeline_middleware.py,sha256=kTp6niYoe2nXIiN6EGRfdpxrJyioo0GPxDkfefbGlEk,2821
25
26
  pypeline/pipelines/middleware/pypeline_middleware.py,sha256=AGQCRmqXcYNyCxinwtGZplHwltrmZ_sH73CVRLu_0EE,8961
26
27
  pypeline/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- pypeline/utils/config_utils.py,sha256=rAIATyoW7kGETZ_Z2DqiXtGd7bJp5uPfcLtfNPOYsNs,2167
28
+ pypeline/utils/config_utils.py,sha256=C-kZUS3L9zer9Ornrx9Sngf5P38c8zC-izaEpefxmBg,2459
28
29
  pypeline/utils/dramatiq_utils.py,sha256=DUdgVywm1182A4i69XzH9EIh1EJ9zAHmJLtOaVSW7pw,3844
30
+ pypeline/utils/executable_job_util.py,sha256=Id4FYvCdzqOCzQYSoU2yeOncubKwSwITUf_BgIPZQUw,1206
29
31
  pypeline/utils/graceful_shutdown_util.py,sha256=gdyf4r_vlunZZP-prcol_9aJQEG9Hk8evivVSe_H0N0,1293
30
32
  pypeline/utils/module_utils.py,sha256=-yEJIukDCoXnmlZVXB6Dww25tH6GdPE5SoFqv6pfdVU,3682
31
33
  pypeline/utils/pipeline_utils.py,sha256=kGP1QwCJikGC5QNRtzRXCDVewyRMpWIqERTNnxGLlSY,4795
32
34
  pypeline/utils/schema_utils.py,sha256=Fgl0y9Cuo_TZeEx_S3gaSVnLjn6467LTkjb2ek7Ms98,851
33
35
  tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- scalable_pypeline-2.1.18.dist-info/LICENSE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174
35
- scalable_pypeline-2.1.18.dist-info/METADATA,sha256=GaWesZImz-Dc7QAypUT-8qi3GKte69QSQakBEOITY2c,5982
36
- scalable_pypeline-2.1.18.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
37
- scalable_pypeline-2.1.18.dist-info/entry_points.txt,sha256=uWs10ODfHSBKo2Cx_QaUjPHQTpZ3e77j9VlAdRRmMyg,119
38
- scalable_pypeline-2.1.18.dist-info/top_level.txt,sha256=C7dpkEOc_-nnsAQb28BfQknjD6XHRyS9ZrvVeoIbV7s,15
39
- scalable_pypeline-2.1.18.dist-info/RECORD,,
36
+ scalable_pypeline-2.1.19.dist-info/LICENSE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174
37
+ scalable_pypeline-2.1.19.dist-info/METADATA,sha256=aW0WuUF0FpWnsnngqIImDLZnru5n0D0VrmqeNYoJ1I0,5982
38
+ scalable_pypeline-2.1.19.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
39
+ scalable_pypeline-2.1.19.dist-info/entry_points.txt,sha256=uWs10ODfHSBKo2Cx_QaUjPHQTpZ3e77j9VlAdRRmMyg,119
40
+ scalable_pypeline-2.1.19.dist-info/top_level.txt,sha256=C7dpkEOc_-nnsAQb28BfQknjD6XHRyS9ZrvVeoIbV7s,15
41
+ scalable_pypeline-2.1.19.dist-info/RECORD,,