azure-ai-evaluation 1.0.0b2__py3-none-any.whl → 1.0.0b4__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 +9 -5
- azure/ai/evaluation/_common/constants.py +4 -2
- azure/ai/evaluation/_common/math.py +18 -0
- azure/ai/evaluation/_common/rai_service.py +54 -62
- azure/ai/evaluation/_common/utils.py +201 -16
- azure/ai/evaluation/_constants.py +12 -0
- azure/ai/evaluation/_evaluate/_batch_run_client/batch_run_context.py +10 -3
- azure/ai/evaluation/_evaluate/_batch_run_client/code_client.py +33 -17
- azure/ai/evaluation/_evaluate/_batch_run_client/proxy_client.py +17 -2
- azure/ai/evaluation/_evaluate/_eval_run.py +26 -10
- azure/ai/evaluation/_evaluate/_evaluate.py +161 -89
- azure/ai/evaluation/_evaluate/_telemetry/__init__.py +16 -17
- azure/ai/evaluation/_evaluate/_utils.py +44 -25
- azure/ai/evaluation/_evaluators/_coherence/_coherence.py +33 -79
- azure/ai/evaluation/_evaluators/_coherence/coherence.prompty +0 -5
- azure/ai/evaluation/_evaluators/_common/__init__.py +13 -0
- azure/ai/evaluation/_evaluators/_common/_base_eval.py +331 -0
- azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +76 -0
- azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +97 -0
- azure/ai/evaluation/_evaluators/_content_safety/__init__.py +0 -4
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety.py +15 -20
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety_chat.py +63 -42
- azure/ai/evaluation/_evaluators/_content_safety/_hate_unfairness.py +18 -41
- azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py +18 -39
- azure/ai/evaluation/_evaluators/_content_safety/_sexual.py +18 -39
- azure/ai/evaluation/_evaluators/_content_safety/_violence.py +18 -39
- azure/ai/evaluation/_evaluators/_eci/_eci.py +18 -55
- azure/ai/evaluation/_evaluators/_f1_score/_f1_score.py +14 -6
- azure/ai/evaluation/_evaluators/_fluency/_fluency.py +30 -74
- azure/ai/evaluation/_evaluators/_fluency/fluency.prompty +0 -5
- azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +34 -80
- azure/ai/evaluation/_evaluators/_groundedness/groundedness.prompty +0 -5
- azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py +18 -65
- azure/ai/evaluation/_evaluators/_qa/_qa.py +4 -3
- azure/ai/evaluation/_evaluators/_relevance/_relevance.py +35 -83
- azure/ai/evaluation/_evaluators/_relevance/relevance.prompty +0 -5
- azure/ai/evaluation/_evaluators/{_chat → _retrieval}/__init__.py +2 -2
- azure/ai/evaluation/_evaluators/{_chat/retrieval → _retrieval}/_retrieval.py +25 -28
- azure/ai/evaluation/_evaluators/{_chat/retrieval → _retrieval}/retrieval.prompty +0 -5
- azure/ai/evaluation/_evaluators/_rouge/_rouge.py +1 -1
- azure/ai/evaluation/_evaluators/_similarity/_similarity.py +23 -17
- azure/ai/evaluation/_evaluators/_similarity/similarity.prompty +0 -5
- azure/ai/evaluation/_evaluators/_xpia/xpia.py +15 -90
- azure/ai/evaluation/_exceptions.py +9 -7
- azure/ai/evaluation/_http_utils.py +203 -132
- azure/ai/evaluation/_model_configurations.py +37 -9
- azure/ai/evaluation/{_evaluators/_chat/retrieval → _vendor}/__init__.py +0 -6
- azure/ai/evaluation/_vendor/rouge_score/__init__.py +14 -0
- azure/ai/evaluation/_vendor/rouge_score/rouge_scorer.py +328 -0
- azure/ai/evaluation/_vendor/rouge_score/scoring.py +63 -0
- azure/ai/evaluation/_vendor/rouge_score/tokenize.py +63 -0
- azure/ai/evaluation/_vendor/rouge_score/tokenizers.py +53 -0
- azure/ai/evaluation/_version.py +1 -1
- azure/ai/evaluation/simulator/_adversarial_simulator.py +85 -60
- azure/ai/evaluation/simulator/_conversation/__init__.py +13 -12
- azure/ai/evaluation/simulator/_conversation/_conversation.py +4 -4
- azure/ai/evaluation/simulator/_direct_attack_simulator.py +24 -66
- azure/ai/evaluation/simulator/_helpers/_experimental.py +20 -9
- azure/ai/evaluation/simulator/_helpers/_simulator_data_classes.py +4 -4
- azure/ai/evaluation/simulator/_indirect_attack_simulator.py +22 -64
- azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +67 -21
- azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +28 -11
- azure/ai/evaluation/simulator/_model_tools/_template_handler.py +68 -24
- azure/ai/evaluation/simulator/_model_tools/models.py +10 -10
- azure/ai/evaluation/simulator/_prompty/task_query_response.prompty +2 -6
- azure/ai/evaluation/simulator/_prompty/task_simulate.prompty +0 -4
- azure/ai/evaluation/simulator/_simulator.py +127 -117
- azure/ai/evaluation/simulator/_tracing.py +4 -4
- {azure_ai_evaluation-1.0.0b2.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/METADATA +129 -43
- azure_ai_evaluation-1.0.0b4.dist-info/NOTICE.txt +50 -0
- azure_ai_evaluation-1.0.0b4.dist-info/RECORD +106 -0
- azure/ai/evaluation/_evaluators/_chat/_chat.py +0 -357
- azure/ai/evaluation/_evaluators/_content_safety/_content_safety_base.py +0 -65
- azure/ai/evaluation/_evaluators/_protected_materials/__init__.py +0 -5
- azure/ai/evaluation/_evaluators/_protected_materials/_protected_materials.py +0 -104
- azure_ai_evaluation-1.0.0b2.dist-info/RECORD +0 -99
- {azure_ai_evaluation-1.0.0b2.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/WHEEL +0 -0
- {azure_ai_evaluation-1.0.0b2.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/top_level.txt +0 -0
|
@@ -2,30 +2,28 @@
|
|
|
2
2
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
# ---------------------------------------------------------
|
|
4
4
|
import logging
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
|
-
from
|
|
6
|
+
from typing_extensions import override
|
|
8
7
|
|
|
9
8
|
from azure.ai.evaluation._common.constants import EvaluationMetrics
|
|
10
|
-
from azure.ai.evaluation._common
|
|
11
|
-
from azure.ai.evaluation._exceptions import ErrorBlame, ErrorCategory, ErrorTarget, EvaluationException
|
|
9
|
+
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
|
|
12
10
|
|
|
13
11
|
logger = logging.getLogger(__name__)
|
|
14
12
|
|
|
15
13
|
|
|
16
|
-
class IndirectAttackEvaluator:
|
|
14
|
+
class IndirectAttackEvaluator(RaiServiceEvaluatorBase):
|
|
17
15
|
"""A Cross-Domain Prompt Injection Attack (XPIA) jailbreak evaluator.
|
|
18
16
|
|
|
19
17
|
Detect whether cross domain injected attacks are present in your AI system's response.
|
|
20
18
|
|
|
19
|
+
:param credential: The credential for connecting to Azure AI project. Required
|
|
20
|
+
:type credential: ~azure.core.credentials.TokenCredential
|
|
21
21
|
:param azure_ai_project: The scope of the Azure AI project. It contains subscription id, resource group, and project
|
|
22
22
|
name.
|
|
23
23
|
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
|
|
24
24
|
:param eval_last_turn: Set to True to evaluate only the most recent exchange in the dialogue,
|
|
25
25
|
focusing on the latest user inquiry and the assistant's corresponding response. Defaults to False
|
|
26
26
|
:type eval_last_turn: bool
|
|
27
|
-
:param credential: The credential for connecting to Azure AI project.
|
|
28
|
-
:type credential: ~azure.core.credentials.TokenCredential
|
|
29
27
|
:return: A function that evaluates and generates metrics for XPIA chat scenario. Metrics include the overall
|
|
30
28
|
evaluation label and reason for the Q/A Pair, as well as sub-labels for manipulated content, intrusion, and
|
|
31
29
|
information.
|
|
@@ -51,89 +49,16 @@ class IndirectAttackEvaluator:
|
|
|
51
49
|
}
|
|
52
50
|
"""
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
self._eval_last_turn = eval_last_turn
|
|
57
|
-
|
|
58
|
-
def __call__(
|
|
52
|
+
@override
|
|
53
|
+
def __init__(
|
|
59
54
|
self,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
**kwargs,
|
|
55
|
+
credential,
|
|
56
|
+
azure_ai_project: dict,
|
|
57
|
+
eval_last_turn: bool = False,
|
|
64
58
|
):
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
:paramtype query: Optional[str]
|
|
71
|
-
:keyword response: The response to be evaluated. Mutually exclusive with 'conversation'.
|
|
72
|
-
:paramtype response: Optional[str]
|
|
73
|
-
:return: The evaluation scores and reasoning.
|
|
74
|
-
:rtype: dict
|
|
75
|
-
"""
|
|
76
|
-
|
|
77
|
-
return self._evaluator(query=query, response=response, **kwargs)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class _AsyncIndirectAttackEvaluator:
|
|
81
|
-
def __init__(self, azure_ai_project: dict, credential=None):
|
|
82
|
-
self._azure_ai_project = azure_ai_project
|
|
83
|
-
self._credential = credential
|
|
84
|
-
|
|
85
|
-
async def __call__(self, *, query: str, response: str, **kwargs):
|
|
86
|
-
"""
|
|
87
|
-
Evaluates content according to this evaluator's metric.
|
|
88
|
-
:keyword query: The query to be evaluated.
|
|
89
|
-
:paramtype query: str
|
|
90
|
-
:keyword response: The response to be evaluated.
|
|
91
|
-
:paramtype response: str
|
|
92
|
-
:return: The evaluation score computation based on the metric (self.metric).
|
|
93
|
-
:rtype: Any
|
|
94
|
-
"""
|
|
95
|
-
# Validate inputs
|
|
96
|
-
# Raises value error if failed, so execution alone signifies success.
|
|
97
|
-
if not (query and query.strip() and query != "None") or not (
|
|
98
|
-
response and response.strip() and response != "None"
|
|
99
|
-
):
|
|
100
|
-
msg = "Both 'query' and 'response' must be non-empty strings."
|
|
101
|
-
raise EvaluationException(
|
|
102
|
-
message=msg,
|
|
103
|
-
internal_message=msg,
|
|
104
|
-
error_category=ErrorCategory.MISSING_FIELD,
|
|
105
|
-
error_blame=ErrorBlame.USER_ERROR,
|
|
106
|
-
error_target=ErrorTarget.INDIRECT_ATTACK_EVALUATOR,
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
# Run score computation based on supplied metric.
|
|
110
|
-
result = await evaluate_with_rai_service(
|
|
111
|
-
metric_name=EvaluationMetrics.XPIA,
|
|
112
|
-
query=query,
|
|
113
|
-
response=response,
|
|
114
|
-
project_scope=self._azure_ai_project,
|
|
115
|
-
credential=self._credential,
|
|
59
|
+
super().__init__(
|
|
60
|
+
eval_metric=EvaluationMetrics.XPIA,
|
|
61
|
+
azure_ai_project=azure_ai_project,
|
|
62
|
+
credential=credential,
|
|
63
|
+
eval_last_turn=eval_last_turn,
|
|
116
64
|
)
|
|
117
|
-
return result
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class _IndirectAttackEvaluator:
|
|
121
|
-
def __init__(self, azure_ai_project: dict, credential=None):
|
|
122
|
-
self._async_evaluator = _AsyncIndirectAttackEvaluator(azure_ai_project, credential)
|
|
123
|
-
|
|
124
|
-
def __call__(self, *, query: str, response: str, **kwargs):
|
|
125
|
-
"""
|
|
126
|
-
Evaluates XPIA content.
|
|
127
|
-
:keyword query: The query to be evaluated.
|
|
128
|
-
:paramtype query: str
|
|
129
|
-
:keyword response: The response to be evaluated.
|
|
130
|
-
:paramtype response: str
|
|
131
|
-
:keyword context: The context to be evaluated.
|
|
132
|
-
:paramtype context: str
|
|
133
|
-
:return: The XPIA score.
|
|
134
|
-
:rtype: dict
|
|
135
|
-
"""
|
|
136
|
-
return async_run_allowing_running_loop(self._async_evaluator, query=query, response=response, **kwargs)
|
|
137
|
-
|
|
138
|
-
def _to_async(self):
|
|
139
|
-
return self._async_evaluator
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"""This includes enums and classes for exceptions for use in azure-ai-evaluation."""
|
|
5
5
|
|
|
6
6
|
from enum import Enum
|
|
7
|
+
from typing import Optional
|
|
7
8
|
|
|
8
9
|
from azure.core.exceptions import AzureError
|
|
9
10
|
|
|
@@ -20,6 +21,7 @@ class ErrorCategory(Enum):
|
|
|
20
21
|
* RESOURCE_NOT_FOUND -> Resource could not be found
|
|
21
22
|
* FAILED_EXECUTION -> Execution failed
|
|
22
23
|
* SERVICE_UNAVAILABLE -> Service is unavailable
|
|
24
|
+
* MISSING_PACKAGE -> Required package is missing
|
|
23
25
|
* UNKNOWN -> Undefined placeholder. Avoid using.
|
|
24
26
|
"""
|
|
25
27
|
|
|
@@ -30,6 +32,7 @@ class ErrorCategory(Enum):
|
|
|
30
32
|
RESOURCE_NOT_FOUND = "RESOURCE NOT FOUND"
|
|
31
33
|
FAILED_EXECUTION = "FAILED_EXECUTION"
|
|
32
34
|
SERVICE_UNAVAILABLE = "SERVICE UNAVAILABLE"
|
|
35
|
+
MISSING_PACKAGE = "MISSING PACKAGE"
|
|
33
36
|
UNKNOWN = "UNKNOWN"
|
|
34
37
|
|
|
35
38
|
|
|
@@ -54,7 +57,6 @@ class ErrorTarget(Enum):
|
|
|
54
57
|
EVAL_RUN = "EvalRun"
|
|
55
58
|
CODE_CLIENT = "CodeClient"
|
|
56
59
|
RAI_CLIENT = "RAIClient"
|
|
57
|
-
CHAT_EVALUATOR = "ChatEvaluator"
|
|
58
60
|
COHERENCE_EVALUATOR = "CoherenceEvaluator"
|
|
59
61
|
CONTENT_SAFETY_CHAT_EVALUATOR = "ContentSafetyEvaluator"
|
|
60
62
|
ECI_EVALUATOR = "ECIEvaluator"
|
|
@@ -75,7 +77,7 @@ class ErrorTarget(Enum):
|
|
|
75
77
|
|
|
76
78
|
|
|
77
79
|
class EvaluationException(AzureError):
|
|
78
|
-
"""The base class for all exceptions raised in
|
|
80
|
+
"""The base class for all exceptions raised in azure-ai-evaluation. If there is a need to define a custom
|
|
79
81
|
exception type, that custom exception type should extend from this class.
|
|
80
82
|
|
|
81
83
|
:param message: A message describing the error. This is the error message the user will see.
|
|
@@ -84,17 +86,17 @@ class EvaluationException(AzureError):
|
|
|
84
86
|
:type internal_message: str
|
|
85
87
|
:param target: The name of the element that caused the exception to be thrown.
|
|
86
88
|
:type target: ~azure.ai.evaluation._exceptions.ErrorTarget
|
|
87
|
-
:param
|
|
88
|
-
:type
|
|
89
|
-
:param
|
|
90
|
-
:type
|
|
89
|
+
:param category: The error category, defaults to Unknown.
|
|
90
|
+
:type category: ~azure.ai.evaluation._exceptions.ErrorCategory
|
|
91
|
+
:param blame: The source of blame for the error, defaults to Unknown.
|
|
92
|
+
:type balance: ~azure.ai.evaluation._exceptions.ErrorBlame
|
|
91
93
|
"""
|
|
92
94
|
|
|
93
95
|
def __init__(
|
|
94
96
|
self,
|
|
95
97
|
message: str,
|
|
96
|
-
internal_message: str,
|
|
97
98
|
*args,
|
|
99
|
+
internal_message: Optional[str] = None,
|
|
98
100
|
target: ErrorTarget = ErrorTarget.UNKNOWN,
|
|
99
101
|
category: ErrorCategory = ErrorCategory.UNKNOWN,
|
|
100
102
|
blame: ErrorBlame = ErrorBlame.UNKNOWN,
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
# ---------------------------------------------------------
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from typing import Any, Awaitable, Callable, Dict, MutableMapping, Optional
|
|
6
|
+
from typing import Any, Dict, MutableMapping, Optional, TypedDict, cast
|
|
8
7
|
|
|
9
|
-
from typing_extensions import Self
|
|
8
|
+
from typing_extensions import Self, Unpack
|
|
10
9
|
|
|
11
10
|
from azure.ai.evaluation._user_agent import USER_AGENT
|
|
12
11
|
from azure.core.configuration import Configuration
|
|
@@ -33,78 +32,25 @@ from azure.core.rest import AsyncHttpResponse, HttpRequest, HttpResponse
|
|
|
33
32
|
from azure.core.rest._rest_py3 import ContentType, FilesType, ParamsType
|
|
34
33
|
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
"""
|
|
35
|
+
class RequestKwargs(TypedDict, total=False):
|
|
36
|
+
"""Keyword arguments for request-style http request functions
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
The f.__name__ is the HTTP method used
|
|
41
|
-
:return: A wrapped callable that sends a `f.__name__` request
|
|
42
|
-
:rtype: Callable
|
|
43
|
-
"""
|
|
38
|
+
.. note::
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
)
|
|
40
|
+
Ideally, we'd be able to express that these are the known subset of kwargs, but it's possible to provide
|
|
41
|
+
others. But that currently isn't possible; there's no way currently to express a TypedDict that expects
|
|
42
|
+
a known set of keys and an unknown set of keys.
|
|
69
43
|
|
|
70
|
-
|
|
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
|
|
44
|
+
PEP 728 - TypedDict with Typed Extra Items (https://peps.python.org/pep-0728/) would rectify this but it's
|
|
45
|
+
still in Draft status.
|
|
80
46
|
"""
|
|
81
47
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
|
48
|
+
params: ParamsType
|
|
49
|
+
headers: MutableMapping[str, str]
|
|
50
|
+
json: Any
|
|
51
|
+
content: ContentType
|
|
52
|
+
data: Dict[str, Any]
|
|
53
|
+
files: FilesType
|
|
108
54
|
|
|
109
55
|
|
|
110
56
|
class HttpPipeline(Pipeline):
|
|
@@ -145,14 +91,32 @@ class HttpPipeline(Pipeline):
|
|
|
145
91
|
:param RedirectPolicy redirect_policy:
|
|
146
92
|
"""
|
|
147
93
|
config = config or Configuration()
|
|
148
|
-
config.headers_policy =
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
config.
|
|
152
|
-
config.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
config.
|
|
94
|
+
config.headers_policy = (
|
|
95
|
+
headers_policy or cast(Optional[HeadersPolicy], config.headers_policy) or HeadersPolicy(**kwargs)
|
|
96
|
+
)
|
|
97
|
+
config.proxy_policy = proxy_policy or cast(Optional[ProxyPolicy], config.proxy_policy) or ProxyPolicy(**kwargs)
|
|
98
|
+
config.redirect_policy = (
|
|
99
|
+
redirect_policy or cast(Optional[RedirectPolicy], config.redirect_policy) or RedirectPolicy(**kwargs)
|
|
100
|
+
)
|
|
101
|
+
config.retry_policy = retry_policy or cast(Optional[RetryPolicy], config.retry_policy) or RetryPolicy(**kwargs)
|
|
102
|
+
config.custom_hook_policy = (
|
|
103
|
+
custom_hook_policy
|
|
104
|
+
or cast(Optional[CustomHookPolicy], config.custom_hook_policy)
|
|
105
|
+
or CustomHookPolicy(**kwargs)
|
|
106
|
+
)
|
|
107
|
+
config.logging_policy = (
|
|
108
|
+
logging_policy
|
|
109
|
+
or cast(Optional[NetworkTraceLoggingPolicy], config.logging_policy)
|
|
110
|
+
or NetworkTraceLoggingPolicy(**kwargs)
|
|
111
|
+
)
|
|
112
|
+
config.http_logging_policy = (
|
|
113
|
+
http_logging_policy
|
|
114
|
+
or cast(Optional[HttpLoggingPolicy], config.http_logging_policy)
|
|
115
|
+
or HttpLoggingPolicy(**kwargs)
|
|
116
|
+
)
|
|
117
|
+
config.user_agent_policy = (
|
|
118
|
+
user_agent_policy or cast(Optional[UserAgentPolicy], config.user_agent_policy) or UserAgentPolicy(**kwargs)
|
|
119
|
+
)
|
|
156
120
|
config.polling_interval = kwargs.get("polling_interval", 30)
|
|
157
121
|
|
|
158
122
|
super().__init__(
|
|
@@ -166,7 +130,6 @@ class HttpPipeline(Pipeline):
|
|
|
166
130
|
config.proxy_policy,
|
|
167
131
|
config.redirect_policy,
|
|
168
132
|
config.retry_policy,
|
|
169
|
-
config.authentication_policy,
|
|
170
133
|
config.custom_hook_policy,
|
|
171
134
|
config.logging_policy,
|
|
172
135
|
],
|
|
@@ -199,7 +162,6 @@ class HttpPipeline(Pipeline):
|
|
|
199
162
|
files: Optional[FilesType] = None,
|
|
200
163
|
**kwargs,
|
|
201
164
|
) -> HttpResponse:
|
|
202
|
-
|
|
203
165
|
request = HttpRequest(
|
|
204
166
|
method,
|
|
205
167
|
url,
|
|
@@ -213,33 +175,78 @@ class HttpPipeline(Pipeline):
|
|
|
213
175
|
|
|
214
176
|
return self.run(request, **kwargs).http_response
|
|
215
177
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"""Send a DELETE request."""
|
|
178
|
+
def delete(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
|
|
179
|
+
"""Send a DELETE request.
|
|
219
180
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
181
|
+
:param str url: The request url
|
|
182
|
+
:returns: The request response
|
|
183
|
+
:rtype: HttpResponse
|
|
184
|
+
"""
|
|
223
185
|
|
|
224
|
-
|
|
225
|
-
def get(self) -> None:
|
|
226
|
-
"""Send a GET request."""
|
|
186
|
+
return self.request(self.delete.__name__.upper(), url, **kwargs)
|
|
227
187
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
"""Send a POST request."""
|
|
188
|
+
def put(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
|
|
189
|
+
"""Send a PUT request.
|
|
231
190
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
191
|
+
:param str url: The request url
|
|
192
|
+
:returns: The request response
|
|
193
|
+
:rtype: HttpResponse
|
|
194
|
+
"""
|
|
235
195
|
|
|
236
|
-
|
|
237
|
-
def options(self) -> None:
|
|
238
|
-
"""Send a OPTIONS request."""
|
|
196
|
+
return self.request(self.put.__name__.upper(), url, **kwargs)
|
|
239
197
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
198
|
+
def get(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
|
|
199
|
+
"""Send a GET request.
|
|
200
|
+
|
|
201
|
+
:param str url: The request url
|
|
202
|
+
:returns: The request response
|
|
203
|
+
:rtype: HttpResponse
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
return self.request(self.get.__name__.upper(), url, **kwargs)
|
|
207
|
+
|
|
208
|
+
def post(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
|
|
209
|
+
"""Send a POST request.
|
|
210
|
+
|
|
211
|
+
:param str url: The request url
|
|
212
|
+
:returns: The request response
|
|
213
|
+
:rtype: HttpResponse
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
return self.request(self.post.__name__.upper(), url, **kwargs)
|
|
217
|
+
|
|
218
|
+
def head(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
|
|
219
|
+
"""Send a HEAD request.
|
|
220
|
+
|
|
221
|
+
:param str url: The request url
|
|
222
|
+
:returns: The request response
|
|
223
|
+
:rtype: HttpResponse
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
return self.request(self.head.__name__.upper(), url, **kwargs)
|
|
227
|
+
|
|
228
|
+
def options(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
|
|
229
|
+
"""Send a OPTIONS request.
|
|
230
|
+
|
|
231
|
+
:param str url: The request url
|
|
232
|
+
:returns: The request response
|
|
233
|
+
:rtype: HttpResponse
|
|
234
|
+
"""
|
|
235
|
+
|
|
236
|
+
return self.request(self.options.__name__.upper(), url, **kwargs)
|
|
237
|
+
|
|
238
|
+
def patch(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
|
|
239
|
+
"""Send a PATCH request.
|
|
240
|
+
|
|
241
|
+
:param str url: The request url
|
|
242
|
+
:returns: The request response
|
|
243
|
+
:rtype: HttpResponse
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
return self.request(self.patch.__name__.upper(), url, **kwargs)
|
|
247
|
+
|
|
248
|
+
def __enter__(self) -> Self:
|
|
249
|
+
return cast(Self, super().__enter__())
|
|
243
250
|
|
|
244
251
|
|
|
245
252
|
class AsyncHttpPipeline(AsyncPipeline):
|
|
@@ -280,14 +287,36 @@ class AsyncHttpPipeline(AsyncPipeline):
|
|
|
280
287
|
:param AsyncRedirectPolicy redirect_policy:
|
|
281
288
|
"""
|
|
282
289
|
config = config or Configuration()
|
|
283
|
-
config.headers_policy =
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
config.
|
|
287
|
-
config.
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
config.headers_policy = (
|
|
291
|
+
headers_policy or cast(Optional[HeadersPolicy], config.headers_policy) or HeadersPolicy(**kwargs)
|
|
292
|
+
)
|
|
293
|
+
config.proxy_policy = proxy_policy or cast(Optional[ProxyPolicy], config.proxy_policy) or ProxyPolicy(**kwargs)
|
|
294
|
+
config.redirect_policy = (
|
|
295
|
+
redirect_policy
|
|
296
|
+
or cast(Optional[AsyncRedirectPolicy], config.redirect_policy)
|
|
297
|
+
or AsyncRedirectPolicy(**kwargs)
|
|
298
|
+
)
|
|
299
|
+
config.retry_policy = (
|
|
300
|
+
retry_policy or cast(Optional[AsyncRetryPolicy], config.retry_policy) or AsyncRetryPolicy(**kwargs)
|
|
301
|
+
)
|
|
302
|
+
config.custom_hook_policy = (
|
|
303
|
+
custom_hook_policy
|
|
304
|
+
or cast(Optional[CustomHookPolicy], config.custom_hook_policy)
|
|
305
|
+
or CustomHookPolicy(**kwargs)
|
|
306
|
+
)
|
|
307
|
+
config.logging_policy = (
|
|
308
|
+
logging_policy
|
|
309
|
+
or cast(Optional[NetworkTraceLoggingPolicy], config.logging_policy)
|
|
310
|
+
or NetworkTraceLoggingPolicy(**kwargs)
|
|
311
|
+
)
|
|
312
|
+
config.http_logging_policy = (
|
|
313
|
+
http_logging_policy
|
|
314
|
+
or cast(Optional[HttpLoggingPolicy], config.http_logging_policy)
|
|
315
|
+
or HttpLoggingPolicy(**kwargs)
|
|
316
|
+
)
|
|
317
|
+
config.user_agent_policy = (
|
|
318
|
+
user_agent_policy or cast(Optional[UserAgentPolicy], config.user_agent_policy) or UserAgentPolicy(**kwargs)
|
|
319
|
+
)
|
|
291
320
|
config.polling_interval = kwargs.get("polling_interval", 30)
|
|
292
321
|
|
|
293
322
|
super().__init__(
|
|
@@ -301,7 +330,6 @@ class AsyncHttpPipeline(AsyncPipeline):
|
|
|
301
330
|
config.proxy_policy,
|
|
302
331
|
config.redirect_policy,
|
|
303
332
|
config.retry_policy,
|
|
304
|
-
config.authentication_policy,
|
|
305
333
|
config.custom_hook_policy,
|
|
306
334
|
config.logging_policy,
|
|
307
335
|
],
|
|
@@ -334,7 +362,6 @@ class AsyncHttpPipeline(AsyncPipeline):
|
|
|
334
362
|
files: Optional[FilesType] = None,
|
|
335
363
|
**kwargs,
|
|
336
364
|
) -> AsyncHttpResponse:
|
|
337
|
-
|
|
338
365
|
request = HttpRequest(
|
|
339
366
|
method,
|
|
340
367
|
url,
|
|
@@ -348,33 +375,77 @@ class AsyncHttpPipeline(AsyncPipeline):
|
|
|
348
375
|
|
|
349
376
|
return (await self.run(request, **kwargs)).http_response
|
|
350
377
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
378
|
+
async def delete(self: "AsyncHttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> AsyncHttpResponse:
|
|
379
|
+
"""Send a DELETE request.
|
|
380
|
+
|
|
381
|
+
:param str url: The request url
|
|
382
|
+
:returns: The request response
|
|
383
|
+
:rtype: AsyncHttpResponse
|
|
384
|
+
"""
|
|
385
|
+
return await self.request(self.delete.__name__.upper(), url, **kwargs)
|
|
386
|
+
|
|
387
|
+
async def put(self: "AsyncHttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> AsyncHttpResponse:
|
|
388
|
+
"""Send a PUT request.
|
|
389
|
+
|
|
390
|
+
:param str url: The request url
|
|
391
|
+
:returns: The request response
|
|
392
|
+
:rtype: AsyncHttpResponse
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
return await self.request(self.put.__name__.upper(), url, **kwargs)
|
|
396
|
+
|
|
397
|
+
async def get(self: "AsyncHttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> AsyncHttpResponse:
|
|
398
|
+
"""Send a GET request.
|
|
399
|
+
|
|
400
|
+
:param str url: The request url
|
|
401
|
+
:returns: The request response
|
|
402
|
+
:rtype: AsyncHttpResponse
|
|
403
|
+
"""
|
|
404
|
+
|
|
405
|
+
return await self.request(self.get.__name__.upper(), url, **kwargs)
|
|
406
|
+
|
|
407
|
+
async def post(self: "AsyncHttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> AsyncHttpResponse:
|
|
408
|
+
"""Send a POST request.
|
|
409
|
+
|
|
410
|
+
:param str url: The request url
|
|
411
|
+
:returns: The request response
|
|
412
|
+
:rtype: AsyncHttpResponse
|
|
413
|
+
"""
|
|
414
|
+
|
|
415
|
+
return await self.request(self.post.__name__.upper(), url, **kwargs)
|
|
416
|
+
|
|
417
|
+
async def head(self: "AsyncHttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> AsyncHttpResponse:
|
|
418
|
+
"""Send a HEAD request.
|
|
354
419
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
420
|
+
:param str url: The request url
|
|
421
|
+
:returns: The request response
|
|
422
|
+
:rtype: AsyncHttpResponse
|
|
423
|
+
"""
|
|
424
|
+
|
|
425
|
+
return await self.request(self.head.__name__.upper(), url, **kwargs)
|
|
426
|
+
|
|
427
|
+
async def options(self: "AsyncHttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> AsyncHttpResponse:
|
|
428
|
+
"""Send a OPTIONS request.
|
|
358
429
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
430
|
+
:param str url: The request url
|
|
431
|
+
:returns: The request response
|
|
432
|
+
:rtype: AsyncHttpResponse
|
|
433
|
+
"""
|
|
434
|
+
|
|
435
|
+
return await self.request(self.options.__name__.upper(), url, **kwargs)
|
|
362
436
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
"""Send a POST request."""
|
|
437
|
+
async def patch(self: "AsyncHttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> AsyncHttpResponse:
|
|
438
|
+
"""Send a PATCH request.
|
|
366
439
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
440
|
+
:param str url: The request url
|
|
441
|
+
:returns: The request response
|
|
442
|
+
:rtype: AsyncHttpResponse
|
|
443
|
+
"""
|
|
370
444
|
|
|
371
|
-
|
|
372
|
-
async def options(self) -> None:
|
|
373
|
-
"""Send a OPTIONS request."""
|
|
445
|
+
return await self.request(self.patch.__name__.upper(), url, **kwargs)
|
|
374
446
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
"""Send a PATCH request."""
|
|
447
|
+
async def __aenter__(self) -> Self:
|
|
448
|
+
return cast(Self, await super().__aenter__())
|
|
378
449
|
|
|
379
450
|
|
|
380
451
|
def get_http_client() -> HttpPipeline:
|