azure-ai-evaluation 1.0.1__py3-none-any.whl → 1.13.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of azure-ai-evaluation might be problematic. Click here for more details.
- azure/ai/evaluation/__init__.py +85 -14
- azure/ai/evaluation/_aoai/__init__.py +10 -0
- azure/ai/evaluation/_aoai/aoai_grader.py +140 -0
- azure/ai/evaluation/_aoai/label_grader.py +68 -0
- azure/ai/evaluation/_aoai/python_grader.py +86 -0
- azure/ai/evaluation/_aoai/score_model_grader.py +94 -0
- azure/ai/evaluation/_aoai/string_check_grader.py +66 -0
- azure/ai/evaluation/_aoai/text_similarity_grader.py +80 -0
- azure/ai/evaluation/_azure/__init__.py +3 -0
- azure/ai/evaluation/_azure/_clients.py +204 -0
- azure/ai/evaluation/_azure/_envs.py +207 -0
- azure/ai/evaluation/_azure/_models.py +227 -0
- azure/ai/evaluation/_azure/_token_manager.py +129 -0
- azure/ai/evaluation/_common/__init__.py +9 -1
- azure/ai/evaluation/_common/constants.py +124 -2
- azure/ai/evaluation/_common/evaluation_onedp_client.py +169 -0
- azure/ai/evaluation/_common/onedp/__init__.py +32 -0
- azure/ai/evaluation/_common/onedp/_client.py +166 -0
- azure/ai/evaluation/_common/onedp/_configuration.py +72 -0
- azure/ai/evaluation/_common/onedp/_model_base.py +1232 -0
- azure/ai/evaluation/_common/onedp/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/_serialization.py +2032 -0
- azure/ai/evaluation/_common/onedp/_types.py +21 -0
- azure/ai/evaluation/_common/onedp/_utils/__init__.py +6 -0
- azure/ai/evaluation/_common/onedp/_utils/model_base.py +1232 -0
- azure/ai/evaluation/_common/onedp/_utils/serialization.py +2032 -0
- azure/ai/evaluation/_common/onedp/_validation.py +66 -0
- azure/ai/evaluation/_common/onedp/_vendor.py +50 -0
- azure/ai/evaluation/_common/onedp/_version.py +9 -0
- azure/ai/evaluation/_common/onedp/aio/__init__.py +29 -0
- azure/ai/evaluation/_common/onedp/aio/_client.py +168 -0
- azure/ai/evaluation/_common/onedp/aio/_configuration.py +72 -0
- azure/ai/evaluation/_common/onedp/aio/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/aio/operations/__init__.py +49 -0
- azure/ai/evaluation/_common/onedp/aio/operations/_operations.py +7143 -0
- azure/ai/evaluation/_common/onedp/aio/operations/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/models/__init__.py +358 -0
- azure/ai/evaluation/_common/onedp/models/_enums.py +447 -0
- azure/ai/evaluation/_common/onedp/models/_models.py +5963 -0
- azure/ai/evaluation/_common/onedp/models/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/operations/__init__.py +49 -0
- azure/ai/evaluation/_common/onedp/operations/_operations.py +8951 -0
- azure/ai/evaluation/_common/onedp/operations/_patch.py +21 -0
- azure/ai/evaluation/_common/onedp/py.typed +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_operations.py +34 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/aio/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/__init__.py +1 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/__init__.py +22 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_operations.py +29 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/aio/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/__init__.py +22 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_operations.py +29 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/buildingblocks/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/operations/_operations.py +34 -0
- azure/ai/evaluation/_common/onedp/servicepatterns/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/rai_service.py +578 -69
- azure/ai/evaluation/_common/raiclient/__init__.py +34 -0
- azure/ai/evaluation/_common/raiclient/_client.py +128 -0
- azure/ai/evaluation/_common/raiclient/_configuration.py +87 -0
- azure/ai/evaluation/_common/raiclient/_model_base.py +1235 -0
- azure/ai/evaluation/_common/raiclient/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/_serialization.py +2050 -0
- azure/ai/evaluation/_common/raiclient/_version.py +9 -0
- azure/ai/evaluation/_common/raiclient/aio/__init__.py +29 -0
- azure/ai/evaluation/_common/raiclient/aio/_client.py +130 -0
- azure/ai/evaluation/_common/raiclient/aio/_configuration.py +87 -0
- azure/ai/evaluation/_common/raiclient/aio/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/aio/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/raiclient/aio/operations/_operations.py +981 -0
- azure/ai/evaluation/_common/raiclient/aio/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/models/__init__.py +60 -0
- azure/ai/evaluation/_common/raiclient/models/_enums.py +18 -0
- azure/ai/evaluation/_common/raiclient/models/_models.py +651 -0
- azure/ai/evaluation/_common/raiclient/models/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/operations/__init__.py +25 -0
- azure/ai/evaluation/_common/raiclient/operations/_operations.py +1238 -0
- azure/ai/evaluation/_common/raiclient/operations/_patch.py +20 -0
- azure/ai/evaluation/_common/raiclient/py.typed +1 -0
- azure/ai/evaluation/_common/utils.py +505 -27
- azure/ai/evaluation/_constants.py +147 -0
- azure/ai/evaluation/_converters/__init__.py +3 -0
- azure/ai/evaluation/_converters/_ai_services.py +899 -0
- azure/ai/evaluation/_converters/_models.py +467 -0
- azure/ai/evaluation/_converters/_sk_services.py +495 -0
- azure/ai/evaluation/_eval_mapping.py +87 -0
- azure/ai/evaluation/_evaluate/_batch_run/__init__.py +10 -2
- azure/ai/evaluation/_evaluate/_batch_run/_run_submitter_client.py +176 -0
- azure/ai/evaluation/_evaluate/_batch_run/batch_clients.py +82 -0
- azure/ai/evaluation/_evaluate/_batch_run/code_client.py +18 -12
- azure/ai/evaluation/_evaluate/_batch_run/eval_run_context.py +19 -6
- azure/ai/evaluation/_evaluate/_batch_run/proxy_client.py +47 -22
- azure/ai/evaluation/_evaluate/_batch_run/target_run_context.py +18 -2
- azure/ai/evaluation/_evaluate/_eval_run.py +32 -46
- azure/ai/evaluation/_evaluate/_evaluate.py +1809 -142
- azure/ai/evaluation/_evaluate/_evaluate_aoai.py +992 -0
- azure/ai/evaluation/_evaluate/_telemetry/__init__.py +5 -90
- azure/ai/evaluation/_evaluate/_utils.py +237 -42
- azure/ai/evaluation/_evaluator_definition.py +76 -0
- azure/ai/evaluation/_evaluators/_bleu/_bleu.py +80 -28
- azure/ai/evaluation/_evaluators/_code_vulnerability/__init__.py +5 -0
- azure/ai/evaluation/_evaluators/_code_vulnerability/_code_vulnerability.py +119 -0
- azure/ai/evaluation/_evaluators/_coherence/_coherence.py +40 -4
- azure/ai/evaluation/_evaluators/_common/__init__.py +2 -0
- azure/ai/evaluation/_evaluators/_common/_base_eval.py +430 -29
- azure/ai/evaluation/_evaluators/_common/_base_multi_eval.py +63 -0
- azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +269 -12
- azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +74 -9
- azure/ai/evaluation/_evaluators/_common/_conversation_aggregators.py +49 -0
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety.py +73 -53
- azure/ai/evaluation/_evaluators/_content_safety/_hate_unfairness.py +35 -5
- azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py +26 -5
- azure/ai/evaluation/_evaluators/_content_safety/_sexual.py +35 -5
- azure/ai/evaluation/_evaluators/_content_safety/_violence.py +34 -4
- azure/ai/evaluation/_evaluators/_document_retrieval/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_document_retrieval/_document_retrieval.py +442 -0
- azure/ai/evaluation/_evaluators/_eci/_eci.py +6 -3
- azure/ai/evaluation/_evaluators/_f1_score/_f1_score.py +97 -70
- azure/ai/evaluation/_evaluators/_fluency/_fluency.py +39 -3
- azure/ai/evaluation/_evaluators/_gleu/_gleu.py +80 -25
- azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +230 -20
- azure/ai/evaluation/_evaluators/_groundedness/groundedness_with_query.prompty +30 -29
- azure/ai/evaluation/_evaluators/_groundedness/groundedness_without_query.prompty +19 -14
- azure/ai/evaluation/_evaluators/_intent_resolution/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_intent_resolution/_intent_resolution.py +196 -0
- azure/ai/evaluation/_evaluators/_intent_resolution/intent_resolution.prompty +275 -0
- azure/ai/evaluation/_evaluators/_meteor/_meteor.py +89 -36
- azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py +22 -4
- azure/ai/evaluation/_evaluators/_qa/_qa.py +94 -35
- azure/ai/evaluation/_evaluators/_relevance/_relevance.py +100 -4
- azure/ai/evaluation/_evaluators/_relevance/relevance.prompty +154 -56
- azure/ai/evaluation/_evaluators/_response_completeness/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_response_completeness/_response_completeness.py +202 -0
- azure/ai/evaluation/_evaluators/_response_completeness/response_completeness.prompty +84 -0
- azure/ai/evaluation/_evaluators/_retrieval/_retrieval.py +39 -3
- azure/ai/evaluation/_evaluators/_rouge/_rouge.py +166 -26
- azure/ai/evaluation/_evaluators/_service_groundedness/_service_groundedness.py +38 -7
- azure/ai/evaluation/_evaluators/_similarity/_similarity.py +81 -85
- azure/ai/evaluation/_evaluators/_task_adherence/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_task_adherence/_task_adherence.py +226 -0
- azure/ai/evaluation/_evaluators/_task_adherence/task_adherence.prompty +101 -0
- azure/ai/evaluation/_evaluators/_task_completion/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_task_completion/_task_completion.py +177 -0
- azure/ai/evaluation/_evaluators/_task_completion/task_completion.prompty +220 -0
- azure/ai/evaluation/_evaluators/_task_navigation_efficiency/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_task_navigation_efficiency/_task_navigation_efficiency.py +384 -0
- azure/ai/evaluation/_evaluators/_tool_call_accuracy/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_tool_call_accuracy/_tool_call_accuracy.py +298 -0
- azure/ai/evaluation/_evaluators/_tool_call_accuracy/tool_call_accuracy.prompty +166 -0
- azure/ai/evaluation/_evaluators/_tool_call_success/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_tool_call_success/_tool_call_success.py +306 -0
- azure/ai/evaluation/_evaluators/_tool_call_success/tool_call_success.prompty +321 -0
- azure/ai/evaluation/_evaluators/_tool_input_accuracy/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_tool_input_accuracy/_tool_input_accuracy.py +263 -0
- azure/ai/evaluation/_evaluators/_tool_input_accuracy/tool_input_accuracy.prompty +76 -0
- azure/ai/evaluation/_evaluators/_tool_output_utilization/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_tool_output_utilization/_tool_output_utilization.py +225 -0
- azure/ai/evaluation/_evaluators/_tool_output_utilization/tool_output_utilization.prompty +221 -0
- azure/ai/evaluation/_evaluators/_tool_selection/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_tool_selection/_tool_selection.py +266 -0
- azure/ai/evaluation/_evaluators/_tool_selection/tool_selection.prompty +104 -0
- azure/ai/evaluation/_evaluators/_ungrounded_attributes/__init__.py +5 -0
- azure/ai/evaluation/_evaluators/_ungrounded_attributes/_ungrounded_attributes.py +102 -0
- azure/ai/evaluation/_evaluators/_xpia/xpia.py +20 -4
- azure/ai/evaluation/_exceptions.py +24 -1
- azure/ai/evaluation/_http_utils.py +7 -5
- azure/ai/evaluation/_legacy/__init__.py +3 -0
- azure/ai/evaluation/_legacy/_adapters/__init__.py +7 -0
- azure/ai/evaluation/_legacy/_adapters/_check.py +17 -0
- azure/ai/evaluation/_legacy/_adapters/_configuration.py +45 -0
- azure/ai/evaluation/_legacy/_adapters/_constants.py +10 -0
- azure/ai/evaluation/_legacy/_adapters/_errors.py +29 -0
- azure/ai/evaluation/_legacy/_adapters/_flows.py +28 -0
- azure/ai/evaluation/_legacy/_adapters/_service.py +16 -0
- azure/ai/evaluation/_legacy/_adapters/client.py +51 -0
- azure/ai/evaluation/_legacy/_adapters/entities.py +26 -0
- azure/ai/evaluation/_legacy/_adapters/tracing.py +28 -0
- azure/ai/evaluation/_legacy/_adapters/types.py +15 -0
- azure/ai/evaluation/_legacy/_adapters/utils.py +31 -0
- azure/ai/evaluation/_legacy/_batch_engine/__init__.py +9 -0
- azure/ai/evaluation/_legacy/_batch_engine/_config.py +48 -0
- azure/ai/evaluation/_legacy/_batch_engine/_engine.py +477 -0
- azure/ai/evaluation/_legacy/_batch_engine/_exceptions.py +88 -0
- azure/ai/evaluation/_legacy/_batch_engine/_openai_injector.py +132 -0
- azure/ai/evaluation/_legacy/_batch_engine/_result.py +107 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run.py +127 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run_storage.py +128 -0
- azure/ai/evaluation/_legacy/_batch_engine/_run_submitter.py +262 -0
- azure/ai/evaluation/_legacy/_batch_engine/_status.py +25 -0
- azure/ai/evaluation/_legacy/_batch_engine/_trace.py +97 -0
- azure/ai/evaluation/_legacy/_batch_engine/_utils.py +97 -0
- azure/ai/evaluation/_legacy/_batch_engine/_utils_deprecated.py +131 -0
- azure/ai/evaluation/_legacy/_common/__init__.py +3 -0
- azure/ai/evaluation/_legacy/_common/_async_token_provider.py +117 -0
- azure/ai/evaluation/_legacy/_common/_logging.py +292 -0
- azure/ai/evaluation/_legacy/_common/_thread_pool_executor_with_context.py +17 -0
- azure/ai/evaluation/_legacy/prompty/__init__.py +36 -0
- azure/ai/evaluation/_legacy/prompty/_connection.py +119 -0
- azure/ai/evaluation/_legacy/prompty/_exceptions.py +139 -0
- azure/ai/evaluation/_legacy/prompty/_prompty.py +430 -0
- azure/ai/evaluation/_legacy/prompty/_utils.py +663 -0
- azure/ai/evaluation/_legacy/prompty/_yaml_utils.py +99 -0
- azure/ai/evaluation/_model_configurations.py +26 -0
- azure/ai/evaluation/_safety_evaluation/__init__.py +3 -0
- azure/ai/evaluation/_safety_evaluation/_generated_rai_client.py +0 -0
- azure/ai/evaluation/_safety_evaluation/_safety_evaluation.py +917 -0
- azure/ai/evaluation/_user_agent.py +32 -1
- azure/ai/evaluation/_vendor/rouge_score/rouge_scorer.py +0 -4
- azure/ai/evaluation/_vendor/rouge_score/scoring.py +0 -4
- azure/ai/evaluation/_vendor/rouge_score/tokenize.py +0 -4
- azure/ai/evaluation/_version.py +2 -1
- azure/ai/evaluation/red_team/__init__.py +22 -0
- azure/ai/evaluation/red_team/_agent/__init__.py +3 -0
- azure/ai/evaluation/red_team/_agent/_agent_functions.py +261 -0
- azure/ai/evaluation/red_team/_agent/_agent_tools.py +461 -0
- azure/ai/evaluation/red_team/_agent/_agent_utils.py +89 -0
- azure/ai/evaluation/red_team/_agent/_semantic_kernel_plugin.py +228 -0
- azure/ai/evaluation/red_team/_attack_objective_generator.py +268 -0
- azure/ai/evaluation/red_team/_attack_strategy.py +49 -0
- azure/ai/evaluation/red_team/_callback_chat_target.py +115 -0
- azure/ai/evaluation/red_team/_default_converter.py +21 -0
- azure/ai/evaluation/red_team/_evaluation_processor.py +505 -0
- azure/ai/evaluation/red_team/_mlflow_integration.py +430 -0
- azure/ai/evaluation/red_team/_orchestrator_manager.py +803 -0
- azure/ai/evaluation/red_team/_red_team.py +1717 -0
- azure/ai/evaluation/red_team/_red_team_result.py +661 -0
- azure/ai/evaluation/red_team/_result_processor.py +1708 -0
- azure/ai/evaluation/red_team/_utils/__init__.py +37 -0
- azure/ai/evaluation/red_team/_utils/_rai_service_eval_chat_target.py +128 -0
- azure/ai/evaluation/red_team/_utils/_rai_service_target.py +601 -0
- azure/ai/evaluation/red_team/_utils/_rai_service_true_false_scorer.py +114 -0
- azure/ai/evaluation/red_team/_utils/constants.py +72 -0
- azure/ai/evaluation/red_team/_utils/exception_utils.py +345 -0
- azure/ai/evaluation/red_team/_utils/file_utils.py +266 -0
- azure/ai/evaluation/red_team/_utils/formatting_utils.py +365 -0
- azure/ai/evaluation/red_team/_utils/logging_utils.py +139 -0
- azure/ai/evaluation/red_team/_utils/metric_mapping.py +73 -0
- azure/ai/evaluation/red_team/_utils/objective_utils.py +46 -0
- azure/ai/evaluation/red_team/_utils/progress_utils.py +252 -0
- azure/ai/evaluation/red_team/_utils/retry_utils.py +218 -0
- azure/ai/evaluation/red_team/_utils/strategy_utils.py +218 -0
- azure/ai/evaluation/simulator/_adversarial_scenario.py +6 -0
- azure/ai/evaluation/simulator/_adversarial_simulator.py +187 -80
- azure/ai/evaluation/simulator/_constants.py +1 -0
- azure/ai/evaluation/simulator/_conversation/__init__.py +138 -11
- azure/ai/evaluation/simulator/_conversation/_conversation.py +6 -2
- azure/ai/evaluation/simulator/_conversation/constants.py +1 -1
- azure/ai/evaluation/simulator/_direct_attack_simulator.py +37 -24
- azure/ai/evaluation/simulator/_helpers/_language_suffix_mapping.py +1 -0
- azure/ai/evaluation/simulator/_indirect_attack_simulator.py +56 -28
- azure/ai/evaluation/simulator/_model_tools/__init__.py +2 -1
- azure/ai/evaluation/simulator/_model_tools/_generated_rai_client.py +225 -0
- azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +12 -10
- azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +100 -45
- azure/ai/evaluation/simulator/_model_tools/_rai_client.py +101 -3
- azure/ai/evaluation/simulator/_model_tools/_template_handler.py +31 -11
- azure/ai/evaluation/simulator/_model_tools/models.py +20 -17
- azure/ai/evaluation/simulator/_simulator.py +43 -19
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info}/METADATA +378 -27
- azure_ai_evaluation-1.13.5.dist-info/RECORD +305 -0
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info}/WHEEL +1 -1
- azure/ai/evaluation/_evaluators/_multimodal/__init__.py +0 -20
- azure/ai/evaluation/_evaluators/_multimodal/_content_safety_multimodal.py +0 -132
- azure/ai/evaluation/_evaluators/_multimodal/_content_safety_multimodal_base.py +0 -55
- azure/ai/evaluation/_evaluators/_multimodal/_hate_unfairness.py +0 -100
- azure/ai/evaluation/_evaluators/_multimodal/_protected_material.py +0 -124
- azure/ai/evaluation/_evaluators/_multimodal/_self_harm.py +0 -100
- azure/ai/evaluation/_evaluators/_multimodal/_sexual.py +0 -100
- azure/ai/evaluation/_evaluators/_multimodal/_violence.py +0 -100
- azure/ai/evaluation/simulator/_tracing.py +0 -89
- azure_ai_evaluation-1.0.1.dist-info/RECORD +0 -119
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info/licenses}/NOTICE.txt +0 -0
- {azure_ai_evaluation-1.0.1.dist-info → azure_ai_evaluation-1.13.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
from logging import Logger
|
|
6
|
+
from typing import Any, Dict, Final, Optional, Set, Union, cast
|
|
7
|
+
from threading import Lock
|
|
8
|
+
from urllib.parse import quote
|
|
9
|
+
from json.decoder import JSONDecodeError
|
|
10
|
+
|
|
11
|
+
from azure.core.credentials import TokenCredential, AzureSasCredential, AccessToken
|
|
12
|
+
from azure.core.rest import HttpResponse
|
|
13
|
+
from azure.ai.evaluation._exceptions import ErrorBlame, ErrorCategory, ErrorTarget, EvaluationException
|
|
14
|
+
from azure.ai.evaluation._http_utils import HttpPipeline, get_http_client
|
|
15
|
+
from azure.ai.evaluation._azure._token_manager import AzureMLTokenManager
|
|
16
|
+
from azure.ai.evaluation._constants import TokenScope
|
|
17
|
+
from ._models import BlobStoreInfo, Workspace
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
API_VERSION: Final[str] = "2024-07-01-preview"
|
|
21
|
+
QUERY_KEY_API_VERSION: Final[str] = "api-version"
|
|
22
|
+
PATH_ML_WORKSPACES = ("providers", "Microsoft.MachineLearningServices", "workspaces")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class LiteMLClient:
|
|
26
|
+
"""A lightweight Azure ML API client.
|
|
27
|
+
|
|
28
|
+
:param subscription_id: Azure subscription ID
|
|
29
|
+
:type subscription_id: str
|
|
30
|
+
:param resource_group: Azure resource group name
|
|
31
|
+
:type resource_group: str
|
|
32
|
+
:param logger: Logger object
|
|
33
|
+
:type logger: logging.Logger
|
|
34
|
+
:keyword credential: Azure credentials
|
|
35
|
+
:paramtype credential: TokenCredential
|
|
36
|
+
:keyword kwargs: Additional keyword arguments
|
|
37
|
+
:paramtype kwargs: Dict
|
|
38
|
+
:keyword str api_version: The API version. Default is 2024-10-01
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
subscription_id: str,
|
|
44
|
+
resource_group: str,
|
|
45
|
+
logger: Logger,
|
|
46
|
+
credential: Optional[TokenCredential] = None,
|
|
47
|
+
**kwargs: Any,
|
|
48
|
+
) -> None:
|
|
49
|
+
subscription_id = quote(subscription_id, safe="")
|
|
50
|
+
resource_group = quote(resource_group, safe="")
|
|
51
|
+
|
|
52
|
+
self._base_url: Final[str] = (
|
|
53
|
+
f"https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/{resource_group}"
|
|
54
|
+
)
|
|
55
|
+
self._logger: Final[Logger] = logger
|
|
56
|
+
self._api_version: Final[str] = kwargs.get("api_version", API_VERSION)
|
|
57
|
+
self._http_client: Final[HttpPipeline] = get_http_client(**kwargs)
|
|
58
|
+
self._lock: Final[Lock] = Lock()
|
|
59
|
+
|
|
60
|
+
# things that can change under lock
|
|
61
|
+
self._token_manager: Optional[AzureMLTokenManager] = None
|
|
62
|
+
self._credential: Optional[TokenCredential] = credential
|
|
63
|
+
|
|
64
|
+
def get_token(self) -> AccessToken:
|
|
65
|
+
return self._get_token_manager().get_token()
|
|
66
|
+
|
|
67
|
+
def get_credential(self) -> TokenCredential:
|
|
68
|
+
# load the token manager to get the credential if needed
|
|
69
|
+
self._get_token_manager()
|
|
70
|
+
return cast(TokenCredential, self._credential)
|
|
71
|
+
|
|
72
|
+
def workspace_get_default_datastore(
|
|
73
|
+
self, workspace_name: str, *, include_credentials: bool = False, **kwargs: Any
|
|
74
|
+
) -> BlobStoreInfo:
|
|
75
|
+
# 1. Get the default blob store
|
|
76
|
+
# REST API documentation:
|
|
77
|
+
# https://learn.microsoft.com/rest/api/azureml/datastores/list?view=rest-azureml-2024-10-01
|
|
78
|
+
url = self._generate_path( # pylint: disable=specify-parameter-names-in-call
|
|
79
|
+
*PATH_ML_WORKSPACES, workspace_name, "datastores"
|
|
80
|
+
)
|
|
81
|
+
headers = self._get_headers()
|
|
82
|
+
|
|
83
|
+
stores_response = self._http_client.request(
|
|
84
|
+
method="GET",
|
|
85
|
+
url=url,
|
|
86
|
+
params={QUERY_KEY_API_VERSION: self._api_version, "isDefault": True, "count": 1, "orderByAsc": "false"},
|
|
87
|
+
headers=headers,
|
|
88
|
+
)
|
|
89
|
+
self._throw_on_http_error(stores_response, "list default workspace datastore")
|
|
90
|
+
|
|
91
|
+
json = stores_response.json()["value"][0]
|
|
92
|
+
props_json = json["properties"]
|
|
93
|
+
name = json["name"]
|
|
94
|
+
account_name = props_json["accountName"]
|
|
95
|
+
endpoint = props_json["endpoint"]
|
|
96
|
+
container_name = props_json["containerName"]
|
|
97
|
+
credential_type = props_json.get("credentials", {}).get("credentialsType")
|
|
98
|
+
|
|
99
|
+
# 2. Get the SAS token to use for accessing the blob store
|
|
100
|
+
# REST API documentation:
|
|
101
|
+
# https://learn.microsoft.com/rest/api/azureml/datastores/list-secrets?view=rest-azureml-2024-10-01
|
|
102
|
+
blob_store_credential: Optional[Union[AzureSasCredential, TokenCredential, str]]
|
|
103
|
+
if not include_credentials:
|
|
104
|
+
blob_store_credential = None
|
|
105
|
+
elif credential_type and credential_type.lower() == "none":
|
|
106
|
+
# If storage account key access is disabled, and only Microsoft Entra ID authentication is available,
|
|
107
|
+
# the credentialsType will be "None" and we should not attempt to get the secrets.
|
|
108
|
+
blob_store_credential = self.get_credential()
|
|
109
|
+
else:
|
|
110
|
+
url = self._generate_path(
|
|
111
|
+
*PATH_ML_WORKSPACES, workspace_name, "datastores", "workspaceblobstore", "listSecrets"
|
|
112
|
+
)
|
|
113
|
+
secrets_response = self._http_client.request(
|
|
114
|
+
method="POST",
|
|
115
|
+
url=url,
|
|
116
|
+
json={
|
|
117
|
+
"expirableSecret": True,
|
|
118
|
+
"expireAfterHours": int(kwargs.get("key_expiration_hours", 1)),
|
|
119
|
+
},
|
|
120
|
+
params={
|
|
121
|
+
QUERY_KEY_API_VERSION: self._api_version,
|
|
122
|
+
},
|
|
123
|
+
headers=headers,
|
|
124
|
+
)
|
|
125
|
+
self._throw_on_http_error(secrets_response, "workspace datastore secrets")
|
|
126
|
+
|
|
127
|
+
secrets_json = secrets_response.json()
|
|
128
|
+
secrets_type = secrets_json["secretsType"].lower()
|
|
129
|
+
|
|
130
|
+
# As per this website, only SAS tokens, access tokens, or Entra IDs are valid for accessing blob data
|
|
131
|
+
# stores:
|
|
132
|
+
# https://learn.microsoft.com/rest/api/storageservices/authorize-requests-to-azure-storage.
|
|
133
|
+
if secrets_type == "sas":
|
|
134
|
+
blob_store_credential = AzureSasCredential(secrets_json["sasToken"])
|
|
135
|
+
elif secrets_type == "accountkey":
|
|
136
|
+
# To support older versions of azure-storage-blob better, we return a string here instead of
|
|
137
|
+
# an AzureNamedKeyCredential
|
|
138
|
+
blob_store_credential = secrets_json["key"]
|
|
139
|
+
else:
|
|
140
|
+
raise EvaluationException(
|
|
141
|
+
message=f"The '{account_name}' blob store does not use a recognized credential type.",
|
|
142
|
+
internal_message=f"The credential type is '{secrets_type}'",
|
|
143
|
+
target=ErrorTarget.EVALUATE,
|
|
144
|
+
category=ErrorCategory.INVALID_VALUE,
|
|
145
|
+
blame=ErrorBlame.SYSTEM_ERROR,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
return BlobStoreInfo(name, account_name, endpoint, container_name, blob_store_credential)
|
|
149
|
+
|
|
150
|
+
def workspace_get_info(self, workspace_name: str) -> Workspace:
|
|
151
|
+
# https://learn.microsoft.com/rest/api/azureml/workspaces/get?view=rest-azureml-2024-10-01
|
|
152
|
+
workspace_response = self._http_client.request(
|
|
153
|
+
"GET",
|
|
154
|
+
self._generate_path(*PATH_ML_WORKSPACES, workspace_name),
|
|
155
|
+
params={QUERY_KEY_API_VERSION: self._api_version},
|
|
156
|
+
headers=self._get_headers(),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
self._throw_on_http_error(workspace_response, f"get '{workspace_name}' workspace")
|
|
160
|
+
workspace = Workspace.deserialize(workspace_response)
|
|
161
|
+
return workspace
|
|
162
|
+
|
|
163
|
+
def _get_token_manager(self) -> AzureMLTokenManager:
|
|
164
|
+
# Lazy init since getting credentials in the constructor can take a long time in some situations
|
|
165
|
+
if self._token_manager is None:
|
|
166
|
+
with self._lock:
|
|
167
|
+
if self._token_manager is None:
|
|
168
|
+
self._token_manager = AzureMLTokenManager(
|
|
169
|
+
TokenScope.DEFAULT_AZURE_MANAGEMENT.value, self._logger, credential=self._credential
|
|
170
|
+
)
|
|
171
|
+
self._credential = self._token_manager.credential
|
|
172
|
+
|
|
173
|
+
return self._token_manager
|
|
174
|
+
|
|
175
|
+
@staticmethod
|
|
176
|
+
def _throw_on_http_error(response: HttpResponse, description: str, valid_status: Optional[Set[int]] = None) -> None:
|
|
177
|
+
if valid_status and (response.status_code in valid_status):
|
|
178
|
+
return
|
|
179
|
+
if response.status_code >= 200 and response.status_code < 300:
|
|
180
|
+
# nothing to see here, move along
|
|
181
|
+
return
|
|
182
|
+
|
|
183
|
+
message = f"The {description} request failed with HTTP {response.status_code}"
|
|
184
|
+
try:
|
|
185
|
+
error_json = response.json()["error"]
|
|
186
|
+
additional_info = f"({error_json['code']}) {error_json['message']}"
|
|
187
|
+
message += f" - {additional_info}"
|
|
188
|
+
except (JSONDecodeError, ValueError, KeyError):
|
|
189
|
+
pass
|
|
190
|
+
|
|
191
|
+
raise EvaluationException(
|
|
192
|
+
message=message,
|
|
193
|
+
target=ErrorTarget.EVALUATE,
|
|
194
|
+
category=ErrorCategory.FAILED_EXECUTION,
|
|
195
|
+
blame=ErrorBlame.SYSTEM_ERROR,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
def _generate_path(self, *paths: str) -> str:
|
|
199
|
+
sanitized_paths = [quote(path, safe="") for path in paths]
|
|
200
|
+
url = self._base_url + "/" + str.join("/", sanitized_paths)
|
|
201
|
+
return url
|
|
202
|
+
|
|
203
|
+
def _get_headers(self) -> Dict[str, str]:
|
|
204
|
+
return {"Authorization": f"Bearer {self.get_token().token}", "Content-Type": "application/json"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
# NOTE:
|
|
6
|
+
# This is a simplified version of the original code from azure-ai-ml:
|
|
7
|
+
# sdk\ml\azure-ai-ml\azure\ai\ml\_azure_environments.py
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
from typing import Any, Dict, Final, Mapping, Optional, Sequence, TypedDict
|
|
13
|
+
|
|
14
|
+
from azure.core import AsyncPipelineClient
|
|
15
|
+
from azure.core.configuration import Configuration
|
|
16
|
+
from azure.core.rest import HttpRequest
|
|
17
|
+
from azure.core.pipeline.policies import ProxyPolicy, AsyncRetryPolicy
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AzureEnvironmentMetadata(TypedDict):
|
|
21
|
+
"""Configuration for various Azure environments. All endpoints include a trailing slash."""
|
|
22
|
+
|
|
23
|
+
portal_endpoint: str
|
|
24
|
+
"""The management portal for the Azure environment (e.g. https://portal.azure.com/)"""
|
|
25
|
+
resource_manager_endpoint: str
|
|
26
|
+
"""The API endpoint for Azure control plan (e.g. https://management.azure.com/)"""
|
|
27
|
+
active_directory_endpoint: str
|
|
28
|
+
"""The active directory endpoint used for authentication (e.g. https://login.microsoftonline.com/)"""
|
|
29
|
+
aml_resource_endpoint: str
|
|
30
|
+
"""The endpoint for Azure Machine Learning resources (e.g. https://ml.azure.com/)"""
|
|
31
|
+
storage_suffix: str
|
|
32
|
+
"""The suffix to use for storage endpoint URLs (e.g. core.windows.net)"""
|
|
33
|
+
registry_discovery_endpoint: str
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
_ENV_ARM_CLOUD_METADATA_URL: Final[str] = "ARM_CLOUD_METADATA_URL"
|
|
37
|
+
_ENV_DEFAULT_CLOUD_NAME: Final[str] = "AZUREML_CURRENT_CLOUD"
|
|
38
|
+
_ENV_REGISTRY_DISCOVERY_URL: Final[str] = "REGISTRY_DISCOVERY_ENDPOINT_URL"
|
|
39
|
+
_ENV_REGISTRY_DISCOVERY_REGION: Final[str] = "REGISTRY_DISCOVERY_ENDPOINT_REGION"
|
|
40
|
+
_DEFAULT_REGISTRY_DISCOVERY_REGION: Final[str] = "west"
|
|
41
|
+
_DEFAULT_AZURE_ENV_NAME: Final[str] = "AzureCloud"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
_ASYNC_LOCK = asyncio.Lock()
|
|
45
|
+
_KNOWN_AZURE_ENVIRONMENTS: Dict[str, AzureEnvironmentMetadata] = {
|
|
46
|
+
_DEFAULT_AZURE_ENV_NAME: {
|
|
47
|
+
"portal_endpoint": "https://portal.azure.com/",
|
|
48
|
+
"resource_manager_endpoint": "https://management.azure.com/",
|
|
49
|
+
"active_directory_endpoint": "https://login.microsoftonline.com/",
|
|
50
|
+
"aml_resource_endpoint": "https://ml.azure.com/",
|
|
51
|
+
"storage_suffix": "core.windows.net",
|
|
52
|
+
"registry_discovery_endpoint": "https://eastus.api.azureml.ms/",
|
|
53
|
+
},
|
|
54
|
+
"AzureChinaCloud": {
|
|
55
|
+
"portal_endpoint": "https://portal.azure.cn/",
|
|
56
|
+
"resource_manager_endpoint": "https://management.chinacloudapi.cn/",
|
|
57
|
+
"active_directory_endpoint": "https://login.chinacloudapi.cn/",
|
|
58
|
+
"aml_resource_endpoint": "https://ml.azure.cn/",
|
|
59
|
+
"storage_suffix": "core.chinacloudapi.cn",
|
|
60
|
+
"registry_discovery_endpoint": "https://chinaeast2.api.ml.azure.cn/",
|
|
61
|
+
},
|
|
62
|
+
"AzureUSGovernment": {
|
|
63
|
+
"portal_endpoint": "https://portal.azure.us/",
|
|
64
|
+
"resource_manager_endpoint": "https://management.usgovcloudapi.net/",
|
|
65
|
+
"active_directory_endpoint": "https://login.microsoftonline.us/",
|
|
66
|
+
"aml_resource_endpoint": "https://ml.azure.us/",
|
|
67
|
+
"storage_suffix": "core.usgovcloudapi.net",
|
|
68
|
+
"registry_discovery_endpoint": "https://usgovarizona.api.ml.azure.us/",
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class AzureEnvironmentClient:
|
|
74
|
+
DEFAULT_API_VERSION: Final[str] = "2019-05-01"
|
|
75
|
+
DEFAULT_AZURE_CLOUD_NAME: Final[str] = _DEFAULT_AZURE_ENV_NAME
|
|
76
|
+
|
|
77
|
+
def __init__(self, *, base_url: Optional[str] = None, **kwargs: Any) -> None:
|
|
78
|
+
base_url = base_url if base_url is not None else AzureEnvironmentClient.get_default_metadata_url()
|
|
79
|
+
|
|
80
|
+
config: Configuration = kwargs.pop("config", Configuration(**kwargs))
|
|
81
|
+
if config.retry_policy is None:
|
|
82
|
+
config.retry_policy = AsyncRetryPolicy(**kwargs)
|
|
83
|
+
if config.proxy_policy is None and "proxy" in kwargs:
|
|
84
|
+
config.proxy_policy = ProxyPolicy(proxies={"http": kwargs["proxy"], "https": kwargs["proxy"]})
|
|
85
|
+
|
|
86
|
+
self._async_client = AsyncPipelineClient(base_url, config=config, **kwargs)
|
|
87
|
+
|
|
88
|
+
async def get_default_cloud_name_async(self, *, update_cached: bool = True) -> str:
|
|
89
|
+
current_cloud_env = os.getenv(_ENV_DEFAULT_CLOUD_NAME)
|
|
90
|
+
if current_cloud_env is not None:
|
|
91
|
+
return current_cloud_env
|
|
92
|
+
|
|
93
|
+
arm_metadata_url = os.getenv(_ENV_ARM_CLOUD_METADATA_URL)
|
|
94
|
+
if arm_metadata_url is None:
|
|
95
|
+
return _DEFAULT_AZURE_ENV_NAME
|
|
96
|
+
|
|
97
|
+
# load clouds from metadata url
|
|
98
|
+
clouds = await self.get_clouds_async(metadata_url=arm_metadata_url, update_cached=update_cached)
|
|
99
|
+
matched = next(filter(lambda t: t[1]["resource_manager_endpoint"] in arm_metadata_url, clouds.items()), None)
|
|
100
|
+
if matched is None:
|
|
101
|
+
return _DEFAULT_AZURE_ENV_NAME
|
|
102
|
+
|
|
103
|
+
os.environ[_ENV_DEFAULT_CLOUD_NAME] = matched[0]
|
|
104
|
+
return matched[0]
|
|
105
|
+
|
|
106
|
+
async def get_cloud_async(self, name: str, *, update_cached: bool = True) -> Optional[AzureEnvironmentMetadata]:
|
|
107
|
+
default_endpoint: Optional[str]
|
|
108
|
+
|
|
109
|
+
def case_insensitive_match(d: Mapping[str, Any], key: str) -> Optional[Any]:
|
|
110
|
+
key = key.strip().lower()
|
|
111
|
+
return next((v for k, v in d.items() if k.strip().lower() == key), None)
|
|
112
|
+
|
|
113
|
+
async with _ASYNC_LOCK:
|
|
114
|
+
cloud = _KNOWN_AZURE_ENVIRONMENTS.get(name) or case_insensitive_match(_KNOWN_AZURE_ENVIRONMENTS, name)
|
|
115
|
+
if cloud:
|
|
116
|
+
return cloud
|
|
117
|
+
default_endpoint = _KNOWN_AZURE_ENVIRONMENTS.get(_DEFAULT_AZURE_ENV_NAME, {}).get(
|
|
118
|
+
"resource_manager_endpoint"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
metadata_url = self.get_default_metadata_url(default_endpoint)
|
|
122
|
+
clouds = await self.get_clouds_async(metadata_url=metadata_url, update_cached=update_cached)
|
|
123
|
+
cloud_metadata = clouds.get(name) or case_insensitive_match(clouds, name)
|
|
124
|
+
|
|
125
|
+
return cloud_metadata
|
|
126
|
+
|
|
127
|
+
async def get_clouds_async(
|
|
128
|
+
self, *, metadata_url: Optional[str] = None, update_cached: bool = True
|
|
129
|
+
) -> Mapping[str, AzureEnvironmentMetadata]:
|
|
130
|
+
metadata_url = metadata_url or self.get_default_metadata_url()
|
|
131
|
+
|
|
132
|
+
clouds: Mapping[str, AzureEnvironmentMetadata]
|
|
133
|
+
async with self._async_client.send_request(HttpRequest("GET", metadata_url)) as response: # type: ignore
|
|
134
|
+
response.raise_for_status()
|
|
135
|
+
clouds = await self._parse_cloud_endpoints_async(response.json())
|
|
136
|
+
|
|
137
|
+
if update_cached:
|
|
138
|
+
async with _ASYNC_LOCK:
|
|
139
|
+
recursive_update(_KNOWN_AZURE_ENVIRONMENTS, clouds)
|
|
140
|
+
return clouds
|
|
141
|
+
|
|
142
|
+
async def close(self) -> None:
|
|
143
|
+
await self._async_client.close()
|
|
144
|
+
|
|
145
|
+
@staticmethod
|
|
146
|
+
def get_default_metadata_url(default_endpoint: Optional[str] = None) -> str:
|
|
147
|
+
default_endpoint = default_endpoint or "https://management.azure.com/"
|
|
148
|
+
metadata_url = os.getenv(
|
|
149
|
+
_ENV_ARM_CLOUD_METADATA_URL,
|
|
150
|
+
f"{default_endpoint}metadata/endpoints?api-version={AzureEnvironmentClient.DEFAULT_API_VERSION}",
|
|
151
|
+
)
|
|
152
|
+
return metadata_url
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
async def _get_registry_discovery_url_async(cloud_name: str, cloud_suffix: str) -> str:
|
|
156
|
+
async with _ASYNC_LOCK:
|
|
157
|
+
discovery_url = _KNOWN_AZURE_ENVIRONMENTS.get(cloud_name, {}).get("registry_discovery_endpoint")
|
|
158
|
+
if discovery_url:
|
|
159
|
+
return discovery_url
|
|
160
|
+
|
|
161
|
+
discovery_url = os.getenv(_ENV_REGISTRY_DISCOVERY_URL)
|
|
162
|
+
if discovery_url is not None:
|
|
163
|
+
return discovery_url
|
|
164
|
+
|
|
165
|
+
region = os.getenv(_ENV_REGISTRY_DISCOVERY_REGION, _DEFAULT_REGISTRY_DISCOVERY_REGION)
|
|
166
|
+
return f"https://{cloud_name.lower()}{region}.api.ml.azure.{cloud_suffix}/"
|
|
167
|
+
|
|
168
|
+
@staticmethod
|
|
169
|
+
async def _parse_cloud_endpoints_async(data: Any) -> Mapping[str, AzureEnvironmentMetadata]:
|
|
170
|
+
# If there is only one cloud, you will get a dict, otherwise a list of dicts
|
|
171
|
+
cloud_data: Sequence[Mapping[str, Any]] = data if not isinstance(data, dict) else [data]
|
|
172
|
+
clouds: Dict[str, AzureEnvironmentMetadata] = {}
|
|
173
|
+
|
|
174
|
+
def append_trailing_slash(url: str) -> str:
|
|
175
|
+
return url if url.endswith("/") else f"{url}/"
|
|
176
|
+
|
|
177
|
+
for cloud in cloud_data:
|
|
178
|
+
try:
|
|
179
|
+
name: str = cloud["name"]
|
|
180
|
+
portal_endpoint: str = cloud["portal"]
|
|
181
|
+
cloud_suffix = ".".join(portal_endpoint.split(".")[2:]).replace("/", "")
|
|
182
|
+
discovery_url = await AzureEnvironmentClient._get_registry_discovery_url_async(name, cloud_suffix)
|
|
183
|
+
clouds[name] = {
|
|
184
|
+
"portal_endpoint": append_trailing_slash(portal_endpoint),
|
|
185
|
+
"resource_manager_endpoint": append_trailing_slash(cloud["resourceManager"]),
|
|
186
|
+
"active_directory_endpoint": append_trailing_slash(cloud["authentication"]["loginEndpoint"]),
|
|
187
|
+
"aml_resource_endpoint": append_trailing_slash(f"https://ml.azure.{cloud_suffix}/"),
|
|
188
|
+
"storage_suffix": cloud["suffixes"]["storage"],
|
|
189
|
+
"registry_discovery_endpoint": append_trailing_slash(discovery_url),
|
|
190
|
+
}
|
|
191
|
+
except KeyError:
|
|
192
|
+
continue
|
|
193
|
+
|
|
194
|
+
return clouds
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def recursive_update(d: Dict, u: Mapping) -> None:
|
|
198
|
+
"""Recursively update a dictionary.
|
|
199
|
+
|
|
200
|
+
:param Dict d: The dictionary to update.
|
|
201
|
+
:param Mapping u: The mapping to update from.
|
|
202
|
+
"""
|
|
203
|
+
for k, v in u.items():
|
|
204
|
+
if isinstance(v, Dict) and k in d:
|
|
205
|
+
recursive_update(d[k], v)
|
|
206
|
+
else:
|
|
207
|
+
d[k] = v
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
# pylint: disable=too-many-instance-attributes
|
|
6
|
+
# pylint: disable=too-many-locals
|
|
7
|
+
# pylint: disable=line-too-long
|
|
8
|
+
|
|
9
|
+
from typing import Dict, List, NamedTuple, Optional, Union
|
|
10
|
+
from msrest.serialization import Model
|
|
11
|
+
from azure.core.credentials import AzureSasCredential, TokenCredential
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BlobStoreInfo(NamedTuple):
|
|
15
|
+
name: str
|
|
16
|
+
account_name: str
|
|
17
|
+
endpoint: str
|
|
18
|
+
container_name: str
|
|
19
|
+
credential: Optional[Union[AzureSasCredential, TokenCredential, str]]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class WorkspaceHubConfig(Model):
|
|
23
|
+
"""WorkspaceHub's configuration object."""
|
|
24
|
+
|
|
25
|
+
_attribute_map = {
|
|
26
|
+
"additional_workspace_storage_accounts": {"key": "additionalWorkspaceStorageAccounts", "type": "[str]"},
|
|
27
|
+
"default_workspace_resource_group": {"key": "defaultWorkspaceResourceGroup", "type": "str"},
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
*,
|
|
33
|
+
additional_workspace_storage_accounts: Optional[List[str]] = None,
|
|
34
|
+
default_workspace_resource_group: Optional[str] = None,
|
|
35
|
+
**kwargs
|
|
36
|
+
):
|
|
37
|
+
super(WorkspaceHubConfig, self).__init__(**kwargs)
|
|
38
|
+
self.additional_workspace_storage_accounts = additional_workspace_storage_accounts
|
|
39
|
+
self.default_workspace_resource_group = default_workspace_resource_group
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Workspace(Model):
|
|
43
|
+
"""An object that represents a machine learning workspace.
|
|
44
|
+
|
|
45
|
+
Variables are only populated by the server, and will be ignored when sending a request."""
|
|
46
|
+
|
|
47
|
+
_validation = {
|
|
48
|
+
"id": {"readonly": True},
|
|
49
|
+
"name": {"readonly": True},
|
|
50
|
+
"type": {"readonly": True},
|
|
51
|
+
#'system_data': {'readonly': True},
|
|
52
|
+
"agents_endpoint_uri": {"readonly": True},
|
|
53
|
+
"ml_flow_tracking_uri": {"readonly": True},
|
|
54
|
+
#'notebook_info': {'readonly': True},
|
|
55
|
+
# "private_endpoint_connections": {"readonly": True},
|
|
56
|
+
#'private_link_count': {'readonly': True},
|
|
57
|
+
"provisioning_state": {"readonly": True},
|
|
58
|
+
"service_provisioned_resource_group": {"readonly": True},
|
|
59
|
+
"storage_hns_enabled": {"readonly": True},
|
|
60
|
+
"tenant_id": {"readonly": True},
|
|
61
|
+
"workspace_id": {"readonly": True},
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
_attribute_map = {
|
|
65
|
+
"id": {"key": "id", "type": "str"},
|
|
66
|
+
"name": {"key": "name", "type": "str"},
|
|
67
|
+
"type": {"key": "type", "type": "str"},
|
|
68
|
+
#'system_data': {'key': 'systemData', 'type': 'SystemData'},
|
|
69
|
+
#'identity': {'key': 'identity', 'type': 'ManagedServiceIdentity'},
|
|
70
|
+
"kind": {"key": "kind", "type": "str"},
|
|
71
|
+
"location": {"key": "location", "type": "str"},
|
|
72
|
+
#'sku': {'key': 'sku', 'type': 'Sku'},
|
|
73
|
+
"tags": {"key": "tags", "type": "{str}"},
|
|
74
|
+
"agents_endpoint_uri": {"key": "properties.agentsEndpointUri", "type": "str"},
|
|
75
|
+
"allow_public_access_when_behind_vnet": {"key": "properties.allowPublicAccessWhenBehindVnet", "type": "bool"},
|
|
76
|
+
"allow_role_assignment_on_rg": {"key": "properties.allowRoleAssignmentOnRG", "type": "bool"},
|
|
77
|
+
"application_insights": {"key": "properties.applicationInsights", "type": "str"},
|
|
78
|
+
"associated_workspaces": {"key": "properties.associatedWorkspaces", "type": "[str]"},
|
|
79
|
+
"container_registries": {"key": "properties.containerRegistries", "type": "[str]"},
|
|
80
|
+
"container_registry": {"key": "properties.containerRegistry", "type": "str"},
|
|
81
|
+
"description": {"key": "properties.description", "type": "str"},
|
|
82
|
+
"discovery_url": {"key": "properties.discoveryUrl", "type": "str"},
|
|
83
|
+
"enable_data_isolation": {"key": "properties.enableDataIsolation", "type": "bool"},
|
|
84
|
+
"enable_service_side_cmk_encryption": {"key": "properties.enableServiceSideCMKEncryption", "type": "bool"},
|
|
85
|
+
"enable_simplified_cmk": {"key": "properties.enableSimplifiedCmk", "type": "bool"},
|
|
86
|
+
"enable_software_bill_of_materials": {"key": "properties.enableSoftwareBillOfMaterials", "type": "bool"},
|
|
87
|
+
#'encryption': {'key': 'properties.encryption', 'type': 'EncryptionProperty'},
|
|
88
|
+
"existing_workspaces": {"key": "properties.existingWorkspaces", "type": "[str]"},
|
|
89
|
+
#'feature_store_settings': {'key': 'properties.featureStoreSettings', 'type': 'FeatureStoreSettings'},
|
|
90
|
+
"friendly_name": {"key": "properties.friendlyName", "type": "str"},
|
|
91
|
+
"hbi_workspace": {"key": "properties.hbiWorkspace", "type": "bool"},
|
|
92
|
+
"hub_resource_id": {"key": "properties.hubResourceId", "type": "str"},
|
|
93
|
+
"image_build_compute": {"key": "properties.imageBuildCompute", "type": "str"},
|
|
94
|
+
"ip_allowlist": {"key": "properties.ipAllowlist", "type": "[str]"},
|
|
95
|
+
"key_vault": {"key": "properties.keyVault", "type": "str"},
|
|
96
|
+
"key_vaults": {"key": "properties.keyVaults", "type": "[str]"},
|
|
97
|
+
#'managed_network': {'key': 'properties.managedNetwork', 'type': 'ManagedNetworkSettings'},
|
|
98
|
+
"ml_flow_tracking_uri": {"key": "properties.mlFlowTrackingUri", "type": "str"},
|
|
99
|
+
#'network_acls': {'key': 'properties.networkAcls', 'type': 'NetworkAcls'},
|
|
100
|
+
#'notebook_info': {'key': 'properties.notebookInfo', 'type': 'NotebookResourceInfo'},
|
|
101
|
+
"primary_user_assigned_identity": {"key": "properties.primaryUserAssignedIdentity", "type": "str"},
|
|
102
|
+
# "private_endpoint_connections": {
|
|
103
|
+
# "key": "properties.privateEndpointConnections",
|
|
104
|
+
# "type": "[PrivateEndpointConnection]",
|
|
105
|
+
# },
|
|
106
|
+
"private_link_count": {"key": "properties.privateLinkCount", "type": "int"},
|
|
107
|
+
"provision_network_now": {"key": "properties.provisionNetworkNow", "type": "bool"},
|
|
108
|
+
"provisioning_state": {"key": "properties.provisioningState", "type": "str"},
|
|
109
|
+
#'public_network_access': {'key': 'properties.publicNetworkAccess', 'type': 'str'},
|
|
110
|
+
#'serverless_compute_settings': {'key': 'properties.serverlessComputeSettings', 'type': 'ServerlessComputeSettings'},
|
|
111
|
+
#'service_managed_resources_settings': {'key': 'properties.serviceManagedResourcesSettings', 'type': 'ServiceManagedResourcesSettings'},
|
|
112
|
+
"service_provisioned_resource_group": {"key": "properties.serviceProvisionedResourceGroup", "type": "str"},
|
|
113
|
+
#'shared_private_link_resources': {'key': 'properties.sharedPrivateLinkResources', 'type': '[SharedPrivateLinkResource]'},
|
|
114
|
+
"soft_delete_retention_in_days": {"key": "properties.softDeleteRetentionInDays", "type": "int"},
|
|
115
|
+
"storage_account": {"key": "properties.storageAccount", "type": "str"},
|
|
116
|
+
"storage_accounts": {"key": "properties.storageAccounts", "type": "[str]"},
|
|
117
|
+
"storage_hns_enabled": {"key": "properties.storageHnsEnabled", "type": "bool"},
|
|
118
|
+
#'system_datastores_auth_mode': {'key': 'properties.systemDatastoresAuthMode', 'type': 'str'},
|
|
119
|
+
"tenant_id": {"key": "properties.tenantId", "type": "str"},
|
|
120
|
+
"v1_legacy_mode": {"key": "properties.v1LegacyMode", "type": "bool"},
|
|
121
|
+
"workspace_hub_config": {"key": "properties.workspaceHubConfig", "type": "WorkspaceHubConfig"},
|
|
122
|
+
"workspace_id": {"key": "properties.workspaceId", "type": "str"},
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
def __init__(
|
|
126
|
+
self,
|
|
127
|
+
*,
|
|
128
|
+
# system_data: Optional[SystemData] = None,
|
|
129
|
+
# identity: Optional["ManagedServiceIdentity"] = None,
|
|
130
|
+
kind: Optional[str] = None,
|
|
131
|
+
location: Optional[str] = None,
|
|
132
|
+
# sku: Optional["Sku"] = None,
|
|
133
|
+
tags: Optional[Dict[str, str]] = None,
|
|
134
|
+
allow_public_access_when_behind_vnet: Optional[bool] = None,
|
|
135
|
+
allow_role_assignment_on_rg: Optional[bool] = None,
|
|
136
|
+
application_insights: Optional[str] = None,
|
|
137
|
+
associated_workspaces: Optional[List[str]] = None,
|
|
138
|
+
container_registries: Optional[List[str]] = None,
|
|
139
|
+
container_registry: Optional[str] = None,
|
|
140
|
+
description: Optional[str] = None,
|
|
141
|
+
discovery_url: Optional[str] = None,
|
|
142
|
+
enable_data_isolation: Optional[bool] = None,
|
|
143
|
+
enable_service_side_cmk_encryption: Optional[bool] = None,
|
|
144
|
+
enable_simplified_cmk: Optional[bool] = None,
|
|
145
|
+
enable_software_bill_of_materials: Optional[bool] = None,
|
|
146
|
+
# encryption: Optional["EncryptionProperty"] = None,
|
|
147
|
+
existing_workspaces: Optional[List[str]] = None,
|
|
148
|
+
# feature_store_settings: Optional["FeatureStoreSettings"] = None,
|
|
149
|
+
friendly_name: Optional[str] = None,
|
|
150
|
+
hbi_workspace: Optional[bool] = None,
|
|
151
|
+
hub_resource_id: Optional[str] = None,
|
|
152
|
+
image_build_compute: Optional[str] = None,
|
|
153
|
+
ip_allowlist: Optional[List[str]] = None,
|
|
154
|
+
key_vault: Optional[str] = None,
|
|
155
|
+
key_vaults: Optional[List[str]] = None,
|
|
156
|
+
# managed_network: Optional["ManagedNetworkSettings"] = None,
|
|
157
|
+
# network_acls: Optional["NetworkAcls"] = None,
|
|
158
|
+
primary_user_assigned_identity: Optional[str] = None,
|
|
159
|
+
provision_network_now: Optional[bool] = None,
|
|
160
|
+
# public_network_access: Optional[Union[str, "PublicNetworkAccessType"]] = None,
|
|
161
|
+
# serverless_compute_settings: Optional["ServerlessComputeSettings"] = None,
|
|
162
|
+
# service_managed_resources_settings: Optional["ServiceManagedResourcesSettings"] = None,
|
|
163
|
+
# shared_private_link_resources: Optional[List["SharedPrivateLinkResource"]] = None,
|
|
164
|
+
soft_delete_retention_in_days: Optional[int] = None,
|
|
165
|
+
storage_account: Optional[str] = None,
|
|
166
|
+
storage_accounts: Optional[List[str]] = None,
|
|
167
|
+
# system_datastores_auth_mode: Optional[Union[str, "SystemDatastoresAuthMode"]] = None,
|
|
168
|
+
v1_legacy_mode: Optional[bool] = None,
|
|
169
|
+
workspace_hub_config: Optional["WorkspaceHubConfig"] = None,
|
|
170
|
+
**kwargs
|
|
171
|
+
):
|
|
172
|
+
super(Workspace, self).__init__(**kwargs)
|
|
173
|
+
self.id: Optional[str] = None
|
|
174
|
+
self.name: Optional[str] = None
|
|
175
|
+
self.type: Optional[str] = None
|
|
176
|
+
# self.system_data = system_data
|
|
177
|
+
# self.identity = identity
|
|
178
|
+
self.kind = kind
|
|
179
|
+
self.location = location
|
|
180
|
+
# self.sku = sku
|
|
181
|
+
self.tags = tags
|
|
182
|
+
self.agents_endpoint_uri = None
|
|
183
|
+
self.allow_public_access_when_behind_vnet = allow_public_access_when_behind_vnet
|
|
184
|
+
self.allow_role_assignment_on_rg = allow_role_assignment_on_rg
|
|
185
|
+
self.application_insights = application_insights
|
|
186
|
+
self.associated_workspaces = associated_workspaces
|
|
187
|
+
self.container_registries = container_registries
|
|
188
|
+
self.container_registry = container_registry
|
|
189
|
+
self.description = description
|
|
190
|
+
self.discovery_url = discovery_url
|
|
191
|
+
self.enable_data_isolation = enable_data_isolation
|
|
192
|
+
self.enable_service_side_cmk_encryption = enable_service_side_cmk_encryption
|
|
193
|
+
self.enable_simplified_cmk = enable_simplified_cmk
|
|
194
|
+
self.enable_software_bill_of_materials = enable_software_bill_of_materials
|
|
195
|
+
# self.encryption = encryption
|
|
196
|
+
self.existing_workspaces = existing_workspaces
|
|
197
|
+
# self.feature_store_settings = feature_store_settings
|
|
198
|
+
self.friendly_name = friendly_name
|
|
199
|
+
self.hbi_workspace = hbi_workspace
|
|
200
|
+
self.hub_resource_id = hub_resource_id
|
|
201
|
+
self.image_build_compute = image_build_compute
|
|
202
|
+
self.ip_allowlist = ip_allowlist
|
|
203
|
+
self.key_vault = key_vault
|
|
204
|
+
self.key_vaults = key_vaults
|
|
205
|
+
# self.managed_network = managed_network
|
|
206
|
+
self.ml_flow_tracking_uri = None
|
|
207
|
+
# self.network_acls = network_acls
|
|
208
|
+
# self.notebook_info = None
|
|
209
|
+
self.primary_user_assigned_identity = primary_user_assigned_identity
|
|
210
|
+
# self.private_endpoint_connections = None
|
|
211
|
+
self.private_link_count = None
|
|
212
|
+
self.provision_network_now = provision_network_now
|
|
213
|
+
self.provisioning_state = None
|
|
214
|
+
# self.public_network_access = public_network_access
|
|
215
|
+
# self.serverless_compute_settings = serverless_compute_settings
|
|
216
|
+
# self.service_managed_resources_settings = service_managed_resources_settings
|
|
217
|
+
self.service_provisioned_resource_group = None
|
|
218
|
+
# self.shared_private_link_resources = shared_private_link_resources
|
|
219
|
+
self.soft_delete_retention_in_days = soft_delete_retention_in_days
|
|
220
|
+
self.storage_account = storage_account
|
|
221
|
+
self.storage_accounts = storage_accounts
|
|
222
|
+
self.storage_hns_enabled = None
|
|
223
|
+
# self.system_datastores_auth_mode = system_datastores_auth_mode
|
|
224
|
+
self.tenant_id = None
|
|
225
|
+
self.v1_legacy_mode = v1_legacy_mode
|
|
226
|
+
self.workspace_hub_config = workspace_hub_config
|
|
227
|
+
self.workspace_id = None
|