scalable-pypeline 2.1.18__py2.py3-none-any.whl → 2.1.20__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 +1 -1
- pypeline/dramatiq.py +15 -1
- pypeline/executable_job_config_schema.py +35 -0
- pypeline/pypeline_yaml.py +10 -0
- pypeline/utils/config_utils.py +10 -0
- pypeline/utils/executable_job_util.py +35 -0
- {scalable_pypeline-2.1.18.dist-info → scalable_pypeline-2.1.20.dist-info}/METADATA +1 -1
- {scalable_pypeline-2.1.18.dist-info → scalable_pypeline-2.1.20.dist-info}/RECORD +12 -10
- {scalable_pypeline-2.1.18.dist-info → scalable_pypeline-2.1.20.dist-info}/LICENSE +0 -0
- {scalable_pypeline-2.1.18.dist-info → scalable_pypeline-2.1.20.dist-info}/WHEEL +0 -0
- {scalable_pypeline-2.1.18.dist-info → scalable_pypeline-2.1.20.dist-info}/entry_points.txt +0 -0
- {scalable_pypeline-2.1.18.dist-info → scalable_pypeline-2.1.20.dist-info}/top_level.txt +0 -0
pypeline/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "2.1.
|
1
|
+
__version__ = "2.1.20"
|
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()
|
pypeline/utils/config_utils.py
CHANGED
@@ -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 or {}:
|
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,11 +1,12 @@
|
|
1
|
-
pypeline/__init__.py,sha256=
|
1
|
+
pypeline/__init__.py,sha256=1o03qONF3c4_EpFCJ6aUvh-e6t48L0nm4t4sDu21mEA,23
|
2
2
|
pypeline/barrier.py,sha256=oO964l9qOCOibweOHyNivmAvufdXOke9nz2tdgclouo,1172
|
3
3
|
pypeline/constants.py,sha256=EGSuLq4KhZ4bxrbtnUgKclELRyya5ipvv0WeybCzNAs,3049
|
4
|
-
pypeline/dramatiq.py,sha256=
|
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=
|
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=
|
28
|
+
pypeline/utils/config_utils.py,sha256=adMuDGKUFLz1G3B0HFzsVhvK5uKUQDXT9bZ6oliEawE,2465
|
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.
|
35
|
-
scalable_pypeline-2.1.
|
36
|
-
scalable_pypeline-2.1.
|
37
|
-
scalable_pypeline-2.1.
|
38
|
-
scalable_pypeline-2.1.
|
39
|
-
scalable_pypeline-2.1.
|
36
|
+
scalable_pypeline-2.1.20.dist-info/LICENSE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174
|
37
|
+
scalable_pypeline-2.1.20.dist-info/METADATA,sha256=nXCNyumIfipzr-IJM6DTfyvTWLXPzFXOy3PhPqno9Cs,5982
|
38
|
+
scalable_pypeline-2.1.20.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
|
39
|
+
scalable_pypeline-2.1.20.dist-info/entry_points.txt,sha256=uWs10ODfHSBKo2Cx_QaUjPHQTpZ3e77j9VlAdRRmMyg,119
|
40
|
+
scalable_pypeline-2.1.20.dist-info/top_level.txt,sha256=C7dpkEOc_-nnsAQb28BfQknjD6XHRyS9ZrvVeoIbV7s,15
|
41
|
+
scalable_pypeline-2.1.20.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|