azure-ai-evaluation 1.0.0b3__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 +1 -1
- 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 +182 -12
- azure/ai/evaluation/_constants.py +10 -2
- 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 +116 -62
- azure/ai/evaluation/_evaluate/_telemetry/__init__.py +16 -17
- azure/ai/evaluation/_evaluate/_utils.py +44 -25
- azure/ai/evaluation/_evaluators/_coherence/_coherence.py +3 -2
- azure/ai/evaluation/_evaluators/_common/_base_eval.py +59 -30
- azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +10 -13
- azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +18 -20
- 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 +4 -4
- azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py +4 -4
- azure/ai/evaluation/_evaluators/_content_safety/_sexual.py +4 -4
- azure/ai/evaluation/_evaluators/_content_safety/_violence.py +4 -4
- azure/ai/evaluation/_evaluators/_eci/_eci.py +4 -4
- azure/ai/evaluation/_evaluators/_f1_score/_f1_score.py +14 -6
- azure/ai/evaluation/_evaluators/_fluency/_fluency.py +3 -2
- azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +3 -2
- azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py +4 -4
- azure/ai/evaluation/_evaluators/_qa/_qa.py +4 -3
- azure/ai/evaluation/_evaluators/_relevance/_relevance.py +3 -2
- azure/ai/evaluation/_evaluators/_retrieval/_retrieval.py +11 -8
- azure/ai/evaluation/_evaluators/_rouge/_rouge.py +1 -1
- azure/ai/evaluation/_evaluators/_similarity/_similarity.py +21 -7
- azure/ai/evaluation/_evaluators/_xpia/xpia.py +4 -5
- azure/ai/evaluation/_exceptions.py +9 -6
- azure/ai/evaluation/_http_utils.py +203 -132
- azure/ai/evaluation/_model_configurations.py +5 -5
- azure/ai/evaluation/_vendor/__init__.py +3 -0
- 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 +0 -5
- azure/ai/evaluation/simulator/_prompty/task_simulate.prompty +0 -4
- azure/ai/evaluation/simulator/_simulator.py +112 -113
- azure/ai/evaluation/simulator/_tracing.py +4 -4
- {azure_ai_evaluation-1.0.0b3.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/METADATA +72 -44
- azure_ai_evaluation-1.0.0b4.dist-info/NOTICE.txt +50 -0
- {azure_ai_evaluation-1.0.0b3.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/RECORD +64 -56
- {azure_ai_evaluation-1.0.0b3.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/WHEEL +0 -0
- {azure_ai_evaluation-1.0.0b3.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/top_level.txt +0 -0
|
@@ -4,22 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
6
|
import logging
|
|
7
|
+
import math
|
|
7
8
|
import os
|
|
8
9
|
import re
|
|
10
|
+
from typing import Union
|
|
9
11
|
|
|
10
|
-
import numpy as np
|
|
11
12
|
from promptflow._utils.async_utils import async_run_allowing_running_loop
|
|
12
13
|
from promptflow.core import AsyncPrompty
|
|
13
14
|
|
|
15
|
+
from azure.ai.evaluation._model_configurations import AzureOpenAIModelConfiguration, OpenAIModelConfiguration
|
|
14
16
|
|
|
15
|
-
from ..._common.
|
|
17
|
+
from ..._common.math import list_mean_nan_safe
|
|
18
|
+
from ..._common.utils import construct_prompty_model_config, validate_model_config
|
|
16
19
|
|
|
17
20
|
logger = logging.getLogger(__name__)
|
|
18
21
|
|
|
19
22
|
try:
|
|
20
23
|
from .._user_agent import USER_AGENT
|
|
21
24
|
except ImportError:
|
|
22
|
-
USER_AGENT = None
|
|
25
|
+
USER_AGENT = "None"
|
|
23
26
|
|
|
24
27
|
|
|
25
28
|
class _AsyncRetrievalScoreEvaluator:
|
|
@@ -28,7 +31,7 @@ class _AsyncRetrievalScoreEvaluator:
|
|
|
28
31
|
LLM_CALL_TIMEOUT = 600
|
|
29
32
|
DEFAULT_OPEN_API_VERSION = "2024-02-15-preview"
|
|
30
33
|
|
|
31
|
-
def __init__(self, model_config:
|
|
34
|
+
def __init__(self, model_config: Union[AzureOpenAIModelConfiguration, OpenAIModelConfiguration]):
|
|
32
35
|
prompty_model_config = construct_prompty_model_config(
|
|
33
36
|
model_config,
|
|
34
37
|
self.DEFAULT_OPEN_API_VERSION,
|
|
@@ -69,7 +72,7 @@ class _AsyncRetrievalScoreEvaluator:
|
|
|
69
72
|
llm_output = await self._flow(
|
|
70
73
|
query=query, history=history, documents=context, timeout=self.LLM_CALL_TIMEOUT, **kwargs
|
|
71
74
|
)
|
|
72
|
-
score =
|
|
75
|
+
score = math.nan
|
|
73
76
|
if llm_output:
|
|
74
77
|
parsed_score_response = re.findall(r"\d+", llm_output.split("# Result")[-1].strip())
|
|
75
78
|
if len(parsed_score_response) > 0:
|
|
@@ -82,10 +85,10 @@ class _AsyncRetrievalScoreEvaluator:
|
|
|
82
85
|
"Evaluator %s failed for turn %s with exception: %s", self.__class__.__name__, turn_num + 1, e
|
|
83
86
|
)
|
|
84
87
|
|
|
85
|
-
per_turn_scores.append(
|
|
88
|
+
per_turn_scores.append(math.nan)
|
|
86
89
|
|
|
87
90
|
return {
|
|
88
|
-
"gpt_retrieval":
|
|
91
|
+
"gpt_retrieval": list_mean_nan_safe(per_turn_scores),
|
|
89
92
|
"evaluation_per_turn": {
|
|
90
93
|
"gpt_retrieval": {
|
|
91
94
|
"score": per_turn_scores,
|
|
@@ -135,7 +138,7 @@ class RetrievalEvaluator:
|
|
|
135
138
|
"""
|
|
136
139
|
|
|
137
140
|
def __init__(self, model_config: dict):
|
|
138
|
-
self._async_evaluator = _AsyncRetrievalScoreEvaluator(model_config)
|
|
141
|
+
self._async_evaluator = _AsyncRetrievalScoreEvaluator(validate_model_config(model_config))
|
|
139
142
|
|
|
140
143
|
def __call__(self, *, conversation, **kwargs):
|
|
141
144
|
"""Evaluates retrieval score chat scenario.
|
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
# ---------------------------------------------------------
|
|
4
4
|
|
|
5
|
+
import math
|
|
5
6
|
import os
|
|
6
7
|
import re
|
|
8
|
+
from typing import Union
|
|
7
9
|
|
|
8
|
-
import numpy as np
|
|
9
10
|
from promptflow._utils.async_utils import async_run_allowing_running_loop
|
|
10
11
|
from promptflow.core import AsyncPrompty
|
|
11
12
|
|
|
12
13
|
from azure.ai.evaluation._exceptions import ErrorBlame, ErrorCategory, ErrorTarget, EvaluationException
|
|
14
|
+
from azure.ai.evaluation._model_configurations import AzureOpenAIModelConfiguration, OpenAIModelConfiguration
|
|
13
15
|
|
|
14
|
-
from ..._common.utils import construct_prompty_model_config
|
|
16
|
+
from ..._common.utils import construct_prompty_model_config, validate_model_config
|
|
15
17
|
|
|
16
18
|
try:
|
|
17
19
|
from ..._user_agent import USER_AGENT
|
|
18
20
|
except ImportError:
|
|
19
|
-
USER_AGENT = None
|
|
21
|
+
USER_AGENT = "None"
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class _AsyncSimilarityEvaluator:
|
|
@@ -25,7 +27,7 @@ class _AsyncSimilarityEvaluator:
|
|
|
25
27
|
LLM_CALL_TIMEOUT = 600
|
|
26
28
|
DEFAULT_OPEN_API_VERSION = "2024-02-15-preview"
|
|
27
29
|
|
|
28
|
-
def __init__(self, model_config:
|
|
30
|
+
def __init__(self, model_config: Union[AzureOpenAIModelConfiguration, OpenAIModelConfiguration]):
|
|
29
31
|
prompty_model_config = construct_prompty_model_config(
|
|
30
32
|
model_config,
|
|
31
33
|
self.DEFAULT_OPEN_API_VERSION,
|
|
@@ -37,6 +39,18 @@ class _AsyncSimilarityEvaluator:
|
|
|
37
39
|
self._flow = AsyncPrompty.load(source=prompty_path, model=prompty_model_config)
|
|
38
40
|
|
|
39
41
|
async def __call__(self, *, query: str, response: str, ground_truth: str, **kwargs):
|
|
42
|
+
"""
|
|
43
|
+
Evaluate similarity.
|
|
44
|
+
|
|
45
|
+
:keyword query: The query to be evaluated.
|
|
46
|
+
:paramtype query: str
|
|
47
|
+
:keyword response: The response to be evaluated.
|
|
48
|
+
:paramtype response: str
|
|
49
|
+
:keyword ground_truth: The ground truth to be evaluated.
|
|
50
|
+
:paramtype ground_truth: str
|
|
51
|
+
:return: The similarity score.
|
|
52
|
+
:rtype: Dict[str, float]
|
|
53
|
+
"""
|
|
40
54
|
# Validate input parameters
|
|
41
55
|
query = str(query or "")
|
|
42
56
|
response = str(response or "")
|
|
@@ -57,7 +71,7 @@ class _AsyncSimilarityEvaluator:
|
|
|
57
71
|
query=query, response=response, ground_truth=ground_truth, timeout=self.LLM_CALL_TIMEOUT, **kwargs
|
|
58
72
|
)
|
|
59
73
|
|
|
60
|
-
score =
|
|
74
|
+
score = math.nan
|
|
61
75
|
if llm_output:
|
|
62
76
|
match = re.search(r"\d", llm_output)
|
|
63
77
|
if match:
|
|
@@ -94,7 +108,7 @@ class SimilarityEvaluator:
|
|
|
94
108
|
"""
|
|
95
109
|
|
|
96
110
|
def __init__(self, model_config: dict):
|
|
97
|
-
self._async_evaluator = _AsyncSimilarityEvaluator(model_config)
|
|
111
|
+
self._async_evaluator = _AsyncSimilarityEvaluator(validate_model_config(model_config))
|
|
98
112
|
|
|
99
113
|
def __call__(self, *, query: str, response: str, ground_truth: str, **kwargs):
|
|
100
114
|
"""
|
|
@@ -107,7 +121,7 @@ class SimilarityEvaluator:
|
|
|
107
121
|
:keyword ground_truth: The ground truth to be evaluated.
|
|
108
122
|
:paramtype ground_truth: str
|
|
109
123
|
:return: The similarity score.
|
|
110
|
-
:rtype:
|
|
124
|
+
:rtype: Dict[str, float]
|
|
111
125
|
"""
|
|
112
126
|
return async_run_allowing_running_loop(
|
|
113
127
|
self._async_evaluator, query=query, response=response, ground_truth=ground_truth, **kwargs
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
# ---------------------------------------------------------
|
|
4
4
|
import logging
|
|
5
5
|
|
|
6
|
-
from typing import Optional
|
|
7
6
|
from typing_extensions import override
|
|
7
|
+
|
|
8
8
|
from azure.ai.evaluation._common.constants import EvaluationMetrics
|
|
9
9
|
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
logger = logging.getLogger(__name__)
|
|
13
12
|
|
|
14
13
|
|
|
@@ -17,14 +16,14 @@ class IndirectAttackEvaluator(RaiServiceEvaluatorBase):
|
|
|
17
16
|
|
|
18
17
|
Detect whether cross domain injected attacks are present in your AI system's response.
|
|
19
18
|
|
|
19
|
+
:param credential: The credential for connecting to Azure AI project. Required
|
|
20
|
+
:type credential: ~azure.core.credentials.TokenCredential
|
|
20
21
|
:param azure_ai_project: The scope of the Azure AI project. It contains subscription id, resource group, and project
|
|
21
22
|
name.
|
|
22
23
|
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
|
|
23
24
|
:param eval_last_turn: Set to True to evaluate only the most recent exchange in the dialogue,
|
|
24
25
|
focusing on the latest user inquiry and the assistant's corresponding response. Defaults to False
|
|
25
26
|
:type eval_last_turn: bool
|
|
26
|
-
:param credential: The credential for connecting to Azure AI project.
|
|
27
|
-
:type credential: Optional[~azure.core.credentials.TokenCredential]
|
|
28
27
|
:return: A function that evaluates and generates metrics for XPIA chat scenario. Metrics include the overall
|
|
29
28
|
evaluation label and reason for the Q/A Pair, as well as sub-labels for manipulated content, intrusion, and
|
|
30
29
|
information.
|
|
@@ -53,8 +52,8 @@ class IndirectAttackEvaluator(RaiServiceEvaluatorBase):
|
|
|
53
52
|
@override
|
|
54
53
|
def __init__(
|
|
55
54
|
self,
|
|
55
|
+
credential,
|
|
56
56
|
azure_ai_project: dict,
|
|
57
|
-
credential: Optional[dict] = None,
|
|
58
57
|
eval_last_turn: bool = False,
|
|
59
58
|
):
|
|
60
59
|
super().__init__(
|
|
@@ -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
|
|
|
@@ -74,7 +77,7 @@ class ErrorTarget(Enum):
|
|
|
74
77
|
|
|
75
78
|
|
|
76
79
|
class EvaluationException(AzureError):
|
|
77
|
-
"""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
|
|
78
81
|
exception type, that custom exception type should extend from this class.
|
|
79
82
|
|
|
80
83
|
:param message: A message describing the error. This is the error message the user will see.
|
|
@@ -83,17 +86,17 @@ class EvaluationException(AzureError):
|
|
|
83
86
|
:type internal_message: str
|
|
84
87
|
:param target: The name of the element that caused the exception to be thrown.
|
|
85
88
|
:type target: ~azure.ai.evaluation._exceptions.ErrorTarget
|
|
86
|
-
:param
|
|
87
|
-
:type
|
|
88
|
-
:param
|
|
89
|
-
: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
|
|
90
93
|
"""
|
|
91
94
|
|
|
92
95
|
def __init__(
|
|
93
96
|
self,
|
|
94
97
|
message: str,
|
|
95
|
-
internal_message: str,
|
|
96
98
|
*args,
|
|
99
|
+
internal_message: Optional[str] = None,
|
|
97
100
|
target: ErrorTarget = ErrorTarget.UNKNOWN,
|
|
98
101
|
category: ErrorCategory = ErrorCategory.UNKNOWN,
|
|
99
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:
|