workbench 0.8.186__py3-none-any.whl → 0.8.188__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.
Potentially problematic release.
This version of workbench might be problematic. Click here for more details.
- workbench/core/artifacts/endpoint_core.py +6 -6
- workbench/core/artifacts/feature_set_core.py +5 -5
- workbench/core/artifacts/model_core.py +18 -0
- workbench/core/transforms/features_to_model/features_to_model.py +5 -0
- workbench/core/views/training_view.py +11 -5
- workbench/core/views/view.py +51 -1
- workbench/core/views/view_utils.py +4 -4
- workbench/model_scripts/xgb_model/generated_model_script.py +6 -6
- workbench/scripts/lambda_launcher.py +39 -0
- workbench/scripts/ml_pipeline_sqs.py +6 -1
- workbench/utils/config_manager.py +2 -6
- workbench/utils/endpoint_utils.py +5 -7
- workbench/utils/license_manager.py +2 -6
- workbench/utils/model_utils.py +6 -8
- workbench/utils/xgboost_model_utils.py +2 -2
- {workbench-0.8.186.dist-info → workbench-0.8.188.dist-info}/METADATA +2 -1
- {workbench-0.8.186.dist-info → workbench-0.8.188.dist-info}/RECORD +21 -21
- {workbench-0.8.186.dist-info → workbench-0.8.188.dist-info}/entry_points.txt +1 -0
- workbench/utils/resource_utils.py +0 -39
- {workbench-0.8.186.dist-info → workbench-0.8.188.dist-info}/WHEEL +0 -0
- {workbench-0.8.186.dist-info → workbench-0.8.188.dist-info}/licenses/LICENSE +0 -0
- {workbench-0.8.186.dist-info → workbench-0.8.188.dist-info}/top_level.txt +0 -0
|
@@ -356,7 +356,7 @@ class EndpointCore(Artifact):
|
|
|
356
356
|
return pd.DataFrame()
|
|
357
357
|
|
|
358
358
|
# Grab the evaluation data from the FeatureSet
|
|
359
|
-
table =
|
|
359
|
+
table = model.training_view().table
|
|
360
360
|
eval_df = fs.query(f'SELECT * FROM "{table}" where training = FALSE')
|
|
361
361
|
capture_name = "auto_inference" if capture else None
|
|
362
362
|
return self.inference(eval_df, capture_name, id_column=fs.id_column)
|
|
@@ -472,7 +472,7 @@ class EndpointCore(Artifact):
|
|
|
472
472
|
self.log.important("UQ Regressor detected, running full inference to get uncertainty estimates...")
|
|
473
473
|
|
|
474
474
|
# Get the training view dataframe for inference
|
|
475
|
-
training_df =
|
|
475
|
+
training_df = model.training_view().pull_dataframe()
|
|
476
476
|
|
|
477
477
|
# Run inference on the endpoint to get UQ outputs
|
|
478
478
|
uq_df = self.inference(training_df)
|
|
@@ -1103,7 +1103,7 @@ class EndpointCore(Artifact):
|
|
|
1103
1103
|
if __name__ == "__main__":
|
|
1104
1104
|
"""Exercise the Endpoint Class"""
|
|
1105
1105
|
from workbench.api import FeatureSet
|
|
1106
|
-
from workbench.utils.endpoint_utils import
|
|
1106
|
+
from workbench.utils.endpoint_utils import get_evaluation_data
|
|
1107
1107
|
import random
|
|
1108
1108
|
|
|
1109
1109
|
# Grab an EndpointCore object and pull some information from it
|
|
@@ -1111,7 +1111,7 @@ if __name__ == "__main__":
|
|
|
1111
1111
|
|
|
1112
1112
|
# Test various error conditions (set row 42 length to pd.NA)
|
|
1113
1113
|
# Note: This test should return ALL rows
|
|
1114
|
-
my_eval_df =
|
|
1114
|
+
my_eval_df = get_evaluation_data(my_endpoint)
|
|
1115
1115
|
my_eval_df.at[42, "length"] = pd.NA
|
|
1116
1116
|
pred_results = my_endpoint.inference(my_eval_df, drop_error_rows=True)
|
|
1117
1117
|
print(f"Sent rows: {len(my_eval_df)}")
|
|
@@ -1182,11 +1182,11 @@ if __name__ == "__main__":
|
|
|
1182
1182
|
# Run Inference where we provide the data
|
|
1183
1183
|
# Note: This dataframe could be from a FeatureSet or any other source
|
|
1184
1184
|
print("Running Inference...")
|
|
1185
|
-
my_eval_df =
|
|
1185
|
+
my_eval_df = get_evaluation_data(my_endpoint)
|
|
1186
1186
|
pred_results = my_endpoint.inference(my_eval_df)
|
|
1187
1187
|
|
|
1188
1188
|
# Now set capture=True to save inference results and metrics
|
|
1189
|
-
my_eval_df =
|
|
1189
|
+
my_eval_df = get_evaluation_data(my_endpoint)
|
|
1190
1190
|
pred_results = my_endpoint.inference(my_eval_df, capture_name="holdout_xyz")
|
|
1191
1191
|
|
|
1192
1192
|
# Run predictions using the fast_inference method
|
|
@@ -194,24 +194,24 @@ class FeatureSetCore(Artifact):
|
|
|
194
194
|
|
|
195
195
|
return View(self, view_name)
|
|
196
196
|
|
|
197
|
-
def set_display_columns(self,
|
|
197
|
+
def set_display_columns(self, display_columns: list[str]):
|
|
198
198
|
"""Set the display columns for this Data Source
|
|
199
199
|
|
|
200
200
|
Args:
|
|
201
|
-
|
|
201
|
+
display_columns (list[str]): The display columns for this Data Source
|
|
202
202
|
"""
|
|
203
203
|
# Check mismatch of display columns to computation columns
|
|
204
204
|
c_view = self.view("computation")
|
|
205
205
|
computation_columns = c_view.columns
|
|
206
|
-
mismatch_columns = [col for col in
|
|
206
|
+
mismatch_columns = [col for col in display_columns if col not in computation_columns]
|
|
207
207
|
if mismatch_columns:
|
|
208
208
|
self.log.monitor(f"Display View/Computation mismatch: {mismatch_columns}")
|
|
209
209
|
|
|
210
|
-
self.log.important(f"Setting Display Columns...{
|
|
210
|
+
self.log.important(f"Setting Display Columns...{display_columns}")
|
|
211
211
|
from workbench.core.views import DisplayView
|
|
212
212
|
|
|
213
213
|
# Create a NEW display view
|
|
214
|
-
DisplayView.create(self, source_table=c_view.table, column_list=
|
|
214
|
+
DisplayView.create(self, source_table=c_view.table, column_list=display_columns)
|
|
215
215
|
|
|
216
216
|
def set_computation_columns(self, computation_columns: list[str], reset_display: bool = True):
|
|
217
217
|
"""Set the computation columns for this FeatureSet
|
|
@@ -592,6 +592,24 @@ class ModelCore(Artifact):
|
|
|
592
592
|
# Return the details
|
|
593
593
|
return details
|
|
594
594
|
|
|
595
|
+
# Training View for this model
|
|
596
|
+
def training_view(self):
|
|
597
|
+
"""Get the training view for this model"""
|
|
598
|
+
from workbench.core.artifacts.feature_set_core import FeatureSetCore
|
|
599
|
+
from workbench.core.views import View
|
|
600
|
+
|
|
601
|
+
# Grab our FeatureSet
|
|
602
|
+
fs = FeatureSetCore(self.get_input())
|
|
603
|
+
|
|
604
|
+
# See if we have a training view for this model
|
|
605
|
+
my_model_training_view = f"{self.name.replace("-", "_")}_training"
|
|
606
|
+
view = View(fs, my_model_training_view, auto_create_view=False)
|
|
607
|
+
if view.exists():
|
|
608
|
+
return view
|
|
609
|
+
else:
|
|
610
|
+
self.log.important(f"No specific training view {my_model_training_view}, returning default training view")
|
|
611
|
+
return fs.view("training")
|
|
612
|
+
|
|
595
613
|
# Pipeline for this model
|
|
596
614
|
def get_pipeline(self) -> str:
|
|
597
615
|
"""Get the pipeline for this model"""
|
|
@@ -264,6 +264,11 @@ class FeaturesToModel(Transform):
|
|
|
264
264
|
self.log.important(f"Creating new model {self.output_name}...")
|
|
265
265
|
self.create_and_register_model(**kwargs)
|
|
266
266
|
|
|
267
|
+
# Make a copy of the training view, to lock-in the training data used for this model
|
|
268
|
+
model_training_view_name = f"{self.output_name.replace("-", "_")}_training"
|
|
269
|
+
self.log.important(f"Creating Model Training View: {model_training_view_name}...")
|
|
270
|
+
feature_set.view("training").copy(f"{model_training_view_name}")
|
|
271
|
+
|
|
267
272
|
def post_transform(self, **kwargs):
|
|
268
273
|
"""Post-Transform: Calling onboard() on the Model"""
|
|
269
274
|
self.log.info("Post-Transform: Calling onboard() on the Model...")
|
|
@@ -10,7 +10,11 @@ from workbench.core.views.view_utils import get_column_list
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class TrainingView(CreateView):
|
|
13
|
-
"""TrainingView Class: A View with an additional training column
|
|
13
|
+
"""TrainingView Class: A View with an additional training column (80/20 or holdout ids).
|
|
14
|
+
The TrainingView class creates a SQL view that includes all columns from the source table
|
|
15
|
+
along with an additional boolean column named "training". This view can also include
|
|
16
|
+
a SQL filter expression to filter the rows included in the view.
|
|
17
|
+
|
|
14
18
|
|
|
15
19
|
Common Usage:
|
|
16
20
|
```python
|
|
@@ -19,8 +23,9 @@ class TrainingView(CreateView):
|
|
|
19
23
|
training_view = TrainingView.create(fs)
|
|
20
24
|
df = training_view.pull_dataframe()
|
|
21
25
|
|
|
22
|
-
# Create a TrainingView with a specific
|
|
23
|
-
training_view = TrainingView.create(fs,
|
|
26
|
+
# Create a TrainingView with a specific filter expression
|
|
27
|
+
training_view = TrainingView.create(fs, id_column="auto_id", filter_expression="age > 30")
|
|
28
|
+
df = training_view.pull_dataframe()
|
|
24
29
|
|
|
25
30
|
# Query the view
|
|
26
31
|
df = training_view.query(f"SELECT * FROM {training_view.table} where training = TRUE")
|
|
@@ -31,20 +36,21 @@ class TrainingView(CreateView):
|
|
|
31
36
|
def create(
|
|
32
37
|
cls,
|
|
33
38
|
feature_set: FeatureSet,
|
|
34
|
-
|
|
39
|
+
*, # Enforce keyword arguments after feature_set
|
|
35
40
|
id_column: str = None,
|
|
36
41
|
holdout_ids: Union[list[str], list[int], None] = None,
|
|
37
42
|
filter_expression: str = None,
|
|
43
|
+
source_table: str = None,
|
|
38
44
|
) -> Union[View, None]:
|
|
39
45
|
"""Factory method to create and return a TrainingView instance.
|
|
40
46
|
|
|
41
47
|
Args:
|
|
42
48
|
feature_set (FeatureSet): A FeatureSet object
|
|
43
|
-
source_table (str, optional): The table/view to create the view from. Defaults to None.
|
|
44
49
|
id_column (str, optional): The name of the id column. Defaults to None.
|
|
45
50
|
holdout_ids (Union[list[str], list[int], None], optional): A list of holdout ids. Defaults to None.
|
|
46
51
|
filter_expression (str, optional): SQL filter expression (e.g., "age > 25 AND status = 'active'").
|
|
47
52
|
Defaults to None.
|
|
53
|
+
source_table (str, optional): The table/view to create the view from. Defaults to None.
|
|
48
54
|
|
|
49
55
|
Returns:
|
|
50
56
|
Union[View, None]: The created View object (or None if failed to create the view)
|
workbench/core/views/view.py
CHANGED
|
@@ -196,12 +196,52 @@ class View:
|
|
|
196
196
|
|
|
197
197
|
# The BaseView always exists
|
|
198
198
|
if self.view_name == "base":
|
|
199
|
-
return
|
|
199
|
+
return
|
|
200
200
|
|
|
201
201
|
# Check the database directly
|
|
202
202
|
if not self._check_database():
|
|
203
203
|
self._auto_create_view()
|
|
204
204
|
|
|
205
|
+
def copy(self, dest_view_name: str) -> "View":
|
|
206
|
+
"""Copy this view to a new view with a different name
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
dest_view_name (str): The destination view name (e.g. "training_v1")
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
View: A new View object for the destination view
|
|
213
|
+
"""
|
|
214
|
+
# Can't copy the base view
|
|
215
|
+
if self.view_name == "base":
|
|
216
|
+
self.log.error("Cannot copy the base view")
|
|
217
|
+
return None
|
|
218
|
+
|
|
219
|
+
# Get the view definition
|
|
220
|
+
get_view_query = f"""
|
|
221
|
+
SELECT view_definition
|
|
222
|
+
FROM information_schema.views
|
|
223
|
+
WHERE table_schema = '{self.database}'
|
|
224
|
+
AND table_name = '{self.table}'
|
|
225
|
+
"""
|
|
226
|
+
df = self.data_source.query(get_view_query)
|
|
227
|
+
|
|
228
|
+
if df.empty:
|
|
229
|
+
self.log.error(f"View {self.table} not found")
|
|
230
|
+
return None
|
|
231
|
+
|
|
232
|
+
view_definition = df.iloc[0]["view_definition"]
|
|
233
|
+
|
|
234
|
+
# Create the new view with the destination name
|
|
235
|
+
dest_table = f"{self.base_table_name}___{dest_view_name}"
|
|
236
|
+
create_view_query = f'CREATE OR REPLACE VIEW "{dest_table}" AS {view_definition}'
|
|
237
|
+
|
|
238
|
+
self.log.important(f"Copying view {self.table} to {dest_table}...")
|
|
239
|
+
self.data_source.execute_statement(create_view_query)
|
|
240
|
+
|
|
241
|
+
# Return a new View object for the destination
|
|
242
|
+
artifact = FeatureSet(self.artifact_name) if self.is_feature_set else DataSource(self.artifact_name)
|
|
243
|
+
return View(artifact, dest_view_name, auto_create_view=False)
|
|
244
|
+
|
|
205
245
|
def _check_database(self) -> bool:
|
|
206
246
|
"""Internal: Check if the view exists in the database
|
|
207
247
|
|
|
@@ -324,3 +364,13 @@ if __name__ == "__main__":
|
|
|
324
364
|
# Test supplemental data tables deletion
|
|
325
365
|
view = View(fs, "test_view")
|
|
326
366
|
view.delete()
|
|
367
|
+
|
|
368
|
+
# Test copying a view
|
|
369
|
+
fs = FeatureSet("test_features")
|
|
370
|
+
display_view = View(fs, "display")
|
|
371
|
+
copied_view = display_view.copy("display_copy")
|
|
372
|
+
print(copied_view)
|
|
373
|
+
print(copied_view.pull_dataframe().head())
|
|
374
|
+
|
|
375
|
+
# Clean up copied view
|
|
376
|
+
copied_view.delete()
|
|
@@ -296,15 +296,15 @@ if __name__ == "__main__":
|
|
|
296
296
|
print("View Details on the FeatureSet Table...")
|
|
297
297
|
print(view_details(my_data_source.table, my_data_source.database, my_data_source.boto3_session))
|
|
298
298
|
|
|
299
|
-
print("View Details on the
|
|
300
|
-
training_view = fs.view("
|
|
299
|
+
print("View Details on the Display View...")
|
|
300
|
+
training_view = fs.view("display")
|
|
301
301
|
print(view_details(training_view.table, training_view.database, my_data_source.boto3_session))
|
|
302
302
|
|
|
303
303
|
# Test get_column_list
|
|
304
304
|
print(get_column_list(my_data_source))
|
|
305
305
|
|
|
306
|
-
# Test get_column_list (with
|
|
307
|
-
training_table = fs.view("
|
|
306
|
+
# Test get_column_list (with display view)
|
|
307
|
+
training_table = fs.view("display").table
|
|
308
308
|
print(get_column_list(my_data_source, training_table))
|
|
309
309
|
|
|
310
310
|
# Test list_views
|
|
@@ -29,12 +29,12 @@ from typing import List, Tuple
|
|
|
29
29
|
# Template Parameters
|
|
30
30
|
TEMPLATE_PARAMS = {
|
|
31
31
|
"model_type": "regressor",
|
|
32
|
-
"target": "
|
|
33
|
-
"features": ['
|
|
32
|
+
"target": "class_number_of_rings",
|
|
33
|
+
"features": ['length', 'diameter', 'height', 'whole_weight', 'shucked_weight', 'viscera_weight', 'shell_weight', 'sex'],
|
|
34
34
|
"compressed_features": [],
|
|
35
|
-
"model_metrics_s3_path": "s3://
|
|
35
|
+
"model_metrics_s3_path": "s3://sandbox-sageworks-artifacts/models/abalone-regression/training",
|
|
36
36
|
"train_all_data": False,
|
|
37
|
-
"hyperparameters": {
|
|
37
|
+
"hyperparameters": {},
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
|
|
@@ -145,7 +145,7 @@ def convert_categorical_types(df: pd.DataFrame, features: list, category_mapping
|
|
|
145
145
|
def decompress_features(
|
|
146
146
|
df: pd.DataFrame, features: List[str], compressed_features: List[str]
|
|
147
147
|
) -> Tuple[pd.DataFrame, List[str]]:
|
|
148
|
-
"""Prepare features for the model
|
|
148
|
+
"""Prepare features for the model by decompressing bitstring features
|
|
149
149
|
|
|
150
150
|
Args:
|
|
151
151
|
df (pd.DataFrame): The features DataFrame
|
|
@@ -170,7 +170,7 @@ def decompress_features(
|
|
|
170
170
|
)
|
|
171
171
|
|
|
172
172
|
# Decompress the specified compressed features
|
|
173
|
-
decompressed_features = features
|
|
173
|
+
decompressed_features = features.copy()
|
|
174
174
|
for feature in compressed_features:
|
|
175
175
|
if (feature not in df.columns) or (feature not in features):
|
|
176
176
|
print(f"Feature '{feature}' not in the features list, skipping decompression.")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import importlib.util
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
if len(sys.argv) != 2:
|
|
8
|
+
print("Usage: lambda_launcher <handler_module_name>")
|
|
9
|
+
sys.exit(1)
|
|
10
|
+
|
|
11
|
+
handler_file = sys.argv[1]
|
|
12
|
+
|
|
13
|
+
# Add .py if not present
|
|
14
|
+
if not handler_file.endswith(".py"):
|
|
15
|
+
handler_file += ".py"
|
|
16
|
+
|
|
17
|
+
# Check if file exists
|
|
18
|
+
if not os.path.exists(handler_file):
|
|
19
|
+
print(f"Error: File '{handler_file}' not found")
|
|
20
|
+
sys.exit(1)
|
|
21
|
+
|
|
22
|
+
# Load the module dynamically
|
|
23
|
+
spec = importlib.util.spec_from_file_location("lambda_module", handler_file)
|
|
24
|
+
lambda_module = importlib.util.module_from_spec(spec)
|
|
25
|
+
spec.loader.exec_module(lambda_module)
|
|
26
|
+
|
|
27
|
+
# Call the lambda_handler
|
|
28
|
+
print(f"Invoking lambda_handler from {handler_file}...")
|
|
29
|
+
print("-" * 50)
|
|
30
|
+
|
|
31
|
+
result = lambda_module.lambda_handler({}, {})
|
|
32
|
+
|
|
33
|
+
print("-" * 50)
|
|
34
|
+
print("Result:")
|
|
35
|
+
print(result)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
main()
|
|
@@ -158,9 +158,14 @@ def main():
|
|
|
158
158
|
action="store_true",
|
|
159
159
|
help="Set DT=True (models and endpoints will have '-dt' suffix)",
|
|
160
160
|
)
|
|
161
|
+
parser.add_argument(
|
|
162
|
+
"--promote",
|
|
163
|
+
action="store_true",
|
|
164
|
+
help="Set Promote=True (models and endpoints will use promoted naming",
|
|
165
|
+
)
|
|
161
166
|
args = parser.parse_args()
|
|
162
167
|
try:
|
|
163
|
-
submit_to_sqs(args.script_file, args.size, realtime=args.realtime, dt=args.dt)
|
|
168
|
+
submit_to_sqs(args.script_file, args.size, realtime=args.realtime, dt=args.dt, promote=args.promote)
|
|
164
169
|
except Exception as e:
|
|
165
170
|
print(f"\n❌ ERROR: {e}")
|
|
166
171
|
log.error(f"Error: {e}")
|
|
@@ -4,16 +4,13 @@ import os
|
|
|
4
4
|
import sys
|
|
5
5
|
import platform
|
|
6
6
|
import logging
|
|
7
|
-
import importlib.resources as resources # noqa: F401 Python 3.9 compatibility
|
|
8
7
|
from typing import Any, Dict
|
|
8
|
+
from importlib.resources import files, as_file
|
|
9
9
|
|
|
10
10
|
# Workbench imports
|
|
11
11
|
from workbench.utils.license_manager import LicenseManager
|
|
12
12
|
from workbench_bridges.utils.execution_environment import running_as_service
|
|
13
13
|
|
|
14
|
-
# Python 3.9 compatibility
|
|
15
|
-
from workbench.utils.resource_utils import get_resource_path
|
|
16
|
-
|
|
17
14
|
|
|
18
15
|
class FatalConfigError(Exception):
|
|
19
16
|
"""Exception raised for errors in the configuration."""
|
|
@@ -172,8 +169,7 @@ class ConfigManager:
|
|
|
172
169
|
Returns:
|
|
173
170
|
str: The open source API key.
|
|
174
171
|
"""
|
|
175
|
-
|
|
176
|
-
with get_resource_path("workbench.resources", "open_source_api.key") as open_source_key_path:
|
|
172
|
+
with as_file(files("workbench.resources").joinpath("open_source_api.key")) as open_source_key_path:
|
|
177
173
|
with open(open_source_key_path, "r") as key_file:
|
|
178
174
|
return key_file.read().strip()
|
|
179
175
|
|
|
@@ -7,9 +7,7 @@ from typing import Union, Optional
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
|
|
9
9
|
# Workbench Imports
|
|
10
|
-
from workbench.api
|
|
11
|
-
from workbench.api.model import Model
|
|
12
|
-
from workbench.api.endpoint import Endpoint
|
|
10
|
+
from workbench.api import FeatureSet, Model, Endpoint
|
|
13
11
|
|
|
14
12
|
# Set up the log
|
|
15
13
|
log = logging.getLogger("workbench")
|
|
@@ -77,7 +75,7 @@ def internal_model_data_url(endpoint_config_name: str, session: boto3.Session) -
|
|
|
77
75
|
return None
|
|
78
76
|
|
|
79
77
|
|
|
80
|
-
def
|
|
78
|
+
def get_training_data(end: Endpoint) -> pd.DataFrame:
|
|
81
79
|
"""Code to get the training data from the FeatureSet used to train the Model
|
|
82
80
|
|
|
83
81
|
Args:
|
|
@@ -100,7 +98,7 @@ def fs_training_data(end: Endpoint) -> pd.DataFrame:
|
|
|
100
98
|
return train_df
|
|
101
99
|
|
|
102
100
|
|
|
103
|
-
def
|
|
101
|
+
def get_evaluation_data(end: Endpoint) -> pd.DataFrame:
|
|
104
102
|
"""Code to get the evaluation data from the FeatureSet NOT used for training
|
|
105
103
|
|
|
106
104
|
Args:
|
|
@@ -178,11 +176,11 @@ if __name__ == "__main__":
|
|
|
178
176
|
print(model_data_url)
|
|
179
177
|
|
|
180
178
|
# Get the training data
|
|
181
|
-
my_train_df =
|
|
179
|
+
my_train_df = get_training_data(my_endpoint)
|
|
182
180
|
print(my_train_df)
|
|
183
181
|
|
|
184
182
|
# Get the evaluation data
|
|
185
|
-
my_eval_df =
|
|
183
|
+
my_eval_df = get_evaluation_data(my_endpoint)
|
|
186
184
|
print(my_eval_df)
|
|
187
185
|
|
|
188
186
|
# Backtrack to the FeatureSet
|
|
@@ -6,15 +6,12 @@ import json
|
|
|
6
6
|
import logging
|
|
7
7
|
import requests
|
|
8
8
|
from typing import Union
|
|
9
|
-
import importlib.resources as resources # noqa: F401 Python 3.9 compatibility
|
|
10
9
|
from datetime import datetime
|
|
11
10
|
from cryptography.hazmat.primitives import hashes
|
|
12
11
|
from cryptography.hazmat.primitives.asymmetric import padding
|
|
13
12
|
from cryptography.hazmat.primitives import serialization
|
|
14
13
|
from cryptography.hazmat.backends import default_backend
|
|
15
|
-
|
|
16
|
-
# Python 3.9 compatibility
|
|
17
|
-
from workbench.utils.resource_utils import get_resource_path
|
|
14
|
+
from importlib.resources import files, as_file
|
|
18
15
|
|
|
19
16
|
|
|
20
17
|
class FatalLicenseError(Exception):
|
|
@@ -140,8 +137,7 @@ class LicenseManager:
|
|
|
140
137
|
Returns:
|
|
141
138
|
The public key as an object.
|
|
142
139
|
"""
|
|
143
|
-
|
|
144
|
-
with get_resource_path("workbench.resources", "signature_verify_pub.pem") as public_key_path:
|
|
140
|
+
with as_file(files("workbench.resources").joinpath("signature_verify_pub.pem")) as public_key_path:
|
|
145
141
|
with open(public_key_path, "rb") as key_file:
|
|
146
142
|
public_key_data = key_file.read()
|
|
147
143
|
|
workbench/utils/model_utils.py
CHANGED
|
@@ -93,12 +93,11 @@ def get_custom_script_path(package: str, script_name: str) -> Path:
|
|
|
93
93
|
return script_path
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
def proximity_model_local(model: "Model"
|
|
96
|
+
def proximity_model_local(model: "Model"):
|
|
97
97
|
"""Create a Proximity Model for this Model
|
|
98
98
|
|
|
99
99
|
Args:
|
|
100
|
-
model (Model): The
|
|
101
|
-
filtered (bool, optional): Use filtered training data for the Proximity Model (default: True)
|
|
100
|
+
model (Model): The Model/FeatureSet used to create the proximity model
|
|
102
101
|
|
|
103
102
|
Returns:
|
|
104
103
|
Proximity: The proximity model
|
|
@@ -110,13 +109,12 @@ def proximity_model_local(model: "Model", filtered: bool = True):
|
|
|
110
109
|
features = model.features()
|
|
111
110
|
target = model.target()
|
|
112
111
|
|
|
113
|
-
#
|
|
112
|
+
# Backtrack our FeatureSet to get the ID column
|
|
114
113
|
fs = FeatureSet(model.get_input())
|
|
115
|
-
if filtered:
|
|
116
|
-
df = fs.view("training").pull_dataframe()
|
|
117
|
-
else:
|
|
118
|
-
df = fs.pull_dataframe()
|
|
119
114
|
id_column = fs.id_column
|
|
115
|
+
|
|
116
|
+
# Create the Proximity Model from our Training Data
|
|
117
|
+
df = model.training_view().pull_dataframe()
|
|
120
118
|
return Proximity(df, id_column, features, target, track_columns=features)
|
|
121
119
|
|
|
122
120
|
|
|
@@ -298,7 +298,7 @@ def cross_fold_inference(workbench_model: Any, nfolds: int = 5) -> Tuple[Dict[st
|
|
|
298
298
|
|
|
299
299
|
# Prepare data
|
|
300
300
|
fs = FeatureSet(workbench_model.get_input())
|
|
301
|
-
df =
|
|
301
|
+
df = workbench_model.training_view().pull_dataframe()
|
|
302
302
|
|
|
303
303
|
# Get id column - assuming FeatureSet has an id_column attribute or similar
|
|
304
304
|
id_col = fs.id_column
|
|
@@ -423,7 +423,7 @@ def leave_one_out_inference(workbench_model: Any) -> pd.DataFrame:
|
|
|
423
423
|
|
|
424
424
|
# Load and prepare data
|
|
425
425
|
fs = FeatureSet(workbench_model.get_input())
|
|
426
|
-
df =
|
|
426
|
+
df = workbench_model.training_view().pull_dataframe()
|
|
427
427
|
id_col = fs.id_column
|
|
428
428
|
target_col = workbench_model.target()
|
|
429
429
|
feature_cols = workbench_model.features()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: workbench
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.188
|
|
4
4
|
Summary: Workbench: A Dashboard and Python API for creating and deploying AWS SageMaker Model Pipelines
|
|
5
5
|
Author-email: SuperCowPowers LLC <support@supercowpowers.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -10,6 +10,7 @@ Classifier: Development Status :: 4 - Beta
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
14
|
Classifier: Topic :: Scientific/Engineering
|
|
14
15
|
Requires-Python: >=3.10
|
|
15
16
|
Description-Content-Type: text/markdown
|
|
@@ -54,9 +54,9 @@ workbench/core/artifacts/cached_artifact_mixin.py,sha256=ngqFLZ4cQx_TFouXZgXZQsv
|
|
|
54
54
|
workbench/core/artifacts/data_capture_core.py,sha256=q8f79rRTYiZ7T4IQRWXl8ZvPpcvZyNxYERwvo8o0OQc,14858
|
|
55
55
|
workbench/core/artifacts/data_source_abstract.py,sha256=5IRCzFVK-17cd4NXPMRfx99vQAmQ0WHE5jcm5RfsVTg,10619
|
|
56
56
|
workbench/core/artifacts/data_source_factory.py,sha256=YL_tA5fsgubbB3dPF6T4tO0rGgz-6oo3ge4i_YXVC-M,2380
|
|
57
|
-
workbench/core/artifacts/endpoint_core.py,sha256=
|
|
58
|
-
workbench/core/artifacts/feature_set_core.py,sha256=
|
|
59
|
-
workbench/core/artifacts/model_core.py,sha256=
|
|
57
|
+
workbench/core/artifacts/endpoint_core.py,sha256=VH-q-R4pfKyjCOXl2Gq1pxMNf4Ir0YdMw9YIHqd7CVU,51974
|
|
58
|
+
workbench/core/artifacts/feature_set_core.py,sha256=6qOJoJ9_qwtyz4neFY6vMn73Ujjeut7E0dy_e8nYfSE,31462
|
|
59
|
+
workbench/core/artifacts/model_core.py,sha256=w9zWNSYHELztiXNvn04pjrIl2n6xYoiHK4Tg1Ze-ukQ,52287
|
|
60
60
|
workbench/core/artifacts/monitor_core.py,sha256=M307yz7tEzOEHgv-LmtVy9jKjSbM98fHW3ckmNYrwlU,27897
|
|
61
61
|
workbench/core/cloud_platform/cloud_meta.py,sha256=-g4-LTC3D0PXb3VfaXdLR1ERijKuHdffeMK_zhD-koQ,8809
|
|
62
62
|
workbench/core/cloud_platform/aws/README.md,sha256=QT5IQXoUHbIA0qQ2wO6_2P2lYjYQFVYuezc22mWY4i8,97
|
|
@@ -102,7 +102,7 @@ workbench/core/transforms/features_to_features/__init__.py,sha256=47DEQpj8HBSa-_
|
|
|
102
102
|
workbench/core/transforms/features_to_features/heavy/emr/Readme.md,sha256=YtQgCEQeKe0CQXQkhzMTYq9xOtCsCYb5P5LW2BmRKWQ,68
|
|
103
103
|
workbench/core/transforms/features_to_features/heavy/glue/Readme.md,sha256=TuyCatWfoDr99zUwvOcxf-TqMkQzaMqXlj5nmFcRzfo,48
|
|
104
104
|
workbench/core/transforms/features_to_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
105
|
-
workbench/core/transforms/features_to_model/features_to_model.py,sha256=
|
|
105
|
+
workbench/core/transforms/features_to_model/features_to_model.py,sha256=1WFrUpGDZtnVhwefobGwObd1YadUh9IpppV98tqaQ7w,20115
|
|
106
106
|
workbench/core/transforms/model_to_endpoint/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
107
107
|
workbench/core/transforms/model_to_endpoint/model_to_endpoint.py,sha256=TIYXvuK0s383PwJ4iS6fCRhuif6oIxsoWb4CpMGJjY4,6358
|
|
108
108
|
workbench/core/transforms/pandas_transforms/__init__.py,sha256=xL4MT8-fZ1SFqDbTLc8XyxjupHtB1YR6Ej0AC2nwd7I,894
|
|
@@ -118,9 +118,9 @@ workbench/core/views/create_view.py,sha256=2Ykzb2NvJGoD4PP4k2Bka46GDog9iGG5SWnAc
|
|
|
118
118
|
workbench/core/views/display_view.py,sha256=9K4O77ZnKOh93aMRhxcQJQ1lqScLhuJnU_tHtYZ_U4E,2598
|
|
119
119
|
workbench/core/views/inference_view.py,sha256=9s70M0dFdGq0tWvzMZfgUK7EPKtuvcQhux0uyRZuuLM,3293
|
|
120
120
|
workbench/core/views/pandas_to_view.py,sha256=20uCsnG2iMh-U1VxqVUUtnrWAY98SeuHjmfJK_wcq1I,6422
|
|
121
|
-
workbench/core/views/training_view.py,sha256=
|
|
122
|
-
workbench/core/views/view.py,sha256=
|
|
123
|
-
workbench/core/views/view_utils.py,sha256=
|
|
121
|
+
workbench/core/views/training_view.py,sha256=Wk5fWvnoapngGCHEkqYzRvSNw2f-ZRvhsrzRMYGZfuE,6274
|
|
122
|
+
workbench/core/views/view.py,sha256=QdUSGcrNzpzcwkSkutyptqrlXJZZReWzd2Uc6xQRd8A,13524
|
|
123
|
+
workbench/core/views/view_utils.py,sha256=CwOlpqXpumCr6REi-ey7Qjz5_tpg-s4oWHmlOVu8POQ,12270
|
|
124
124
|
workbench/core/views/storage/mdq_view.py,sha256=qf_ep1KwaXOIfO930laEwNIiCYP7VNOqjE3VdHfopRE,5195
|
|
125
125
|
workbench/model_scripts/script_generation.py,sha256=dLxVRrvrrI_HQatJRAXta6UEbFFbkgITNvDJllQZyCM,7905
|
|
126
126
|
workbench/model_scripts/custom_models/chem_info/Readme.md,sha256=mH1lxJ4Pb7F5nBnVXaiuxpi8zS_yjUw_LBJepVKXhlA,574
|
|
@@ -159,7 +159,7 @@ workbench/model_scripts/scikit_learn/scikit_learn.template,sha256=QQvqx-eX9ZTbYm
|
|
|
159
159
|
workbench/model_scripts/uq_models/generated_model_script.py,sha256=U4_41APyNISnJ3EHnXiaSIEdb3E1M1JT7ECNjsoX4fI,21197
|
|
160
160
|
workbench/model_scripts/uq_models/mapie.template,sha256=2HIwB_658IsZiLIV1RViIZBIGgXxDsJPZinDUu8SchU,18961
|
|
161
161
|
workbench/model_scripts/uq_models/requirements.txt,sha256=fw7T7t_YJAXK3T6Ysbesxh_Agx_tv0oYx72cEBTqRDY,98
|
|
162
|
-
workbench/model_scripts/xgb_model/generated_model_script.py,sha256=
|
|
162
|
+
workbench/model_scripts/xgb_model/generated_model_script.py,sha256=W3koc4swpjOncpMKWqBHnTGDie0CoDpY9U1oj4OUJrI,17990
|
|
163
163
|
workbench/model_scripts/xgb_model/requirements.txt,sha256=jWlGc7HH7vqyukTm38LN4EyDi8jDUPEay4n45z-30uc,104
|
|
164
164
|
workbench/model_scripts/xgb_model/xgb_model.template,sha256=0uXknIEqgUaIFUfu2gfkxa3WHUr8HBBqBepGUTDvrhQ,17917
|
|
165
165
|
workbench/repl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -168,8 +168,9 @@ workbench/resources/open_source_api.key,sha256=3S0OTblsmC0msUPdE_dbBmI83xJNmYscu
|
|
|
168
168
|
workbench/resources/signature_verify_pub.pem,sha256=V3-u-3_z2PH-805ybkKvzDOBwAbvHxcKn0jLBImEtzM,272
|
|
169
169
|
workbench/scripts/check_double_bond_stereo.py,sha256=p5hnL54Weq77ES0HCELq9JeoM-PyUGkvVSeWYF2dKyo,7776
|
|
170
170
|
workbench/scripts/glue_launcher.py,sha256=bIKQvfGxpAhzbeNvTnHfRW_5kQhY-169_868ZnCejJk,10692
|
|
171
|
+
workbench/scripts/lambda_launcher.py,sha256=U5HevvWdwN0SUrN2kpbkf0doY-5Ih_LzjJTH-45LBJ8,925
|
|
171
172
|
workbench/scripts/ml_pipeline_batch.py,sha256=1T5JnLlUJR7bwAGBLHmLPOuj1xFRqVIQX8PsuDhHy8o,4907
|
|
172
|
-
workbench/scripts/ml_pipeline_sqs.py,sha256=
|
|
173
|
+
workbench/scripts/ml_pipeline_sqs.py,sha256=ebe8clE6dMONF43_JiX5Qx1WESPfGlF2-AifvJOde50,6578
|
|
173
174
|
workbench/scripts/monitor_cloud_watch.py,sha256=s7MY4bsHts0nup9G0lWESCvgJZ9Mw1Eo-c8aKRgLjMw,9235
|
|
174
175
|
workbench/scripts/redis_expire.py,sha256=DxI_RKSNlrW2BsJZXcsSbaWGBgPZdPhtzHjV9SUtElE,1120
|
|
175
176
|
workbench/scripts/redis_report.py,sha256=iaJSuGPyLCs6e0TMcZDoT0YyJ43xJ1u74YD8FLnnUg4,990
|
|
@@ -202,24 +203,24 @@ workbench/utils/cache.py,sha256=0R5RXYEz_XHARK3anmQC4VRMawMks_cJ8S4vwC2roAE,5524
|
|
|
202
203
|
workbench/utils/cloudwatch_handler.py,sha256=t0L280Qa1nMq95dwnf8lB5g8FHrQAyGY5S4JwP3yIa8,5165
|
|
203
204
|
workbench/utils/cloudwatch_utils.py,sha256=wXSqKcJlSnHyC0D6d4RsH8wwmx_0CsffcetUgXlZ_78,4828
|
|
204
205
|
workbench/utils/color_utils.py,sha256=TmDGLK44t975lkfjt_1O-ee02QxrKfke7vPuXb-V-Uo,11779
|
|
205
|
-
workbench/utils/config_manager.py,sha256=
|
|
206
|
+
workbench/utils/config_manager.py,sha256=UPP9SHTLfPyPKEfsgH2YXp9WlImmVZ5zqFft4BxRdlo,17499
|
|
206
207
|
workbench/utils/dashboard_metrics.py,sha256=cNFI0GIAjd_IiDzM1oebsJ2QkRZuW068W_66ZC3J100,7398
|
|
207
208
|
workbench/utils/datetime_utils.py,sha256=r3G_KB2euu26lwVbDXYXPJEpJCZwin2Iph7BiBIoybg,4454
|
|
208
209
|
workbench/utils/deprecated_utils.py,sha256=qniHVpDGuwOnhxn65LofDQ_EA2OhSUcZLPxAXtx7FgA,3540
|
|
209
210
|
workbench/utils/df_to_endpoint.py,sha256=bIb1CDko8_BClX5wcQuBbmcGH79n3oHUcb_1jdUX_7s,5292
|
|
210
211
|
workbench/utils/ecs_info.py,sha256=Gs9jNb4vcj2pziufIOI4BVIH1J-3XBMtWm1phVh8oRY,2873
|
|
211
212
|
workbench/utils/endpoint_metrics.py,sha256=_4WVU6cLLuV0t_i0PSvhi0EoA5ss5aDFe7ZDpumx2R8,7822
|
|
212
|
-
workbench/utils/endpoint_utils.py,sha256=
|
|
213
|
+
workbench/utils/endpoint_utils.py,sha256=1zVy78H2OCE9tSRlS-AdIuF3uePTMq2mW2rnmwLmDv4,7031
|
|
213
214
|
workbench/utils/extract_model_artifact.py,sha256=sFwkJd5mfJ1PU37pIHVmUIQS-taIUJdqi3D9-qRmy8g,7870
|
|
214
215
|
workbench/utils/glue_utils.py,sha256=dslfXQcJ4C-mGmsD6LqeK8vsXBez570t3fZBVZLV7HA,2039
|
|
215
216
|
workbench/utils/graph_utils.py,sha256=T4aslYVbzPmFe0_qKCQP6PZnaw1KATNXQNVO-yDGBxY,10839
|
|
216
217
|
workbench/utils/ipython_utils.py,sha256=skbdbBwUT-iuY3FZwy3ACS7-FWSe9M2qVXfLlQWnikE,700
|
|
217
218
|
workbench/utils/json_utils.py,sha256=FSxzcD88TbIEJDw0FHue5-ZGny94wm5NeLs4zYlLLpU,4881
|
|
218
219
|
workbench/utils/lambda_utils.py,sha256=7GhGRPyXn9o-toWb9HBGSnI8-DhK9YRkwhCSk_mNKMI,1893
|
|
219
|
-
workbench/utils/license_manager.py,sha256=
|
|
220
|
+
workbench/utils/license_manager.py,sha256=lNE9zZIglmX3zqqCKBdN1xqTgHCEZgJDxavF6pdG7fc,6825
|
|
220
221
|
workbench/utils/log_utils.py,sha256=7n1NJXO_jUX82e6LWAQug6oPo3wiPDBYsqk9gsYab_A,3167
|
|
221
222
|
workbench/utils/markdown_utils.py,sha256=4lEqzgG4EVmLcvvKKNUwNxVCySLQKJTJmWDiaDroI1w,8306
|
|
222
|
-
workbench/utils/model_utils.py,sha256=
|
|
223
|
+
workbench/utils/model_utils.py,sha256=YKqvDbSv1qV8nvA7s-xGIxRMj4NT7Lp0zz8aXg3WdtI,13468
|
|
223
224
|
workbench/utils/monitor_utils.py,sha256=kVaJ7BgUXs3VPMFYfLC03wkIV4Dq-pEhoXS0wkJFxCc,7858
|
|
224
225
|
workbench/utils/pandas_utils.py,sha256=uTUx-d1KYfjbS9PMQp2_9FogCV7xVZR6XLzU5YAGmfs,39371
|
|
225
226
|
workbench/utils/performance_utils.py,sha256=WDNvz-bOdC99cDuXl0urAV4DJ7alk_V3yzKPwvqgST4,1329
|
|
@@ -229,7 +230,6 @@ workbench/utils/plugin_manager.py,sha256=JWfyFHQih_J_MMtAT1cgjGVnNVPk9bM917LkfH8
|
|
|
229
230
|
workbench/utils/prox_utils.py,sha256=V0YSxI6lboZl8Bed1GUobFqfMhfpehn2FtgqHpkuhDQ,6170
|
|
230
231
|
workbench/utils/redis_cache.py,sha256=39LFSWmOlNNcah02D3sBnmibc-DPeKC3SNq71K4HaB4,12893
|
|
231
232
|
workbench/utils/repl_utils.py,sha256=rWOMv2HiEIp8ZL6Ps6DlwiJlGr-pOhv9OZQhm3aR-1A,4668
|
|
232
|
-
workbench/utils/resource_utils.py,sha256=EM4SrMmRUQnG80aR5M7hmzw86hYdP_S7fRPuqhpDSVo,1435
|
|
233
233
|
workbench/utils/s3_utils.py,sha256=Xme_o_cftC_jWnw6R9YKS6-6C11zaCBAoQDlY3dZb5o,7337
|
|
234
234
|
workbench/utils/shap_utils.py,sha256=dtjSIwSyvYSaQjjvIp5A9LGS7pr-5Vt907rvVKOrqNY,12651
|
|
235
235
|
workbench/utils/shapley_values.py,sha256=3DvQz4HIPnxW42idgtuQ5vtzU-oF4_lToaWzLRjU-E4,3673
|
|
@@ -242,7 +242,7 @@ workbench/utils/workbench_cache.py,sha256=IQchxB81iR4eVggHBxUJdXxUCRkqWz1jKe5gxN
|
|
|
242
242
|
workbench/utils/workbench_event_bridge.py,sha256=z1GmXOB-Qs7VOgC6Hjnp2DI9nSEWepaSXejACxTIR7o,4150
|
|
243
243
|
workbench/utils/workbench_logging.py,sha256=WCuMWhQwibrvcGAyj96h2wowh6dH7zNlDJ7sWUzdCeI,10263
|
|
244
244
|
workbench/utils/workbench_sqs.py,sha256=RwM80z7YWwdtMaCKh7KWF8v38f7eBRU7kyC7ZhTRuI0,2072
|
|
245
|
-
workbench/utils/xgboost_model_utils.py,sha256=
|
|
245
|
+
workbench/utils/xgboost_model_utils.py,sha256=Si2VB-YW-Mjb6hCby_m4KWWajoRzH8e2NwBZSe98tsM,21621
|
|
246
246
|
workbench/utils/chem_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
247
247
|
workbench/utils/chem_utils/fingerprints.py,sha256=Qvs8jaUwguWUq3Q3j695MY0t0Wk3BvroW-oWBwalMUo,5255
|
|
248
248
|
workbench/utils/chem_utils/misc.py,sha256=Nevf8_opu-uIPrv_1_0ubuFVVo2_fGUkMoLAHB3XAeo,7372
|
|
@@ -287,9 +287,9 @@ workbench/web_interface/page_views/main_page.py,sha256=X4-KyGTKLAdxR-Zk2niuLJB2Y
|
|
|
287
287
|
workbench/web_interface/page_views/models_page_view.py,sha256=M0bdC7bAzLyIaE2jviY12FF4abdMFZmg6sFuOY_LaGI,2650
|
|
288
288
|
workbench/web_interface/page_views/page_view.py,sha256=Gh6YnpOGlUejx-bHZAf5pzqoQ1H1R0OSwOpGhOBO06w,455
|
|
289
289
|
workbench/web_interface/page_views/pipelines_page_view.py,sha256=v2pxrIbsHBcYiblfius3JK766NZ7ciD2yPx0t3E5IJo,2656
|
|
290
|
-
workbench-0.8.
|
|
291
|
-
workbench-0.8.
|
|
292
|
-
workbench-0.8.
|
|
293
|
-
workbench-0.8.
|
|
294
|
-
workbench-0.8.
|
|
295
|
-
workbench-0.8.
|
|
290
|
+
workbench-0.8.188.dist-info/licenses/LICENSE,sha256=z4QMMPlLJkZjU8VOKqJkZiQZCEZ--saIU2Z8-p3aVc0,1080
|
|
291
|
+
workbench-0.8.188.dist-info/METADATA,sha256=E6u7eeASQ5dzeL4IMVmaOUmuxp6Vr3vPWeq4oVBvAl4,9261
|
|
292
|
+
workbench-0.8.188.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
293
|
+
workbench-0.8.188.dist-info/entry_points.txt,sha256=o7ohD4D2oygnHp7i9-C0LfcHDuPW5Tv0JXGAg97DpGk,413
|
|
294
|
+
workbench-0.8.188.dist-info/top_level.txt,sha256=Dhy72zTxaA_o_yRkPZx5zw-fwumnjGaeGf0hBN3jc_w,10
|
|
295
|
+
workbench-0.8.188.dist-info/RECORD,,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
[console_scripts]
|
|
2
2
|
cloud_watch = workbench.scripts.monitor_cloud_watch:main
|
|
3
3
|
glue_launcher = workbench.scripts.glue_launcher:main
|
|
4
|
+
lambda_launcher = workbench.scripts.lambda_launcher:main
|
|
4
5
|
ml_pipeline_batch = workbench.scripts.ml_pipeline_batch:main
|
|
5
6
|
ml_pipeline_sqs = workbench.scripts.ml_pipeline_sqs:main
|
|
6
7
|
workbench = workbench.repl.workbench_shell:launch_shell
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"""Resource utilities for Workbench"""
|
|
2
|
-
|
|
3
|
-
import sys
|
|
4
|
-
import importlib.resources as resources
|
|
5
|
-
import pathlib
|
|
6
|
-
import pkg_resources
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def get_resource_path(package: str, resource: str) -> pathlib.Path:
|
|
10
|
-
"""Get the path to a resource file, compatible with Python 3.9 and higher.
|
|
11
|
-
|
|
12
|
-
Args:
|
|
13
|
-
package (str): The package where the resource is located.
|
|
14
|
-
resource (str): The name of the resource file.
|
|
15
|
-
|
|
16
|
-
Returns:
|
|
17
|
-
pathlib.Path: The path to the resource file.
|
|
18
|
-
"""
|
|
19
|
-
if sys.version_info >= (3, 10):
|
|
20
|
-
# Python 3.10 and higher: use importlib.resources.path
|
|
21
|
-
with resources.path(package, resource) as path:
|
|
22
|
-
return path
|
|
23
|
-
else:
|
|
24
|
-
# Python 3.9 and lower: manually construct the path based on package location
|
|
25
|
-
# Get the location of the installed package
|
|
26
|
-
package_location = pathlib.Path(pkg_resources.get_distribution(package.split(".")[0]).location)
|
|
27
|
-
resource_path = package_location / package.replace(".", "/") / resource
|
|
28
|
-
|
|
29
|
-
if resource_path.exists():
|
|
30
|
-
return resource_path
|
|
31
|
-
else:
|
|
32
|
-
raise FileNotFoundError(f"Resource '{resource}' not found in package '{package}'.")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if __name__ == "__main__":
|
|
36
|
-
# Test the resource utilities
|
|
37
|
-
with get_resource_path("workbench.resources", "open_source_api.key") as open_source_key_path:
|
|
38
|
-
with open(open_source_key_path, "r") as key_file:
|
|
39
|
-
print(key_file.read().strip())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|