1+ # pylint: disable=line-too-long,useless-suppression
12# coding=utf-8
23# --------------------------------------------------------------------------
34# Copyright (c) Microsoft Corporation. All rights reserved.
78
89Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
910"""
11+ import json
12+ from typing import Any , Callable , Dict , IO , Mapping , Optional , TypeVar , Union , cast , overload , Generic , TYPE_CHECKING
13+ from collections .abc import MutableMapping # pylint:disable=import-error
14+ from urllib .parse import urlparse
15+ from azure .core .exceptions import (
16+ HttpResponseError ,
17+ )
18+ from azure .core .pipeline import PipelineResponse
19+ from azure .core .polling import LROPoller , NoPolling , PollingMethod
20+ from azure .core .polling .base_polling import LROBasePolling
21+ from azure .core .rest import HttpRequest , HttpResponse
22+ from azure .core .tracing .decorator import distributed_trace
23+ from azure .core .utils import case_insensitive_dict
24+ from azure .core .credentials import AzureKeyCredential
25+ from azure .core .paging import ItemPaged
26+ from ._client import ConversationAnalysisClient as AnalysisClientGenerated
27+ from .models import AnalyzeConversationOperationInput , AnalyzeConversationOperationState , ConversationActions
28+ from ._utils .serialization import Serializer
1029
30+ from ._validation import api_version_validation
1131
12- __all__ : list [str ] = [] # Add all objects you want publicly available to users at this package level
32+ if TYPE_CHECKING :
33+ from azure .core .credentials import TokenCredential
34+
35+ JSON = MutableMapping [str , Any ]
36+ T = TypeVar ("T" )
37+ ClsType = Optional [Callable [[PipelineResponse [HttpRequest , HttpResponse ], T , Dict [str , Any ]], Any ]]
38+
39+ _SERIALIZER = Serializer ()
40+ _SERIALIZER .client_side_validation = False
41+
42+
43+ def _parse_operation_id (op_loc : Optional [str ]) -> Optional [str ]:
44+ """Extract the operation ID from an Operation-Location URL.
45+
46+ :param op_loc: The ``Operation-Location`` header value or URL to parse.
47+ If ``None`` or malformed, no ID can be extracted.
48+ :type op_loc: Optional[str]
49+ :return: The trailing path segment as the operation ID, or ``None`` if not found.
50+ :rtype: Optional[str]
51+ """
52+ if not op_loc :
53+ return None
54+ path = urlparse (op_loc ).path .rstrip ("/" )
55+ if "/" not in path :
56+ return None
57+ return path .rsplit ("/" , 1 )[- 1 ]
58+
59+
60+ PollingReturnType_co = TypeVar ("PollingReturnType_co" , covariant = True )
61+
62+
63+ class AnalyzeConversationLROPoller (LROPoller [PollingReturnType_co ], Generic [PollingReturnType_co ]):
64+ """Custom poller that returns PollingReturnType_co and exposes operation metadata."""
65+
66+ def __init__ (self , * args : Any , ** kwargs : Any ) -> None :
67+ super ().__init__ (* args , ** kwargs )
68+ # populated by the deserialization callback in your begin_* method
69+ self ._last_state : Optional ["AnalyzeConversationOperationState" ] = None
70+
71+ def _record_state_for_details (self , state : "AnalyzeConversationOperationState" ) -> None :
72+ """Internal: update the state used by ``.details``.
73+
74+ :param state: The latest operation state to expose via ``details``.
75+ :type state: AnalyzeConversationOperationState
76+ :return: None
77+ :rtype: None
78+ """
79+ self ._last_state = state
80+
81+ @property
82+ def details (self ) -> Mapping [str , Any ]:
83+ """Metadata associated with the long-running operation.
84+
85+ :return: A mapping with keys like ``operation_id`` and, when available,
86+ ``status``, ``job_id``, ``display_name``, ``created_date_time``,
87+ ``last_updated_date_time``, ``expiration_date_time``, ``statistics``,
88+ ``errors``, and ``next_link``.
89+ :rtype: Mapping[str, Any]
90+ """
91+ try :
92+ headers = getattr (self .polling_method (), "_initial_response" ).http_response .headers # type: ignore[attr-defined]
93+ op_loc = headers .get ("Operation-Location" ) or headers .get ("operation-location" )
94+ except (AttributeError , TypeError ):
95+ # missing attributes in the chain, or headers is not a mapping
96+ op_loc = None
97+
98+ op_id = _parse_operation_id (op_loc )
99+ info : Dict [str , Any ] = {"operation_id" : op_id }
100+
101+ # Merge fields from the final state (if available)
102+ if self ._last_state is not None :
103+ s = self ._last_state
104+ info .update (
105+ {
106+ "status" : s .status ,
107+ "job_id" : s .job_id ,
108+ "display_name" : s .display_name ,
109+ "created_date_time" : s .created_date_time ,
110+ "last_updated_date_time" : s .last_updated_date_time ,
111+ "expiration_date_time" : s .expiration_date_time ,
112+ "statistics" : s .statistics ,
113+ "errors" : s .errors ,
114+ "next_link" : s .next_link ,
115+ }
116+ )
117+ return info
118+
119+ @classmethod
120+ def from_continuation_token (
121+ cls ,
122+ polling_method : PollingMethod [PollingReturnType_co ],
123+ continuation_token : str ,
124+ ** kwargs : Any ,
125+ ) -> "AnalyzeConversationLROPoller[PollingReturnType_co]" :
126+ client , initial_response , deserialization_callback = polling_method .from_continuation_token (
127+ continuation_token , ** kwargs
128+ )
129+ return cls (client , initial_response , deserialization_callback , polling_method )
130+
131+
132+ class ConversationAnalysisClient (AnalysisClientGenerated ):
133+
134+ def __init__ (
135+ self ,
136+ endpoint : str ,
137+ credential : Union [AzureKeyCredential , "TokenCredential" ],
138+ * ,
139+ api_version : Optional [str ] = None ,
140+ ** kwargs : Any ,
141+ ) -> None :
142+ """Create a ConversationAnalysisClient.
143+ :param endpoint: Supported Cognitive Services endpoint.
144+ :type endpoint: str
145+ :param credential: Key or token credential.
146+ :type credential: ~azure.core.credentials.AzureKeyCredential or ~azure.core.credentials.TokenCredential
147+ :keyword api_version: The API version to use for this operation. Default value is
148+ "2025-05-15-preview". Note that overriding this default value may result in unsupported
149+ behavior.
150+ :paramtype api_version: str`
151+ """
152+ if api_version is not None :
153+ kwargs ["api_version" ] = api_version
154+ super ().__init__ (endpoint = endpoint , credential = credential , ** kwargs )
155+
156+ @overload
157+ def begin_analyze_conversation_job (
158+ self , body : AnalyzeConversationOperationInput , * , content_type : str = "application/json" , ** kwargs : Any
159+ ) -> AnalyzeConversationLROPoller [ItemPaged ["ConversationActions" ]]:
160+ """Analyzes the input conversation utterance.
161+
162+ :param body: The input for the analyze conversations operation. Required.
163+ :type body: ~azure.ai.language.conversations.models.AnalyzeConversationOperationInput
164+ :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
165+ Default value is "application/json".
166+ :paramtype content_type: str
167+ :return: A poller whose ``result()`` yields ``ItemPaged[ConversationActions]`` and exposes metadata via ``.details``.
168+ :rtype: ~azure.ai.language.conversations.AnalyzeConversationLROPoller[
169+ ~azure.core.paging.ItemPaged[~azure.ai.language.conversations.models.ConversationActions]]
170+ :raises ~azure.core.exceptions.HttpResponseError:
171+ """
172+
173+ @overload
174+ def begin_analyze_conversation_job (
175+ self , body : JSON , * , content_type : str = "application/json" , ** kwargs : Any
176+ ) -> AnalyzeConversationLROPoller [ItemPaged ["ConversationActions" ]]:
177+ """Analyzes the input conversation utterance.
178+
179+ :param body: The input for the analyze conversations operation. Required.
180+ :type body: JSON
181+ :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
182+ Default value is "application/json".
183+ :paramtype content_type: str
184+ :return: A poller whose ``result()`` yields ``ItemPaged[ConversationActions]`` and exposes metadata via ``.details``.
185+ :rtype: ~azure.ai.language.conversations.AnalyzeConversationLROPoller[
186+ ~azure.core.paging.ItemPaged[~azure.ai.language.conversations.models.ConversationActions]]
187+ :raises ~azure.core.exceptions.HttpResponseError:
188+ """
189+
190+ @overload
191+ def begin_analyze_conversation_job (
192+ self , body : IO [bytes ], * , content_type : str = "application/json" , ** kwargs : Any
193+ ) -> AnalyzeConversationLROPoller [ItemPaged ["ConversationActions" ]]:
194+ """Analyzes the input conversation utterance.
195+
196+ :param body: The input for the analyze conversations operation. Required.
197+ :type body: IO[bytes]
198+ :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
199+ Default value is "application/json".
200+ :paramtype content_type: str
201+ :return: A poller whose ``result()`` yields ``ItemPaged[ConversationActions]`` and exposes metadata via ``.details``.
202+ :rtype: ~azure.ai.language.conversations.AnalyzeConversationLROPoller[
203+ ~azure.core.paging.ItemPaged[~azure.ai.language.conversations.models.ConversationActions]]
204+ :raises ~azure.core.exceptions.HttpResponseError:
205+ """
206+
207+ @distributed_trace
208+ @api_version_validation (
209+ method_added_on = "2023-04-01" ,
210+ params_added_on = {"2023-04-01" : ["api_version" , "content_type" , "accept" ]},
211+ api_versions_list = ["2023-04-01" , "2024-05-01" , "2024-11-01" , "2024-11-15-preview" , "2025-05-15-preview" ],
212+ )
213+ def begin_analyze_conversation_job ( # type: ignore[override]
214+ self , body : Union [AnalyzeConversationOperationInput , JSON , IO [bytes ]], ** kwargs : Any
215+ ) -> AnalyzeConversationLROPoller [ItemPaged ["ConversationActions" ]]:
216+ """Analyzes the input conversation utterance.
217+
218+ :param body: The input for the analyze conversations operation. Required.
219+ :type body: ~azure.ai.language.conversations.models.AnalyzeConversationOperationInput or JSON or IO[bytes]
220+ :return: A poller whose ``result()`` yields ``ItemPaged[ConversationActions]`` and exposes metadata via ``.details``.
221+ :rtype: ~azure.ai.language.conversations.AnalyzeConversationLROPoller[
222+ ~azure.core.paging.ItemPaged[~azure.ai.language.conversations.models.ConversationActions]]
223+ :raises ~azure.core.exceptions.HttpResponseError:
224+ """
225+ _headers = case_insensitive_dict (kwargs .pop ("headers" , {}) or {})
226+ _params = kwargs .pop ("params" , {}) or {}
227+
228+ content_type : Optional [str ] = kwargs .pop ("content_type" , _headers .pop ("Content-Type" , None ))
229+ polling : Union [bool , PollingMethod [ItemPaged ["ConversationActions" ]]] = kwargs .pop ("polling" , True )
230+ lro_delay = kwargs .pop ("polling_interval" , self ._config .polling_interval )
231+ cont_token : Optional [str ] = kwargs .pop ("continuation_token" , None )
232+ cls = kwargs .pop ("cls" , None ) # optional custom deserializer
233+ kwargs .pop ("error_map" , None )
234+
235+ path_format_arguments = {
236+ "Endpoint" : self ._serialize .url ("self._config.endpoint" , self ._config .endpoint , "str" ),
237+ }
238+
239+ def _fetch_state_by_next_link (next_link : str ) -> AnalyzeConversationOperationState :
240+ req = HttpRequest ("GET" , next_link )
241+ resp = self ._client .send_request (req ) # type: ignore[attr-defined]
242+ if resp .status_code != 200 :
243+ raise HttpResponseError (response = resp )
244+ data = json .loads (resp .text ())
245+ return AnalyzeConversationOperationState (data )
246+
247+ def _build_pager_from_state (state : AnalyzeConversationOperationState ) -> ItemPaged ["ConversationActions" ]:
248+ def extract_data (s : AnalyzeConversationOperationState ):
249+ next_link = s .next_link
250+ actions : ConversationActions = s .actions
251+ return next_link , [actions ]
252+
253+ def get_next (token : Optional [str ]) -> Optional [AnalyzeConversationOperationState ]:
254+ if token is None :
255+ return state
256+ if not token :
257+ return None
258+ return _fetch_state_by_next_link (token )
259+
260+ return ItemPaged (get_next , extract_data )
261+
262+ # ----- end paging helpers
263+
264+ # filled after creating the poller; used inside the deserializer
265+ poller_holder : Dict [str , AnalyzeConversationLROPoller [ItemPaged ["ConversationActions" ]]] = {}
266+
267+ def get_long_running_output (pipeline_response ):
268+ final_response = pipeline_response .http_response
269+ if final_response .status_code == 200 :
270+ data = json .loads (final_response .text ())
271+ op_state = AnalyzeConversationOperationState (data )
272+
273+ # stash state on the custom poller for `.details`
274+ poller_ref = poller_holder ["poller" ]
275+ poller_ref ._record_state_for_details (op_state ) # pylint:disable=protected-access
276+
277+ paged = _build_pager_from_state (op_state )
278+ return cls (pipeline_response , paged , {}) if cls else paged
279+ raise HttpResponseError (response = final_response )
280+
281+ # ----- polling method selection
282+ if polling is True :
283+ polling_method : PollingMethod [ItemPaged ["ConversationActions" ]] = cast (
284+ PollingMethod [ItemPaged ["ConversationActions" ]],
285+ LROBasePolling (lro_delay , path_format_arguments = path_format_arguments , ** kwargs ),
286+ )
287+ elif polling is False :
288+ polling_method = cast (PollingMethod [ItemPaged ["ConversationActions" ]], NoPolling ())
289+ else :
290+ polling_method = cast (PollingMethod [ItemPaged ["ConversationActions" ]], polling )
291+
292+ if cont_token :
293+ return AnalyzeConversationLROPoller [ItemPaged ["ConversationActions" ]].from_continuation_token (
294+ polling_method = polling_method ,
295+ continuation_token = cont_token ,
296+ )
297+
298+ # Submit the job
299+ raw_result = self ._analyze_conversation_job_initial (
300+ body = body , content_type = content_type , cls = lambda x , y , z : x , headers = _headers , params = _params , ** kwargs
301+ )
302+
303+ lro : AnalyzeConversationLROPoller [ItemPaged ["ConversationActions" ]] = AnalyzeConversationLROPoller (
304+ self ._client , raw_result , get_long_running_output , polling_method
305+ )
306+ poller_holder ["poller" ] = lro
307+ return lro
13308
14309
15310def patch_sdk ():
@@ -19,3 +314,6 @@ def patch_sdk():
19314 you can't accomplish using the techniques described in
20315 https://aka.ms/azsdk/python/dpcodegen/python/customize
21316 """
317+
318+
319+ __all__ = ["ConversationAnalysisClient" , "AnalyzeConversationLROPoller" ]
0 commit comments