scalable-pypeline 2.1.0__tar.gz → 2.1.1__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.
- {scalable-pypeline-2.1.0/scalable_pypeline.egg-info → scalable-pypeline-2.1.1}/PKG-INFO +1 -1
- scalable-pypeline-2.1.1/pypeline/__init__.py +1 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipeline_settings_schema.py +211 -4
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1/scalable_pypeline.egg-info}/PKG-INFO +1 -1
- scalable-pypeline-2.1.0/pypeline/__init__.py +0 -1
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/LICENSE +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/MANIFEST.in +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/README.md +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/barrier.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/constants.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/dramatiq.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/extensions.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/flask/__init__.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/flask/api/__init__.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/flask/api/pipelines.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/flask/api/schedules.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/flask/decorators.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/flask/flask_pypeline.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipeline_config_schema.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/__init__.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/composition/__init__.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/composition/parallel_pipeline_composition.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/composition/pypeline_composition.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/factory.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/middleware/__init__.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/middleware/parallel_pipeline_middleware.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/middleware/pypeline_middleware.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pypeline_yaml.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/schedule_config_schema.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/utils/__init__.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/utils/config_utils.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/utils/dramatiq_utils.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/utils/module_utils.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/utils/pipeline_utils.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/utils/schema_utils.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/requirements.txt +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/SOURCES.txt +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/dependency_links.txt +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/entry_points.txt +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/requires.txt +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/top_level.txt +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/setup.cfg +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/setup.py +0 -0
- {scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/tests/fixtures/__init__.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "2.1.1"
|
@@ -32,11 +32,39 @@ def create_pipeline_settings_schema(pipeline_settings_schema_data):
|
|
32
32
|
"float": fields.Float,
|
33
33
|
"boolean": fields.Boolean,
|
34
34
|
"datetime": fields.DateTime,
|
35
|
+
"array": fields.List,
|
36
|
+
"object": fields.Nested,
|
35
37
|
}.get(data_type)
|
36
38
|
|
37
39
|
if not field_type:
|
38
40
|
raise ValidationError(f"Unsupported dataType `{data_type}` for `{key}`.")
|
39
41
|
|
42
|
+
# Handle array type
|
43
|
+
if data_type == "array":
|
44
|
+
element_type = config.get("elementType")
|
45
|
+
if not element_type:
|
46
|
+
raise ValidationError(f"`elementType` is required for array `{key}`.")
|
47
|
+
field_args["cls_or_instance"] = {
|
48
|
+
"string": fields.String,
|
49
|
+
"int": fields.Integer,
|
50
|
+
"float": fields.Float,
|
51
|
+
"boolean": fields.Boolean,
|
52
|
+
"datetime": fields.DateTime,
|
53
|
+
}.get(element_type)
|
54
|
+
if not field_args["cls_or_instance"]:
|
55
|
+
raise ValidationError(
|
56
|
+
f"Unsupported elementType `{element_type}` for array `{key}`."
|
57
|
+
)
|
58
|
+
|
59
|
+
# Handle object type
|
60
|
+
if data_type == "object":
|
61
|
+
properties = config.get("properties")
|
62
|
+
if not properties:
|
63
|
+
raise ValidationError(f"`properties` is required for object `{key}`.")
|
64
|
+
# Recursively create a schema for the nested object
|
65
|
+
nested_schema = create_pipeline_settings_schema({"properties": properties})
|
66
|
+
field_args["schema"] = nested_schema
|
67
|
+
|
40
68
|
# Handle range validation for numeric fields
|
41
69
|
if data_type in ["int", "float"]:
|
42
70
|
if "minimum" in config or "maximum" in config:
|
@@ -64,6 +92,97 @@ def create_pipeline_settings_schema(pipeline_settings_schema_data):
|
|
64
92
|
return DynamicPipelineSettingsSchema()
|
65
93
|
|
66
94
|
|
95
|
+
def create_pipeline_settings_schema(pipeline_settings_schema_data):
|
96
|
+
"""
|
97
|
+
Dynamically create a schema to validate user data based on settings.
|
98
|
+
|
99
|
+
Args:
|
100
|
+
pipeline_settings_schema_data (dict): The settings schema data containing
|
101
|
+
field configurations.
|
102
|
+
|
103
|
+
Returns:
|
104
|
+
Schema: A dynamically created schema class for validating user data.
|
105
|
+
"""
|
106
|
+
|
107
|
+
# Dictionary to store dynamically generated fields
|
108
|
+
schema_fields = {}
|
109
|
+
|
110
|
+
for key, config in pipeline_settings_schema_data["properties"].items():
|
111
|
+
data_type = config.get("dataType")
|
112
|
+
input_type = config.get("inputType")
|
113
|
+
field_args = {}
|
114
|
+
|
115
|
+
# Map dataType to Marshmallow field type
|
116
|
+
field_type = {
|
117
|
+
"string": fields.String,
|
118
|
+
"int": fields.Integer,
|
119
|
+
"float": fields.Float,
|
120
|
+
"boolean": fields.Boolean,
|
121
|
+
"datetime": fields.DateTime,
|
122
|
+
"array": fields.List,
|
123
|
+
"object": fields.Nested,
|
124
|
+
}.get(data_type)
|
125
|
+
|
126
|
+
if not field_type:
|
127
|
+
raise ValidationError(f"Unsupported dataType `{data_type}` for `{key}`.")
|
128
|
+
|
129
|
+
# Handle array type
|
130
|
+
if data_type == "array":
|
131
|
+
element_type = config.get("elementType")
|
132
|
+
if not element_type:
|
133
|
+
raise ValidationError(f"`elementType` is required for array `{key}`.")
|
134
|
+
field_args["cls_or_instance"] = {
|
135
|
+
"string": fields.String,
|
136
|
+
"int": fields.Integer,
|
137
|
+
"float": fields.Float,
|
138
|
+
"boolean": fields.Boolean,
|
139
|
+
"datetime": fields.DateTime,
|
140
|
+
}.get(element_type)
|
141
|
+
if not field_args["cls_or_instance"]:
|
142
|
+
raise ValidationError(
|
143
|
+
f"Unsupported elementType `{element_type}` for array `{key}`."
|
144
|
+
)
|
145
|
+
|
146
|
+
# Handle object type
|
147
|
+
if data_type == "object":
|
148
|
+
properties = config.get("properties")
|
149
|
+
if not properties:
|
150
|
+
raise ValidationError(f"`properties` is required for object `{key}`.")
|
151
|
+
# Recursively create a schema for the nested object
|
152
|
+
nested_schema = create_pipeline_settings_schema({"properties": properties})
|
153
|
+
# Use the nested schema as the `nested` argument for fields.Nested
|
154
|
+
field_type = fields.Nested(nested_schema)
|
155
|
+
|
156
|
+
# Handle range validation for numeric fields
|
157
|
+
if data_type in ["int", "float"]:
|
158
|
+
if "minimum" in config or "maximum" in config:
|
159
|
+
field_args["validate"] = validate.Range(
|
160
|
+
min=config.get("minimum"), max=config.get("maximum")
|
161
|
+
)
|
162
|
+
|
163
|
+
# Handle dropdown or radio input options
|
164
|
+
if input_type in ["dropdown", "radio"] and "options" in config:
|
165
|
+
allowed_values = [option["value"] for option in config["options"]]
|
166
|
+
field_args["validate"] = validate.OneOf(allowed_values)
|
167
|
+
|
168
|
+
# Mark the field as required if specified
|
169
|
+
if key in pipeline_settings_schema_data.get("required", []):
|
170
|
+
field_args["required"] = True
|
171
|
+
|
172
|
+
# Create the field and add to the schema fields dictionary
|
173
|
+
if data_type == "object":
|
174
|
+
schema_fields[key] = field_type
|
175
|
+
else:
|
176
|
+
schema_fields[key] = field_type(**field_args)
|
177
|
+
|
178
|
+
# Dynamically create a schema class with the generated fields
|
179
|
+
DynamicPipelineSettingsSchema = type(
|
180
|
+
"DynamicPipelineSettingsSchema", (Schema,), schema_fields
|
181
|
+
)
|
182
|
+
|
183
|
+
return DynamicPipelineSettingsSchema()
|
184
|
+
|
185
|
+
|
67
186
|
class OptionSchema(Schema):
|
68
187
|
label = fields.String(
|
69
188
|
required=True,
|
@@ -103,13 +222,15 @@ def validate_min_max(data):
|
|
103
222
|
class SettingSchema(Schema):
|
104
223
|
dataType = fields.String(
|
105
224
|
required=True,
|
106
|
-
validate=validate.OneOf(
|
225
|
+
validate=validate.OneOf(
|
226
|
+
["string", "int", "float", "boolean", "datetime", "array", "object"]
|
227
|
+
),
|
107
228
|
metadata={"description": "The underlying data type of the setting"},
|
108
229
|
)
|
109
230
|
inputType = fields.String(
|
110
231
|
required=True,
|
111
232
|
validate=validate.OneOf(
|
112
|
-
["text", "dropdown", "radio", "checkbox", "searchable"]
|
233
|
+
["text", "dropdown", "radio", "checkbox", "searchable", "custom"]
|
113
234
|
),
|
114
235
|
metadata={"description": "The type of input UI element"},
|
115
236
|
)
|
@@ -133,6 +254,17 @@ class SettingSchema(Schema):
|
|
133
254
|
searchEndpoint = fields.String(
|
134
255
|
metadata={"description": "Endpoint for searchable fields"}
|
135
256
|
)
|
257
|
+
component = fields.String(
|
258
|
+
metadata={"description": "React component for custom input types"}
|
259
|
+
)
|
260
|
+
elementType = fields.String(
|
261
|
+
metadata={"description": "Element type for array data types"}
|
262
|
+
)
|
263
|
+
properties = fields.Dict(
|
264
|
+
keys=fields.String(),
|
265
|
+
values=fields.Nested(lambda: SettingSchema),
|
266
|
+
metadata={"description": "Properties for object data types"},
|
267
|
+
)
|
136
268
|
|
137
269
|
class Meta:
|
138
270
|
ordered = True
|
@@ -197,6 +329,57 @@ class SettingSchema(Schema):
|
|
197
329
|
field_name="searchEndpoint",
|
198
330
|
)
|
199
331
|
|
332
|
+
@validates_schema
|
333
|
+
def validate_custom_component(self, data, **kwargs):
|
334
|
+
"""Ensure component is provided for custom input types."""
|
335
|
+
input_type = data.get("inputType")
|
336
|
+
component = data.get("component")
|
337
|
+
|
338
|
+
if input_type == "custom" and not component:
|
339
|
+
raise ValidationError(
|
340
|
+
"`component` is required for `custom` input types.",
|
341
|
+
field_name="component",
|
342
|
+
)
|
343
|
+
elif input_type != "custom" and component:
|
344
|
+
raise ValidationError(
|
345
|
+
"`component` is not allowed for non-custom input types.",
|
346
|
+
field_name="component",
|
347
|
+
)
|
348
|
+
|
349
|
+
@validates_schema
|
350
|
+
def validate_array_element_type(self, data, **kwargs):
|
351
|
+
"""Ensure elementType is provided for array data types."""
|
352
|
+
data_type = data.get("dataType")
|
353
|
+
element_type = data.get("elementType")
|
354
|
+
|
355
|
+
if data_type == "array" and not element_type:
|
356
|
+
raise ValidationError(
|
357
|
+
"`elementType` is required for `array` data types.",
|
358
|
+
field_name="elementType",
|
359
|
+
)
|
360
|
+
elif data_type != "array" and element_type:
|
361
|
+
raise ValidationError(
|
362
|
+
"`elementType` is not allowed for non-array data types.",
|
363
|
+
field_name="elementType",
|
364
|
+
)
|
365
|
+
|
366
|
+
@validates_schema
|
367
|
+
def validate_object_properties(self, data, **kwargs):
|
368
|
+
"""Ensure properties are provided for object data types."""
|
369
|
+
data_type = data.get("dataType")
|
370
|
+
properties = data.get("properties")
|
371
|
+
|
372
|
+
if data_type == "object" and not properties:
|
373
|
+
raise ValidationError(
|
374
|
+
"`properties` is required for `object` data types.",
|
375
|
+
field_name="properties",
|
376
|
+
)
|
377
|
+
elif data_type != "object" and properties:
|
378
|
+
raise ValidationError(
|
379
|
+
"`properties` is not allowed for non-object data types.",
|
380
|
+
field_name="properties",
|
381
|
+
)
|
382
|
+
|
200
383
|
|
201
384
|
class PipelineSettingsSchema(Schema):
|
202
385
|
properties = fields.Dict(
|
@@ -288,8 +471,8 @@ if __name__ == "__main__":
|
|
288
471
|
"dataType": "int",
|
289
472
|
"inputType": "text",
|
290
473
|
"label": "Parameter 2",
|
291
|
-
"minimum": 1,
|
292
|
-
"maximum":
|
474
|
+
"minimum": -1,
|
475
|
+
"maximum": 1,
|
293
476
|
},
|
294
477
|
"param3": {
|
295
478
|
"dataType": "boolean",
|
@@ -322,6 +505,30 @@ if __name__ == "__main__":
|
|
322
505
|
"label": "Select Pipeline",
|
323
506
|
"searchEndpoint": "/api/pipelines",
|
324
507
|
},
|
508
|
+
"param7": {
|
509
|
+
"dataType": "array",
|
510
|
+
"inputType": "text",
|
511
|
+
"label": "Array of Integers",
|
512
|
+
"elementType": "int",
|
513
|
+
},
|
514
|
+
"param8": {
|
515
|
+
"dataType": "object",
|
516
|
+
"inputType": "custom",
|
517
|
+
"label": "Custom Object",
|
518
|
+
"component": "CustomObjectComponent",
|
519
|
+
"properties": {
|
520
|
+
"subParam1": {
|
521
|
+
"dataType": "string",
|
522
|
+
"inputType": "text",
|
523
|
+
"label": "Sub Parameter 1",
|
524
|
+
},
|
525
|
+
"subParam2": {
|
526
|
+
"dataType": "int",
|
527
|
+
"inputType": "text",
|
528
|
+
"label": "Sub Parameter 2",
|
529
|
+
},
|
530
|
+
},
|
531
|
+
},
|
325
532
|
},
|
326
533
|
"required": ["param1", "param2", "param4"],
|
327
534
|
}
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "2.1.0"
|
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
|
{scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/composition/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/pypeline/pipelines/middleware/__init__.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
|
{scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/dependency_links.txt
RENAMED
File without changes
|
{scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/entry_points.txt
RENAMED
File without changes
|
File without changes
|
{scalable-pypeline-2.1.0 → scalable-pypeline-2.1.1}/scalable_pypeline.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|