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.

Files changed (64) hide show
  1. azure/ai/evaluation/__init__.py +1 -1
  2. azure/ai/evaluation/_common/constants.py +4 -2
  3. azure/ai/evaluation/_common/math.py +18 -0
  4. azure/ai/evaluation/_common/rai_service.py +54 -62
  5. azure/ai/evaluation/_common/utils.py +182 -12
  6. azure/ai/evaluation/_constants.py +10 -2
  7. azure/ai/evaluation/_evaluate/_batch_run_client/batch_run_context.py +10 -3
  8. azure/ai/evaluation/_evaluate/_batch_run_client/code_client.py +33 -17
  9. azure/ai/evaluation/_evaluate/_batch_run_client/proxy_client.py +17 -2
  10. azure/ai/evaluation/_evaluate/_eval_run.py +26 -10
  11. azure/ai/evaluation/_evaluate/_evaluate.py +116 -62
  12. azure/ai/evaluation/_evaluate/_telemetry/__init__.py +16 -17
  13. azure/ai/evaluation/_evaluate/_utils.py +44 -25
  14. azure/ai/evaluation/_evaluators/_coherence/_coherence.py +3 -2
  15. azure/ai/evaluation/_evaluators/_common/_base_eval.py +59 -30
  16. azure/ai/evaluation/_evaluators/_common/_base_prompty_eval.py +10 -13
  17. azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py +18 -20
  18. azure/ai/evaluation/_evaluators/_content_safety/_content_safety.py +15 -20
  19. azure/ai/evaluation/_evaluators/_content_safety/_content_safety_chat.py +63 -42
  20. azure/ai/evaluation/_evaluators/_content_safety/_hate_unfairness.py +4 -4
  21. azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py +4 -4
  22. azure/ai/evaluation/_evaluators/_content_safety/_sexual.py +4 -4
  23. azure/ai/evaluation/_evaluators/_content_safety/_violence.py +4 -4
  24. azure/ai/evaluation/_evaluators/_eci/_eci.py +4 -4
  25. azure/ai/evaluation/_evaluators/_f1_score/_f1_score.py +14 -6
  26. azure/ai/evaluation/_evaluators/_fluency/_fluency.py +3 -2
  27. azure/ai/evaluation/_evaluators/_groundedness/_groundedness.py +3 -2
  28. azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py +4 -4
  29. azure/ai/evaluation/_evaluators/_qa/_qa.py +4 -3
  30. azure/ai/evaluation/_evaluators/_relevance/_relevance.py +3 -2
  31. azure/ai/evaluation/_evaluators/_retrieval/_retrieval.py +11 -8
  32. azure/ai/evaluation/_evaluators/_rouge/_rouge.py +1 -1
  33. azure/ai/evaluation/_evaluators/_similarity/_similarity.py +21 -7
  34. azure/ai/evaluation/_evaluators/_xpia/xpia.py +4 -5
  35. azure/ai/evaluation/_exceptions.py +9 -6
  36. azure/ai/evaluation/_http_utils.py +203 -132
  37. azure/ai/evaluation/_model_configurations.py +5 -5
  38. azure/ai/evaluation/_vendor/__init__.py +3 -0
  39. azure/ai/evaluation/_vendor/rouge_score/__init__.py +14 -0
  40. azure/ai/evaluation/_vendor/rouge_score/rouge_scorer.py +328 -0
  41. azure/ai/evaluation/_vendor/rouge_score/scoring.py +63 -0
  42. azure/ai/evaluation/_vendor/rouge_score/tokenize.py +63 -0
  43. azure/ai/evaluation/_vendor/rouge_score/tokenizers.py +53 -0
  44. azure/ai/evaluation/_version.py +1 -1
  45. azure/ai/evaluation/simulator/_adversarial_simulator.py +85 -60
  46. azure/ai/evaluation/simulator/_conversation/__init__.py +13 -12
  47. azure/ai/evaluation/simulator/_conversation/_conversation.py +4 -4
  48. azure/ai/evaluation/simulator/_direct_attack_simulator.py +24 -66
  49. azure/ai/evaluation/simulator/_helpers/_experimental.py +20 -9
  50. azure/ai/evaluation/simulator/_helpers/_simulator_data_classes.py +4 -4
  51. azure/ai/evaluation/simulator/_indirect_attack_simulator.py +22 -64
  52. azure/ai/evaluation/simulator/_model_tools/_identity_manager.py +67 -21
  53. azure/ai/evaluation/simulator/_model_tools/_proxy_completion_model.py +28 -11
  54. azure/ai/evaluation/simulator/_model_tools/_template_handler.py +68 -24
  55. azure/ai/evaluation/simulator/_model_tools/models.py +10 -10
  56. azure/ai/evaluation/simulator/_prompty/task_query_response.prompty +0 -5
  57. azure/ai/evaluation/simulator/_prompty/task_simulate.prompty +0 -4
  58. azure/ai/evaluation/simulator/_simulator.py +112 -113
  59. azure/ai/evaluation/simulator/_tracing.py +4 -4
  60. {azure_ai_evaluation-1.0.0b3.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/METADATA +72 -44
  61. azure_ai_evaluation-1.0.0b4.dist-info/NOTICE.txt +50 -0
  62. {azure_ai_evaluation-1.0.0b3.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/RECORD +64 -56
  63. {azure_ai_evaluation-1.0.0b3.dist-info → azure_ai_evaluation-1.0.0b4.dist-info}/WHEEL +0 -0
  64. {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.utils import construct_prompty_model_config
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: dict):
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 = np.nan
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(np.nan)
88
+ per_turn_scores.append(math.nan)
86
89
 
87
90
  return {
88
- "gpt_retrieval": np.nanmean(per_turn_scores),
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.
@@ -4,7 +4,7 @@
4
4
  from enum import Enum
5
5
 
6
6
  from promptflow._utils.async_utils import async_run_allowing_running_loop
7
- from rouge_score import rouge_scorer
7
+ from azure.ai.evaluation._vendor.rouge_score import rouge_scorer
8
8
 
9
9
  from azure.core import CaseInsensitiveEnumMeta
10
10
 
@@ -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: dict):
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 = np.nan
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: dict
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 pazure-ai-evaluation. If there is a need to define a custom
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 error_category: The error category, defaults to Unknown.
87
- :type error_category: ~azure.ai.evaluation._exceptionsErrorCategory
88
- :param error: The original exception if any.
89
- :type error: Exception
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 functools import wraps
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
- def _request_fn(f: Callable[["HttpPipeline"], None]):
37
- """Decorator to generate convenience methods for HTTP method.
35
+ class RequestKwargs(TypedDict, total=False):
36
+ """Keyword arguments for request-style http request functions
38
37
 
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
- """
38
+ .. note::
44
39
 
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
- )
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
- 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
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
- @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
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 = 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)
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
- @_request_fn
217
- def delete(self) -> None:
218
- """Send a DELETE request."""
178
+ def delete(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
179
+ """Send a DELETE request.
219
180
 
220
- @_request_fn
221
- def put(self) -> None:
222
- """Send a PUT request."""
181
+ :param str url: The request url
182
+ :returns: The request response
183
+ :rtype: HttpResponse
184
+ """
223
185
 
224
- @_request_fn
225
- def get(self) -> None:
226
- """Send a GET request."""
186
+ return self.request(self.delete.__name__.upper(), url, **kwargs)
227
187
 
228
- @_request_fn
229
- def post(self) -> None:
230
- """Send a POST request."""
188
+ def put(self: "HttpPipeline", url: str, **kwargs: Unpack[RequestKwargs]) -> HttpResponse:
189
+ """Send a PUT request.
231
190
 
232
- @_request_fn
233
- def head(self) -> None:
234
- """Send a HEAD request."""
191
+ :param str url: The request url
192
+ :returns: The request response
193
+ :rtype: HttpResponse
194
+ """
235
195
 
236
- @_request_fn
237
- def options(self) -> None:
238
- """Send a OPTIONS request."""
196
+ return self.request(self.put.__name__.upper(), url, **kwargs)
239
197
 
240
- @_request_fn
241
- def patch(self) -> None:
242
- """Send a PATCH request."""
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 = 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)
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
- @_async_request_fn
352
- async def delete(self) -> None:
353
- """Send a DELETE request."""
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
- @_async_request_fn
356
- async def put(self) -> None:
357
- """Send a PUT request."""
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
- @_async_request_fn
360
- async def get(self) -> None:
361
- """Send a GET request."""
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
- @_async_request_fn
364
- async def post(self) -> None:
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
- @_async_request_fn
368
- async def head(self) -> None:
369
- """Send a HEAD request."""
440
+ :param str url: The request url
441
+ :returns: The request response
442
+ :rtype: AsyncHttpResponse
443
+ """
370
444
 
371
- @_async_request_fn
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
- @_async_request_fn
376
- async def patch(self) -> None:
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: