oracle-ads 2.13.9rc0__py3-none-any.whl → 2.13.9rc1__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.
- ads/aqua/__init__.py +40 -0
- ads/aqua/app.py +506 -0
- ads/aqua/cli.py +96 -0
- ads/aqua/client/__init__.py +3 -0
- ads/aqua/client/client.py +836 -0
- ads/aqua/client/openai_client.py +305 -0
- ads/aqua/common/__init__.py +5 -0
- ads/aqua/common/decorator.py +125 -0
- ads/aqua/common/entities.py +269 -0
- ads/aqua/common/enums.py +122 -0
- ads/aqua/common/errors.py +109 -0
- ads/aqua/common/utils.py +1285 -0
- ads/aqua/config/__init__.py +4 -0
- ads/aqua/config/container_config.py +248 -0
- ads/aqua/config/evaluation/__init__.py +4 -0
- ads/aqua/config/evaluation/evaluation_service_config.py +147 -0
- ads/aqua/config/utils/__init__.py +4 -0
- ads/aqua/config/utils/serializer.py +339 -0
- ads/aqua/constants.py +116 -0
- ads/aqua/data.py +14 -0
- ads/aqua/dummy_data/icon.txt +1 -0
- ads/aqua/dummy_data/oci_model_deployments.json +56 -0
- ads/aqua/dummy_data/oci_models.json +1 -0
- ads/aqua/dummy_data/readme.md +26 -0
- ads/aqua/evaluation/__init__.py +8 -0
- ads/aqua/evaluation/constants.py +53 -0
- ads/aqua/evaluation/entities.py +186 -0
- ads/aqua/evaluation/errors.py +70 -0
- ads/aqua/evaluation/evaluation.py +1814 -0
- ads/aqua/extension/__init__.py +42 -0
- ads/aqua/extension/aqua_ws_msg_handler.py +76 -0
- ads/aqua/extension/base_handler.py +90 -0
- ads/aqua/extension/common_handler.py +121 -0
- ads/aqua/extension/common_ws_msg_handler.py +36 -0
- ads/aqua/extension/deployment_handler.py +298 -0
- ads/aqua/extension/deployment_ws_msg_handler.py +54 -0
- ads/aqua/extension/errors.py +30 -0
- ads/aqua/extension/evaluation_handler.py +129 -0
- ads/aqua/extension/evaluation_ws_msg_handler.py +61 -0
- ads/aqua/extension/finetune_handler.py +96 -0
- ads/aqua/extension/model_handler.py +390 -0
- ads/aqua/extension/models/__init__.py +0 -0
- ads/aqua/extension/models/ws_models.py +145 -0
- ads/aqua/extension/models_ws_msg_handler.py +50 -0
- ads/aqua/extension/ui_handler.py +282 -0
- ads/aqua/extension/ui_websocket_handler.py +130 -0
- ads/aqua/extension/utils.py +133 -0
- ads/aqua/finetuning/__init__.py +7 -0
- ads/aqua/finetuning/constants.py +23 -0
- ads/aqua/finetuning/entities.py +181 -0
- ads/aqua/finetuning/finetuning.py +749 -0
- ads/aqua/model/__init__.py +8 -0
- ads/aqua/model/constants.py +60 -0
- ads/aqua/model/entities.py +385 -0
- ads/aqua/model/enums.py +32 -0
- ads/aqua/model/model.py +2114 -0
- ads/aqua/modeldeployment/__init__.py +8 -0
- ads/aqua/modeldeployment/constants.py +10 -0
- ads/aqua/modeldeployment/deployment.py +1326 -0
- ads/aqua/modeldeployment/entities.py +653 -0
- ads/aqua/modeldeployment/inference.py +74 -0
- ads/aqua/modeldeployment/utils.py +543 -0
- ads/aqua/resources/gpu_shapes_index.json +94 -0
- ads/aqua/server/__init__.py +4 -0
- ads/aqua/server/__main__.py +24 -0
- ads/aqua/server/app.py +47 -0
- ads/aqua/server/aqua_spec.yml +1291 -0
- ads/aqua/training/__init__.py +4 -0
- ads/aqua/training/exceptions.py +476 -0
- ads/aqua/ui.py +499 -0
- ads/automl/__init__.py +9 -0
- ads/automl/driver.py +330 -0
- ads/automl/provider.py +975 -0
- ads/bds/__init__.py +5 -0
- ads/bds/auth.py +127 -0
- ads/bds/big_data_service.py +255 -0
- ads/catalog/__init__.py +19 -0
- ads/catalog/model.py +1576 -0
- ads/catalog/notebook.py +461 -0
- ads/catalog/project.py +468 -0
- ads/catalog/summary.py +178 -0
- ads/common/__init__.py +11 -0
- ads/common/analyzer.py +65 -0
- ads/common/artifact/.model-ignore +63 -0
- ads/common/artifact/__init__.py +10 -0
- ads/common/auth.py +1122 -0
- ads/common/card_identifier.py +83 -0
- ads/common/config.py +647 -0
- ads/common/data.py +165 -0
- ads/common/decorator/__init__.py +9 -0
- ads/common/decorator/argument_to_case.py +88 -0
- ads/common/decorator/deprecate.py +69 -0
- ads/common/decorator/require_nonempty_arg.py +65 -0
- ads/common/decorator/runtime_dependency.py +178 -0
- ads/common/decorator/threaded.py +97 -0
- ads/common/decorator/utils.py +35 -0
- ads/common/dsc_file_system.py +303 -0
- ads/common/error.py +14 -0
- ads/common/extended_enum.py +81 -0
- ads/common/function/__init__.py +5 -0
- ads/common/function/fn_util.py +142 -0
- ads/common/function/func_conf.yaml +25 -0
- ads/common/ipython.py +76 -0
- ads/common/model.py +679 -0
- ads/common/model_artifact.py +1759 -0
- ads/common/model_artifact_schema.json +107 -0
- ads/common/model_export_util.py +664 -0
- ads/common/model_metadata.py +24 -0
- ads/common/object_storage_details.py +296 -0
- ads/common/oci_client.py +175 -0
- ads/common/oci_datascience.py +46 -0
- ads/common/oci_logging.py +1144 -0
- ads/common/oci_mixin.py +957 -0
- ads/common/oci_resource.py +136 -0
- ads/common/serializer.py +559 -0
- ads/common/utils.py +1852 -0
- ads/common/word_lists.py +1491 -0
- ads/common/work_request.py +189 -0
- ads/data_labeling/__init__.py +13 -0
- ads/data_labeling/boundingbox.py +253 -0
- ads/data_labeling/constants.py +47 -0
- ads/data_labeling/data_labeling_service.py +244 -0
- ads/data_labeling/interface/__init__.py +5 -0
- ads/data_labeling/interface/loader.py +16 -0
- ads/data_labeling/interface/parser.py +16 -0
- ads/data_labeling/interface/reader.py +23 -0
- ads/data_labeling/loader/__init__.py +5 -0
- ads/data_labeling/loader/file_loader.py +241 -0
- ads/data_labeling/metadata.py +110 -0
- ads/data_labeling/mixin/__init__.py +5 -0
- ads/data_labeling/mixin/data_labeling.py +232 -0
- ads/data_labeling/ner.py +129 -0
- ads/data_labeling/parser/__init__.py +5 -0
- ads/data_labeling/parser/dls_record_parser.py +388 -0
- ads/data_labeling/parser/export_metadata_parser.py +94 -0
- ads/data_labeling/parser/export_record_parser.py +473 -0
- ads/data_labeling/reader/__init__.py +5 -0
- ads/data_labeling/reader/dataset_reader.py +574 -0
- ads/data_labeling/reader/dls_record_reader.py +121 -0
- ads/data_labeling/reader/export_record_reader.py +62 -0
- ads/data_labeling/reader/jsonl_reader.py +75 -0
- ads/data_labeling/reader/metadata_reader.py +203 -0
- ads/data_labeling/reader/record_reader.py +263 -0
- ads/data_labeling/record.py +52 -0
- ads/data_labeling/visualizer/__init__.py +5 -0
- ads/data_labeling/visualizer/image_visualizer.py +525 -0
- ads/data_labeling/visualizer/text_visualizer.py +357 -0
- ads/database/__init__.py +5 -0
- ads/database/connection.py +338 -0
- ads/dataset/__init__.py +10 -0
- ads/dataset/capabilities.md +51 -0
- ads/dataset/classification_dataset.py +339 -0
- ads/dataset/correlation.py +226 -0
- ads/dataset/correlation_plot.py +563 -0
- ads/dataset/dask_series.py +173 -0
- ads/dataset/dataframe_transformer.py +110 -0
- ads/dataset/dataset.py +1979 -0
- ads/dataset/dataset_browser.py +360 -0
- ads/dataset/dataset_with_target.py +995 -0
- ads/dataset/exception.py +25 -0
- ads/dataset/factory.py +987 -0
- ads/dataset/feature_engineering_transformer.py +35 -0
- ads/dataset/feature_selection.py +107 -0
- ads/dataset/forecasting_dataset.py +26 -0
- ads/dataset/helper.py +1450 -0
- ads/dataset/label_encoder.py +99 -0
- ads/dataset/mixin/__init__.py +5 -0
- ads/dataset/mixin/dataset_accessor.py +134 -0
- ads/dataset/pipeline.py +58 -0
- ads/dataset/plot.py +710 -0
- ads/dataset/progress.py +86 -0
- ads/dataset/recommendation.py +297 -0
- ads/dataset/recommendation_transformer.py +502 -0
- ads/dataset/regression_dataset.py +14 -0
- ads/dataset/sampled_dataset.py +1050 -0
- ads/dataset/target.py +98 -0
- ads/dataset/timeseries.py +18 -0
- ads/dbmixin/__init__.py +5 -0
- ads/dbmixin/db_pandas_accessor.py +153 -0
- ads/environment/__init__.py +9 -0
- ads/environment/ml_runtime.py +66 -0
- ads/evaluations/README.md +14 -0
- ads/evaluations/__init__.py +109 -0
- ads/evaluations/evaluation_plot.py +983 -0
- ads/evaluations/evaluator.py +1334 -0
- ads/evaluations/statistical_metrics.py +543 -0
- ads/experiments/__init__.py +9 -0
- ads/experiments/capabilities.md +0 -0
- ads/explanations/__init__.py +21 -0
- ads/explanations/base_explainer.py +142 -0
- ads/explanations/capabilities.md +83 -0
- ads/explanations/explainer.py +190 -0
- ads/explanations/mlx_global_explainer.py +1050 -0
- ads/explanations/mlx_interface.py +386 -0
- ads/explanations/mlx_local_explainer.py +287 -0
- ads/explanations/mlx_whatif_explainer.py +201 -0
- ads/feature_engineering/__init__.py +20 -0
- ads/feature_engineering/accessor/__init__.py +5 -0
- ads/feature_engineering/accessor/dataframe_accessor.py +535 -0
- ads/feature_engineering/accessor/mixin/__init__.py +5 -0
- ads/feature_engineering/accessor/mixin/correlation.py +166 -0
- ads/feature_engineering/accessor/mixin/eda_mixin.py +266 -0
- ads/feature_engineering/accessor/mixin/eda_mixin_series.py +85 -0
- ads/feature_engineering/accessor/mixin/feature_types_mixin.py +211 -0
- ads/feature_engineering/accessor/mixin/utils.py +65 -0
- ads/feature_engineering/accessor/series_accessor.py +431 -0
- ads/feature_engineering/adsimage/__init__.py +5 -0
- ads/feature_engineering/adsimage/image.py +192 -0
- ads/feature_engineering/adsimage/image_reader.py +170 -0
- ads/feature_engineering/adsimage/interface/__init__.py +5 -0
- ads/feature_engineering/adsimage/interface/reader.py +19 -0
- ads/feature_engineering/adsstring/__init__.py +7 -0
- ads/feature_engineering/adsstring/oci_language/__init__.py +8 -0
- ads/feature_engineering/adsstring/string/__init__.py +8 -0
- ads/feature_engineering/data_schema.json +57 -0
- ads/feature_engineering/dataset/__init__.py +5 -0
- ads/feature_engineering/dataset/zip_code_data.py +42062 -0
- ads/feature_engineering/exceptions.py +40 -0
- ads/feature_engineering/feature_type/__init__.py +133 -0
- ads/feature_engineering/feature_type/address.py +184 -0
- ads/feature_engineering/feature_type/adsstring/__init__.py +5 -0
- ads/feature_engineering/feature_type/adsstring/common_regex_mixin.py +164 -0
- ads/feature_engineering/feature_type/adsstring/oci_language.py +93 -0
- ads/feature_engineering/feature_type/adsstring/parsers/__init__.py +5 -0
- ads/feature_engineering/feature_type/adsstring/parsers/base.py +47 -0
- ads/feature_engineering/feature_type/adsstring/parsers/nltk_parser.py +96 -0
- ads/feature_engineering/feature_type/adsstring/parsers/spacy_parser.py +221 -0
- ads/feature_engineering/feature_type/adsstring/string.py +258 -0
- ads/feature_engineering/feature_type/base.py +58 -0
- ads/feature_engineering/feature_type/boolean.py +183 -0
- ads/feature_engineering/feature_type/category.py +146 -0
- ads/feature_engineering/feature_type/constant.py +137 -0
- ads/feature_engineering/feature_type/continuous.py +151 -0
- ads/feature_engineering/feature_type/creditcard.py +314 -0
- ads/feature_engineering/feature_type/datetime.py +190 -0
- ads/feature_engineering/feature_type/discrete.py +134 -0
- ads/feature_engineering/feature_type/document.py +43 -0
- ads/feature_engineering/feature_type/gis.py +251 -0
- ads/feature_engineering/feature_type/handler/__init__.py +5 -0
- ads/feature_engineering/feature_type/handler/feature_validator.py +524 -0
- ads/feature_engineering/feature_type/handler/feature_warning.py +319 -0
- ads/feature_engineering/feature_type/handler/warnings.py +128 -0
- ads/feature_engineering/feature_type/integer.py +142 -0
- ads/feature_engineering/feature_type/ip_address.py +144 -0
- ads/feature_engineering/feature_type/ip_address_v4.py +138 -0
- ads/feature_engineering/feature_type/ip_address_v6.py +138 -0
- ads/feature_engineering/feature_type/lat_long.py +256 -0
- ads/feature_engineering/feature_type/object.py +43 -0
- ads/feature_engineering/feature_type/ordinal.py +132 -0
- ads/feature_engineering/feature_type/phone_number.py +135 -0
- ads/feature_engineering/feature_type/string.py +171 -0
- ads/feature_engineering/feature_type/text.py +93 -0
- ads/feature_engineering/feature_type/unknown.py +43 -0
- ads/feature_engineering/feature_type/zip_code.py +164 -0
- ads/feature_engineering/feature_type_manager.py +406 -0
- ads/feature_engineering/schema.py +795 -0
- ads/feature_engineering/utils.py +245 -0
- ads/feature_store/.readthedocs.yaml +19 -0
- ads/feature_store/README.md +65 -0
- ads/feature_store/__init__.py +9 -0
- ads/feature_store/common/__init__.py +0 -0
- ads/feature_store/common/enums.py +339 -0
- ads/feature_store/common/exceptions.py +18 -0
- ads/feature_store/common/spark_session_singleton.py +125 -0
- ads/feature_store/common/utils/__init__.py +0 -0
- ads/feature_store/common/utils/base64_encoder_decoder.py +72 -0
- ads/feature_store/common/utils/feature_schema_mapper.py +283 -0
- ads/feature_store/common/utils/transformation_utils.py +82 -0
- ads/feature_store/common/utils/utility.py +403 -0
- ads/feature_store/data_validation/__init__.py +0 -0
- ads/feature_store/data_validation/great_expectation.py +129 -0
- ads/feature_store/dataset.py +1230 -0
- ads/feature_store/dataset_job.py +530 -0
- ads/feature_store/docs/Dockerfile +7 -0
- ads/feature_store/docs/Makefile +44 -0
- ads/feature_store/docs/conf.py +28 -0
- ads/feature_store/docs/requirements.txt +14 -0
- ads/feature_store/docs/source/ads.feature_store.query.rst +20 -0
- ads/feature_store/docs/source/cicd.rst +137 -0
- ads/feature_store/docs/source/conf.py +86 -0
- ads/feature_store/docs/source/data_versioning.rst +33 -0
- ads/feature_store/docs/source/dataset.rst +388 -0
- ads/feature_store/docs/source/dataset_job.rst +27 -0
- ads/feature_store/docs/source/demo.rst +70 -0
- ads/feature_store/docs/source/entity.rst +78 -0
- ads/feature_store/docs/source/feature_group.rst +624 -0
- ads/feature_store/docs/source/feature_group_job.rst +29 -0
- ads/feature_store/docs/source/feature_store.rst +122 -0
- ads/feature_store/docs/source/feature_store_class.rst +123 -0
- ads/feature_store/docs/source/feature_validation.rst +66 -0
- ads/feature_store/docs/source/figures/cicd.png +0 -0
- ads/feature_store/docs/source/figures/data_validation.png +0 -0
- ads/feature_store/docs/source/figures/data_versioning.png +0 -0
- ads/feature_store/docs/source/figures/dataset.gif +0 -0
- ads/feature_store/docs/source/figures/dataset.png +0 -0
- ads/feature_store/docs/source/figures/dataset_lineage.png +0 -0
- ads/feature_store/docs/source/figures/dataset_statistics.png +0 -0
- ads/feature_store/docs/source/figures/dataset_statistics_viz.png +0 -0
- ads/feature_store/docs/source/figures/dataset_validation_results.png +0 -0
- ads/feature_store/docs/source/figures/dataset_validation_summary.png +0 -0
- ads/feature_store/docs/source/figures/drift_monitoring.png +0 -0
- ads/feature_store/docs/source/figures/entity.png +0 -0
- ads/feature_store/docs/source/figures/feature_group.png +0 -0
- ads/feature_store/docs/source/figures/feature_group_lineage.png +0 -0
- ads/feature_store/docs/source/figures/feature_group_statistics_viz.png +0 -0
- ads/feature_store/docs/source/figures/feature_store_deployment.png +0 -0
- ads/feature_store/docs/source/figures/feature_store_overview.png +0 -0
- ads/feature_store/docs/source/figures/featuregroup.gif +0 -0
- ads/feature_store/docs/source/figures/lineage_d1.png +0 -0
- ads/feature_store/docs/source/figures/lineage_d2.png +0 -0
- ads/feature_store/docs/source/figures/lineage_fg.png +0 -0
- ads/feature_store/docs/source/figures/logo-dark-mode.png +0 -0
- ads/feature_store/docs/source/figures/logo-light-mode.png +0 -0
- ads/feature_store/docs/source/figures/overview.png +0 -0
- ads/feature_store/docs/source/figures/resource_manager.png +0 -0
- ads/feature_store/docs/source/figures/resource_manager_feature_store_stack.png +0 -0
- ads/feature_store/docs/source/figures/resource_manager_home.png +0 -0
- ads/feature_store/docs/source/figures/stats_1.png +0 -0
- ads/feature_store/docs/source/figures/stats_2.png +0 -0
- ads/feature_store/docs/source/figures/stats_d.png +0 -0
- ads/feature_store/docs/source/figures/stats_fg.png +0 -0
- ads/feature_store/docs/source/figures/transformation.png +0 -0
- ads/feature_store/docs/source/figures/transformations.gif +0 -0
- ads/feature_store/docs/source/figures/validation.png +0 -0
- ads/feature_store/docs/source/figures/validation_fg.png +0 -0
- ads/feature_store/docs/source/figures/validation_results.png +0 -0
- ads/feature_store/docs/source/figures/validation_summary.png +0 -0
- ads/feature_store/docs/source/index.rst +81 -0
- ads/feature_store/docs/source/module.rst +8 -0
- ads/feature_store/docs/source/notebook.rst +94 -0
- ads/feature_store/docs/source/overview.rst +47 -0
- ads/feature_store/docs/source/quickstart.rst +176 -0
- ads/feature_store/docs/source/release_notes.rst +194 -0
- ads/feature_store/docs/source/setup_feature_store.rst +81 -0
- ads/feature_store/docs/source/statistics.rst +58 -0
- ads/feature_store/docs/source/transformation.rst +199 -0
- ads/feature_store/docs/source/ui.rst +65 -0
- ads/feature_store/docs/source/user_guides.setup.feature_store_operator.rst +66 -0
- ads/feature_store/docs/source/user_guides.setup.helm_chart.rst +192 -0
- ads/feature_store/docs/source/user_guides.setup.terraform.rst +338 -0
- ads/feature_store/entity.py +718 -0
- ads/feature_store/execution_strategy/__init__.py +0 -0
- ads/feature_store/execution_strategy/delta_lake/__init__.py +0 -0
- ads/feature_store/execution_strategy/delta_lake/delta_lake_service.py +375 -0
- ads/feature_store/execution_strategy/engine/__init__.py +0 -0
- ads/feature_store/execution_strategy/engine/spark_engine.py +316 -0
- ads/feature_store/execution_strategy/execution_strategy.py +113 -0
- ads/feature_store/execution_strategy/execution_strategy_provider.py +47 -0
- ads/feature_store/execution_strategy/spark/__init__.py +0 -0
- ads/feature_store/execution_strategy/spark/spark_execution.py +618 -0
- ads/feature_store/feature.py +192 -0
- ads/feature_store/feature_group.py +1494 -0
- ads/feature_store/feature_group_expectation.py +346 -0
- ads/feature_store/feature_group_job.py +602 -0
- ads/feature_store/feature_lineage/__init__.py +0 -0
- ads/feature_store/feature_lineage/graphviz_service.py +180 -0
- ads/feature_store/feature_option_details.py +50 -0
- ads/feature_store/feature_statistics/__init__.py +0 -0
- ads/feature_store/feature_statistics/statistics_service.py +99 -0
- ads/feature_store/feature_store.py +699 -0
- ads/feature_store/feature_store_registrar.py +518 -0
- ads/feature_store/input_feature_detail.py +149 -0
- ads/feature_store/mixin/__init__.py +4 -0
- ads/feature_store/mixin/oci_feature_store.py +145 -0
- ads/feature_store/model_details.py +73 -0
- ads/feature_store/query/__init__.py +0 -0
- ads/feature_store/query/filter.py +266 -0
- ads/feature_store/query/generator/__init__.py +0 -0
- ads/feature_store/query/generator/query_generator.py +298 -0
- ads/feature_store/query/join.py +161 -0
- ads/feature_store/query/query.py +403 -0
- ads/feature_store/query/validator/__init__.py +0 -0
- ads/feature_store/query/validator/query_validator.py +57 -0
- ads/feature_store/response/__init__.py +0 -0
- ads/feature_store/response/response_builder.py +68 -0
- ads/feature_store/service/__init__.py +0 -0
- ads/feature_store/service/oci_dataset.py +139 -0
- ads/feature_store/service/oci_dataset_job.py +199 -0
- ads/feature_store/service/oci_entity.py +125 -0
- ads/feature_store/service/oci_feature_group.py +164 -0
- ads/feature_store/service/oci_feature_group_job.py +214 -0
- ads/feature_store/service/oci_feature_store.py +182 -0
- ads/feature_store/service/oci_lineage.py +87 -0
- ads/feature_store/service/oci_transformation.py +104 -0
- ads/feature_store/statistics/__init__.py +0 -0
- ads/feature_store/statistics/abs_feature_value.py +49 -0
- ads/feature_store/statistics/charts/__init__.py +0 -0
- ads/feature_store/statistics/charts/abstract_feature_plot.py +37 -0
- ads/feature_store/statistics/charts/box_plot.py +148 -0
- ads/feature_store/statistics/charts/frequency_distribution.py +65 -0
- ads/feature_store/statistics/charts/probability_distribution.py +68 -0
- ads/feature_store/statistics/charts/top_k_frequent_elements.py +98 -0
- ads/feature_store/statistics/feature_stat.py +126 -0
- ads/feature_store/statistics/generic_feature_value.py +33 -0
- ads/feature_store/statistics/statistics.py +41 -0
- ads/feature_store/statistics_config.py +101 -0
- ads/feature_store/templates/feature_store_template.yaml +45 -0
- ads/feature_store/transformation.py +499 -0
- ads/feature_store/validation_output.py +57 -0
- ads/hpo/__init__.py +9 -0
- ads/hpo/_imports.py +91 -0
- ads/hpo/ads_search_space.py +439 -0
- ads/hpo/distributions.py +325 -0
- ads/hpo/objective.py +280 -0
- ads/hpo/search_cv.py +1657 -0
- ads/hpo/stopping_criterion.py +75 -0
- ads/hpo/tuner_artifact.py +413 -0
- ads/hpo/utils.py +91 -0
- ads/hpo/validation.py +140 -0
- ads/hpo/visualization/__init__.py +5 -0
- ads/hpo/visualization/_contour.py +23 -0
- ads/hpo/visualization/_edf.py +20 -0
- ads/hpo/visualization/_intermediate_values.py +21 -0
- ads/hpo/visualization/_optimization_history.py +25 -0
- ads/hpo/visualization/_parallel_coordinate.py +169 -0
- ads/hpo/visualization/_param_importances.py +26 -0
- ads/jobs/__init__.py +53 -0
- ads/jobs/ads_job.py +663 -0
- ads/jobs/builders/__init__.py +5 -0
- ads/jobs/builders/base.py +156 -0
- ads/jobs/builders/infrastructure/__init__.py +6 -0
- ads/jobs/builders/infrastructure/base.py +165 -0
- ads/jobs/builders/infrastructure/dataflow.py +1252 -0
- ads/jobs/builders/infrastructure/dsc_job.py +1894 -0
- ads/jobs/builders/infrastructure/dsc_job_runtime.py +1233 -0
- ads/jobs/builders/infrastructure/utils.py +65 -0
- ads/jobs/builders/runtimes/__init__.py +5 -0
- ads/jobs/builders/runtimes/artifact.py +338 -0
- ads/jobs/builders/runtimes/base.py +325 -0
- ads/jobs/builders/runtimes/container_runtime.py +242 -0
- ads/jobs/builders/runtimes/python_runtime.py +1016 -0
- ads/jobs/builders/runtimes/pytorch_runtime.py +204 -0
- ads/jobs/cli.py +104 -0
- ads/jobs/env_var_parser.py +131 -0
- ads/jobs/extension.py +160 -0
- ads/jobs/schema/__init__.py +5 -0
- ads/jobs/schema/infrastructure_schema.json +116 -0
- ads/jobs/schema/job_schema.json +42 -0
- ads/jobs/schema/runtime_schema.json +183 -0
- ads/jobs/schema/validator.py +141 -0
- ads/jobs/serializer.py +296 -0
- ads/jobs/templates/__init__.py +5 -0
- ads/jobs/templates/container.py +6 -0
- ads/jobs/templates/driver_notebook.py +177 -0
- ads/jobs/templates/driver_oci.py +500 -0
- ads/jobs/templates/driver_python.py +48 -0
- ads/jobs/templates/driver_pytorch.py +852 -0
- ads/jobs/templates/driver_utils.py +615 -0
- ads/jobs/templates/hostname_from_env.c +55 -0
- ads/jobs/templates/oci_metrics.py +181 -0
- ads/jobs/utils.py +104 -0
- ads/llm/__init__.py +28 -0
- ads/llm/autogen/__init__.py +2 -0
- ads/llm/autogen/constants.py +15 -0
- ads/llm/autogen/reports/__init__.py +2 -0
- ads/llm/autogen/reports/base.py +67 -0
- ads/llm/autogen/reports/data.py +103 -0
- ads/llm/autogen/reports/session.py +526 -0
- ads/llm/autogen/reports/templates/chat_box.html +13 -0
- ads/llm/autogen/reports/templates/chat_box_lt.html +5 -0
- ads/llm/autogen/reports/templates/chat_box_rt.html +6 -0
- ads/llm/autogen/reports/utils.py +56 -0
- ads/llm/autogen/v02/__init__.py +4 -0
- ads/llm/autogen/v02/client.py +295 -0
- ads/llm/autogen/v02/log_handlers/__init__.py +2 -0
- ads/llm/autogen/v02/log_handlers/oci_file_handler.py +83 -0
- ads/llm/autogen/v02/loggers/__init__.py +6 -0
- ads/llm/autogen/v02/loggers/metric_logger.py +320 -0
- ads/llm/autogen/v02/loggers/session_logger.py +580 -0
- ads/llm/autogen/v02/loggers/utils.py +86 -0
- ads/llm/autogen/v02/runtime_logging.py +163 -0
- ads/llm/chain.py +268 -0
- ads/llm/chat_template.py +31 -0
- ads/llm/deploy.py +63 -0
- ads/llm/guardrails/__init__.py +5 -0
- ads/llm/guardrails/base.py +442 -0
- ads/llm/guardrails/huggingface.py +44 -0
- ads/llm/langchain/__init__.py +5 -0
- ads/llm/langchain/plugins/__init__.py +5 -0
- ads/llm/langchain/plugins/chat_models/__init__.py +5 -0
- ads/llm/langchain/plugins/chat_models/oci_data_science.py +1027 -0
- ads/llm/langchain/plugins/embeddings/__init__.py +4 -0
- ads/llm/langchain/plugins/embeddings/oci_data_science_model_deployment_endpoint.py +184 -0
- ads/llm/langchain/plugins/llms/__init__.py +5 -0
- ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +979 -0
- ads/llm/requirements.txt +3 -0
- ads/llm/serialize.py +219 -0
- ads/llm/serializers/__init__.py +0 -0
- ads/llm/serializers/retrieval_qa.py +153 -0
- ads/llm/serializers/runnable_parallel.py +27 -0
- ads/llm/templates/score_chain.jinja2 +155 -0
- ads/llm/templates/tool_chat_template_hermes.jinja +130 -0
- ads/llm/templates/tool_chat_template_mistral_parallel.jinja +94 -0
- ads/model/__init__.py +52 -0
- ads/model/artifact.py +573 -0
- ads/model/artifact_downloader.py +254 -0
- ads/model/artifact_uploader.py +267 -0
- ads/model/base_properties.py +238 -0
- ads/model/common/.model-ignore +66 -0
- ads/model/common/__init__.py +5 -0
- ads/model/common/utils.py +142 -0
- ads/model/datascience_model.py +2635 -0
- ads/model/deployment/__init__.py +20 -0
- ads/model/deployment/common/__init__.py +5 -0
- ads/model/deployment/common/utils.py +308 -0
- ads/model/deployment/model_deployer.py +466 -0
- ads/model/deployment/model_deployment.py +1846 -0
- ads/model/deployment/model_deployment_infrastructure.py +671 -0
- ads/model/deployment/model_deployment_properties.py +493 -0
- ads/model/deployment/model_deployment_runtime.py +838 -0
- ads/model/extractor/__init__.py +5 -0
- ads/model/extractor/automl_extractor.py +74 -0
- ads/model/extractor/embedding_onnx_extractor.py +80 -0
- ads/model/extractor/huggingface_extractor.py +88 -0
- ads/model/extractor/keras_extractor.py +84 -0
- ads/model/extractor/lightgbm_extractor.py +93 -0
- ads/model/extractor/model_info_extractor.py +114 -0
- ads/model/extractor/model_info_extractor_factory.py +105 -0
- ads/model/extractor/pytorch_extractor.py +87 -0
- ads/model/extractor/sklearn_extractor.py +112 -0
- ads/model/extractor/spark_extractor.py +89 -0
- ads/model/extractor/tensorflow_extractor.py +85 -0
- ads/model/extractor/xgboost_extractor.py +94 -0
- ads/model/framework/__init__.py +5 -0
- ads/model/framework/automl_model.py +178 -0
- ads/model/framework/embedding_onnx_model.py +438 -0
- ads/model/framework/huggingface_model.py +399 -0
- ads/model/framework/lightgbm_model.py +266 -0
- ads/model/framework/pytorch_model.py +266 -0
- ads/model/framework/sklearn_model.py +250 -0
- ads/model/framework/spark_model.py +326 -0
- ads/model/framework/tensorflow_model.py +254 -0
- ads/model/framework/xgboost_model.py +258 -0
- ads/model/generic_model.py +3518 -0
- ads/model/model_artifact_boilerplate/README.md +381 -0
- ads/model/model_artifact_boilerplate/__init__.py +5 -0
- ads/model/model_artifact_boilerplate/artifact_introspection_test/__init__.py +5 -0
- ads/model/model_artifact_boilerplate/artifact_introspection_test/model_artifact_validate.py +427 -0
- ads/model/model_artifact_boilerplate/artifact_introspection_test/requirements.txt +2 -0
- ads/model/model_artifact_boilerplate/runtime.yaml +7 -0
- ads/model/model_artifact_boilerplate/score.py +61 -0
- ads/model/model_file_description_schema.json +68 -0
- ads/model/model_introspect.py +331 -0
- ads/model/model_metadata.py +1810 -0
- ads/model/model_metadata_mixin.py +460 -0
- ads/model/model_properties.py +63 -0
- ads/model/model_version_set.py +739 -0
- ads/model/runtime/__init__.py +5 -0
- ads/model/runtime/env_info.py +306 -0
- ads/model/runtime/model_deployment_details.py +37 -0
- ads/model/runtime/model_provenance_details.py +58 -0
- ads/model/runtime/runtime_info.py +81 -0
- ads/model/runtime/schemas/inference_env_info_schema.yaml +16 -0
- ads/model/runtime/schemas/model_provenance_schema.yaml +36 -0
- ads/model/runtime/schemas/training_env_info_schema.yaml +16 -0
- ads/model/runtime/utils.py +201 -0
- ads/model/serde/__init__.py +5 -0
- ads/model/serde/common.py +40 -0
- ads/model/serde/model_input.py +547 -0
- ads/model/serde/model_serializer.py +1184 -0
- ads/model/service/__init__.py +5 -0
- ads/model/service/oci_datascience_model.py +1076 -0
- ads/model/service/oci_datascience_model_deployment.py +500 -0
- ads/model/service/oci_datascience_model_version_set.py +176 -0
- ads/model/transformer/__init__.py +5 -0
- ads/model/transformer/onnx_transformer.py +324 -0
- ads/mysqldb/__init__.py +5 -0
- ads/mysqldb/mysql_db.py +227 -0
- ads/opctl/__init__.py +18 -0
- ads/opctl/anomaly_detection.py +11 -0
- ads/opctl/backend/__init__.py +5 -0
- ads/opctl/backend/ads_dataflow.py +353 -0
- ads/opctl/backend/ads_ml_job.py +710 -0
- ads/opctl/backend/ads_ml_pipeline.py +164 -0
- ads/opctl/backend/ads_model_deployment.py +209 -0
- ads/opctl/backend/base.py +146 -0
- ads/opctl/backend/local.py +1053 -0
- ads/opctl/backend/marketplace/__init__.py +9 -0
- ads/opctl/backend/marketplace/helm_helper.py +173 -0
- ads/opctl/backend/marketplace/local_marketplace.py +271 -0
- ads/opctl/backend/marketplace/marketplace_backend_runner.py +71 -0
- ads/opctl/backend/marketplace/marketplace_operator_interface.py +44 -0
- ads/opctl/backend/marketplace/marketplace_operator_runner.py +24 -0
- ads/opctl/backend/marketplace/marketplace_utils.py +212 -0
- ads/opctl/backend/marketplace/models/__init__.py +5 -0
- ads/opctl/backend/marketplace/models/bearer_token.py +94 -0
- ads/opctl/backend/marketplace/models/marketplace_type.py +70 -0
- ads/opctl/backend/marketplace/models/ocir_details.py +56 -0
- ads/opctl/backend/marketplace/prerequisite_checker.py +238 -0
- ads/opctl/cli.py +707 -0
- ads/opctl/cmds.py +869 -0
- ads/opctl/conda/__init__.py +5 -0
- ads/opctl/conda/cli.py +193 -0
- ads/opctl/conda/cmds.py +749 -0
- ads/opctl/conda/config.yaml +34 -0
- ads/opctl/conda/manifest_template.yaml +13 -0
- ads/opctl/conda/multipart_uploader.py +188 -0
- ads/opctl/conda/pack.py +89 -0
- ads/opctl/config/__init__.py +5 -0
- ads/opctl/config/base.py +57 -0
- ads/opctl/config/diagnostics/__init__.py +5 -0
- ads/opctl/config/diagnostics/distributed/default_requirements_config.yaml +62 -0
- ads/opctl/config/merger.py +255 -0
- ads/opctl/config/resolver.py +297 -0
- ads/opctl/config/utils.py +79 -0
- ads/opctl/config/validator.py +17 -0
- ads/opctl/config/versioner.py +68 -0
- ads/opctl/config/yaml_parsers/__init__.py +7 -0
- ads/opctl/config/yaml_parsers/base.py +58 -0
- ads/opctl/config/yaml_parsers/distributed/__init__.py +7 -0
- ads/opctl/config/yaml_parsers/distributed/yaml_parser.py +201 -0
- ads/opctl/constants.py +66 -0
- ads/opctl/decorator/__init__.py +5 -0
- ads/opctl/decorator/common.py +129 -0
- ads/opctl/diagnostics/__init__.py +5 -0
- ads/opctl/diagnostics/__main__.py +25 -0
- ads/opctl/diagnostics/check_distributed_job_requirements.py +212 -0
- ads/opctl/diagnostics/check_requirements.py +144 -0
- ads/opctl/diagnostics/requirement_exception.py +9 -0
- ads/opctl/distributed/README.md +109 -0
- ads/opctl/distributed/__init__.py +5 -0
- ads/opctl/distributed/certificates.py +32 -0
- ads/opctl/distributed/cli.py +207 -0
- ads/opctl/distributed/cmds.py +731 -0
- ads/opctl/distributed/common/__init__.py +5 -0
- ads/opctl/distributed/common/abstract_cluster_provider.py +449 -0
- ads/opctl/distributed/common/abstract_framework_spec_builder.py +88 -0
- ads/opctl/distributed/common/cluster_config_helper.py +103 -0
- ads/opctl/distributed/common/cluster_provider_factory.py +21 -0
- ads/opctl/distributed/common/cluster_runner.py +54 -0
- ads/opctl/distributed/common/framework_factory.py +29 -0
- ads/opctl/docker/Dockerfile.job +103 -0
- ads/opctl/docker/Dockerfile.job.arm +107 -0
- ads/opctl/docker/Dockerfile.job.gpu +175 -0
- ads/opctl/docker/base-env.yaml +13 -0
- ads/opctl/docker/cuda.repo +6 -0
- ads/opctl/docker/operator/.dockerignore +0 -0
- ads/opctl/docker/operator/Dockerfile +41 -0
- ads/opctl/docker/operator/Dockerfile.gpu +85 -0
- ads/opctl/docker/operator/cuda.repo +6 -0
- ads/opctl/docker/operator/environment.yaml +8 -0
- ads/opctl/forecast.py +11 -0
- ads/opctl/index.yaml +3 -0
- ads/opctl/model/__init__.py +5 -0
- ads/opctl/model/cli.py +65 -0
- ads/opctl/model/cmds.py +73 -0
- ads/opctl/operator/README.md +4 -0
- ads/opctl/operator/__init__.py +31 -0
- ads/opctl/operator/cli.py +344 -0
- ads/opctl/operator/cmd.py +596 -0
- ads/opctl/operator/common/__init__.py +5 -0
- ads/opctl/operator/common/backend_factory.py +460 -0
- ads/opctl/operator/common/const.py +27 -0
- ads/opctl/operator/common/data/synthetic.csv +16001 -0
- ads/opctl/operator/common/dictionary_merger.py +148 -0
- ads/opctl/operator/common/errors.py +42 -0
- ads/opctl/operator/common/operator_config.py +99 -0
- ads/opctl/operator/common/operator_loader.py +811 -0
- ads/opctl/operator/common/operator_schema.yaml +130 -0
- ads/opctl/operator/common/operator_yaml_generator.py +152 -0
- ads/opctl/operator/common/utils.py +208 -0
- ads/opctl/operator/lowcode/__init__.py +5 -0
- ads/opctl/operator/lowcode/anomaly/MLoperator +16 -0
- ads/opctl/operator/lowcode/anomaly/README.md +207 -0
- ads/opctl/operator/lowcode/anomaly/__init__.py +5 -0
- ads/opctl/operator/lowcode/anomaly/__main__.py +103 -0
- ads/opctl/operator/lowcode/anomaly/cmd.py +35 -0
- ads/opctl/operator/lowcode/anomaly/const.py +167 -0
- ads/opctl/operator/lowcode/anomaly/environment.yaml +10 -0
- ads/opctl/operator/lowcode/anomaly/model/__init__.py +5 -0
- ads/opctl/operator/lowcode/anomaly/model/anomaly_dataset.py +146 -0
- ads/opctl/operator/lowcode/anomaly/model/anomaly_merlion.py +162 -0
- ads/opctl/operator/lowcode/anomaly/model/automlx.py +99 -0
- ads/opctl/operator/lowcode/anomaly/model/autots.py +115 -0
- ads/opctl/operator/lowcode/anomaly/model/base_model.py +404 -0
- ads/opctl/operator/lowcode/anomaly/model/factory.py +110 -0
- ads/opctl/operator/lowcode/anomaly/model/isolationforest.py +78 -0
- ads/opctl/operator/lowcode/anomaly/model/oneclasssvm.py +78 -0
- ads/opctl/operator/lowcode/anomaly/model/randomcutforest.py +120 -0
- ads/opctl/operator/lowcode/anomaly/model/tods.py +119 -0
- ads/opctl/operator/lowcode/anomaly/operator_config.py +127 -0
- ads/opctl/operator/lowcode/anomaly/schema.yaml +401 -0
- ads/opctl/operator/lowcode/anomaly/utils.py +88 -0
- ads/opctl/operator/lowcode/common/__init__.py +5 -0
- ads/opctl/operator/lowcode/common/const.py +10 -0
- ads/opctl/operator/lowcode/common/data.py +116 -0
- ads/opctl/operator/lowcode/common/errors.py +47 -0
- ads/opctl/operator/lowcode/common/transformations.py +296 -0
- ads/opctl/operator/lowcode/common/utils.py +384 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/MLoperator +13 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/README.md +30 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/__init__.py +5 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/__main__.py +116 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/cmd.py +85 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/const.py +15 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/environment.yaml +0 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/models/__init__.py +4 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/models/apigw_config.py +32 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/models/db_config.py +43 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/models/mysql_config.py +120 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/models/serializable_yaml_model.py +34 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/operator_utils.py +386 -0
- ads/opctl/operator/lowcode/feature_store_marketplace/schema.yaml +160 -0
- ads/opctl/operator/lowcode/forecast/MLoperator +25 -0
- ads/opctl/operator/lowcode/forecast/README.md +209 -0
- ads/opctl/operator/lowcode/forecast/__init__.py +5 -0
- ads/opctl/operator/lowcode/forecast/__main__.py +89 -0
- ads/opctl/operator/lowcode/forecast/cmd.py +40 -0
- ads/opctl/operator/lowcode/forecast/const.py +92 -0
- ads/opctl/operator/lowcode/forecast/environment.yaml +20 -0
- ads/opctl/operator/lowcode/forecast/errors.py +26 -0
- ads/opctl/operator/lowcode/forecast/model/__init__.py +5 -0
- ads/opctl/operator/lowcode/forecast/model/arima.py +279 -0
- ads/opctl/operator/lowcode/forecast/model/automlx.py +553 -0
- ads/opctl/operator/lowcode/forecast/model/autots.py +312 -0
- ads/opctl/operator/lowcode/forecast/model/base_model.py +875 -0
- ads/opctl/operator/lowcode/forecast/model/factory.py +106 -0
- ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +492 -0
- ads/opctl/operator/lowcode/forecast/model/ml_forecast.py +243 -0
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +482 -0
- ads/opctl/operator/lowcode/forecast/model/prophet.py +445 -0
- ads/opctl/operator/lowcode/forecast/model_evaluator.py +244 -0
- ads/opctl/operator/lowcode/forecast/operator_config.py +234 -0
- ads/opctl/operator/lowcode/forecast/schema.yaml +506 -0
- ads/opctl/operator/lowcode/forecast/utils.py +397 -0
- ads/opctl/operator/lowcode/forecast/whatifserve/__init__.py +7 -0
- ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +285 -0
- ads/opctl/operator/lowcode/forecast/whatifserve/score.py +246 -0
- ads/opctl/operator/lowcode/pii/MLoperator +17 -0
- ads/opctl/operator/lowcode/pii/README.md +208 -0
- ads/opctl/operator/lowcode/pii/__init__.py +5 -0
- ads/opctl/operator/lowcode/pii/__main__.py +78 -0
- ads/opctl/operator/lowcode/pii/cmd.py +39 -0
- ads/opctl/operator/lowcode/pii/constant.py +84 -0
- ads/opctl/operator/lowcode/pii/environment.yaml +17 -0
- ads/opctl/operator/lowcode/pii/errors.py +27 -0
- ads/opctl/operator/lowcode/pii/model/__init__.py +5 -0
- ads/opctl/operator/lowcode/pii/model/factory.py +82 -0
- ads/opctl/operator/lowcode/pii/model/guardrails.py +167 -0
- ads/opctl/operator/lowcode/pii/model/pii.py +145 -0
- ads/opctl/operator/lowcode/pii/model/processor/__init__.py +34 -0
- ads/opctl/operator/lowcode/pii/model/processor/email_replacer.py +34 -0
- ads/opctl/operator/lowcode/pii/model/processor/mbi_replacer.py +35 -0
- ads/opctl/operator/lowcode/pii/model/processor/name_replacer.py +225 -0
- ads/opctl/operator/lowcode/pii/model/processor/number_replacer.py +73 -0
- ads/opctl/operator/lowcode/pii/model/processor/remover.py +26 -0
- ads/opctl/operator/lowcode/pii/model/report.py +487 -0
- ads/opctl/operator/lowcode/pii/operator_config.py +95 -0
- ads/opctl/operator/lowcode/pii/schema.yaml +108 -0
- ads/opctl/operator/lowcode/pii/utils.py +43 -0
- ads/opctl/operator/lowcode/recommender/MLoperator +16 -0
- ads/opctl/operator/lowcode/recommender/README.md +206 -0
- ads/opctl/operator/lowcode/recommender/__init__.py +5 -0
- ads/opctl/operator/lowcode/recommender/__main__.py +82 -0
- ads/opctl/operator/lowcode/recommender/cmd.py +33 -0
- ads/opctl/operator/lowcode/recommender/constant.py +30 -0
- ads/opctl/operator/lowcode/recommender/environment.yaml +11 -0
- ads/opctl/operator/lowcode/recommender/model/base_model.py +212 -0
- ads/opctl/operator/lowcode/recommender/model/factory.py +56 -0
- ads/opctl/operator/lowcode/recommender/model/recommender_dataset.py +25 -0
- ads/opctl/operator/lowcode/recommender/model/svd.py +106 -0
- ads/opctl/operator/lowcode/recommender/operator_config.py +81 -0
- ads/opctl/operator/lowcode/recommender/schema.yaml +265 -0
- ads/opctl/operator/lowcode/recommender/utils.py +13 -0
- ads/opctl/operator/runtime/__init__.py +5 -0
- ads/opctl/operator/runtime/const.py +17 -0
- ads/opctl/operator/runtime/container_runtime_schema.yaml +50 -0
- ads/opctl/operator/runtime/marketplace_runtime.py +50 -0
- ads/opctl/operator/runtime/python_marketplace_runtime_schema.yaml +21 -0
- ads/opctl/operator/runtime/python_runtime_schema.yaml +21 -0
- ads/opctl/operator/runtime/runtime.py +115 -0
- ads/opctl/schema.yaml.yml +36 -0
- ads/opctl/script.py +40 -0
- ads/opctl/spark/__init__.py +5 -0
- ads/opctl/spark/cli.py +43 -0
- ads/opctl/spark/cmds.py +147 -0
- ads/opctl/templates/diagnostic_report_template.jinja2 +102 -0
- ads/opctl/utils.py +344 -0
- ads/oracledb/__init__.py +5 -0
- ads/oracledb/oracle_db.py +346 -0
- ads/pipeline/__init__.py +39 -0
- ads/pipeline/ads_pipeline.py +2279 -0
- ads/pipeline/ads_pipeline_run.py +772 -0
- ads/pipeline/ads_pipeline_step.py +605 -0
- ads/pipeline/builders/__init__.py +5 -0
- ads/pipeline/builders/infrastructure/__init__.py +5 -0
- ads/pipeline/builders/infrastructure/custom_script.py +32 -0
- ads/pipeline/cli.py +119 -0
- ads/pipeline/extension.py +291 -0
- ads/pipeline/schema/__init__.py +5 -0
- ads/pipeline/schema/cs_step_schema.json +35 -0
- ads/pipeline/schema/ml_step_schema.json +31 -0
- ads/pipeline/schema/pipeline_schema.json +71 -0
- ads/pipeline/visualizer/__init__.py +5 -0
- ads/pipeline/visualizer/base.py +570 -0
- ads/pipeline/visualizer/graph_renderer.py +272 -0
- ads/pipeline/visualizer/text_renderer.py +84 -0
- ads/secrets/__init__.py +11 -0
- ads/secrets/adb.py +386 -0
- ads/secrets/auth_token.py +86 -0
- ads/secrets/big_data_service.py +365 -0
- ads/secrets/mysqldb.py +149 -0
- ads/secrets/oracledb.py +160 -0
- ads/secrets/secrets.py +407 -0
- ads/telemetry/__init__.py +7 -0
- ads/telemetry/base.py +69 -0
- ads/telemetry/client.py +125 -0
- ads/telemetry/telemetry.py +257 -0
- ads/templates/dataflow_pyspark.jinja2 +13 -0
- ads/templates/dataflow_sparksql.jinja2 +22 -0
- ads/templates/func.jinja2 +20 -0
- ads/templates/schemas/openapi.json +1740 -0
- ads/templates/score-pkl.jinja2 +173 -0
- ads/templates/score.jinja2 +322 -0
- ads/templates/score_embedding_onnx.jinja2 +202 -0
- ads/templates/score_generic.jinja2 +165 -0
- ads/templates/score_huggingface_pipeline.jinja2 +217 -0
- ads/templates/score_lightgbm.jinja2 +185 -0
- ads/templates/score_onnx.jinja2 +407 -0
- ads/templates/score_onnx_new.jinja2 +473 -0
- ads/templates/score_oracle_automl.jinja2 +185 -0
- ads/templates/score_pyspark.jinja2 +154 -0
- ads/templates/score_pytorch.jinja2 +219 -0
- ads/templates/score_scikit-learn.jinja2 +184 -0
- ads/templates/score_tensorflow.jinja2 +184 -0
- ads/templates/score_xgboost.jinja2 +178 -0
- ads/text_dataset/__init__.py +5 -0
- ads/text_dataset/backends.py +211 -0
- ads/text_dataset/dataset.py +445 -0
- ads/text_dataset/extractor.py +207 -0
- ads/text_dataset/options.py +53 -0
- ads/text_dataset/udfs.py +22 -0
- ads/text_dataset/utils.py +49 -0
- ads/type_discovery/__init__.py +9 -0
- ads/type_discovery/abstract_detector.py +21 -0
- ads/type_discovery/constant_detector.py +41 -0
- ads/type_discovery/continuous_detector.py +54 -0
- ads/type_discovery/credit_card_detector.py +99 -0
- ads/type_discovery/datetime_detector.py +92 -0
- ads/type_discovery/discrete_detector.py +118 -0
- ads/type_discovery/document_detector.py +146 -0
- ads/type_discovery/ip_detector.py +68 -0
- ads/type_discovery/latlon_detector.py +90 -0
- ads/type_discovery/phone_number_detector.py +63 -0
- ads/type_discovery/type_discovery_driver.py +87 -0
- ads/type_discovery/typed_feature.py +594 -0
- ads/type_discovery/unknown_detector.py +41 -0
- ads/type_discovery/zipcode_detector.py +48 -0
- ads/vault/__init__.py +7 -0
- ads/vault/vault.py +237 -0
- {oracle_ads-2.13.9rc0.dist-info → oracle_ads-2.13.9rc1.dist-info}/METADATA +150 -150
- oracle_ads-2.13.9rc1.dist-info/RECORD +858 -0
- {oracle_ads-2.13.9rc0.dist-info → oracle_ads-2.13.9rc1.dist-info}/WHEEL +1 -2
- {oracle_ads-2.13.9rc0.dist-info → oracle_ads-2.13.9rc1.dist-info}/entry_points.txt +2 -1
- oracle_ads-2.13.9rc0.dist-info/RECORD +0 -9
- oracle_ads-2.13.9rc0.dist-info/top_level.txt +0 -1
- {oracle_ads-2.13.9rc0.dist-info → oracle_ads-2.13.9rc1.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,2279 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8; -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2022, 2023 Oracle and/or its affiliates.
|
5
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
|
+
|
7
|
+
import copy
|
8
|
+
import datetime
|
9
|
+
import logging
|
10
|
+
import os
|
11
|
+
import traceback
|
12
|
+
from typing import Any, Dict, List, Optional
|
13
|
+
|
14
|
+
import fsspec
|
15
|
+
import oci
|
16
|
+
import oci.util as oci_util
|
17
|
+
|
18
|
+
from ads.common import utils
|
19
|
+
from ads.common.oci_datascience import DSCNotebookSession, OCIDataScienceMixin
|
20
|
+
from ads.common.oci_logging import OCILog
|
21
|
+
from ads.common.oci_resource import ResourceNotFoundError
|
22
|
+
from ads.config import COMPARTMENT_OCID, NB_SESSION_OCID, PROJECT_OCID
|
23
|
+
from ads.jobs.builders.base import Builder
|
24
|
+
from ads.jobs.builders.infrastructure.dsc_job import DataScienceJob, DSCJob
|
25
|
+
from ads.jobs.builders.infrastructure.dsc_job_runtime import (
|
26
|
+
DataScienceJobRuntimeManager,
|
27
|
+
)
|
28
|
+
from ads.jobs.builders.runtimes.artifact import Artifact
|
29
|
+
from ads.jobs.builders.runtimes.python_runtime import (
|
30
|
+
GitPythonRuntime,
|
31
|
+
NotebookRuntime,
|
32
|
+
PythonRuntime,
|
33
|
+
ScriptRuntime,
|
34
|
+
)
|
35
|
+
from ads.pipeline.ads_pipeline_run import PipelineRun
|
36
|
+
from ads.pipeline.ads_pipeline_step import PipelineStep
|
37
|
+
from ads.pipeline.visualizer.base import GraphOrientation, PipelineVisualizer
|
38
|
+
from ads.pipeline.visualizer.graph_renderer import PipelineGraphRenderer
|
39
|
+
|
40
|
+
logger = logging.getLogger(__name__)
|
41
|
+
|
42
|
+
MAXIMUM_TIMEOUT = 1800
|
43
|
+
DEFAULT_WAITER_KWARGS = {"max_wait_seconds": MAXIMUM_TIMEOUT}
|
44
|
+
DEFAULT_OPERATION_KWARGS = {
|
45
|
+
"delete_related_pipeline_runs": True,
|
46
|
+
"delete_related_job_runs": True,
|
47
|
+
}
|
48
|
+
ALLOWED_OPERATION_KWARGS = [
|
49
|
+
"allow_control_chars",
|
50
|
+
"retry_strategy",
|
51
|
+
"delete_related_job_runs",
|
52
|
+
"delete_related_pipeline_runs",
|
53
|
+
"if_match",
|
54
|
+
"opc_request_id",
|
55
|
+
]
|
56
|
+
ALLOWED_WAITER_KWARGS = [
|
57
|
+
"max_interval_seconds",
|
58
|
+
"max_wait_seconds",
|
59
|
+
"succeed_on_not_found",
|
60
|
+
"wait_callback",
|
61
|
+
"fetch_func",
|
62
|
+
]
|
63
|
+
|
64
|
+
|
65
|
+
class Pipeline(Builder):
|
66
|
+
"""Represents a Data Science Machine Learning Pipeline."""
|
67
|
+
|
68
|
+
CONST_ID = "id"
|
69
|
+
CONST_PIPELINE_ID = "pipelineId"
|
70
|
+
CONST_DISPLAY_NAME = "displayName"
|
71
|
+
CONST_STEP_DETAILS = "stepDetails"
|
72
|
+
CONST_STEP_OVERRIDE_DETAILS = "stepOverrideDetails"
|
73
|
+
CONST_COMPARTMENT_ID = "compartmentId"
|
74
|
+
CONST_PROJECT_ID = "projectId"
|
75
|
+
CONST_LOG_GROUP_ID = "logGroupId"
|
76
|
+
CONST_LOG_ID = "logId"
|
77
|
+
CONST_SERVICE_LOG_ID = "serviceLogId"
|
78
|
+
CONST_ENABLE_SERVICE_LOG = "enableServiceLog"
|
79
|
+
CONST_ENVIRONMENT_VARIABLES = "environmentVariables"
|
80
|
+
CONST_COMMAND_LINE_ARGUMENTS = "commandLineArguments"
|
81
|
+
CONST_CREATED_BY = "createdBy"
|
82
|
+
CONST_DESCRIPTION = "description"
|
83
|
+
CONST_TYPE = "type"
|
84
|
+
CONST_MAXIMUM_RUNTIME_IN_MINUTES = "maximumRuntimeInMinutes"
|
85
|
+
CONST_ENABLE_LOGGING = "enableLogging"
|
86
|
+
CONST_ENABLE_AUTO_LOG_CREATION = "enableAutoLogCreation"
|
87
|
+
CONST_CONFIGURATION_DETAILS = "configurationDetails"
|
88
|
+
CONST_CONFIGURATION_OVERRIDE_DETAILS = "configurationOverrideDetails"
|
89
|
+
CONST_LOG_CONFIGURATION_DETAILS = "logConfigurationDetails"
|
90
|
+
CONST_LOG_CONFIGURATION_OVERRIDE_DETAILS = "logConfigurationOverrideDetails"
|
91
|
+
CONST_FREEFROM_TAGS = "freeformTags"
|
92
|
+
CONST_DEFINED_TAGS = "definedTags"
|
93
|
+
CONST_SYSTEM_TAGS = "systemTags"
|
94
|
+
CONST_INFRA_CONFIG_DETAILS = "infrastructureConfigurationDetails"
|
95
|
+
CONST_SHAPE_NAME = "shapeName"
|
96
|
+
CONST_BLOCK_STORAGE_SIZE = "blockStorageSizeInGBs"
|
97
|
+
CONST_SHAPE_CONFIG_DETAILS = "shapeConfigDetails"
|
98
|
+
CONST_OCPUS = "ocpus"
|
99
|
+
CONST_MEMORY_IN_GBS = "memoryInGBs"
|
100
|
+
CONST_SERVICE_LOG_CATEGORY = "pipelinerunlog"
|
101
|
+
CONST_SERVICE = "datascience"
|
102
|
+
CONST_DAG = "dag"
|
103
|
+
|
104
|
+
LIFECYCLE_STATE_CREATING = "CREATING"
|
105
|
+
LIFECYCLE_STATE_ACTIVE = "ACTIVE"
|
106
|
+
LIFECYCLE_STATE_DELETING = "DELETING"
|
107
|
+
LIFECYCLE_STATE_FAILED = "FAILED"
|
108
|
+
LIFECYCLE_STATE_DELETED = "DELETED"
|
109
|
+
|
110
|
+
def __init__(self, name: str = None, spec: Dict = None, **kwargs) -> None:
|
111
|
+
"""Initialize a pipeline.
|
112
|
+
|
113
|
+
Parameters
|
114
|
+
----------
|
115
|
+
name: str
|
116
|
+
The name of the pipeline, default to None. If a name is not provided, a randomly generated easy to remember
|
117
|
+
name with timestamp will be generated, like 'strange-spider-2022-08-17-23:55.02'.
|
118
|
+
spec : dict, optional
|
119
|
+
Object specification, default to None
|
120
|
+
kwargs: dict
|
121
|
+
Specification as keyword arguments.
|
122
|
+
If spec contains the same key as the one in kwargs, the value from kwargs will be used.
|
123
|
+
|
124
|
+
- project_id: str
|
125
|
+
- compartment_id: str
|
126
|
+
- display_name: str
|
127
|
+
- description: str
|
128
|
+
- maximum_runtime_in_minutes: int
|
129
|
+
- environment_variables: dict(str, str)
|
130
|
+
- command_line_arguments: str
|
131
|
+
- log_id: str
|
132
|
+
- log_group_id: str
|
133
|
+
- enable_service_log: bool
|
134
|
+
- shape_name: str
|
135
|
+
- block_storage_size_in_gbs: int
|
136
|
+
- shape_config_details: dict
|
137
|
+
- step_details: list[PipelineStep]
|
138
|
+
- dag: list[str]
|
139
|
+
- defined_tags: dict(str, dict(str, object))
|
140
|
+
- freeform_tags: dict[str, str]
|
141
|
+
|
142
|
+
Attributes
|
143
|
+
----------
|
144
|
+
kind: str
|
145
|
+
The kind of the object as showing in YAML.
|
146
|
+
name: str
|
147
|
+
The name of pipeline.
|
148
|
+
id: str
|
149
|
+
The id of pipeline.
|
150
|
+
step_details: List[PipelineStep]
|
151
|
+
The step details of pipeline.
|
152
|
+
dag_details: List[str]
|
153
|
+
The dag details of pipeline.
|
154
|
+
log_group_id: str
|
155
|
+
The log group id of pipeline.
|
156
|
+
log_id: str
|
157
|
+
The log id of pipeline.
|
158
|
+
project_id: str
|
159
|
+
The project id of pipeline.
|
160
|
+
compartment_id: str
|
161
|
+
The compartment id of pipeline.
|
162
|
+
created_by: str
|
163
|
+
The created by of pipeline.
|
164
|
+
description: str
|
165
|
+
The description of pipeline.
|
166
|
+
environment_variable: dict
|
167
|
+
The environment variables of pipeline.
|
168
|
+
argument: str
|
169
|
+
The command line argument of pipeline.
|
170
|
+
maximum_runtime_in_minutes: int
|
171
|
+
The maximum runtime in minutes of pipeline.
|
172
|
+
shape_name: str
|
173
|
+
The shape name of pipeline infrastructure.
|
174
|
+
block_storage_size_in_gbs: int
|
175
|
+
The block storage of pipeline infrastructure.
|
176
|
+
shape_config_details: dict
|
177
|
+
The shape config details of pipeline infrastructure.
|
178
|
+
enable_service_log: bool
|
179
|
+
The value to enable service log or not.
|
180
|
+
service_log_id: str
|
181
|
+
The service log id of pipeline.
|
182
|
+
status: str
|
183
|
+
The status of the pipeline.
|
184
|
+
|
185
|
+
Methods
|
186
|
+
-------
|
187
|
+
with_name(self, name: str) -> Pipeline
|
188
|
+
Sets the name of pipeline.
|
189
|
+
with_id(self, id: str) -> Pipeline
|
190
|
+
Sets the ocid of pipeline.
|
191
|
+
with_step_details(self, step_details: List[PipelineStep]) -> Pipeline
|
192
|
+
Sets the step details of pipeline.
|
193
|
+
with_dag_details(self, dag_details: List[str]) -> Pipeline
|
194
|
+
Sets the dag details of pipeline.
|
195
|
+
with_log_group_id(self, log_group_id: str) -> Pipeline
|
196
|
+
Sets the log group id of pipeline.
|
197
|
+
with_log_id(self, log_id: str) -> Pipeline
|
198
|
+
Sets the log id of pipeline.
|
199
|
+
with_project_id(self, project_id: str) -> Pipeline
|
200
|
+
Sets the project id of pipeline.
|
201
|
+
with_compartment_id(self, compartment_id: str) -> Pipeline
|
202
|
+
Sets the compartment id of pipeline.
|
203
|
+
with_created_by(self, created_by: str) -> Pipeline
|
204
|
+
Sets the created by of pipeline.
|
205
|
+
with_description(self, description: str) -> Pipeline
|
206
|
+
Sets the description of pipeline.
|
207
|
+
with_environment_variable(self, **kwargs) -> Pipeline
|
208
|
+
Sets the environment variables of pipeline.
|
209
|
+
with_argument(self, *args, **kwargs) -> Pipeline
|
210
|
+
Sets the command line arguments of pipeline.
|
211
|
+
with_maximum_runtime_in_minutes(self, maximum_runtime_in_minutes: int) -> Pipeline
|
212
|
+
Sets the maximum runtime in minutes of pipeline.
|
213
|
+
with_freeform_tags(self, freeform_tags: Dict) -> Pipeline
|
214
|
+
Sets the freeform tags of pipeline.
|
215
|
+
with_defined_tags(self, defined_tags: Dict) -> Pipeline
|
216
|
+
Sets the defined tags of pipeline.
|
217
|
+
with_shape_name(self, shape_name: str) -> Pipeline
|
218
|
+
Sets the shape name of pipeline infrastructure.
|
219
|
+
with_block_storage_size_in_gbs(self, block_storage_size_in_gbs: int) -> Pipeline
|
220
|
+
Sets the block storage size of pipeline infrastructure.
|
221
|
+
with_shape_config_details(self, shape_config_details: Dict) -> Pipeline
|
222
|
+
Sets the shape config details of pipeline infrastructure.
|
223
|
+
with_enable_service_log(self, enable_service_log: bool) -> Pipeline
|
224
|
+
Sets the value to enable the service log of pipeline.
|
225
|
+
to_dict(self) -> dict:
|
226
|
+
Serializes the pipeline specifications to a dictionary.
|
227
|
+
from_dict(cls, obj_dict: dict):
|
228
|
+
Initializes the object from a dictionary.
|
229
|
+
create(self, delete_if_fail: bool = True) -> Pipeline
|
230
|
+
Creates an ADS pipeline.
|
231
|
+
show(self, rankdir: str = GraphOrientation.TOP_BOTTOM)
|
232
|
+
Render pipeline with step information in a graph.
|
233
|
+
to_svg(self, uri: str = None, rankdir: str = GraphOrientation.TOP_BOTTOM, **kwargs) -> str:
|
234
|
+
Renders pipeline as graph into SVG.
|
235
|
+
run(self, display_name: Optional[str] = None, project_id: Optional[str] = None, compartment_id: Optional[str] = None, configuration_override_details: Optional[dict] = None, log_configuration_override_details: Optional[dict] = None, step_override_details: Optional[list] = None, free_form_tags: Optional[dict] = None, defined_tags: Optional[dict] = None, system_tags: Optional[dict] = None) -> PipelineRun
|
236
|
+
Creates and/or overrides an ADS pipeline run.
|
237
|
+
delete(self, delete_related_pipeline_runs: Optional[bool] = True, delete_related_job_runs: Optional[bool] = True, max_wait_seconds: Optional[int] = MAXIMUM_TIMEOUT, **kwargs) -> Pipeline
|
238
|
+
Deletes an ADS pipeline run.
|
239
|
+
from_ocid(cls, ocid: str) -> Pipeline
|
240
|
+
Creates an ADS pipeline from ocid.
|
241
|
+
from_id(cls, id: str) -> Pipeline
|
242
|
+
Creates an ADS pipeline from ocid.
|
243
|
+
to_yaml(self, uri=None, **kwargs)
|
244
|
+
Returns Pipeline serialized as a YAML string
|
245
|
+
from_yaml(cls, yaml_string=None, uri=None, **kwargs)
|
246
|
+
Creates an Pipeline from YAML string provided or from URI location containing YAML string
|
247
|
+
list(cls, compartment_id: Optional[str] = None, **kwargs) -> List[Pipeline]
|
248
|
+
List pipelines in a given compartment.
|
249
|
+
run_list(self, **kwargs) -> List[PipelineRun]
|
250
|
+
Gets a list of runs of the pipeline.
|
251
|
+
|
252
|
+
Example
|
253
|
+
-------
|
254
|
+
Here is an example for creating and running a pipeline using builder:
|
255
|
+
|
256
|
+
.. code-block:: python
|
257
|
+
|
258
|
+
from ads.pipeline import Pipeline, CustomScriptStep, ScriptRuntime
|
259
|
+
# Define an OCI Data Science pipeline
|
260
|
+
pipeline = (
|
261
|
+
Pipeline(name="<pipeline_name>")
|
262
|
+
.with_compartment_id("<compartment_id>")
|
263
|
+
.with_project_id("<project_id>")
|
264
|
+
.with_log_group_id("<log_group_id>")
|
265
|
+
.with_log_id("<log_id>")
|
266
|
+
.with_description("<description>")
|
267
|
+
.with_maximum_runtime_in_minutes(200)
|
268
|
+
.with_argument("argument", key="value")
|
269
|
+
.with_environment_variable(env="value")
|
270
|
+
.with_freeform_tags({"key": "value"})
|
271
|
+
.with_step_details([
|
272
|
+
(
|
273
|
+
PipelineStep(name="PipelineStepOne")
|
274
|
+
.with_job_id("<job_id>")
|
275
|
+
.with_description("<description>")
|
276
|
+
),
|
277
|
+
(
|
278
|
+
PipelineStep(name="PipelineStepTwo")
|
279
|
+
.with_infrastructure(
|
280
|
+
CustomScriptStep()
|
281
|
+
.with_shape_name("VM.Standard2.1")
|
282
|
+
.with_block_storage_size(50)
|
283
|
+
)
|
284
|
+
.with_runtime(
|
285
|
+
ScriptRuntime()
|
286
|
+
.with_source("oci://bucket_name@namespace/path/to/script.py")
|
287
|
+
.with_service_conda("tensorflow26_p37_cpu_v2")
|
288
|
+
.with_environment_variable(ENV="value")
|
289
|
+
.with_argument("argument", key="value")
|
290
|
+
.with_maximum_runtime_in_minutes(200)
|
291
|
+
)
|
292
|
+
)
|
293
|
+
])
|
294
|
+
.with_dag_details(["PipelineStepOne >> PipelineStepTwo"])
|
295
|
+
)
|
296
|
+
# Create and Run the pipeline
|
297
|
+
run = pipeline.create().run()
|
298
|
+
# Stream the pipeline run outputs
|
299
|
+
run.watch()
|
300
|
+
|
301
|
+
See Also
|
302
|
+
--------
|
303
|
+
https://docs.oracle.com/en-us/iaas/tools/ads-sdk/latest/user_guide/pipeline/index.html
|
304
|
+
"""
|
305
|
+
self.attribute_set = {
|
306
|
+
"id",
|
307
|
+
"createdBy",
|
308
|
+
"projectId",
|
309
|
+
"compartmentId",
|
310
|
+
"description",
|
311
|
+
"pipelineId",
|
312
|
+
"displayName",
|
313
|
+
"configurationDetails",
|
314
|
+
"logConfigurationDetails",
|
315
|
+
"infrastructureConfigurationDetails",
|
316
|
+
"stepDetails",
|
317
|
+
"lifecycleState",
|
318
|
+
"freeformTags",
|
319
|
+
"definedTags",
|
320
|
+
"systemTags",
|
321
|
+
"dag",
|
322
|
+
"logId",
|
323
|
+
"logGroupId",
|
324
|
+
}
|
325
|
+
|
326
|
+
self.attribute_map = {
|
327
|
+
"projectId": "project_id",
|
328
|
+
"compartmentId": "compartment_id",
|
329
|
+
"displayName": "display_name",
|
330
|
+
"description": "description",
|
331
|
+
"maximumRuntimeInMinutes": "maximum_runtime_in_minutes",
|
332
|
+
"environmentVariables": "environment_variables",
|
333
|
+
"commandLineArguments": "command_line_arguments",
|
334
|
+
"logId": "log_id",
|
335
|
+
"logGroupId": "log_group_id",
|
336
|
+
"enableServiceLog": "enable_service_log",
|
337
|
+
"stepDetails": "step_details",
|
338
|
+
"freeformTags": "freeform_tags",
|
339
|
+
"definedTags": "defined_tags",
|
340
|
+
"shapeName": "shape_name",
|
341
|
+
"blockStorageSizeInGBs": "block_storage_size_in_gbs",
|
342
|
+
"shapeConfigDetails": "shape_config_details",
|
343
|
+
"dag": "dag",
|
344
|
+
"id": "id",
|
345
|
+
}
|
346
|
+
|
347
|
+
self._artifact_content_map = {}
|
348
|
+
super().__init__(spec=spec, **kwargs)
|
349
|
+
name = (
|
350
|
+
name
|
351
|
+
or self.get_spec(self.CONST_DISPLAY_NAME)
|
352
|
+
or utils.get_random_name_for_resource()
|
353
|
+
)
|
354
|
+
self.set_spec(self.CONST_DISPLAY_NAME, name)
|
355
|
+
if "dag" in kwargs:
|
356
|
+
self.with_dag(kwargs.get("dag"))
|
357
|
+
elif spec and "dag" in spec:
|
358
|
+
self.with_dag(spec.get("dag"))
|
359
|
+
self.data_science_pipeline = None
|
360
|
+
self.service_logging = None
|
361
|
+
|
362
|
+
def _load_default_properties(self) -> Dict:
|
363
|
+
"""Load default properties from environment variables, notebook session, etc.
|
364
|
+
|
365
|
+
Returns
|
366
|
+
-------
|
367
|
+
Dict
|
368
|
+
A dictionary of default properties.
|
369
|
+
"""
|
370
|
+
defaults = super()._load_default_properties()
|
371
|
+
if COMPARTMENT_OCID:
|
372
|
+
defaults[self.CONST_COMPARTMENT_ID] = COMPARTMENT_OCID
|
373
|
+
if PROJECT_OCID:
|
374
|
+
defaults[self.CONST_PROJECT_ID] = PROJECT_OCID
|
375
|
+
|
376
|
+
if NB_SESSION_OCID:
|
377
|
+
try:
|
378
|
+
nb_session = DSCNotebookSession.from_ocid(NB_SESSION_OCID)
|
379
|
+
nb_config = nb_session.notebook_session_configuration_details
|
380
|
+
defaults[self.CONST_SHAPE_NAME] = nb_config.shape
|
381
|
+
defaults[
|
382
|
+
self.CONST_BLOCK_STORAGE_SIZE
|
383
|
+
] = nb_config.block_storage_size_in_gbs
|
384
|
+
|
385
|
+
if nb_config.notebook_session_shape_config_details:
|
386
|
+
notebook_shape_config_details = oci_util.to_dict(
|
387
|
+
nb_config.notebook_session_shape_config_details
|
388
|
+
)
|
389
|
+
defaults[self.CONST_SHAPE_CONFIG_DETAILS] = copy.deepcopy(
|
390
|
+
notebook_shape_config_details
|
391
|
+
)
|
392
|
+
|
393
|
+
except Exception as e:
|
394
|
+
logger.warning(
|
395
|
+
f"Error fetching details about Notebook "
|
396
|
+
f"session: {NB_SESSION_OCID}. {e}"
|
397
|
+
)
|
398
|
+
logger.debug(traceback.format_exc())
|
399
|
+
|
400
|
+
return defaults
|
401
|
+
|
402
|
+
@property
|
403
|
+
def kind(self) -> str:
|
404
|
+
"""The kind of the object as showing in YAML.
|
405
|
+
|
406
|
+
Returns
|
407
|
+
-------
|
408
|
+
str
|
409
|
+
pipeline
|
410
|
+
"""
|
411
|
+
return "pipeline"
|
412
|
+
|
413
|
+
@property
|
414
|
+
def name(self) -> str:
|
415
|
+
"""The name of the pipeline.
|
416
|
+
|
417
|
+
Returns
|
418
|
+
-------
|
419
|
+
str
|
420
|
+
The name of the pipeline.
|
421
|
+
"""
|
422
|
+
return self.get_spec(self.CONST_DISPLAY_NAME)
|
423
|
+
|
424
|
+
def with_name(self, name: str) -> "Pipeline":
|
425
|
+
"""Sets the name of pipeline.
|
426
|
+
|
427
|
+
Parameters
|
428
|
+
----------
|
429
|
+
name: str
|
430
|
+
The name of pipeline.
|
431
|
+
|
432
|
+
Returns
|
433
|
+
-------
|
434
|
+
Pipeline
|
435
|
+
The Pipeline instance (self).
|
436
|
+
"""
|
437
|
+
return self.set_spec(self.CONST_DISPLAY_NAME, name)
|
438
|
+
|
439
|
+
@property
|
440
|
+
def id(self) -> str:
|
441
|
+
"""The id of the pipeline.
|
442
|
+
|
443
|
+
Returns
|
444
|
+
-------
|
445
|
+
str
|
446
|
+
The id of the pipeline.
|
447
|
+
"""
|
448
|
+
return self.get_spec(self.CONST_ID)
|
449
|
+
|
450
|
+
def with_id(self, id: str) -> "Pipeline":
|
451
|
+
"""Sets the id of pipeline.
|
452
|
+
|
453
|
+
Parameters
|
454
|
+
----------
|
455
|
+
id: str
|
456
|
+
The id of pipeline.
|
457
|
+
|
458
|
+
Returns
|
459
|
+
-------
|
460
|
+
Pipeline
|
461
|
+
The Pipeline instance (self).
|
462
|
+
"""
|
463
|
+
return self.set_spec(self.CONST_ID, id)
|
464
|
+
|
465
|
+
@property
|
466
|
+
def step_details(self) -> List["PipelineStep"]:
|
467
|
+
"""The step details of the pipeline.
|
468
|
+
|
469
|
+
Returns
|
470
|
+
-------
|
471
|
+
list
|
472
|
+
The step details of the pipeline.
|
473
|
+
"""
|
474
|
+
return self.get_spec(self.CONST_STEP_DETAILS)
|
475
|
+
|
476
|
+
def with_step_details(self, step_details: List["PipelineStep"]) -> "Pipeline":
|
477
|
+
"""Sets the pipeline step details for the pipeline.
|
478
|
+
|
479
|
+
Parameters
|
480
|
+
----------
|
481
|
+
step_details: list
|
482
|
+
A list of steps in the pipeline.
|
483
|
+
|
484
|
+
Returns
|
485
|
+
-------
|
486
|
+
Pipeline
|
487
|
+
The Pipeline instance (self).
|
488
|
+
"""
|
489
|
+
self.set_spec(self.CONST_DAG, None)
|
490
|
+
return self.set_spec(self.CONST_STEP_DETAILS, step_details)
|
491
|
+
|
492
|
+
@property
|
493
|
+
def dag(self) -> List[str]:
|
494
|
+
"""The dag details of the pipeline.
|
495
|
+
|
496
|
+
Returns
|
497
|
+
-------
|
498
|
+
list
|
499
|
+
The dag details of the pipeline.
|
500
|
+
"""
|
501
|
+
return self.get_spec(self.CONST_DAG)
|
502
|
+
|
503
|
+
def with_dag(self, dag: List[str]) -> "Pipeline":
|
504
|
+
"""Sets the pipeline dag details for the pipeline.
|
505
|
+
|
506
|
+
Parameters
|
507
|
+
----------
|
508
|
+
dag: list
|
509
|
+
A list of dag representing step dependencies in the pipeline.
|
510
|
+
|
511
|
+
Returns
|
512
|
+
-------
|
513
|
+
Pipeline
|
514
|
+
The Pipeline instance (self).
|
515
|
+
"""
|
516
|
+
self.set_spec(self.CONST_DAG, dag)
|
517
|
+
|
518
|
+
if not self.step_details:
|
519
|
+
raise ValueError("Pipeline step details must be specified first.")
|
520
|
+
|
521
|
+
stepname_to_step_map = {x.name: x for x in self.step_details}
|
522
|
+
updated_step_details = Pipeline._add_dag_to_node(dag, stepname_to_step_map)
|
523
|
+
|
524
|
+
return self.set_spec(self.CONST_STEP_DETAILS, updated_step_details)
|
525
|
+
|
526
|
+
@staticmethod
|
527
|
+
def _add_dag_to_node(
|
528
|
+
dag: List[str], stepname_to_step_map: dict
|
529
|
+
) -> List["PipelineStep"]:
|
530
|
+
"""Add dependencies to pipeline steps.
|
531
|
+
|
532
|
+
Parameters
|
533
|
+
----------
|
534
|
+
dag: list
|
535
|
+
A list of dag representing step dependencies in the pipeline.
|
536
|
+
stepname_to_step_map: dict
|
537
|
+
A dict mapping PipelineStep name to the PipelineStep object.
|
538
|
+
|
539
|
+
Returns
|
540
|
+
-------
|
541
|
+
List
|
542
|
+
A list of PipelineStep.
|
543
|
+
"""
|
544
|
+
|
545
|
+
dag_mapping = {x: [] for x in stepname_to_step_map}
|
546
|
+
updated_step_details = []
|
547
|
+
if dag:
|
548
|
+
for dag_line in dag:
|
549
|
+
dependency = [
|
550
|
+
x.strip().strip("()").split(",") for x in dag_line.split(">>")
|
551
|
+
]
|
552
|
+
for i in range(len(dependency) - 1):
|
553
|
+
for node1 in dependency[i]:
|
554
|
+
for node2 in dependency[i + 1]:
|
555
|
+
node1 = node1.strip()
|
556
|
+
node2 = node2.strip()
|
557
|
+
if node1 not in stepname_to_step_map:
|
558
|
+
raise ValueError(
|
559
|
+
f"Pipeline step with name {node1} does not exist. Please provide a valid step name."
|
560
|
+
)
|
561
|
+
if node2 not in stepname_to_step_map:
|
562
|
+
raise ValueError(
|
563
|
+
f"Pipeline step with name {node2} does not exist. Please provide a valid step name."
|
564
|
+
)
|
565
|
+
|
566
|
+
dag_mapping[node2].append(node1)
|
567
|
+
|
568
|
+
for node, prev_list in dag_mapping.items():
|
569
|
+
node_list = [stepname_to_step_map[x] for x in prev_list]
|
570
|
+
stepname_to_step_map[node]._with_depends_on(node_list)
|
571
|
+
updated_step_details.append(stepname_to_step_map[node])
|
572
|
+
|
573
|
+
return updated_step_details
|
574
|
+
|
575
|
+
@property
|
576
|
+
def log_group_id(self) -> str:
|
577
|
+
"""The log group id of the pipeline.
|
578
|
+
|
579
|
+
Returns
|
580
|
+
-------
|
581
|
+
str:
|
582
|
+
The log group id of the pipeline.
|
583
|
+
"""
|
584
|
+
return self.get_spec(self.CONST_LOG_GROUP_ID)
|
585
|
+
|
586
|
+
def with_log_group_id(self, log_group_id: str) -> "Pipeline":
|
587
|
+
"""Sets the log group id of the pipeline.
|
588
|
+
|
589
|
+
Parameters
|
590
|
+
----------
|
591
|
+
log_group_id: str
|
592
|
+
The log group id of the pipeline.
|
593
|
+
|
594
|
+
Returns
|
595
|
+
-------
|
596
|
+
Pipeline
|
597
|
+
The Pipeline instance (self).
|
598
|
+
"""
|
599
|
+
return self.set_spec(self.CONST_LOG_GROUP_ID, log_group_id)
|
600
|
+
|
601
|
+
@property
|
602
|
+
def log_id(self) -> str:
|
603
|
+
"""The log id of the pipeline.
|
604
|
+
|
605
|
+
Returns
|
606
|
+
-------
|
607
|
+
str:
|
608
|
+
The log id of the pipeline.
|
609
|
+
"""
|
610
|
+
return self.get_spec(self.CONST_LOG_ID)
|
611
|
+
|
612
|
+
def with_log_id(self, log_id: str) -> "Pipeline":
|
613
|
+
"""Sets the log id of the pipeline.
|
614
|
+
|
615
|
+
Parameters
|
616
|
+
----------
|
617
|
+
log_id: str
|
618
|
+
The log id of the pipeline.
|
619
|
+
|
620
|
+
Returns
|
621
|
+
-------
|
622
|
+
Pipeline
|
623
|
+
The Pipeline instance (self).
|
624
|
+
"""
|
625
|
+
return self.set_spec(self.CONST_LOG_ID, log_id)
|
626
|
+
|
627
|
+
@property
|
628
|
+
def project_id(self) -> str:
|
629
|
+
"""The project id of the pipeline.
|
630
|
+
|
631
|
+
Returns
|
632
|
+
-------
|
633
|
+
str:
|
634
|
+
The project id of the pipeline.
|
635
|
+
"""
|
636
|
+
return self.get_spec(self.CONST_PROJECT_ID)
|
637
|
+
|
638
|
+
def with_project_id(self, project_id: str) -> "Pipeline":
|
639
|
+
"""Sets the project id of the pipeline.
|
640
|
+
|
641
|
+
Parameters
|
642
|
+
----------
|
643
|
+
project_id: str
|
644
|
+
The project id of the pipeline.
|
645
|
+
|
646
|
+
Returns
|
647
|
+
-------
|
648
|
+
Pipeline
|
649
|
+
The Pipeline instance (self).
|
650
|
+
"""
|
651
|
+
return self.set_spec(self.CONST_PROJECT_ID, project_id)
|
652
|
+
|
653
|
+
@property
|
654
|
+
def compartment_id(self) -> str:
|
655
|
+
"""The compartment id of the pipeline.
|
656
|
+
|
657
|
+
Returns
|
658
|
+
-------
|
659
|
+
str:
|
660
|
+
The compartment id of the pipeline.
|
661
|
+
"""
|
662
|
+
return self.get_spec(self.CONST_COMPARTMENT_ID)
|
663
|
+
|
664
|
+
def with_compartment_id(self, compartment_id: str) -> "Pipeline":
|
665
|
+
"""Sets the compartment id of the pipeline.
|
666
|
+
|
667
|
+
Parameters
|
668
|
+
----------
|
669
|
+
compartment_id: str
|
670
|
+
The compartment id of the pipeline.
|
671
|
+
|
672
|
+
Returns
|
673
|
+
-------
|
674
|
+
Pipeline
|
675
|
+
The Pipeline instance (self).
|
676
|
+
"""
|
677
|
+
return self.set_spec(self.CONST_COMPARTMENT_ID, compartment_id)
|
678
|
+
|
679
|
+
@property
|
680
|
+
def created_by(self) -> str:
|
681
|
+
"""The id that creates the pipeline.
|
682
|
+
|
683
|
+
Returns
|
684
|
+
-------
|
685
|
+
str:
|
686
|
+
The id that creates the pipeline.
|
687
|
+
"""
|
688
|
+
return self.get_spec(self.CONST_CREATED_BY)
|
689
|
+
|
690
|
+
def with_created_by(self, created_by: str) -> "Pipeline":
|
691
|
+
"""Sets the id that creates the pipeline.
|
692
|
+
|
693
|
+
Parameters
|
694
|
+
----------
|
695
|
+
created_by: str
|
696
|
+
The id that creates the pipeline.
|
697
|
+
|
698
|
+
Returns
|
699
|
+
-------
|
700
|
+
Pipeline
|
701
|
+
The Pipeline instance (self).
|
702
|
+
"""
|
703
|
+
return self.set_spec(self.CONST_CREATED_BY, created_by)
|
704
|
+
|
705
|
+
@property
|
706
|
+
def description(self) -> str:
|
707
|
+
"""The description of pipeline.
|
708
|
+
|
709
|
+
Returns
|
710
|
+
-------
|
711
|
+
str:
|
712
|
+
The description of pipeline.
|
713
|
+
"""
|
714
|
+
return self.get_spec(self.CONST_DESCRIPTION)
|
715
|
+
|
716
|
+
def with_description(self, description: str) -> "Pipeline":
|
717
|
+
"""Sets the description of the pipeline.
|
718
|
+
|
719
|
+
Parameters
|
720
|
+
----------
|
721
|
+
description: str
|
722
|
+
The description of the pipeline.
|
723
|
+
|
724
|
+
Returns
|
725
|
+
-------
|
726
|
+
Pipeline
|
727
|
+
The Pipeline instance (self).
|
728
|
+
"""
|
729
|
+
return self.set_spec(self.CONST_DESCRIPTION, description)
|
730
|
+
|
731
|
+
@property
|
732
|
+
def environment_variable(self) -> dict:
|
733
|
+
"""The environment variables of the pipeline.
|
734
|
+
|
735
|
+
Returns
|
736
|
+
-------
|
737
|
+
dict:
|
738
|
+
The environment variables of the pipeline.
|
739
|
+
"""
|
740
|
+
return self.get_spec(self.CONST_ENVIRONMENT_VARIABLES)
|
741
|
+
|
742
|
+
def with_environment_variable(self, **kwargs) -> "Pipeline":
|
743
|
+
"""Sets environment variables of the pipeline.
|
744
|
+
|
745
|
+
Parameters
|
746
|
+
----------
|
747
|
+
kwargs:
|
748
|
+
Keyword arguments.
|
749
|
+
To add a keyword argument without value, set the value to None.
|
750
|
+
|
751
|
+
Returns
|
752
|
+
-------
|
753
|
+
Pipeline
|
754
|
+
The Pipeline instance (self).
|
755
|
+
"""
|
756
|
+
if kwargs:
|
757
|
+
environment_variable_dict = {}
|
758
|
+
for k, v in kwargs.items():
|
759
|
+
environment_variable_dict[k] = v
|
760
|
+
self.set_spec(self.CONST_ENVIRONMENT_VARIABLES, environment_variable_dict)
|
761
|
+
return self
|
762
|
+
|
763
|
+
@property
|
764
|
+
def argument(self) -> str:
|
765
|
+
"""The command line arguments of the pipeline.
|
766
|
+
|
767
|
+
Returns
|
768
|
+
-------
|
769
|
+
str:
|
770
|
+
The command line arguments of the pipeline.
|
771
|
+
"""
|
772
|
+
return self.get_spec(self.CONST_COMMAND_LINE_ARGUMENTS)
|
773
|
+
|
774
|
+
def with_argument(self, *args, **kwargs) -> "Pipeline":
|
775
|
+
"""Adds command line arguments to the pipeline.
|
776
|
+
Existing arguments will be preserved.
|
777
|
+
This method can be called (chained) multiple times to add various arguments.
|
778
|
+
For example, pipeline.with_argument(key="val").with_argument("path/to/file")
|
779
|
+
will result in: "--key val path/to/file"
|
780
|
+
|
781
|
+
Parameters
|
782
|
+
----------
|
783
|
+
args:
|
784
|
+
Positional arguments.
|
785
|
+
In a single method call, positional arguments are always added before keyword arguments.
|
786
|
+
You can call with_argument() to add positional arguments after keyword arguments.
|
787
|
+
|
788
|
+
kwargs:
|
789
|
+
Keyword arguments.
|
790
|
+
To add a keyword argument without value, set the value to None.
|
791
|
+
|
792
|
+
Returns
|
793
|
+
-------
|
794
|
+
Pipeline
|
795
|
+
The Pipeline instance (self).
|
796
|
+
|
797
|
+
Raises
|
798
|
+
------
|
799
|
+
ValueError
|
800
|
+
Keyword arguments with space in a key.
|
801
|
+
"""
|
802
|
+
arg_values = self.get_spec(self.CONST_COMMAND_LINE_ARGUMENTS, [])
|
803
|
+
args = [str(arg) for arg in args]
|
804
|
+
arg_values.extend(args)
|
805
|
+
for k, v in kwargs.items():
|
806
|
+
if " " in k:
|
807
|
+
raise ValueError("Argument key %s cannot contain space.", str(k))
|
808
|
+
arg_values.append(f"--{str(k)}")
|
809
|
+
# Ignore None value
|
810
|
+
if v is None:
|
811
|
+
continue
|
812
|
+
arg_values.append(str(v))
|
813
|
+
arg_string = " ".join(arg_values)
|
814
|
+
self.set_spec(self.CONST_COMMAND_LINE_ARGUMENTS, arg_string)
|
815
|
+
return self
|
816
|
+
|
817
|
+
@property
|
818
|
+
def maximum_runtime_in_minutes(self) -> int:
|
819
|
+
"""The maximum runtime in minutes of the pipeline.
|
820
|
+
|
821
|
+
Returns
|
822
|
+
-------
|
823
|
+
int:
|
824
|
+
The maximum runtime minutes of the pipeline.
|
825
|
+
"""
|
826
|
+
return self.get_spec(self.CONST_MAXIMUM_RUNTIME_IN_MINUTES)
|
827
|
+
|
828
|
+
def with_maximum_runtime_in_minutes(
|
829
|
+
self, maximum_runtime_in_minutes: int
|
830
|
+
) -> "Pipeline":
|
831
|
+
"""Sets the maximum runtime in minutes of the pipeline.
|
832
|
+
|
833
|
+
Parameters
|
834
|
+
----------
|
835
|
+
maximum_runtime_in_minutes: int
|
836
|
+
The maximum_runtime_in_minutes of the pipeline.
|
837
|
+
|
838
|
+
Returns
|
839
|
+
-------
|
840
|
+
Pipeline
|
841
|
+
The Pipeline instance (self).
|
842
|
+
"""
|
843
|
+
return self.set_spec(
|
844
|
+
self.CONST_MAXIMUM_RUNTIME_IN_MINUTES, maximum_runtime_in_minutes
|
845
|
+
)
|
846
|
+
|
847
|
+
def with_freeform_tags(self, freeform_tags: Dict) -> "Pipeline":
|
848
|
+
"""Sets freeform tags of the pipeline.
|
849
|
+
|
850
|
+
Parameters
|
851
|
+
----------
|
852
|
+
freeform_tags: dict
|
853
|
+
The freeform tags dictionary.
|
854
|
+
|
855
|
+
Returns
|
856
|
+
-------
|
857
|
+
Pipeline
|
858
|
+
The Pipeline instance (self).
|
859
|
+
"""
|
860
|
+
return self.set_spec(self.CONST_FREEFROM_TAGS, freeform_tags)
|
861
|
+
|
862
|
+
def with_defined_tags(self, defined_tags: Dict) -> "Pipeline":
|
863
|
+
"""Sets defined tags of the pipeline.
|
864
|
+
|
865
|
+
Parameters
|
866
|
+
----------
|
867
|
+
defined_tags: dict
|
868
|
+
The defined tags dictionary.
|
869
|
+
|
870
|
+
Returns
|
871
|
+
-------
|
872
|
+
Pipeline
|
873
|
+
The Pipeline instance (self).
|
874
|
+
"""
|
875
|
+
return self.set_spec(self.CONST_DEFINED_TAGS, defined_tags)
|
876
|
+
|
877
|
+
@property
|
878
|
+
def shape_name(self) -> str:
|
879
|
+
"""The shape name of pipeline infrastructure.
|
880
|
+
|
881
|
+
Returns
|
882
|
+
-------
|
883
|
+
str:
|
884
|
+
The shape name of the pipeline infrastructure.
|
885
|
+
"""
|
886
|
+
return self.get_spec(self.CONST_SHAPE_NAME)
|
887
|
+
|
888
|
+
def with_shape_name(self, shape_name: str) -> "Pipeline":
|
889
|
+
"""Sets the shape name of pipeline infrastructure.
|
890
|
+
|
891
|
+
Parameters
|
892
|
+
----------
|
893
|
+
shape_name: str
|
894
|
+
The shape name of the pipeline infrastructure.
|
895
|
+
|
896
|
+
Returns
|
897
|
+
-------
|
898
|
+
Pipeline
|
899
|
+
The Pipeline instance (self).
|
900
|
+
"""
|
901
|
+
return self.set_spec(self.CONST_SHAPE_NAME, shape_name)
|
902
|
+
|
903
|
+
@property
|
904
|
+
def block_storage_size_in_gbs(self) -> int:
|
905
|
+
"""The block storage size of pipeline infrastructure.
|
906
|
+
|
907
|
+
Returns
|
908
|
+
-------
|
909
|
+
int:
|
910
|
+
The block storage size of the pipeline infrastructure.
|
911
|
+
"""
|
912
|
+
return self.get_spec(self.CONST_BLOCK_STORAGE_SIZE)
|
913
|
+
|
914
|
+
def with_block_storage_size_in_gbs(
|
915
|
+
self, block_storage_size_in_gbs: int
|
916
|
+
) -> "Pipeline":
|
917
|
+
"""Sets the block storage size of pipeline infrastructure.
|
918
|
+
|
919
|
+
Parameters
|
920
|
+
----------
|
921
|
+
block_storage_size_in_gbs: int
|
922
|
+
The block storage size of pipeline infrastructure.
|
923
|
+
|
924
|
+
Returns
|
925
|
+
-------
|
926
|
+
Pipeline
|
927
|
+
The Pipeline instance (self).
|
928
|
+
"""
|
929
|
+
return self.set_spec(self.CONST_BLOCK_STORAGE_SIZE, block_storage_size_in_gbs)
|
930
|
+
|
931
|
+
@property
|
932
|
+
def shape_config_details(self) -> dict:
|
933
|
+
"""The shape config details of pipeline infrastructure.
|
934
|
+
|
935
|
+
Returns
|
936
|
+
-------
|
937
|
+
dict:
|
938
|
+
The shape config details of the pipeline infrastructure.
|
939
|
+
"""
|
940
|
+
return self.get_spec(self.CONST_SHAPE_CONFIG_DETAILS)
|
941
|
+
|
942
|
+
def with_shape_config_details(
|
943
|
+
self, memory_in_gbs: float, ocpus: float, **kwargs: Dict[str, Any]
|
944
|
+
) -> "Pipeline":
|
945
|
+
"""
|
946
|
+
Sets the shape config details of pipeline infrastructure.
|
947
|
+
Specify only when a flex shape is selected.
|
948
|
+
For example `VM.Standard.E3.Flex` allows the memory_in_gbs and cpu count to be specified.
|
949
|
+
|
950
|
+
Parameters
|
951
|
+
----------
|
952
|
+
memory_in_gbs: float
|
953
|
+
The size of the memory in GBs.
|
954
|
+
ocpus: float
|
955
|
+
The OCPUs count.
|
956
|
+
kwargs
|
957
|
+
Additional keyword arguments.
|
958
|
+
|
959
|
+
Returns
|
960
|
+
-------
|
961
|
+
Pipeline
|
962
|
+
The Pipeline instance (self).
|
963
|
+
"""
|
964
|
+
return self.set_spec(
|
965
|
+
self.CONST_SHAPE_CONFIG_DETAILS,
|
966
|
+
{
|
967
|
+
self.CONST_OCPUS: ocpus,
|
968
|
+
self.CONST_MEMORY_IN_GBS: memory_in_gbs,
|
969
|
+
**kwargs,
|
970
|
+
},
|
971
|
+
)
|
972
|
+
|
973
|
+
@property
|
974
|
+
def enable_service_log(self) -> bool:
|
975
|
+
"""Enables service log of pipeline.
|
976
|
+
|
977
|
+
Returns
|
978
|
+
-------
|
979
|
+
bool:
|
980
|
+
The bool value to enable service log of pipeline.
|
981
|
+
"""
|
982
|
+
return self.get_spec(self.CONST_ENABLE_SERVICE_LOG)
|
983
|
+
|
984
|
+
def with_enable_service_log(self, enable_service_log: bool) -> "Pipeline":
|
985
|
+
"""Sets the bool value to enable the service log of pipeline.
|
986
|
+
|
987
|
+
Parameters
|
988
|
+
----------
|
989
|
+
enable_service_log: bool
|
990
|
+
The value to enable the service log of pipeline.
|
991
|
+
|
992
|
+
Returns
|
993
|
+
-------
|
994
|
+
Pipeline
|
995
|
+
The Pipeline instance (self).
|
996
|
+
"""
|
997
|
+
return self.set_spec(self.CONST_ENABLE_SERVICE_LOG, enable_service_log)
|
998
|
+
|
999
|
+
@property
|
1000
|
+
def service_log_id(self) -> str:
|
1001
|
+
"""The service log id of pipeline.
|
1002
|
+
|
1003
|
+
Returns
|
1004
|
+
-------
|
1005
|
+
str:
|
1006
|
+
The service log id of pipeline.
|
1007
|
+
"""
|
1008
|
+
return self.get_spec(self.CONST_SERVICE_LOG_ID)
|
1009
|
+
|
1010
|
+
def to_dict(self, **kwargs) -> dict:
|
1011
|
+
"""Serializes the pipeline specifications to a dictionary.
|
1012
|
+
|
1013
|
+
Returns
|
1014
|
+
-------
|
1015
|
+
dict
|
1016
|
+
A dictionary containing pipeline specifications.
|
1017
|
+
"""
|
1018
|
+
dict_details = copy.deepcopy(super().to_dict(**kwargs))
|
1019
|
+
dict_details["spec"][self.CONST_DAG] = self.get_spec(self.CONST_DAG)
|
1020
|
+
|
1021
|
+
step_details_list = []
|
1022
|
+
if self.step_details:
|
1023
|
+
for step in self.step_details:
|
1024
|
+
if isinstance(step, PipelineStep):
|
1025
|
+
step = step.to_dict()
|
1026
|
+
|
1027
|
+
if not isinstance(step, dict):
|
1028
|
+
raise TypeError("Pipeline step is not a valid type")
|
1029
|
+
step_dict = copy.deepcopy(step)
|
1030
|
+
step_dict["spec"].pop("dependsOn", None)
|
1031
|
+
step_details_list.append(step_dict)
|
1032
|
+
|
1033
|
+
dict_details["spec"][self.CONST_STEP_DETAILS] = step_details_list
|
1034
|
+
return dict_details
|
1035
|
+
|
1036
|
+
@classmethod
|
1037
|
+
def from_dict(cls, obj_dict: dict):
|
1038
|
+
"""Initializes the object from a dictionary."""
|
1039
|
+
temp_obj_dict = copy.deepcopy(obj_dict)
|
1040
|
+
step_mapping = {}
|
1041
|
+
for step in temp_obj_dict["spec"][cls.CONST_STEP_DETAILS]:
|
1042
|
+
pipeline_step = PipelineStep.from_dict(step)
|
1043
|
+
step_mapping[pipeline_step.name] = pipeline_step
|
1044
|
+
|
1045
|
+
if cls.CONST_DAG not in temp_obj_dict["spec"]:
|
1046
|
+
temp_obj_dict["spec"][cls.CONST_DAG] = None
|
1047
|
+
|
1048
|
+
step_details = Pipeline._add_dag_to_node(
|
1049
|
+
temp_obj_dict["spec"][cls.CONST_DAG], step_mapping
|
1050
|
+
)
|
1051
|
+
temp_obj_dict["spec"][cls.CONST_STEP_DETAILS] = step_details
|
1052
|
+
|
1053
|
+
return cls(spec=temp_obj_dict["spec"])
|
1054
|
+
|
1055
|
+
def create(self, delete_if_fail: bool = True) -> "Pipeline":
|
1056
|
+
"""Creates an ADS pipeline.
|
1057
|
+
|
1058
|
+
Returns
|
1059
|
+
-------
|
1060
|
+
Pipeline:
|
1061
|
+
The ADS Pipeline instance.
|
1062
|
+
"""
|
1063
|
+
pipeline_details = self.__pipeline_details()
|
1064
|
+
self.data_science_pipeline = DataSciencePipeline(**pipeline_details).create(
|
1065
|
+
self.step_details, delete_if_fail
|
1066
|
+
)
|
1067
|
+
self.set_spec(self.CONST_ID, self.data_science_pipeline.id)
|
1068
|
+
if self.enable_service_log and not self.service_log_id:
|
1069
|
+
try:
|
1070
|
+
self.__create_service_log()
|
1071
|
+
except Exception as ex:
|
1072
|
+
logger.warning("Failed to create service log: %s", str(ex))
|
1073
|
+
return self
|
1074
|
+
|
1075
|
+
def _show(self) -> PipelineVisualizer:
|
1076
|
+
"""
|
1077
|
+
Prepeares `PipelineVisualizer` instance to render a graph.
|
1078
|
+
|
1079
|
+
Returns
|
1080
|
+
-------
|
1081
|
+
PipelineVisualizer
|
1082
|
+
"""
|
1083
|
+
return (
|
1084
|
+
PipelineVisualizer()
|
1085
|
+
.with_renderer(PipelineGraphRenderer(show_status=False))
|
1086
|
+
.with_pipeline(self)
|
1087
|
+
)
|
1088
|
+
|
1089
|
+
def show(self, rankdir: str = GraphOrientation.TOP_BOTTOM) -> None:
|
1090
|
+
"""
|
1091
|
+
Render pipeline with step information in a graph
|
1092
|
+
|
1093
|
+
Returns
|
1094
|
+
-------
|
1095
|
+
None
|
1096
|
+
"""
|
1097
|
+
self._show().render(rankdir=rankdir)
|
1098
|
+
|
1099
|
+
def to_svg(
|
1100
|
+
self, uri: str = None, rankdir: str = GraphOrientation.TOP_BOTTOM, **kwargs
|
1101
|
+
) -> str:
|
1102
|
+
"""
|
1103
|
+
Renders pipeline as graph in svg string.
|
1104
|
+
|
1105
|
+
Parameters
|
1106
|
+
----------
|
1107
|
+
uri: (string, optional). Defaults to None.
|
1108
|
+
URI location to save the SVG string.
|
1109
|
+
rankdir: str, default to "TB".
|
1110
|
+
Direction of the rendered graph; allowed Values are {"TB", "LR"}.
|
1111
|
+
|
1112
|
+
Returns
|
1113
|
+
-------
|
1114
|
+
str
|
1115
|
+
Graph in svg format.
|
1116
|
+
"""
|
1117
|
+
return self._show().to_svg(uri=uri, rankdir=rankdir, **kwargs)
|
1118
|
+
|
1119
|
+
def run(
|
1120
|
+
self,
|
1121
|
+
display_name: Optional[str] = None,
|
1122
|
+
project_id: Optional[str] = None,
|
1123
|
+
compartment_id: Optional[str] = None,
|
1124
|
+
configuration_override_details: Optional[dict] = None,
|
1125
|
+
log_configuration_override_details: Optional[dict] = None,
|
1126
|
+
step_override_details: Optional[list] = None,
|
1127
|
+
free_form_tags: Optional[dict] = None,
|
1128
|
+
defined_tags: Optional[dict] = None,
|
1129
|
+
system_tags: Optional[dict] = None,
|
1130
|
+
) -> "PipelineRun":
|
1131
|
+
"""Creates an ADS pipeline run.
|
1132
|
+
|
1133
|
+
Parameters
|
1134
|
+
----------
|
1135
|
+
display_name: str, optional
|
1136
|
+
The display name to override the one defined previously. Defaults to None.
|
1137
|
+
|
1138
|
+
project_id: str, optional
|
1139
|
+
The project id to override the one defined previously. Defaults to None.
|
1140
|
+
|
1141
|
+
compartment_id: str, optional
|
1142
|
+
The compartment id to override the one defined previously. Defaults to None.
|
1143
|
+
|
1144
|
+
configuration_override_details: dict, optional
|
1145
|
+
The configuration details dictionary to override the one defined previously.
|
1146
|
+
Defaults to None.
|
1147
|
+
The configuration_override_details contains the following keys:
|
1148
|
+
* "type": str, only "DEFAULT" is allowed.
|
1149
|
+
* "environment_variables": dict, optional, the environment variables
|
1150
|
+
* "command_line_arguments": str, optional, the command line arguments
|
1151
|
+
* "maximum_runtime_in_minutes": int, optional, the maximum runtime allowed in minutes
|
1152
|
+
|
1153
|
+
log_configuration_override_details: dict(str, str), optional
|
1154
|
+
The log configuration details dictionary to override the one defined previously.
|
1155
|
+
Defaults to None.
|
1156
|
+
The log_configuration_override_details contains the following keys:
|
1157
|
+
* "log_group_id": str, optional, the log group id
|
1158
|
+
* "log_id": str, optional, the log id
|
1159
|
+
|
1160
|
+
step_override_details: list[PipelineStepOverrideDetails], optional
|
1161
|
+
The step details list to override the one defined previously.
|
1162
|
+
Defaults to None.
|
1163
|
+
The PipelineStepOverrideDetails is a dict which contains the following keys:
|
1164
|
+
* step_name: str, the name of step to override
|
1165
|
+
* step_configuration_details: dict, which contains:
|
1166
|
+
* "maximum_runtime_in_minutes": int, optional
|
1167
|
+
* "environment_variables": dict, optional
|
1168
|
+
* "command_line_arguments": str, optional
|
1169
|
+
|
1170
|
+
free_form_tags: dict(str, str), optional
|
1171
|
+
The free from tags dictionary to override the one defined previously.
|
1172
|
+
Defaults to None.
|
1173
|
+
|
1174
|
+
defined_tags: dict(str, dict(str, object)), optional
|
1175
|
+
The defined tags dictionary to override the one defined previously.
|
1176
|
+
Defaults to None.
|
1177
|
+
|
1178
|
+
system_tags: dict(str, dict(str, object)), optional
|
1179
|
+
The system tags dictionary to override the one defined previously.
|
1180
|
+
Defaults to None.
|
1181
|
+
|
1182
|
+
Example
|
1183
|
+
--------
|
1184
|
+
.. code-block:: python
|
1185
|
+
|
1186
|
+
# Creates a pipeline run using pipeline configurations
|
1187
|
+
pipeline.run()
|
1188
|
+
|
1189
|
+
# Creates a pipeline run by overriding pipeline configurations
|
1190
|
+
pipeline.run(
|
1191
|
+
display_name="OverrideDisplayName",
|
1192
|
+
configuration_override_details={
|
1193
|
+
"maximum_runtime_in_minutes":30,
|
1194
|
+
"type":"DEFAULT",
|
1195
|
+
"environment_variables": {
|
1196
|
+
"key": "value"
|
1197
|
+
},
|
1198
|
+
"command_line_arguments": "ARGUMENT --KEY VALUE",
|
1199
|
+
},
|
1200
|
+
log_configuration_override_details={
|
1201
|
+
"log_group_id": "<log_group_id>"
|
1202
|
+
},
|
1203
|
+
step_override_details=[{
|
1204
|
+
"step_name" : "<step_name>",
|
1205
|
+
"step_configuration_details" : {
|
1206
|
+
"maximum_runtime_in_minutes": 200,
|
1207
|
+
"environment_variables": {
|
1208
|
+
"1":"2"
|
1209
|
+
},
|
1210
|
+
"command_line_arguments": "argument --key value",
|
1211
|
+
}
|
1212
|
+
}]
|
1213
|
+
)
|
1214
|
+
|
1215
|
+
Returns
|
1216
|
+
-------
|
1217
|
+
PipelineRun:
|
1218
|
+
The ADS PipelineRun instance.
|
1219
|
+
"""
|
1220
|
+
pipeline_details = self.__pipeline_details()
|
1221
|
+
self.__override_configurations(
|
1222
|
+
pipeline_details,
|
1223
|
+
display_name,
|
1224
|
+
project_id,
|
1225
|
+
compartment_id,
|
1226
|
+
configuration_override_details,
|
1227
|
+
log_configuration_override_details,
|
1228
|
+
step_override_details,
|
1229
|
+
free_form_tags,
|
1230
|
+
defined_tags,
|
1231
|
+
system_tags,
|
1232
|
+
)
|
1233
|
+
if not self.data_science_pipeline:
|
1234
|
+
self.data_science_pipeline = DataSciencePipeline(**pipeline_details)
|
1235
|
+
|
1236
|
+
if self.enable_service_log:
|
1237
|
+
return self.data_science_pipeline.run(
|
1238
|
+
pipeline_details, self.service_logging
|
1239
|
+
)
|
1240
|
+
|
1241
|
+
return self.data_science_pipeline.run(pipeline_details)
|
1242
|
+
|
1243
|
+
def delete(
|
1244
|
+
self,
|
1245
|
+
delete_related_pipeline_runs: Optional[bool] = True,
|
1246
|
+
delete_related_job_runs: Optional[bool] = True,
|
1247
|
+
max_wait_seconds: Optional[int] = MAXIMUM_TIMEOUT,
|
1248
|
+
**kwargs,
|
1249
|
+
) -> "Pipeline":
|
1250
|
+
"""Deteles an ADS pipeline.
|
1251
|
+
|
1252
|
+
Parameters
|
1253
|
+
----------
|
1254
|
+
delete_related_pipeline_runs: bool, optional
|
1255
|
+
Specify whether to delete related PipelineRuns or not. Defaults to True.
|
1256
|
+
delete_related_job_runs: bool, optional
|
1257
|
+
Specify whether to delete related JobRuns or not. Defaults to True.
|
1258
|
+
max_wait_seconds: int, optional
|
1259
|
+
The maximum time to wait, in seconds. Defaults to 1800.
|
1260
|
+
|
1261
|
+
kwargs: optional
|
1262
|
+
The kwargs to be executed when deleting the pipeline.
|
1263
|
+
The allowed keys are:
|
1264
|
+
* "allow_control_chars": bool, to indicate whether or not this request should
|
1265
|
+
allow control characters in the response object. By default, the response will
|
1266
|
+
not allow control characters in strings.
|
1267
|
+
* "retry_strategy": obj, to apply to this specific operation/call. This will
|
1268
|
+
override any retry strategy set at the client-level. This should be one of the
|
1269
|
+
strategies available in the :py:mod:`~oci.retry` module. This operation will not
|
1270
|
+
retry by default, users can also use the convenient :py:data:`~oci.retry.DEFAULT_RETRY_STRATEGY`
|
1271
|
+
provided by the SDK to enable retries for it. The specifics of the default retry
|
1272
|
+
strategy are described `here <https://docs.oracle.com/en-us/iaas/tools/python/latest/sdk_behaviors/retries.html>`__.
|
1273
|
+
To have this operation explicitly not perform any retries, pass an instance of :py:class:`~oci.retry.NoneRetryStrategy`.
|
1274
|
+
* "if_match": str, for optimistic concurrency control. In the PUT or DELETE call
|
1275
|
+
for a resource, set the `if-match` parameter to the value of the etag from a
|
1276
|
+
previous GET or POST response for that resource. The resource is updated or
|
1277
|
+
deleted only if the `etag` you provide matches the resource's current `etag` value.
|
1278
|
+
* "opc_request_id": str, unique Oracle assigned identifier for the request.
|
1279
|
+
If you need to contact Oracle about a particular request, then provide the request ID.
|
1280
|
+
* "max_interval_seconds": int, the maximum interval between queries, in seconds.
|
1281
|
+
* "succeed_on_not_found": bool, to determine whether or not the waiter should
|
1282
|
+
return successfully if the data we're waiting on is not found
|
1283
|
+
(e.g. a 404 is returned from the service). This defaults to False and so a 404 would
|
1284
|
+
cause an exception to be thrown by this function. Setting it to True may be useful in
|
1285
|
+
scenarios when waiting for a resource to be terminated/deleted since it is possible that
|
1286
|
+
the resource would not be returned by the a GET call anymore.
|
1287
|
+
* "wait_callback": A function which will be called each time that we have to do an initial
|
1288
|
+
wait (i.e. because the property of the resource was not in the correct state,
|
1289
|
+
or the ``evaluate_response`` function returned False). This function should take two
|
1290
|
+
arguments - the first argument is the number of times we have checked the resource,
|
1291
|
+
and the second argument is the result of the most recent check.
|
1292
|
+
* "fetch_func": A function to be called to fetch the updated state from the server.
|
1293
|
+
This can be used if the call to check for state needs to be more complex than a single
|
1294
|
+
GET request. For example, if the goal is to wait until an item appears in a list,
|
1295
|
+
fetch_func can be a function that paginates through a full list on the server.
|
1296
|
+
|
1297
|
+
Returns
|
1298
|
+
-------
|
1299
|
+
Pipeline:
|
1300
|
+
The ADS Pipeline instance.
|
1301
|
+
"""
|
1302
|
+
if not self.data_science_pipeline:
|
1303
|
+
self.data_science_pipeline = DataSciencePipeline()
|
1304
|
+
|
1305
|
+
operation_kwargs = {
|
1306
|
+
"delete_related_pipeline_runs": delete_related_pipeline_runs,
|
1307
|
+
"delete_related_job_runs": delete_related_job_runs,
|
1308
|
+
}
|
1309
|
+
waiter_kwargs = {"max_wait_seconds": max_wait_seconds}
|
1310
|
+
for key, value in kwargs.items():
|
1311
|
+
if key in ALLOWED_OPERATION_KWARGS:
|
1312
|
+
operation_kwargs[key] = value
|
1313
|
+
elif key in ALLOWED_WAITER_KWARGS:
|
1314
|
+
waiter_kwargs[key] = value
|
1315
|
+
|
1316
|
+
self.data_science_pipeline.delete(
|
1317
|
+
id=self.id, operation_kwargs=operation_kwargs, waiter_kwargs=waiter_kwargs
|
1318
|
+
)
|
1319
|
+
return self
|
1320
|
+
|
1321
|
+
def download(
|
1322
|
+
self, to_dir: str, override_if_exists: Optional[bool] = False
|
1323
|
+
) -> "Pipeline":
|
1324
|
+
"""Downloads artifacts from pipeline.
|
1325
|
+
|
1326
|
+
Parameters
|
1327
|
+
----------
|
1328
|
+
to_dir : str
|
1329
|
+
Local directory to which the artifacts will be downloaded to.
|
1330
|
+
override_if_exists: bool, optional
|
1331
|
+
Bool to decide whether to override existing folder/file or not. Defaults to False.
|
1332
|
+
|
1333
|
+
Returns
|
1334
|
+
-------
|
1335
|
+
Pipeline:
|
1336
|
+
The ADS Pipeline instance.
|
1337
|
+
"""
|
1338
|
+
if not self.data_science_pipeline or not self.id:
|
1339
|
+
print("Pipeline hasn't been created.")
|
1340
|
+
return self
|
1341
|
+
|
1342
|
+
if (
|
1343
|
+
self.data_science_pipeline.sync().lifecycle_state
|
1344
|
+
!= self.LIFECYCLE_STATE_ACTIVE
|
1345
|
+
):
|
1346
|
+
print("Pipeline hasn't been created or not in ACTIVE state.")
|
1347
|
+
return self
|
1348
|
+
|
1349
|
+
pipeline_folder = os.path.join(to_dir, self.id)
|
1350
|
+
if not os.path.exists(pipeline_folder):
|
1351
|
+
print("Creating directory: " + pipeline_folder)
|
1352
|
+
os.mkdir(pipeline_folder)
|
1353
|
+
elif not override_if_exists:
|
1354
|
+
print(
|
1355
|
+
f"Folder {pipeline_folder} already exists. Set override_if_exists to True to override."
|
1356
|
+
)
|
1357
|
+
return self
|
1358
|
+
|
1359
|
+
for step in self.step_details:
|
1360
|
+
if step.kind == "CUSTOM_SCRIPT":
|
1361
|
+
res = self.data_science_pipeline.client.get_step_artifact_content(
|
1362
|
+
self.id, step.name
|
1363
|
+
)
|
1364
|
+
|
1365
|
+
if not res or not res.data or not res.data.raw:
|
1366
|
+
print(f"Failed to download {step.name} artifact.")
|
1367
|
+
return self
|
1368
|
+
|
1369
|
+
content_disposition = res.headers.get("Content-Disposition", "")
|
1370
|
+
artifact_name = str(content_disposition).replace(
|
1371
|
+
"attachment; filename=", ""
|
1372
|
+
)
|
1373
|
+
step_folder = os.path.join(pipeline_folder, step.name)
|
1374
|
+
if not os.path.exists(step_folder):
|
1375
|
+
print("Creating directory: " + step_folder)
|
1376
|
+
os.mkdir(step_folder)
|
1377
|
+
elif not override_if_exists:
|
1378
|
+
print(
|
1379
|
+
f"Folder {step_folder} already exists. Set override_if_exists to True to override."
|
1380
|
+
)
|
1381
|
+
continue
|
1382
|
+
file_name = os.path.join(step_folder, artifact_name)
|
1383
|
+
with open(file_name, "wb") as f:
|
1384
|
+
f.write(res.data.raw.read())
|
1385
|
+
|
1386
|
+
return self
|
1387
|
+
|
1388
|
+
def _populate_step_artifact_content(self):
|
1389
|
+
"""Populates artifact information to CUSTOM_SCRIPT step.
|
1390
|
+
This method is only invoked when the existing pipeline needs to be loaded.
|
1391
|
+
"""
|
1392
|
+
if (
|
1393
|
+
not self.data_science_pipeline
|
1394
|
+
or not self.id
|
1395
|
+
or self.status != self.LIFECYCLE_STATE_ACTIVE
|
1396
|
+
):
|
1397
|
+
return
|
1398
|
+
|
1399
|
+
for step in self.step_details:
|
1400
|
+
if step.kind == "CUSTOM_SCRIPT":
|
1401
|
+
artifact_name = self._artifact_content_map.get(step.name)
|
1402
|
+
if not artifact_name:
|
1403
|
+
res = self.data_science_pipeline.client.get_step_artifact_content(
|
1404
|
+
self.id, step.name
|
1405
|
+
)
|
1406
|
+
content_disposition = res.headers.get("Content-Disposition", "")
|
1407
|
+
artifact_name = str(content_disposition).replace(
|
1408
|
+
"attachment; filename=", ""
|
1409
|
+
)
|
1410
|
+
self._artifact_content_map[step.name] = artifact_name
|
1411
|
+
if isinstance(step.runtime, ScriptRuntime):
|
1412
|
+
step.runtime.with_script(artifact_name)
|
1413
|
+
elif isinstance(step.runtime, PythonRuntime):
|
1414
|
+
step.runtime.with_working_dir(artifact_name)
|
1415
|
+
elif isinstance(step.runtime, NotebookRuntime):
|
1416
|
+
step.runtime.with_notebook(artifact_name)
|
1417
|
+
elif isinstance(step.runtime, GitPythonRuntime):
|
1418
|
+
step.runtime.with_source(artifact_name)
|
1419
|
+
|
1420
|
+
@classmethod
|
1421
|
+
def from_ocid(cls, ocid: str) -> "Pipeline":
|
1422
|
+
"""Creates a pipeline by OCID.
|
1423
|
+
|
1424
|
+
Parameters
|
1425
|
+
----------
|
1426
|
+
ocid: str
|
1427
|
+
The OCID of pipeline.
|
1428
|
+
|
1429
|
+
Returns
|
1430
|
+
-------
|
1431
|
+
Pipeline:
|
1432
|
+
The Pipeline instance.
|
1433
|
+
"""
|
1434
|
+
pipeline = DataSciencePipeline.from_ocid(ocid).build_ads_pipeline()
|
1435
|
+
pipeline._populate_step_artifact_content()
|
1436
|
+
return pipeline
|
1437
|
+
|
1438
|
+
@classmethod
|
1439
|
+
def from_id(cls, id: str) -> "Pipeline":
|
1440
|
+
"""Creates a pipeline by OCID.
|
1441
|
+
|
1442
|
+
Parameters
|
1443
|
+
----------
|
1444
|
+
id: str
|
1445
|
+
The OCID of pipeline.
|
1446
|
+
|
1447
|
+
Returns
|
1448
|
+
-------
|
1449
|
+
Pipeline:
|
1450
|
+
The Pipeline instance.
|
1451
|
+
"""
|
1452
|
+
return cls.from_ocid(id)
|
1453
|
+
|
1454
|
+
def __create_service_log(self) -> "Pipeline":
|
1455
|
+
"""Creates a service log for pipeline.
|
1456
|
+
|
1457
|
+
Returns
|
1458
|
+
-------
|
1459
|
+
Pipeline:
|
1460
|
+
The ADS Pipeline instance.
|
1461
|
+
"""
|
1462
|
+
if not self.log_group_id:
|
1463
|
+
raise ValueError(
|
1464
|
+
"Log group OCID is not specified for this pipeline. Call with_log_group_id to add it."
|
1465
|
+
)
|
1466
|
+
if not self.id:
|
1467
|
+
raise ValueError("Pipeline is not created yet. Call the create method.")
|
1468
|
+
|
1469
|
+
oci_service = oci.logging.models.OciService(
|
1470
|
+
service=self.CONST_SERVICE,
|
1471
|
+
resource=self.id,
|
1472
|
+
category=self.CONST_SERVICE_LOG_CATEGORY,
|
1473
|
+
)
|
1474
|
+
|
1475
|
+
archiving = oci.logging.models.Archiving(is_enabled=False)
|
1476
|
+
|
1477
|
+
configuration = oci.logging.models.Configuration(
|
1478
|
+
source=oci_service, compartment_id=self.compartment_id, archiving=archiving
|
1479
|
+
)
|
1480
|
+
|
1481
|
+
timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M")
|
1482
|
+
service_logging = OCILog(
|
1483
|
+
display_name=self.name + f"-{timestamp}",
|
1484
|
+
log_group_id=self.log_group_id,
|
1485
|
+
log_type="SERVICE",
|
1486
|
+
configuration=configuration,
|
1487
|
+
annotation="service",
|
1488
|
+
).create()
|
1489
|
+
|
1490
|
+
self.__set_service_logging_resource(service_logging)
|
1491
|
+
self.set_spec(self.CONST_SERVICE_LOG_ID, self.service_logging.id)
|
1492
|
+
return self
|
1493
|
+
|
1494
|
+
def __set_service_logging_resource(self, service_logging: OCILog):
|
1495
|
+
"""Sets the service logging for pipeline.
|
1496
|
+
|
1497
|
+
Parameters
|
1498
|
+
----------
|
1499
|
+
service_logging: OCILog
|
1500
|
+
An OCILog instance containing the service logging resources.
|
1501
|
+
"""
|
1502
|
+
self.service_logging = service_logging
|
1503
|
+
|
1504
|
+
def _convert_step_details_to_dag(
|
1505
|
+
self, step_details: List["PipelineStep"] = []
|
1506
|
+
) -> List[str]:
|
1507
|
+
"""Converts step_details to the DAG representation.
|
1508
|
+
|
1509
|
+
Parameters
|
1510
|
+
----------
|
1511
|
+
step_details: list
|
1512
|
+
A list of PipelineStep objects, default to empty list.
|
1513
|
+
|
1514
|
+
Returns
|
1515
|
+
-------
|
1516
|
+
List
|
1517
|
+
A list of str representing step dependencies.
|
1518
|
+
"""
|
1519
|
+
dag_list = []
|
1520
|
+
for step in step_details:
|
1521
|
+
if isinstance(step, PipelineStep):
|
1522
|
+
step = step.to_dict()["spec"]
|
1523
|
+
step_name = step["name"]
|
1524
|
+
else:
|
1525
|
+
step_name = step["stepName"]
|
1526
|
+
|
1527
|
+
if not step["dependsOn"]:
|
1528
|
+
continue
|
1529
|
+
if len(step["dependsOn"]) == 1:
|
1530
|
+
dag = step["dependsOn"][0] + " >> " + step_name
|
1531
|
+
else:
|
1532
|
+
dag = "(" + ", ".join(step["dependsOn"]) + ") >> " + step_name
|
1533
|
+
dag_list.append(dag)
|
1534
|
+
|
1535
|
+
return dag_list
|
1536
|
+
|
1537
|
+
def __pipeline_details(self) -> dict:
|
1538
|
+
"""Converts pipeline attributes to a dictionary.
|
1539
|
+
|
1540
|
+
Returns
|
1541
|
+
-------
|
1542
|
+
dict:
|
1543
|
+
A dictionary that contains pipeline details.
|
1544
|
+
"""
|
1545
|
+
pipeline_details = copy.deepcopy(self._spec)
|
1546
|
+
pipeline_details.pop(self.CONST_ENABLE_SERVICE_LOG, None)
|
1547
|
+
pipeline_details.pop(self.CONST_SERVICE_LOG_ID, None)
|
1548
|
+
pipeline_configuration_details = self.__pipeline_configuration_details(
|
1549
|
+
pipeline_details
|
1550
|
+
)
|
1551
|
+
if pipeline_configuration_details:
|
1552
|
+
pipeline_details[
|
1553
|
+
self.CONST_CONFIGURATION_DETAILS
|
1554
|
+
] = pipeline_configuration_details
|
1555
|
+
|
1556
|
+
pipeline_log_configuration_details = self.__pipeline_log_configuration_details(
|
1557
|
+
pipeline_details
|
1558
|
+
)
|
1559
|
+
if pipeline_log_configuration_details:
|
1560
|
+
pipeline_details[
|
1561
|
+
self.CONST_LOG_CONFIGURATION_DETAILS
|
1562
|
+
] = pipeline_log_configuration_details
|
1563
|
+
|
1564
|
+
pipeline_infrastructure_configuration_details = (
|
1565
|
+
self.__pipeline_infrastructure_configuration_details(pipeline_details)
|
1566
|
+
)
|
1567
|
+
if pipeline_infrastructure_configuration_details:
|
1568
|
+
pipeline_details[
|
1569
|
+
self.CONST_INFRA_CONFIG_DETAILS
|
1570
|
+
] = pipeline_infrastructure_configuration_details
|
1571
|
+
|
1572
|
+
if self.id:
|
1573
|
+
pipeline_details[self.CONST_PIPELINE_ID] = self.id
|
1574
|
+
pipeline_details.pop(self.CONST_ID)
|
1575
|
+
|
1576
|
+
step_details_list = self.__step_details(pipeline_details)
|
1577
|
+
pipeline_details[self.CONST_STEP_DETAILS] = step_details_list
|
1578
|
+
|
1579
|
+
return pipeline_details
|
1580
|
+
|
1581
|
+
def __pipeline_configuration_details(self, pipeline_details: Dict) -> dict:
|
1582
|
+
"""Converts pipeline configuration details to a dictionary.
|
1583
|
+
|
1584
|
+
Parameters
|
1585
|
+
----------
|
1586
|
+
pipeline_details: dict
|
1587
|
+
A dictionary that contains pipeline details.
|
1588
|
+
|
1589
|
+
Returns
|
1590
|
+
-------
|
1591
|
+
dict:
|
1592
|
+
A dictionary that contains pipeline configuration details.
|
1593
|
+
"""
|
1594
|
+
pipeline_configuration_details = {}
|
1595
|
+
if self.maximum_runtime_in_minutes:
|
1596
|
+
pipeline_configuration_details[
|
1597
|
+
self.CONST_MAXIMUM_RUNTIME_IN_MINUTES
|
1598
|
+
] = self.maximum_runtime_in_minutes
|
1599
|
+
pipeline_details.pop(self.CONST_MAXIMUM_RUNTIME_IN_MINUTES)
|
1600
|
+
if self.environment_variable:
|
1601
|
+
pipeline_configuration_details[
|
1602
|
+
self.CONST_ENVIRONMENT_VARIABLES
|
1603
|
+
] = self.environment_variable
|
1604
|
+
pipeline_details.pop(self.CONST_ENVIRONMENT_VARIABLES)
|
1605
|
+
if self.argument:
|
1606
|
+
pipeline_configuration_details[
|
1607
|
+
self.CONST_COMMAND_LINE_ARGUMENTS
|
1608
|
+
] = self.argument
|
1609
|
+
pipeline_details.pop(self.CONST_COMMAND_LINE_ARGUMENTS)
|
1610
|
+
pipeline_configuration_details[self.CONST_TYPE] = "DEFAULT"
|
1611
|
+
return pipeline_configuration_details
|
1612
|
+
|
1613
|
+
def __pipeline_log_configuration_details(self, pipeline_details: Dict) -> dict:
|
1614
|
+
"""Converts pipeline log configuration details to a dictionary.
|
1615
|
+
|
1616
|
+
Parameters
|
1617
|
+
----------
|
1618
|
+
pipeline_details: dict
|
1619
|
+
A dictionary that contains pipeline details.
|
1620
|
+
|
1621
|
+
Returns
|
1622
|
+
-------
|
1623
|
+
dict:
|
1624
|
+
A dictionary that contains pipeline log configuration details.
|
1625
|
+
"""
|
1626
|
+
pipeline_log_configuration_details = {}
|
1627
|
+
if self.log_id:
|
1628
|
+
pipeline_log_configuration_details[self.CONST_LOG_ID] = self.log_id
|
1629
|
+
if not self.log_group_id:
|
1630
|
+
try:
|
1631
|
+
log_obj = OCILog.from_ocid(self.log_id)
|
1632
|
+
except ResourceNotFoundError:
|
1633
|
+
raise ResourceNotFoundError(
|
1634
|
+
f"Unable to determine log group ID for Log ({self.log_id})."
|
1635
|
+
" The log resource may not exist or You may not have the required permission."
|
1636
|
+
" Try to avoid this by specifying the log group ID."
|
1637
|
+
)
|
1638
|
+
self.with_log_group_id(log_obj.log_group_id)
|
1639
|
+
|
1640
|
+
if self.log_group_id:
|
1641
|
+
pipeline_log_configuration_details[
|
1642
|
+
self.CONST_LOG_GROUP_ID
|
1643
|
+
] = self.log_group_id
|
1644
|
+
|
1645
|
+
if self.log_id:
|
1646
|
+
pipeline_log_configuration_details[self.CONST_ENABLE_LOGGING] = True
|
1647
|
+
pipeline_log_configuration_details[
|
1648
|
+
self.CONST_ENABLE_AUTO_LOG_CREATION
|
1649
|
+
] = False
|
1650
|
+
pipeline_details.pop(self.CONST_LOG_ID)
|
1651
|
+
pipeline_details.pop(self.CONST_LOG_GROUP_ID, None)
|
1652
|
+
else:
|
1653
|
+
if self.log_group_id:
|
1654
|
+
pipeline_log_configuration_details[self.CONST_ENABLE_LOGGING] = True
|
1655
|
+
pipeline_log_configuration_details[
|
1656
|
+
self.CONST_ENABLE_AUTO_LOG_CREATION
|
1657
|
+
] = True
|
1658
|
+
pipeline_details.pop(self.CONST_LOG_GROUP_ID)
|
1659
|
+
else:
|
1660
|
+
pipeline_log_configuration_details[self.CONST_ENABLE_LOGGING] = False
|
1661
|
+
pipeline_log_configuration_details[
|
1662
|
+
self.CONST_ENABLE_AUTO_LOG_CREATION
|
1663
|
+
] = False
|
1664
|
+
return pipeline_log_configuration_details
|
1665
|
+
|
1666
|
+
def __pipeline_infrastructure_configuration_details(
|
1667
|
+
self, pipeline_details: Dict
|
1668
|
+
) -> dict:
|
1669
|
+
pipeline_infrastructure_details = {}
|
1670
|
+
if self.shape_name:
|
1671
|
+
pipeline_infrastructure_details[self.CONST_SHAPE_NAME] = self.shape_name
|
1672
|
+
pipeline_details.pop(self.CONST_SHAPE_NAME)
|
1673
|
+
if self.block_storage_size_in_gbs:
|
1674
|
+
pipeline_infrastructure_details[
|
1675
|
+
self.CONST_BLOCK_STORAGE_SIZE
|
1676
|
+
] = self.block_storage_size_in_gbs
|
1677
|
+
pipeline_details.pop(self.CONST_BLOCK_STORAGE_SIZE)
|
1678
|
+
if self.shape_config_details:
|
1679
|
+
pipeline_infrastructure_details[
|
1680
|
+
self.CONST_SHAPE_CONFIG_DETAILS
|
1681
|
+
] = self.shape_config_details
|
1682
|
+
pipeline_details.pop(self.CONST_SHAPE_CONFIG_DETAILS)
|
1683
|
+
|
1684
|
+
return pipeline_infrastructure_details
|
1685
|
+
|
1686
|
+
def __step_details(self, pipeline_details: Dict) -> list:
|
1687
|
+
"""Converts pipeline step details to a dictionary.
|
1688
|
+
|
1689
|
+
Parameters
|
1690
|
+
----------
|
1691
|
+
pipeline_details: dict
|
1692
|
+
A dictionary that contains pipeline details.
|
1693
|
+
|
1694
|
+
Returns
|
1695
|
+
-------
|
1696
|
+
list:
|
1697
|
+
A list that contains pipeline step details.
|
1698
|
+
"""
|
1699
|
+
step_details_list = []
|
1700
|
+
if self.step_details:
|
1701
|
+
for step in self.step_details:
|
1702
|
+
step_details = copy.deepcopy(step._spec)
|
1703
|
+
step_details["stepName"] = step.name
|
1704
|
+
step_details.pop("name", None)
|
1705
|
+
if not step.depends_on:
|
1706
|
+
step_details[step.CONST_DEPENDS_ON] = []
|
1707
|
+
if not step.job_id:
|
1708
|
+
step_infrastructure_configuration_details = (
|
1709
|
+
self.__step_infrastructure_configuration_details(step)
|
1710
|
+
)
|
1711
|
+
step_details[
|
1712
|
+
step.CONST_STEP_INFRA_CONFIG_DETAILS
|
1713
|
+
] = step_infrastructure_configuration_details
|
1714
|
+
step_details.pop(step.CONST_INFRASTRUCTURE, None)
|
1715
|
+
step_details.pop(step.CONST_RUNTIME, None)
|
1716
|
+
|
1717
|
+
step_configuration_details = self.__step_configuration_details(
|
1718
|
+
pipeline_details, step
|
1719
|
+
)
|
1720
|
+
step_details[
|
1721
|
+
step.CONST_STEP_CONFIG_DETAILS
|
1722
|
+
] = step_configuration_details
|
1723
|
+
step_details.pop(self.CONST_MAXIMUM_RUNTIME_IN_MINUTES, None)
|
1724
|
+
step_details.pop(self.CONST_ENVIRONMENT_VARIABLES, None)
|
1725
|
+
step_details.pop(self.CONST_COMMAND_LINE_ARGUMENTS, None)
|
1726
|
+
step_details_list.append(step_details)
|
1727
|
+
return step_details_list
|
1728
|
+
|
1729
|
+
def __step_infrastructure_configuration_details(self, step) -> dict:
|
1730
|
+
step_infrastructure_configuration_details = {}
|
1731
|
+
step_infrastructure_configuration_details[
|
1732
|
+
"blockStorageSizeInGBs"
|
1733
|
+
] = step.infrastructure.block_storage_size
|
1734
|
+
step_infrastructure_configuration_details[
|
1735
|
+
"shapeName"
|
1736
|
+
] = step.infrastructure.shape_name
|
1737
|
+
step_infrastructure_configuration_details[
|
1738
|
+
"shapeConfigDetails"
|
1739
|
+
] = step.infrastructure.shape_config_details
|
1740
|
+
return step_infrastructure_configuration_details
|
1741
|
+
|
1742
|
+
def __step_configuration_details(self, pipeline_details: Dict, step) -> dict:
|
1743
|
+
step_configuration_details = {}
|
1744
|
+
step_configuration_details[self.CONST_TYPE] = "DEFAULT"
|
1745
|
+
if step.runtime:
|
1746
|
+
payload = DataScienceJobRuntimeManager(step.infrastructure).translate(
|
1747
|
+
step.runtime
|
1748
|
+
)
|
1749
|
+
if "job_configuration_details" in payload:
|
1750
|
+
job_configuration_details = payload["job_configuration_details"]
|
1751
|
+
if "environment_variables" in job_configuration_details:
|
1752
|
+
step_configuration_details[
|
1753
|
+
self.CONST_ENVIRONMENT_VARIABLES
|
1754
|
+
] = job_configuration_details["environment_variables"]
|
1755
|
+
if "command_line_arguments" in job_configuration_details:
|
1756
|
+
step_configuration_details[
|
1757
|
+
self.CONST_COMMAND_LINE_ARGUMENTS
|
1758
|
+
] = job_configuration_details["command_line_arguments"]
|
1759
|
+
if "maximum_runtime_in_minutes" in job_configuration_details:
|
1760
|
+
step_configuration_details[
|
1761
|
+
self.CONST_MAXIMUM_RUNTIME_IN_MINUTES
|
1762
|
+
] = job_configuration_details["maximum_runtime_in_minutes"]
|
1763
|
+
elif step.CONST_STEP_CONFIG_DETAILS in step._spec:
|
1764
|
+
step_configuration_details = step._spec[step.CONST_STEP_CONFIG_DETAILS]
|
1765
|
+
|
1766
|
+
if len(step_configuration_details) == 1:
|
1767
|
+
if step.environment_variable:
|
1768
|
+
step_configuration_details[
|
1769
|
+
self.CONST_ENVIRONMENT_VARIABLES
|
1770
|
+
] = step.environment_variable
|
1771
|
+
if step.argument:
|
1772
|
+
step_configuration_details[
|
1773
|
+
self.CONST_COMMAND_LINE_ARGUMENTS
|
1774
|
+
] = step.argument
|
1775
|
+
if step.maximum_runtime_in_minutes:
|
1776
|
+
step_configuration_details[
|
1777
|
+
self.CONST_MAXIMUM_RUNTIME_IN_MINUTES
|
1778
|
+
] = step.maximum_runtime_in_minutes
|
1779
|
+
|
1780
|
+
if len(step_configuration_details) == 1:
|
1781
|
+
if self.CONST_CONFIGURATION_DETAILS in pipeline_details:
|
1782
|
+
step_configuration_details = pipeline_details[
|
1783
|
+
self.CONST_CONFIGURATION_DETAILS
|
1784
|
+
]
|
1785
|
+
|
1786
|
+
return step_configuration_details
|
1787
|
+
|
1788
|
+
def __override_configurations(
|
1789
|
+
self,
|
1790
|
+
pipeline_details,
|
1791
|
+
display_name,
|
1792
|
+
project_id,
|
1793
|
+
compartment_id,
|
1794
|
+
configuration_override_details,
|
1795
|
+
log_configuration_override_details,
|
1796
|
+
step_override_details,
|
1797
|
+
free_form_tags,
|
1798
|
+
defined_tags,
|
1799
|
+
system_tags,
|
1800
|
+
) -> dict:
|
1801
|
+
if display_name:
|
1802
|
+
pipeline_details[self.CONST_DISPLAY_NAME] = display_name
|
1803
|
+
|
1804
|
+
if project_id:
|
1805
|
+
pipeline_details[self.CONST_PROJECT_ID] = project_id
|
1806
|
+
|
1807
|
+
if compartment_id:
|
1808
|
+
pipeline_details[self.CONST_COMPARTMENT_ID] = compartment_id
|
1809
|
+
|
1810
|
+
if configuration_override_details:
|
1811
|
+
configuration_override_details[self.CONST_TYPE] = "DEFAULT"
|
1812
|
+
pipeline_details[
|
1813
|
+
self.CONST_CONFIGURATION_OVERRIDE_DETAILS
|
1814
|
+
] = self._standardize_spec(configuration_override_details)
|
1815
|
+
|
1816
|
+
if log_configuration_override_details:
|
1817
|
+
pipeline_details[
|
1818
|
+
self.CONST_LOG_CONFIGURATION_OVERRIDE_DETAILS
|
1819
|
+
] = self._standardize_spec(log_configuration_override_details)
|
1820
|
+
log_configuration_override_details = pipeline_details[
|
1821
|
+
self.CONST_LOG_CONFIGURATION_OVERRIDE_DETAILS
|
1822
|
+
]
|
1823
|
+
|
1824
|
+
if (
|
1825
|
+
self.CONST_LOG_ID in log_configuration_override_details
|
1826
|
+
and self.CONST_LOG_GROUP_ID not in log_configuration_override_details
|
1827
|
+
):
|
1828
|
+
try:
|
1829
|
+
log_obj = OCILog.from_ocid(
|
1830
|
+
log_configuration_override_details[self.CONST_LOG_ID]
|
1831
|
+
)
|
1832
|
+
except ResourceNotFoundError:
|
1833
|
+
raise ResourceNotFoundError(
|
1834
|
+
f"Unable to determine log group ID for Log ({log_configuration_override_details[self.CONST_LOG_ID]})."
|
1835
|
+
" The log resource may not exist or You may not have the required permission."
|
1836
|
+
" Try to avoid this by specifying the log group ID."
|
1837
|
+
)
|
1838
|
+
if log_obj and log_obj.log_group_id:
|
1839
|
+
log_configuration_override_details[
|
1840
|
+
self.CONST_LOG_GROUP_ID
|
1841
|
+
] = log_obj.log_group_id
|
1842
|
+
|
1843
|
+
if self.CONST_LOG_ID in log_configuration_override_details:
|
1844
|
+
log_configuration_override_details[self.CONST_ENABLE_LOGGING] = True
|
1845
|
+
log_configuration_override_details[
|
1846
|
+
self.CONST_ENABLE_AUTO_LOG_CREATION
|
1847
|
+
] = False
|
1848
|
+
else:
|
1849
|
+
if self.CONST_LOG_GROUP_ID in log_configuration_override_details:
|
1850
|
+
log_configuration_override_details[self.CONST_ENABLE_LOGGING] = True
|
1851
|
+
log_configuration_override_details[
|
1852
|
+
self.CONST_ENABLE_AUTO_LOG_CREATION
|
1853
|
+
] = True
|
1854
|
+
else:
|
1855
|
+
log_configuration_override_details[
|
1856
|
+
self.CONST_ENABLE_LOGGING
|
1857
|
+
] = False
|
1858
|
+
log_configuration_override_details[
|
1859
|
+
self.CONST_ENABLE_AUTO_LOG_CREATION
|
1860
|
+
] = False
|
1861
|
+
|
1862
|
+
if step_override_details:
|
1863
|
+
step_override_details_list = []
|
1864
|
+
for step in step_override_details:
|
1865
|
+
step_detail = {}
|
1866
|
+
step_detail["stepName"] = step["step_name"]
|
1867
|
+
step_detail["stepConfigurationDetails"] = self._standardize_spec(
|
1868
|
+
step["step_configuration_details"]
|
1869
|
+
)
|
1870
|
+
step_override_details_list.append(step_detail)
|
1871
|
+
pipeline_details[
|
1872
|
+
self.CONST_STEP_OVERRIDE_DETAILS
|
1873
|
+
] = step_override_details_list
|
1874
|
+
|
1875
|
+
if free_form_tags:
|
1876
|
+
pipeline_details[self.CONST_FREEFROM_TAGS] = free_form_tags
|
1877
|
+
|
1878
|
+
if defined_tags:
|
1879
|
+
pipeline_details[self.CONST_DEFINED_TAGS] = defined_tags
|
1880
|
+
|
1881
|
+
if system_tags:
|
1882
|
+
pipeline_details[self.CONST_SYSTEM_TAGS] = system_tags
|
1883
|
+
|
1884
|
+
# TODO: Needs to improve the validation logic
|
1885
|
+
# Ticket: https://jira.oci.oraclecorp.com/browse/ODSC-31996
|
1886
|
+
# @classmethod
|
1887
|
+
# def from_yaml(cls, uri: str) -> "Pipeline":
|
1888
|
+
# pipeline_schema = {}
|
1889
|
+
# schema_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "schema")
|
1890
|
+
# with open(
|
1891
|
+
# os.path.join(schema_path, "pipeline_schema.json")
|
1892
|
+
# ) as pipeline_schema_file:
|
1893
|
+
# pipeline_schema = json.load(pipeline_schema_file)
|
1894
|
+
|
1895
|
+
# cs_step_schema = {}
|
1896
|
+
# with open(
|
1897
|
+
# os.path.join(schema_path, "cs_step_schema.json")
|
1898
|
+
# ) as cs_step_schema_file:
|
1899
|
+
# cs_step_schema = json.load(cs_step_schema_file)
|
1900
|
+
|
1901
|
+
# ml_step_schema = {}
|
1902
|
+
# with open(
|
1903
|
+
# os.path.join(schema_path, "ml_step_schema.json")
|
1904
|
+
# ) as ml_step_schema_file:
|
1905
|
+
# ml_step_schema = json.load(ml_step_schema_file)
|
1906
|
+
|
1907
|
+
# yaml_dict = yaml.load(Pipeline._read_from_file(uri=uri), Loader=yaml.FullLoader)
|
1908
|
+
|
1909
|
+
# pipeline_validator = Validator(pipeline_schema)
|
1910
|
+
# if not pipeline_validator.validate(yaml_dict):
|
1911
|
+
# raise ValueError(pipeline_validator.errors)
|
1912
|
+
|
1913
|
+
# step_details = yaml_dict["spec"]["stepDetails"]
|
1914
|
+
# if len(step_details) == 0:
|
1915
|
+
# raise ValueError("Pipeline must have at least one step.")
|
1916
|
+
|
1917
|
+
# ml_step_validator = Validator(ml_step_schema)
|
1918
|
+
# cs_step_validator = Validator(cs_step_schema)
|
1919
|
+
# for step in step_details:
|
1920
|
+
# if not ml_step_validator.validate(step) and not cs_step_validator.validate(
|
1921
|
+
# step
|
1922
|
+
# ):
|
1923
|
+
# if ml_step_validator.errors:
|
1924
|
+
# raise ValueError(ml_step_validator.errors)
|
1925
|
+
# else:
|
1926
|
+
# raise ValueError(cs_step_validator.errors)
|
1927
|
+
|
1928
|
+
# return super().from_yaml(uri=uri)
|
1929
|
+
|
1930
|
+
@classmethod
|
1931
|
+
def list(cls, compartment_id: Optional[str] = None, **kwargs) -> List["Pipeline"]:
|
1932
|
+
"""
|
1933
|
+
List pipelines in a given compartment.
|
1934
|
+
|
1935
|
+
Parameters
|
1936
|
+
----------
|
1937
|
+
compartment_id: (str, optional). Defaults to None.
|
1938
|
+
The OCID of compartment.
|
1939
|
+
If `None`, the value will be taken from the environment variables.
|
1940
|
+
kwargs
|
1941
|
+
Additional keyword arguments for filtering pipelines.
|
1942
|
+
- project_id: str
|
1943
|
+
- lifecycle_state: str. Allowed values: "CREATING", "ACTIVE", "DELETING", "FAILED", "DELETED"
|
1944
|
+
- created_by: str
|
1945
|
+
- limit: int
|
1946
|
+
|
1947
|
+
Returns
|
1948
|
+
-------
|
1949
|
+
List[Pipeline]
|
1950
|
+
The list of pipelines.
|
1951
|
+
"""
|
1952
|
+
result = []
|
1953
|
+
for item in DataSciencePipeline.list_resource(compartment_id, **kwargs):
|
1954
|
+
pipeline = item.build_ads_pipeline()
|
1955
|
+
pipeline._populate_step_artifact_content()
|
1956
|
+
result.append(pipeline)
|
1957
|
+
return result
|
1958
|
+
|
1959
|
+
def run_list(self, **kwargs) -> List[PipelineRun]:
|
1960
|
+
"""Gets a list of runs of the pipeline.
|
1961
|
+
|
1962
|
+
Returns
|
1963
|
+
-------
|
1964
|
+
List[PipelineRun]
|
1965
|
+
A list of pipeline run instances.
|
1966
|
+
"""
|
1967
|
+
return PipelineRun.list(
|
1968
|
+
compartment_id=self.compartment_id, pipeline_id=self.id, **kwargs
|
1969
|
+
)
|
1970
|
+
|
1971
|
+
@property
|
1972
|
+
def status(self) -> Optional[str]:
|
1973
|
+
"""Status of the pipeline.
|
1974
|
+
|
1975
|
+
Returns
|
1976
|
+
-------
|
1977
|
+
str
|
1978
|
+
Status of the pipeline.
|
1979
|
+
"""
|
1980
|
+
if self.data_science_pipeline:
|
1981
|
+
return self.data_science_pipeline.lifecycle_state
|
1982
|
+
return None
|
1983
|
+
|
1984
|
+
def init(self, **kwargs) -> "Pipeline":
|
1985
|
+
"""Initializes a starter specification for the Pipeline.
|
1986
|
+
|
1987
|
+
Returns
|
1988
|
+
-------
|
1989
|
+
Pipeline
|
1990
|
+
The Pipeline instance (self)
|
1991
|
+
"""
|
1992
|
+
return (
|
1993
|
+
self.build()
|
1994
|
+
.with_compartment_id(self.compartment_id or "{Provide a compartment OCID}")
|
1995
|
+
.with_project_id(self.project_id or "{Provide a project OCID}")
|
1996
|
+
)
|
1997
|
+
|
1998
|
+
|
1999
|
+
class DataSciencePipeline(OCIDataScienceMixin, oci.data_science.models.Pipeline):
|
2000
|
+
@classmethod
|
2001
|
+
def from_ocid(cls, ocid: str) -> "DataSciencePipeline":
|
2002
|
+
"""Gets a datascience pipeline by OCID.
|
2003
|
+
|
2004
|
+
Parameters
|
2005
|
+
----------
|
2006
|
+
ocid: str
|
2007
|
+
The OCID of the datascience pipeline.
|
2008
|
+
|
2009
|
+
Returns
|
2010
|
+
-------
|
2011
|
+
DataSciencePipeline
|
2012
|
+
An instance of DataSciencePipeline.
|
2013
|
+
"""
|
2014
|
+
return super().from_ocid(ocid)
|
2015
|
+
|
2016
|
+
def build_ads_pipeline(self) -> "Pipeline":
|
2017
|
+
"""Builds an ADS pipeline from OCI datascience pipeline.
|
2018
|
+
|
2019
|
+
Returns
|
2020
|
+
-------
|
2021
|
+
Pipeline:
|
2022
|
+
ADS Pipeline instance.
|
2023
|
+
"""
|
2024
|
+
pipeline_details = self.to_dict()
|
2025
|
+
ads_pipeline = Pipeline(pipeline_details["displayName"])
|
2026
|
+
ads_pipeline.data_science_pipeline = self
|
2027
|
+
|
2028
|
+
for key in pipeline_details:
|
2029
|
+
if key in ads_pipeline.attribute_set:
|
2030
|
+
if key == "stepDetails":
|
2031
|
+
step_details = []
|
2032
|
+
for step in pipeline_details[key]:
|
2033
|
+
step_details.append(self.build_ads_pipeline_step(step))
|
2034
|
+
ads_pipeline.set_spec(key, step_details)
|
2035
|
+
elif key in ["freeformTags", "systemTags", "definedTags"]:
|
2036
|
+
ads_pipeline.set_spec(key, pipeline_details[key])
|
2037
|
+
elif type(pipeline_details[key]) is dict:
|
2038
|
+
for attribute in pipeline_details[key]:
|
2039
|
+
ads_pipeline.set_spec(
|
2040
|
+
attribute, pipeline_details[key][attribute]
|
2041
|
+
)
|
2042
|
+
else:
|
2043
|
+
ads_pipeline.set_spec(key, pipeline_details[key])
|
2044
|
+
|
2045
|
+
dag_list = ads_pipeline._convert_step_details_to_dag(
|
2046
|
+
pipeline_details["stepDetails"]
|
2047
|
+
)
|
2048
|
+
ads_pipeline.set_spec(Pipeline.CONST_DAG, dag_list)
|
2049
|
+
|
2050
|
+
return ads_pipeline
|
2051
|
+
|
2052
|
+
def build_ads_pipeline_step(self, step: Dict) -> "PipelineStep":
|
2053
|
+
"""Builds an ADS pipeline step from OCI pipeline response.
|
2054
|
+
|
2055
|
+
Parameters
|
2056
|
+
----------
|
2057
|
+
step: dict
|
2058
|
+
A dictionary that contains the information of a pipeline step.
|
2059
|
+
|
2060
|
+
Returns
|
2061
|
+
-------
|
2062
|
+
Pipeline:
|
2063
|
+
ADS PipelineStep instance.
|
2064
|
+
"""
|
2065
|
+
ads_pipeline_step = PipelineStep(step["stepName"])
|
2066
|
+
|
2067
|
+
for key in step:
|
2068
|
+
if key in ads_pipeline_step.attribute_set:
|
2069
|
+
infrastructure = DataScienceJob()
|
2070
|
+
if key == ads_pipeline_step.CONST_STEP_INFRA_CONFIG_DETAILS:
|
2071
|
+
for attribute in step[key]:
|
2072
|
+
infrastructure.set_spec(attribute, step[key][attribute])
|
2073
|
+
ads_pipeline_step.set_spec(
|
2074
|
+
ads_pipeline_step.CONST_INFRASTRUCTURE, infrastructure
|
2075
|
+
)
|
2076
|
+
elif key == ads_pipeline_step.CONST_STEP_CONFIG_DETAILS:
|
2077
|
+
if step["stepType"] == "CUSTOM_SCRIPT":
|
2078
|
+
job_configuration_details_dict = {}
|
2079
|
+
for attribute in step[key]:
|
2080
|
+
job_configuration_details_dict[
|
2081
|
+
infrastructure.CONST_JOB_TYPE
|
2082
|
+
] = "DEFAULT"
|
2083
|
+
job_configuration_details_dict[attribute] = step[key][
|
2084
|
+
attribute
|
2085
|
+
]
|
2086
|
+
dsc_job = DSCJob(
|
2087
|
+
job_configuration_details=job_configuration_details_dict
|
2088
|
+
)
|
2089
|
+
runtime = DataScienceJobRuntimeManager(infrastructure).extract(
|
2090
|
+
dsc_job
|
2091
|
+
)
|
2092
|
+
ads_pipeline_step.set_spec(
|
2093
|
+
ads_pipeline_step.CONST_RUNTIME, runtime
|
2094
|
+
)
|
2095
|
+
else:
|
2096
|
+
for attribute in step[key]:
|
2097
|
+
ads_pipeline_step.set_spec(attribute, step[key][attribute])
|
2098
|
+
else:
|
2099
|
+
ads_pipeline_step.set_spec(key, step[key])
|
2100
|
+
return ads_pipeline_step
|
2101
|
+
|
2102
|
+
def create(self, step_details: List, delete_if_fail: bool) -> str:
|
2103
|
+
"""Creates an OCI pipeline.
|
2104
|
+
|
2105
|
+
Parameters
|
2106
|
+
----------
|
2107
|
+
step_details: list
|
2108
|
+
List of pipeline step details.
|
2109
|
+
|
2110
|
+
Returns
|
2111
|
+
-------
|
2112
|
+
str:
|
2113
|
+
The id of OCI pipeline.
|
2114
|
+
"""
|
2115
|
+
response = self.client.create_pipeline(
|
2116
|
+
self.to_oci_model(oci.data_science.models.CreatePipelineDetails)
|
2117
|
+
)
|
2118
|
+
self.update_from_oci_model(response.data)
|
2119
|
+
try:
|
2120
|
+
self.upload_artifact(step_details)
|
2121
|
+
except Exception as ex:
|
2122
|
+
if delete_if_fail:
|
2123
|
+
self.delete(self.id)
|
2124
|
+
raise ex
|
2125
|
+
self.step_details = step_details
|
2126
|
+
return self
|
2127
|
+
|
2128
|
+
def upload_artifact(self, step_details: List) -> "DataSciencePipeline":
|
2129
|
+
"""Uploads artifacts to pipeline.
|
2130
|
+
|
2131
|
+
Parameters
|
2132
|
+
----------
|
2133
|
+
step_details: list
|
2134
|
+
List of pipeline step details.
|
2135
|
+
|
2136
|
+
Returns
|
2137
|
+
-------
|
2138
|
+
DataSciencePipeline:
|
2139
|
+
DataSciencePipeline instance.
|
2140
|
+
"""
|
2141
|
+
for step in step_details:
|
2142
|
+
if step.runtime:
|
2143
|
+
payload = DataScienceJobRuntimeManager(step.infrastructure).translate(
|
2144
|
+
step.runtime
|
2145
|
+
)
|
2146
|
+
target_artifact = payload["artifact"]
|
2147
|
+
if issubclass(target_artifact.__class__, Artifact):
|
2148
|
+
with target_artifact as artifact:
|
2149
|
+
self.create_step_artifact(artifact.path, step.name)
|
2150
|
+
else:
|
2151
|
+
self.create_step_artifact(target_artifact, step.name)
|
2152
|
+
return self
|
2153
|
+
|
2154
|
+
def create_step_artifact(
|
2155
|
+
self, artifact_path: str, step_name: str
|
2156
|
+
) -> "DataSciencePipeline":
|
2157
|
+
"""Creates step artifact.
|
2158
|
+
|
2159
|
+
Parameters
|
2160
|
+
----------
|
2161
|
+
artifact_path: str
|
2162
|
+
Local path to artifact.
|
2163
|
+
step_name: str
|
2164
|
+
Pipeline step name.
|
2165
|
+
|
2166
|
+
Returns
|
2167
|
+
-------
|
2168
|
+
DataSciencePipeline:
|
2169
|
+
DataSciencePipeline instance.
|
2170
|
+
"""
|
2171
|
+
with fsspec.open(artifact_path, "rb") as f:
|
2172
|
+
self.client.create_step_artifact(
|
2173
|
+
self.id,
|
2174
|
+
step_name,
|
2175
|
+
f,
|
2176
|
+
content_disposition=f"attachment; filename={os.path.basename(artifact_path)}",
|
2177
|
+
)
|
2178
|
+
return self
|
2179
|
+
|
2180
|
+
def run(
|
2181
|
+
self, pipeline_details: Dict, service_logging: OCILog = None
|
2182
|
+
) -> "PipelineRun":
|
2183
|
+
"""Runs an OCI pipeline.
|
2184
|
+
|
2185
|
+
Parameters
|
2186
|
+
----------
|
2187
|
+
pipeline_details: dict
|
2188
|
+
A dictionary that contains pipeline details.
|
2189
|
+
service_logging: OCILog instance.
|
2190
|
+
The OCILog instance.
|
2191
|
+
|
2192
|
+
Returns
|
2193
|
+
-------
|
2194
|
+
PipelineRun:
|
2195
|
+
PipelineRun instance.
|
2196
|
+
"""
|
2197
|
+
data_science_pipeline_run = PipelineRun(**pipeline_details)
|
2198
|
+
if service_logging:
|
2199
|
+
data_science_pipeline_run._set_service_logging_resource(service_logging)
|
2200
|
+
data_science_pipeline_run.create()
|
2201
|
+
|
2202
|
+
return data_science_pipeline_run
|
2203
|
+
|
2204
|
+
def delete(
|
2205
|
+
self,
|
2206
|
+
id: str,
|
2207
|
+
operation_kwargs: Dict = DEFAULT_OPERATION_KWARGS,
|
2208
|
+
waiter_kwargs: Dict = DEFAULT_WAITER_KWARGS,
|
2209
|
+
) -> "DataSciencePipeline":
|
2210
|
+
"""Deletes an OCI pipeline.
|
2211
|
+
|
2212
|
+
Parameters
|
2213
|
+
----------
|
2214
|
+
id: str
|
2215
|
+
The ocid of pipeline.
|
2216
|
+
Parameters
|
2217
|
+
----------
|
2218
|
+
operation_kwargs: dict, optional
|
2219
|
+
The operational kwargs to be executed when deleting the pipeline.
|
2220
|
+
Defaults to: {"delete_related_pipeline_runs": True, "delete_related_job_runs": True},
|
2221
|
+
which will delete the corresponding pipeline runs and job runs.
|
2222
|
+
|
2223
|
+
The allowed keys are:
|
2224
|
+
* "delete_related_pipeline_runs": bool, to specify whether to delete related
|
2225
|
+
PipelineRuns or not.
|
2226
|
+
* "delete_related_job_runs": bool, to specify whether to delete related JobRuns or not.
|
2227
|
+
* "allow_control_chars": bool, to indicate whether or not this request should
|
2228
|
+
allow control characters in the response object. By default, the response will not
|
2229
|
+
allow control characters in strings
|
2230
|
+
* "retry_strategy": obj, to apply to this specific operation/call. This will
|
2231
|
+
override any retry strategy set at the client-level. This should be one of the
|
2232
|
+
strategies available in the :py:mod:`~oci.retry` module. This operation will not retry
|
2233
|
+
by default, users can also use the convenient :py:data:`~oci.retry.DEFAULT_RETRY_STRATEGY`
|
2234
|
+
provided by the SDK to enable retries for it. The specifics of the default retry strategy
|
2235
|
+
are described `here <https://docs.oracle.com/en-us/iaas/tools/python/latest/sdk_behaviors/retries.html>`__.
|
2236
|
+
To have this operation explicitly not perform any retries, pass an instance of :py:class:`~oci.retry.NoneRetryStrategy`.
|
2237
|
+
* "if_match": str, for optimistic concurrency control. In the PUT or DELETE call
|
2238
|
+
for a resource, set the `if-match` parameter to the value of the etag from a previous
|
2239
|
+
GET or POST response for that resource. The resource is updated or deleted only if the
|
2240
|
+
`etag` you provide matches the resource's current `etag` value.
|
2241
|
+
* "opc_request_id": str, unique Oracle assigned identifier for the request. If you need
|
2242
|
+
to contact Oracle about a particular request, then provide the request ID.
|
2243
|
+
|
2244
|
+
waiter_kwargs: dict, optional
|
2245
|
+
The waiter kwargs to be passed when deleting the pipeline.
|
2246
|
+
Defaults to: {"max_wait_seconds": 1800}, which will allow a maximum wait time to 1800 seconds to delete the pipeline.
|
2247
|
+
The allowed keys are:
|
2248
|
+
* "max_wait_seconds": int, the maximum time to wait, in seconds.
|
2249
|
+
* "max_interval_seconds": int, the maximum interval between queries, in seconds.
|
2250
|
+
* "succeed_on_not_found": bool, to determine whether or not the waiter should return
|
2251
|
+
successfully if the data we're waiting on is not found (e.g. a 404 is returned from the service).
|
2252
|
+
This defaults to False and so a 404 would cause an exception to be thrown by this function.
|
2253
|
+
Setting it to True may be useful in scenarios when waiting for a resource to be
|
2254
|
+
terminated/deleted since it is possible that the resource would not be returned by the a GET call anymore.
|
2255
|
+
* "wait_callback": A function which will be called each time that we have to do an initial
|
2256
|
+
wait (i.e. because the property of the resource was not in the correct state,
|
2257
|
+
or the ``evaluate_response`` function returned False). This function should take two
|
2258
|
+
arguments - the first argument is the number of times we have checked the resource,
|
2259
|
+
and the second argument is the result of the most recent check.
|
2260
|
+
* "fetch_func": A function to be called to fetch the updated state from the server.
|
2261
|
+
This can be used if the call to check for state needs to be more complex than a single
|
2262
|
+
GET request. For example, if the goal is to wait until an item appears in a list,
|
2263
|
+
fetch_func can be a function that paginates through a full list on the server.
|
2264
|
+
|
2265
|
+
Returns
|
2266
|
+
-------
|
2267
|
+
DataSciencePipeline:
|
2268
|
+
DataSciencePipeline instance.
|
2269
|
+
"""
|
2270
|
+
self.client_composite.delete_pipeline_and_wait_for_state(
|
2271
|
+
pipeline_id=id,
|
2272
|
+
wait_for_states=[
|
2273
|
+
oci.data_science.models.WorkRequest.STATUS_SUCCEEDED,
|
2274
|
+
oci.data_science.models.WorkRequest.STATUS_FAILED,
|
2275
|
+
],
|
2276
|
+
operation_kwargs=operation_kwargs,
|
2277
|
+
waiter_kwargs=waiter_kwargs,
|
2278
|
+
)
|
2279
|
+
return self.sync()
|