azure-ai-evaluation 0.0.0b0__py3-none-any.whl → 1.0.0b1__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 +60 -0
- azure/ai/evaluation/_common/__init__.py +16 -0
- azure/ai/evaluation/_common/constants.py +65 -0
- azure/ai/evaluation/_common/rai_service.py +452 -0
- azure/ai/evaluation/_common/utils.py +87 -0
- azure/ai/evaluation/_constants.py +50 -0
- azure/ai/evaluation/_evaluate/__init__.py +3 -0
- azure/ai/evaluation/_evaluate/_batch_run_client/__init__.py +8 -0
- azure/ai/evaluation/_evaluate/_batch_run_client/batch_run_context.py +72 -0
- azure/ai/evaluation/_evaluate/_batch_run_client/code_client.py +150 -0
- azure/ai/evaluation/_evaluate/_batch_run_client/proxy_client.py +61 -0
- azure/ai/evaluation/_evaluate/_eval_run.py +494 -0
- azure/ai/evaluation/_evaluate/_evaluate.py +689 -0
- azure/ai/evaluation/_evaluate/_telemetry/__init__.py +174 -0
- azure/ai/evaluation/_evaluate/_utils.py +237 -0
- azure/ai/evaluation/_evaluators/__init__.py +3 -0
- azure/ai/evaluation/_evaluators/_bleu/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_bleu/_bleu.py +73 -0
- azure/ai/evaluation/_evaluators/_chat/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_chat/_chat.py +350 -0
- azure/ai/evaluation/_evaluators/_chat/retrieval/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_chat/retrieval/_retrieval.py +163 -0
- azure/ai/evaluation/_evaluators/_chat/retrieval/retrieval.prompty +48 -0
- azure/ai/evaluation/_evaluators/_coherence/__init__.py +7 -0
- azure/ai/evaluation/_evaluators/_coherence/_coherence.py +122 -0
- azure/ai/evaluation/_evaluators/_coherence/coherence.prompty +62 -0
- azure/ai/evaluation/_evaluators/_content_safety/__init__.py +21 -0
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety.py +108 -0
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety_base.py +66 -0
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety_chat.py +296 -0
- azure/ai/evaluation/_evaluators/_content_safety/_hate_unfairness.py +78 -0
- azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py +76 -0
- azure/ai/evaluation/_evaluators/_content_safety/_sexual.py +76 -0
- azure/ai/evaluation/_evaluators/_content_safety/_violence.py +76 -0
- azure/ai/evaluation/_evaluators/_eci/__init__.py +0 -0
- azure/ai/evaluation/_evaluators/_eci/_eci.py +99 -0
- azure/ai/evaluation/_evaluators/_f1_score/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_f1_score/_f1_score.py +141 -0
- azure/ai/evaluation/_evaluators/_fluency/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_fluency/_fluency.py +122 -0
- azure/ai/evaluation/_evaluators/_fluency/fluency.prompty +61 -0
- azure/ai/evaluation/_evaluators/_gleu/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_gleu/_gleu.py +71 -0
- azure/ai/evaluation/_evaluators/_groundedness/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +123 -0
- azure/ai/evaluation/_evaluators/_groundedness/groundedness.prompty +54 -0
- azure/ai/evaluation/_evaluators/_meteor/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_meteor/_meteor.py +96 -0
- azure/ai/evaluation/_evaluators/_protected_material/__init__.py +5 -0
- azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py +104 -0
- azure/ai/evaluation/_evaluators/_protected_materials/__init__.py +5 -0
- azure/ai/evaluation/_evaluators/_protected_materials/_protected_materials.py +104 -0
- azure/ai/evaluation/_evaluators/_qa/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_qa/_qa.py +111 -0
- azure/ai/evaluation/_evaluators/_relevance/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_relevance/_relevance.py +131 -0
- azure/ai/evaluation/_evaluators/_relevance/relevance.prompty +69 -0
- azure/ai/evaluation/_evaluators/_rouge/__init__.py +10 -0
- azure/ai/evaluation/_evaluators/_rouge/_rouge.py +98 -0
- azure/ai/evaluation/_evaluators/_similarity/__init__.py +9 -0
- azure/ai/evaluation/_evaluators/_similarity/_similarity.py +130 -0
- azure/ai/evaluation/_evaluators/_similarity/similarity.prompty +71 -0
- azure/ai/evaluation/_evaluators/_xpia/__init__.py +5 -0
- azure/ai/evaluation/_evaluators/_xpia/xpia.py +140 -0
- azure/ai/evaluation/_exceptions.py +107 -0
- azure/ai/evaluation/_http_utils.py +395 -0
- azure/ai/evaluation/_model_configurations.py +27 -0
- azure/ai/evaluation/_user_agent.py +6 -0
- azure/ai/evaluation/_version.py +5 -0
- azure/ai/evaluation/py.typed +0 -0
- azure/ai/evaluation/simulator/__init__.py +15 -0
- azure/ai/evaluation/simulator/_adversarial_scenario.py +27 -0
- azure/ai/evaluation/simulator/_adversarial_simulator.py +450 -0
- azure/ai/evaluation/simulator/_constants.py +17 -0
- azure/ai/evaluation/simulator/_conversation/__init__.py +315 -0
- azure/ai/evaluation/simulator/_conversation/_conversation.py +178 -0
- azure/ai/evaluation/simulator/_conversation/constants.py +30 -0
- azure/ai/evaluation/simulator/_direct_attack_simulator.py +252 -0
- azure/ai/evaluation/simulator/_helpers/__init__.py +4 -0
- azure/ai/evaluation/simulator/_helpers/_language_suffix_mapping.py +17 -0
- azure/ai/evaluation/simulator/_helpers/_simulator_data_classes.py +93 -0
- azure/ai/evaluation/simulator/_indirect_attack_simulator.py +207 -0
- azure/ai/evaluation/simulator/_model_tools/__init__.py +23 -0
- azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +147 -0
- azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +228 -0
- azure/ai/evaluation/simulator/_model_tools/_rai_client.py +157 -0
- azure/ai/evaluation/simulator/_model_tools/_template_handler.py +157 -0
- azure/ai/evaluation/simulator/_model_tools/models.py +616 -0
- azure/ai/evaluation/simulator/_prompty/task_query_response.prompty +69 -0
- azure/ai/evaluation/simulator/_prompty/task_simulate.prompty +36 -0
- azure/ai/evaluation/simulator/_tracing.py +92 -0
- azure/ai/evaluation/simulator/_utils.py +111 -0
- azure/ai/evaluation/simulator/simulator.py +579 -0
- azure_ai_evaluation-1.0.0b1.dist-info/METADATA +377 -0
- azure_ai_evaluation-1.0.0b1.dist-info/RECORD +97 -0
- {azure_ai_evaluation-0.0.0b0.dist-info → azure_ai_evaluation-1.0.0b1.dist-info}/WHEEL +1 -1
- azure_ai_evaluation-1.0.0b1.dist-info/top_level.txt +1 -0
- azure_ai_evaluation-0.0.0b0.dist-info/METADATA +0 -7
- azure_ai_evaluation-0.0.0b0.dist-info/RECORD +0 -4
- azure_ai_evaluation-0.0.0b0.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from promptflow._utils.async_utils import async_run_allowing_running_loop
|
|
8
|
+
|
|
9
|
+
from azure.ai.evaluation._common.constants import EvaluationMetrics
|
|
10
|
+
from azure.ai.evaluation._common.rai_service import evaluate_with_rai_service
|
|
11
|
+
from azure.ai.evaluation._exceptions import EvaluationException, ErrorBlame, ErrorCategory, ErrorTarget
|
|
12
|
+
from azure.ai.evaluation._model_configurations import AzureAIProject
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class IndirectAttackEvaluator:
|
|
18
|
+
"""A Cross-Domain Prompt Injection Attack (XPIA) jailbreak evaluator.
|
|
19
|
+
|
|
20
|
+
Detect whether cross domain injected attacks are present in your AI system's response.
|
|
21
|
+
|
|
22
|
+
:param azure_ai_project: The scope of the Azure AI project. It contains subscription id, resource group, and project
|
|
23
|
+
name.
|
|
24
|
+
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
|
|
25
|
+
:param eval_last_turn: Set to True to evaluate only the most recent exchange in the dialogue,
|
|
26
|
+
focusing on the latest user inquiry and the assistant's corresponding response. Defaults to False
|
|
27
|
+
:type eval_last_turn: bool
|
|
28
|
+
:param credential: The credential for connecting to Azure AI project.
|
|
29
|
+
:type credential: ~azure.core.credentials.TokenCredential
|
|
30
|
+
:return: A function that evaluates and generates metrics for XPIA chat scenario. Metrics include the overall
|
|
31
|
+
evaluation label and reason for the Q/A Pair, as well as sub-labels for manipulated content, intrusion, and
|
|
32
|
+
information.
|
|
33
|
+
:rtype: Callable
|
|
34
|
+
**Usage**
|
|
35
|
+
|
|
36
|
+
.. code-block:: python
|
|
37
|
+
|
|
38
|
+
eval_fn = IndirectAttackEvaluator(model_config)
|
|
39
|
+
result = eval_fn(query="What is the capital of France?", response="Paris.")
|
|
40
|
+
|
|
41
|
+
**Output format for question-answer pair**
|
|
42
|
+
|
|
43
|
+
.. code-block:: python
|
|
44
|
+
|
|
45
|
+
{
|
|
46
|
+
'xpia_label': False,
|
|
47
|
+
'xpia_reason': 'The conversation does not contain any manipulated content, intrusion or
|
|
48
|
+
information gathering.'
|
|
49
|
+
'xpia_information_gathering': False,
|
|
50
|
+
'xpia_intrusion': False
|
|
51
|
+
'xpia_manipulated_content': False
|
|
52
|
+
}
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, azure_ai_project: dict, eval_last_turn: bool = False, credential=None):
|
|
56
|
+
self._evaluator = _IndirectAttackEvaluator(azure_ai_project, credential)
|
|
57
|
+
self._eval_last_turn = eval_last_turn
|
|
58
|
+
|
|
59
|
+
def __call__(
|
|
60
|
+
self,
|
|
61
|
+
*,
|
|
62
|
+
query: Optional[str],
|
|
63
|
+
response: Optional[str],
|
|
64
|
+
**kwargs,
|
|
65
|
+
):
|
|
66
|
+
"""
|
|
67
|
+
Evaluates content according to the presence of attacks injected into the conversation context to
|
|
68
|
+
interrupt normal expected functionality by eliciting manipulated content, intrusion and attempting
|
|
69
|
+
to gather information outside the scope of your AI system.
|
|
70
|
+
:keyword query: The query to be evaluated. Mutually exclusive with 'conversation'.
|
|
71
|
+
:paramtype query: Optional[str]
|
|
72
|
+
:keyword response: The response to be evaluated. Mutually exclusive with 'conversation'.
|
|
73
|
+
:paramtype response: Optional[str]
|
|
74
|
+
:return: The evaluation scores and reasoning.
|
|
75
|
+
:rtype: dict
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
return self._evaluator(query=query, response=response, **kwargs)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class _AsyncIndirectAttackEvaluator:
|
|
82
|
+
def __init__(self, azure_ai_project: dict, credential=None):
|
|
83
|
+
self._azure_ai_project = azure_ai_project
|
|
84
|
+
self._credential = credential
|
|
85
|
+
|
|
86
|
+
async def __call__(self, *, query: str, response: str, **kwargs):
|
|
87
|
+
"""
|
|
88
|
+
Evaluates content according to this evaluator's metric.
|
|
89
|
+
:keyword query: The query to be evaluated.
|
|
90
|
+
:paramtype query: str
|
|
91
|
+
:keyword response: The response to be evaluated.
|
|
92
|
+
:paramtype response: str
|
|
93
|
+
:return: The evaluation score computation based on the metric (self.metric).
|
|
94
|
+
:rtype: Any
|
|
95
|
+
"""
|
|
96
|
+
# Validate inputs
|
|
97
|
+
# Raises value error if failed, so execution alone signifies success.
|
|
98
|
+
if not (query and query.strip() and query != "None") or not (
|
|
99
|
+
response and response.strip() and response != "None"
|
|
100
|
+
):
|
|
101
|
+
msg = "Both 'query' and 'response' must be non-empty strings."
|
|
102
|
+
raise EvaluationException(
|
|
103
|
+
message=msg,
|
|
104
|
+
internal_message=msg,
|
|
105
|
+
error_category=ErrorCategory.MISSING_FIELD,
|
|
106
|
+
error_blame=ErrorBlame.USER_ERROR,
|
|
107
|
+
error_target=ErrorTarget.INDIRECT_ATTACK_EVALUATOR,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Run score computation based on supplied metric.
|
|
111
|
+
result = await evaluate_with_rai_service(
|
|
112
|
+
metric_name=EvaluationMetrics.XPIA,
|
|
113
|
+
query=query,
|
|
114
|
+
response=response,
|
|
115
|
+
project_scope=self._azure_ai_project,
|
|
116
|
+
credential=self._credential,
|
|
117
|
+
)
|
|
118
|
+
return result
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class _IndirectAttackEvaluator:
|
|
122
|
+
def __init__(self, azure_ai_project: dict, credential=None):
|
|
123
|
+
self._async_evaluator = _AsyncIndirectAttackEvaluator(azure_ai_project, credential)
|
|
124
|
+
|
|
125
|
+
def __call__(self, *, query: str, response: str, **kwargs):
|
|
126
|
+
"""
|
|
127
|
+
Evaluates XPIA content.
|
|
128
|
+
:keyword query: The query to be evaluated.
|
|
129
|
+
:paramtype query: str
|
|
130
|
+
:keyword response: The response to be evaluated.
|
|
131
|
+
:paramtype response: str
|
|
132
|
+
:keyword context: The context to be evaluated.
|
|
133
|
+
:paramtype context: str
|
|
134
|
+
:return: The XPIA score.
|
|
135
|
+
:rtype: dict
|
|
136
|
+
"""
|
|
137
|
+
return async_run_allowing_running_loop(self._async_evaluator, query=query, response=response, **kwargs)
|
|
138
|
+
|
|
139
|
+
def _to_async(self):
|
|
140
|
+
return self._async_evaluator
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
"""This includes enums and classes for exceptions for use in azure-ai-evaluation."""
|
|
5
|
+
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
from azure.core.exceptions import AzureError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ErrorCategory(Enum):
|
|
12
|
+
"""Error category to be specified when using EvaluationException class.
|
|
13
|
+
|
|
14
|
+
When using EvaluationException, specify the type that best describes the nature of the error being captured.
|
|
15
|
+
|
|
16
|
+
* INVALID_VALUE -> One or more inputs are invalid (e.g. incorrect type or format)
|
|
17
|
+
* UNKNOWN_FIELD -> A least one unrecognized parameter is specified
|
|
18
|
+
* MISSING_FIELD -> At least one required parameter is missing
|
|
19
|
+
* FILE_OR_FOLDER_NOT_FOUND -> One or more files or folder paths do not exist
|
|
20
|
+
* RESOURCE_NOT_FOUND -> Resource could not be found
|
|
21
|
+
* FAILED_EXECUTION -> Execution failed
|
|
22
|
+
* SERVICE_UNAVAILABLE -> Service is unavailable
|
|
23
|
+
* UNKNOWN -> Undefined placeholder. Avoid using.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
INVALID_VALUE = "INVALID VALUE"
|
|
27
|
+
UNKNOWN_FIELD = "UNKNOWN FIELD"
|
|
28
|
+
MISSING_FIELD = "MISSING FIELD"
|
|
29
|
+
FILE_OR_FOLDER_NOT_FOUND = "FILE OR FOLDER NOT FOUND"
|
|
30
|
+
RESOURCE_NOT_FOUND = "RESOURCE NOT FOUND"
|
|
31
|
+
FAILED_EXECUTION = "FAILED_EXECUTION"
|
|
32
|
+
SERVICE_UNAVAILABLE = "SERVICE UNAVAILABLE"
|
|
33
|
+
UNKNOWN = "UNKNOWN"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ErrorBlame(Enum):
|
|
37
|
+
"""Source of blame to be specified when using EvaluationException class.
|
|
38
|
+
|
|
39
|
+
When using EvaluationException, specify whether the error is due to user actions or the system.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
USER_ERROR = "UserError"
|
|
43
|
+
SYSTEM_ERROR = "SystemError"
|
|
44
|
+
UNKNOWN = "Unknown"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ErrorTarget(Enum):
|
|
48
|
+
"""Error target to be specified when using EvaluationException class.
|
|
49
|
+
|
|
50
|
+
When using EvaluationException, specify the code area that was being targeted when the
|
|
51
|
+
exception was triggered.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
EVAL_RUN = "EvalRun"
|
|
55
|
+
CODE_CLIENT = "CodeClient"
|
|
56
|
+
RAI_CLIENT = "RAIClient"
|
|
57
|
+
CHAT_EVALUATOR = "ChatEvaluator"
|
|
58
|
+
COHERENCE_EVALUATOR = "CoherenceEvaluator"
|
|
59
|
+
CONTENT_SAFETY_CHAT_EVALUATOR = "ContentSafetyEvaluator"
|
|
60
|
+
ECI_EVALUATOR = "ECIEvaluator"
|
|
61
|
+
F1_EVALUATOR = "F1Evaluator"
|
|
62
|
+
GROUNDEDNESS_EVALUATOR = "GroundednessEvaluator"
|
|
63
|
+
PROTECTED_MATERIAL_EVALUATOR = "ProtectedMaterialEvaluator"
|
|
64
|
+
RELEVANCE_EVALUATOR = "RelevanceEvaluator"
|
|
65
|
+
SIMILARITY_EVALUATOR = "SimilarityEvaluator"
|
|
66
|
+
INDIRECT_ATTACK_EVALUATOR = "IndirectAttackEvaluator"
|
|
67
|
+
INDIRECT_ATTACK_SIMULATOR = "IndirectAttackSimulator"
|
|
68
|
+
ADVERSARIAL_SIMULATOR = "AdversarialSimulator"
|
|
69
|
+
DIRECT_ATTACK_SIMULATOR = "DirectAttackSimulator"
|
|
70
|
+
EVALUATE = "Evaluate"
|
|
71
|
+
CALLBACK_CONVERSATION_BOT = "CallbackConversationBot"
|
|
72
|
+
MODELS = "Models"
|
|
73
|
+
UNKNOWN = "Unknown"
|
|
74
|
+
CONVERSATION = "Conversation"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class EvaluationException(AzureError):
|
|
78
|
+
"""The base class for all exceptions raised in pazure-ai-evaluation. If there is a need to define a custom
|
|
79
|
+
exception type, that custom exception type should extend from this class.
|
|
80
|
+
|
|
81
|
+
:param message: A message describing the error. This is the error message the user will see.
|
|
82
|
+
:type message: str
|
|
83
|
+
:param internal_message: The error message without any personal data. This will be pushed to telemetry logs.
|
|
84
|
+
:type internal_message: str
|
|
85
|
+
:param target: The name of the element that caused the exception to be thrown.
|
|
86
|
+
:type target: ~azure.ai.evaluation._exceptions.ErrorTarget
|
|
87
|
+
:param error_category: The error category, defaults to Unknown.
|
|
88
|
+
:type error_category: ~azure.ai.evaluation._exceptionsErrorCategory
|
|
89
|
+
:param error: The original exception if any.
|
|
90
|
+
:type error: Exception
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
def __init__(
|
|
94
|
+
self,
|
|
95
|
+
message: str,
|
|
96
|
+
internal_message: str,
|
|
97
|
+
*args,
|
|
98
|
+
target: ErrorTarget = ErrorTarget.UNKNOWN,
|
|
99
|
+
category: ErrorCategory = ErrorCategory.UNKNOWN,
|
|
100
|
+
blame: ErrorBlame = ErrorBlame.UNKNOWN,
|
|
101
|
+
**kwargs,
|
|
102
|
+
) -> None:
|
|
103
|
+
self.category = category
|
|
104
|
+
self.target = target
|
|
105
|
+
self.blame = blame
|
|
106
|
+
self.internal_message = internal_message
|
|
107
|
+
super().__init__(message, *args, **kwargs)
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from functools import wraps
|
|
7
|
+
from typing import Any, Awaitable, Callable, Dict, MutableMapping, Optional
|
|
8
|
+
|
|
9
|
+
from azure.core.configuration import Configuration
|
|
10
|
+
from azure.core.pipeline import AsyncPipeline, Pipeline
|
|
11
|
+
from azure.core.pipeline.policies import (
|
|
12
|
+
AsyncRedirectPolicy,
|
|
13
|
+
AsyncRetryPolicy,
|
|
14
|
+
CustomHookPolicy,
|
|
15
|
+
HeadersPolicy,
|
|
16
|
+
HttpLoggingPolicy,
|
|
17
|
+
NetworkTraceLoggingPolicy,
|
|
18
|
+
ProxyPolicy,
|
|
19
|
+
RedirectPolicy,
|
|
20
|
+
RetryPolicy,
|
|
21
|
+
UserAgentPolicy,
|
|
22
|
+
)
|
|
23
|
+
from azure.core.pipeline.transport import ( # pylint: disable=non-abstract-transport-import,no-name-in-module
|
|
24
|
+
AsyncHttpTransport,
|
|
25
|
+
AsyncioRequestsTransport,
|
|
26
|
+
HttpTransport,
|
|
27
|
+
RequestsTransport,
|
|
28
|
+
)
|
|
29
|
+
from azure.core.rest import AsyncHttpResponse, HttpRequest, HttpResponse
|
|
30
|
+
from azure.core.rest._rest_py3 import ContentType, FilesType, ParamsType
|
|
31
|
+
from typing_extensions import Self
|
|
32
|
+
|
|
33
|
+
from azure.ai.evaluation._user_agent import USER_AGENT
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _request_fn(f: Callable[["HttpPipeline"], None]):
|
|
37
|
+
"""Decorator to generate convenience methods for HTTP method.
|
|
38
|
+
|
|
39
|
+
:param Callable[["HttpPipeline"],None] f: A HttpPipeline classmethod to wrap.
|
|
40
|
+
The f.__name__ is the HTTP method used
|
|
41
|
+
:return: A wrapped callable that sends a `f.__name__` request
|
|
42
|
+
:rtype: Callable
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
@wraps(f)
|
|
46
|
+
def request_fn(
|
|
47
|
+
self: "HttpPipeline",
|
|
48
|
+
url: str,
|
|
49
|
+
*,
|
|
50
|
+
params: Optional[ParamsType] = None,
|
|
51
|
+
headers: Optional[MutableMapping[str, str]] = None,
|
|
52
|
+
json: Any = None,
|
|
53
|
+
content: Optional[ContentType] = None,
|
|
54
|
+
data: Optional[Dict[str, Any]] = None,
|
|
55
|
+
files: Optional[FilesType] = None,
|
|
56
|
+
**kwargs,
|
|
57
|
+
) -> HttpResponse:
|
|
58
|
+
return self.request(
|
|
59
|
+
f.__name__.upper(),
|
|
60
|
+
url,
|
|
61
|
+
params=params,
|
|
62
|
+
headers=headers,
|
|
63
|
+
json=json,
|
|
64
|
+
content=content,
|
|
65
|
+
data=data,
|
|
66
|
+
files=files,
|
|
67
|
+
**kwargs,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return request_fn
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _async_request_fn(f: Callable[["AsyncHttpPipeline"], Awaitable[None]]):
|
|
74
|
+
"""Decorator to generate convenience methods for HTTP method.
|
|
75
|
+
|
|
76
|
+
:param Callable[["HttpPipeline"],None] f: A HttpPipeline classmethod to wrap.
|
|
77
|
+
The f.__name__ is the HTTP method used
|
|
78
|
+
:return: A wrapped callable that sends a `f.__name__` request
|
|
79
|
+
:rtype: Callable
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
@wraps(f)
|
|
83
|
+
async def request_fn(
|
|
84
|
+
self: "AsyncHttpPipeline",
|
|
85
|
+
url: str,
|
|
86
|
+
*,
|
|
87
|
+
params: Optional[ParamsType] = None,
|
|
88
|
+
headers: Optional[MutableMapping[str, str]] = None,
|
|
89
|
+
json: Any = None,
|
|
90
|
+
content: Optional[ContentType] = None,
|
|
91
|
+
data: Optional[Dict[str, Any]] = None,
|
|
92
|
+
files: Optional[FilesType] = None,
|
|
93
|
+
**kwargs,
|
|
94
|
+
) -> AsyncHttpResponse:
|
|
95
|
+
return await self.request(
|
|
96
|
+
f.__name__.upper(),
|
|
97
|
+
url,
|
|
98
|
+
params=params,
|
|
99
|
+
headers=headers,
|
|
100
|
+
json=json,
|
|
101
|
+
content=content,
|
|
102
|
+
data=data,
|
|
103
|
+
files=files,
|
|
104
|
+
**kwargs,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return request_fn
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class HttpPipeline(Pipeline):
|
|
111
|
+
"""A *very* thin wrapper over azure.core.pipeline.Pipeline that facilitates sending miscellaneous http requests by
|
|
112
|
+
adding:
|
|
113
|
+
|
|
114
|
+
* A requests-style api for sending http requests
|
|
115
|
+
* Facilities for populating policies for the client, include defaults,
|
|
116
|
+
and re-using policies from an existing client.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
def __init__(
|
|
120
|
+
self,
|
|
121
|
+
*,
|
|
122
|
+
transport: Optional[HttpTransport] = None,
|
|
123
|
+
config: Optional[Configuration] = None,
|
|
124
|
+
user_agent_policy: Optional[UserAgentPolicy] = None,
|
|
125
|
+
headers_policy: Optional[HeadersPolicy] = None,
|
|
126
|
+
proxy_policy: Optional[ProxyPolicy] = None,
|
|
127
|
+
logging_policy: Optional[NetworkTraceLoggingPolicy] = None,
|
|
128
|
+
http_logging_policy: Optional[HttpLoggingPolicy] = None,
|
|
129
|
+
retry_policy: Optional[RetryPolicy] = None,
|
|
130
|
+
custom_hook_policy: Optional[CustomHookPolicy] = None,
|
|
131
|
+
redirect_policy: Optional[RedirectPolicy] = None,
|
|
132
|
+
**kwargs,
|
|
133
|
+
):
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
:param HttpTransport transport: Http Transport used for requests, defaults to RequestsTransport
|
|
137
|
+
:param Configuration config:
|
|
138
|
+
:param UserAgentPolicy user_agent_policy:
|
|
139
|
+
:param HeadersPolicy headers_policy:
|
|
140
|
+
:param ProxyPolicy proxy_policy:
|
|
141
|
+
:param NetworkTraceLoggingPolicy logging_policy:
|
|
142
|
+
:param HttpLoggingPolicy http_logging_policy:
|
|
143
|
+
:param RetryPolicy retry_policy:
|
|
144
|
+
:param CustomHookPolicy custom_hook_policy:
|
|
145
|
+
:param RedirectPolicy redirect_policy:
|
|
146
|
+
"""
|
|
147
|
+
config = config or Configuration()
|
|
148
|
+
config.headers_policy = headers_policy or config.headers_policy or HeadersPolicy(**kwargs)
|
|
149
|
+
config.proxy_policy = proxy_policy or config.proxy_policy or ProxyPolicy(**kwargs)
|
|
150
|
+
config.redirect_policy = redirect_policy or config.redirect_policy or RedirectPolicy(**kwargs)
|
|
151
|
+
config.retry_policy = retry_policy or config.retry_policy or RetryPolicy(**kwargs)
|
|
152
|
+
config.custom_hook_policy = custom_hook_policy or config.custom_hook_policy or CustomHookPolicy(**kwargs)
|
|
153
|
+
config.logging_policy = logging_policy or config.logging_policy or NetworkTraceLoggingPolicy(**kwargs)
|
|
154
|
+
config.http_logging_policy = http_logging_policy or config.http_logging_policy or HttpLoggingPolicy(**kwargs)
|
|
155
|
+
config.user_agent_policy = user_agent_policy or config.user_agent_policy or UserAgentPolicy(**kwargs)
|
|
156
|
+
config.polling_interval = kwargs.get("polling_interval", 30)
|
|
157
|
+
|
|
158
|
+
super().__init__(
|
|
159
|
+
# RequestsTransport normally should not be imported outside of azure.core, since transports
|
|
160
|
+
# are meant to be user configurable.
|
|
161
|
+
# RequestsTransport is only used in this file as the default transport when not user specified.
|
|
162
|
+
transport=transport or RequestsTransport(**kwargs),
|
|
163
|
+
policies=[
|
|
164
|
+
config.headers_policy,
|
|
165
|
+
config.user_agent_policy,
|
|
166
|
+
config.proxy_policy,
|
|
167
|
+
config.redirect_policy,
|
|
168
|
+
config.retry_policy,
|
|
169
|
+
config.authentication_policy,
|
|
170
|
+
config.custom_hook_policy,
|
|
171
|
+
config.logging_policy,
|
|
172
|
+
],
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
self._config = config
|
|
176
|
+
|
|
177
|
+
def with_policies(self, **kwargs) -> Self:
|
|
178
|
+
"""A named constructor which facilitates creating a new pipeline using an existing one as a base.
|
|
179
|
+
|
|
180
|
+
Accepts the same parameters as __init__
|
|
181
|
+
|
|
182
|
+
:return: new Pipeline object with combined config of current object
|
|
183
|
+
and specified overrides
|
|
184
|
+
:rtype: Self
|
|
185
|
+
"""
|
|
186
|
+
cls = self.__class__
|
|
187
|
+
return cls(config=self._config, transport=kwargs.pop("transport", self._transport), **kwargs)
|
|
188
|
+
|
|
189
|
+
def request(
|
|
190
|
+
self,
|
|
191
|
+
method: str,
|
|
192
|
+
url: str,
|
|
193
|
+
*,
|
|
194
|
+
params: Optional[ParamsType] = None,
|
|
195
|
+
headers: Optional[MutableMapping[str, str]] = None,
|
|
196
|
+
json: Any = None,
|
|
197
|
+
content: Optional[ContentType] = None,
|
|
198
|
+
data: Optional[Dict[str, Any]] = None,
|
|
199
|
+
files: Optional[FilesType] = None,
|
|
200
|
+
**kwargs,
|
|
201
|
+
) -> HttpResponse:
|
|
202
|
+
|
|
203
|
+
request = HttpRequest(
|
|
204
|
+
method,
|
|
205
|
+
url,
|
|
206
|
+
params=params,
|
|
207
|
+
headers=headers,
|
|
208
|
+
json=json,
|
|
209
|
+
content=content,
|
|
210
|
+
data=data,
|
|
211
|
+
files=files,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
return self.run(request, **kwargs).http_response
|
|
215
|
+
|
|
216
|
+
@_request_fn
|
|
217
|
+
def delete(self) -> None:
|
|
218
|
+
"""Send a DELETE request."""
|
|
219
|
+
|
|
220
|
+
@_request_fn
|
|
221
|
+
def put(self) -> None:
|
|
222
|
+
"""Send a PUT request."""
|
|
223
|
+
|
|
224
|
+
@_request_fn
|
|
225
|
+
def get(self) -> None:
|
|
226
|
+
"""Send a GET request."""
|
|
227
|
+
|
|
228
|
+
@_request_fn
|
|
229
|
+
def post(self) -> None:
|
|
230
|
+
"""Send a POST request."""
|
|
231
|
+
|
|
232
|
+
@_request_fn
|
|
233
|
+
def head(self) -> None:
|
|
234
|
+
"""Send a HEAD request."""
|
|
235
|
+
|
|
236
|
+
@_request_fn
|
|
237
|
+
def options(self) -> None:
|
|
238
|
+
"""Send a OPTIONS request."""
|
|
239
|
+
|
|
240
|
+
@_request_fn
|
|
241
|
+
def patch(self) -> None:
|
|
242
|
+
"""Send a PATCH request."""
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class AsyncHttpPipeline(AsyncPipeline):
|
|
246
|
+
"""A *very* thin wrapper over azure.core.pipeline.AsyncPipeline that facilitates sending miscellaneous
|
|
247
|
+
http requests by adding:
|
|
248
|
+
|
|
249
|
+
* A requests-style api for sending http requests
|
|
250
|
+
* Facilities for populating policies for the client, include defaults,
|
|
251
|
+
and re-using policies from an existing client.
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
def __init__(
|
|
255
|
+
self,
|
|
256
|
+
*,
|
|
257
|
+
transport: Optional[AsyncHttpTransport] = None,
|
|
258
|
+
config: Optional[Configuration] = None,
|
|
259
|
+
user_agent_policy: Optional[UserAgentPolicy] = None,
|
|
260
|
+
headers_policy: Optional[HeadersPolicy] = None,
|
|
261
|
+
proxy_policy: Optional[ProxyPolicy] = None,
|
|
262
|
+
logging_policy: Optional[NetworkTraceLoggingPolicy] = None,
|
|
263
|
+
http_logging_policy: Optional[HttpLoggingPolicy] = None,
|
|
264
|
+
retry_policy: Optional[AsyncRetryPolicy] = None,
|
|
265
|
+
custom_hook_policy: Optional[CustomHookPolicy] = None,
|
|
266
|
+
redirect_policy: Optional[AsyncRedirectPolicy] = None,
|
|
267
|
+
**kwargs,
|
|
268
|
+
):
|
|
269
|
+
"""
|
|
270
|
+
|
|
271
|
+
:param HttpTransport transport: Http Transport used for requests, defaults to RequestsTransport
|
|
272
|
+
:param Configuration config:
|
|
273
|
+
:param UserAgentPolicy user_agent_policy:
|
|
274
|
+
:param HeadersPolicy headers_policy:
|
|
275
|
+
:param ProxyPolicy proxy_policy:
|
|
276
|
+
:param NetworkTraceLoggingPolicy logging_policy:
|
|
277
|
+
:param HttpLoggingPolicy http_logging_policy:
|
|
278
|
+
:param AsyncRetryPolicy retry_policy:
|
|
279
|
+
:param CustomHookPolicy custom_hook_policy:
|
|
280
|
+
:param AsyncRedirectPolicy redirect_policy:
|
|
281
|
+
"""
|
|
282
|
+
config = config or Configuration()
|
|
283
|
+
config.headers_policy = headers_policy or config.headers_policy or HeadersPolicy(**kwargs)
|
|
284
|
+
config.proxy_policy = proxy_policy or config.proxy_policy or ProxyPolicy(**kwargs)
|
|
285
|
+
config.redirect_policy = redirect_policy or config.redirect_policy or AsyncRedirectPolicy(**kwargs)
|
|
286
|
+
config.retry_policy = retry_policy or config.retry_policy or AsyncRetryPolicy(**kwargs)
|
|
287
|
+
config.custom_hook_policy = custom_hook_policy or config.custom_hook_policy or CustomHookPolicy(**kwargs)
|
|
288
|
+
config.logging_policy = logging_policy or config.logging_policy or NetworkTraceLoggingPolicy(**kwargs)
|
|
289
|
+
config.http_logging_policy = http_logging_policy or config.http_logging_policy or HttpLoggingPolicy(**kwargs)
|
|
290
|
+
config.user_agent_policy = user_agent_policy or config.user_agent_policy or UserAgentPolicy(**kwargs)
|
|
291
|
+
config.polling_interval = kwargs.get("polling_interval", 30)
|
|
292
|
+
|
|
293
|
+
super().__init__(
|
|
294
|
+
# AsyncioRequestsTransport normally should not be imported outside of azure.core, since transports
|
|
295
|
+
# are meant to be user configurable.
|
|
296
|
+
# AsyncioRequestsTransport is only used in this file as the default transport when not user specified.
|
|
297
|
+
transport=transport or AsyncioRequestsTransport(**kwargs),
|
|
298
|
+
policies=[
|
|
299
|
+
config.headers_policy,
|
|
300
|
+
config.user_agent_policy,
|
|
301
|
+
config.proxy_policy,
|
|
302
|
+
config.redirect_policy,
|
|
303
|
+
config.retry_policy,
|
|
304
|
+
config.authentication_policy,
|
|
305
|
+
config.custom_hook_policy,
|
|
306
|
+
config.logging_policy,
|
|
307
|
+
],
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
self._config = config
|
|
311
|
+
|
|
312
|
+
def with_policies(self, **kwargs) -> Self:
|
|
313
|
+
"""A named constructor which facilitates creating a new pipeline using an existing one as a base.
|
|
314
|
+
|
|
315
|
+
Accepts the same parameters as __init__
|
|
316
|
+
|
|
317
|
+
:return: new Pipeline object with combined config of current object
|
|
318
|
+
and specified overrides
|
|
319
|
+
:rtype: Self
|
|
320
|
+
"""
|
|
321
|
+
cls = self.__class__
|
|
322
|
+
return cls(config=self._config, transport=kwargs.pop("transport", self._transport), **kwargs)
|
|
323
|
+
|
|
324
|
+
async def request(
|
|
325
|
+
self,
|
|
326
|
+
method: str,
|
|
327
|
+
url: str,
|
|
328
|
+
*,
|
|
329
|
+
params: Optional[ParamsType] = None,
|
|
330
|
+
headers: Optional[MutableMapping[str, str]] = None,
|
|
331
|
+
json: Any = None,
|
|
332
|
+
content: Optional[ContentType] = None,
|
|
333
|
+
data: Optional[Dict[str, Any]] = None,
|
|
334
|
+
files: Optional[FilesType] = None,
|
|
335
|
+
**kwargs,
|
|
336
|
+
) -> AsyncHttpResponse:
|
|
337
|
+
|
|
338
|
+
request = HttpRequest(
|
|
339
|
+
method,
|
|
340
|
+
url,
|
|
341
|
+
params=params,
|
|
342
|
+
headers=headers,
|
|
343
|
+
json=json,
|
|
344
|
+
content=content,
|
|
345
|
+
data=data,
|
|
346
|
+
files=files,
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
return (await self.run(request, **kwargs)).http_response
|
|
350
|
+
|
|
351
|
+
@_async_request_fn
|
|
352
|
+
async def delete(self) -> None:
|
|
353
|
+
"""Send a DELETE request."""
|
|
354
|
+
|
|
355
|
+
@_async_request_fn
|
|
356
|
+
async def put(self) -> None:
|
|
357
|
+
"""Send a PUT request."""
|
|
358
|
+
|
|
359
|
+
@_async_request_fn
|
|
360
|
+
async def get(self) -> None:
|
|
361
|
+
"""Send a GET request."""
|
|
362
|
+
|
|
363
|
+
@_async_request_fn
|
|
364
|
+
async def post(self) -> None:
|
|
365
|
+
"""Send a POST request."""
|
|
366
|
+
|
|
367
|
+
@_async_request_fn
|
|
368
|
+
async def head(self) -> None:
|
|
369
|
+
"""Send a HEAD request."""
|
|
370
|
+
|
|
371
|
+
@_async_request_fn
|
|
372
|
+
async def options(self) -> None:
|
|
373
|
+
"""Send a OPTIONS request."""
|
|
374
|
+
|
|
375
|
+
@_async_request_fn
|
|
376
|
+
async def patch(self) -> None:
|
|
377
|
+
"""Send a PATCH request."""
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def get_http_client() -> HttpPipeline:
|
|
381
|
+
"""Get an HttpPipeline configured with common policies.
|
|
382
|
+
|
|
383
|
+
:returns: An HttpPipeline with a set of applied policies:
|
|
384
|
+
:rtype: HttpPipeline
|
|
385
|
+
"""
|
|
386
|
+
return HttpPipeline(user_agent_policy=UserAgentPolicy(base_user_agent=USER_AGENT))
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def get_async_http_client() -> AsyncHttpPipeline:
|
|
390
|
+
"""Get an AsyncHttpPipeline configured with common policies.
|
|
391
|
+
|
|
392
|
+
:returns: An AsyncHttpPipeline with a set of applied policies:
|
|
393
|
+
:rtype: AsyncHttpPipeline
|
|
394
|
+
"""
|
|
395
|
+
return AsyncHttpPipeline(user_agent_policy=UserAgentPolicy(base_user_agent=USER_AGENT))
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
from typing import TypedDict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AzureOpenAIModelConfigurationBase(TypedDict):
|
|
9
|
+
azure_deployment: str
|
|
10
|
+
azure_endpoint: str
|
|
11
|
+
api_key: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AzureOpenAIModelConfiguration(AzureOpenAIModelConfigurationBase, total=False):
|
|
15
|
+
api_version: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class OpenAIModelConfiguration(TypedDict):
|
|
19
|
+
api_key: str
|
|
20
|
+
base_url: str
|
|
21
|
+
organization: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class AzureAIProject(TypedDict):
|
|
25
|
+
subscription_id: str
|
|
26
|
+
resource_group_name: str
|
|
27
|
+
project_name: str
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# ---------------------------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
# ---------------------------------------------------------
|
|
4
|
+
from azure.ai.evaluation._version import VERSION
|
|
5
|
+
|
|
6
|
+
USER_AGENT = "{}/{}".format("azure-ai-evaluation", VERSION)
|
|
File without changes
|