azure-ai-transcription 1.0.0b2__py3-none-any.whl → 1.0.0b3__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.
@@ -27,7 +27,7 @@ class TranscriptionClient(_TranscriptionClientOperationsMixin):
27
27
  """TranscriptionClient.
28
28
 
29
29
  :param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
30
- `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_.
30
+ `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_).
31
31
  Required.
32
32
  :type endpoint: str
33
33
  :param credential: Credential used to authenticate requests to the service. Is either a key
@@ -24,7 +24,7 @@ class TranscriptionClientConfiguration: # pylint: disable=too-many-instance-att
24
24
  attributes.
25
25
 
26
26
  :param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
27
- `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_.
27
+ `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_).
28
28
  Required.
29
29
  :type endpoint: str
30
30
  :param credential: Credential used to authenticate requests to the service. Is either a key
@@ -110,12 +110,11 @@ class _TranscriptionClientOperationsMixin(
110
110
  _body = body.as_dict() if isinstance(body, _Model) else body
111
111
  _file_fields: list[str] = ["audio"]
112
112
  _data_fields: list[str] = ["definition"]
113
- _files, _data = prepare_multipart_form_data(_body, _file_fields, _data_fields)
113
+ _files = prepare_multipart_form_data(_body, _file_fields, _data_fields)
114
114
 
115
115
  _request = build_transcription_transcribe_request(
116
116
  api_version=self._config.api_version,
117
117
  files=_files,
118
- data=_data,
119
118
  headers=_headers,
120
119
  params=_params,
121
120
  )
@@ -12,7 +12,14 @@ from collections.abc import MutableMapping
12
12
  from typing import Any, Optional
13
13
  import json
14
14
  from azure.core.tracing.decorator import distributed_trace
15
- from azure.core.exceptions import map_error, HttpResponseError, ClientAuthenticationError, ResourceNotFoundError, ResourceExistsError, ResourceNotModifiedError
15
+ from azure.core.exceptions import (
16
+ map_error,
17
+ HttpResponseError,
18
+ ClientAuthenticationError,
19
+ ResourceNotFoundError,
20
+ ResourceExistsError,
21
+ ResourceNotModifiedError,
22
+ )
16
23
 
17
24
  from .. import models as _models
18
25
  from .._utils.model_base import _deserialize, SdkJSONEncoder
@@ -93,7 +100,9 @@ class _TranscriptionClientOperationsMixin(_TranscriptionClientOperationsMixinGen
93
100
  }
94
101
  _request.url = self._client.format_url(_request.url, **path_format_arguments)
95
102
 
96
- pipeline_response = self._client._pipeline.run(_request, stream=False, **kwargs) # pylint: disable=protected-access
103
+ pipeline_response = self._client._pipeline.run( # pylint: disable=protected-access
104
+ _request, stream=False, **kwargs
105
+ )
97
106
  response = pipeline_response.http_response
98
107
 
99
108
  if response.status_code not in [200]:
@@ -37,6 +37,7 @@ __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"]
37
37
 
38
38
  TZ_UTC = timezone.utc
39
39
  _T = typing.TypeVar("_T")
40
+ _NONE_TYPE = type(None)
40
41
 
41
42
 
42
43
  def _timedelta_as_isostr(td: timedelta) -> str:
@@ -171,6 +172,21 @@ _VALID_RFC7231 = re.compile(
171
172
  r"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{4}\s\d{2}:\d{2}:\d{2}\sGMT"
172
173
  )
173
174
 
175
+ _ARRAY_ENCODE_MAPPING = {
176
+ "pipeDelimited": "|",
177
+ "spaceDelimited": " ",
178
+ "commaDelimited": ",",
179
+ "newlineDelimited": "\n",
180
+ }
181
+
182
+
183
+ def _deserialize_array_encoded(delimit: str, attr):
184
+ if isinstance(attr, str):
185
+ if attr == "":
186
+ return []
187
+ return attr.split(delimit)
188
+ return attr
189
+
174
190
 
175
191
  def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime:
176
192
  """Deserialize ISO-8601 formatted string into Datetime object.
@@ -202,7 +218,7 @@ def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime:
202
218
  test_utc = date_obj.utctimetuple()
203
219
  if test_utc.tm_year > 9999 or test_utc.tm_year < 1:
204
220
  raise OverflowError("Hit max or min date")
205
- return date_obj
221
+ return date_obj # type: ignore[no-any-return]
206
222
 
207
223
 
208
224
  def _deserialize_datetime_rfc7231(attr: typing.Union[str, datetime]) -> datetime:
@@ -256,7 +272,7 @@ def _deserialize_time(attr: typing.Union[str, time]) -> time:
256
272
  """
257
273
  if isinstance(attr, time):
258
274
  return attr
259
- return isodate.parse_time(attr)
275
+ return isodate.parse_time(attr) # type: ignore[no-any-return]
260
276
 
261
277
 
262
278
  def _deserialize_bytes(attr):
@@ -315,6 +331,8 @@ _DESERIALIZE_MAPPING_WITHFORMAT = {
315
331
  def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = None):
316
332
  if annotation is int and rf and rf._format == "str":
317
333
  return _deserialize_int_as_str
334
+ if annotation is str and rf and rf._format in _ARRAY_ENCODE_MAPPING:
335
+ return functools.partial(_deserialize_array_encoded, _ARRAY_ENCODE_MAPPING[rf._format])
318
336
  if rf and rf._format:
319
337
  return _DESERIALIZE_MAPPING_WITHFORMAT.get(rf._format)
320
338
  return _DESERIALIZE_MAPPING.get(annotation) # pyright: ignore
@@ -353,9 +371,39 @@ class _MyMutableMapping(MutableMapping[str, typing.Any]):
353
371
  return key in self._data
354
372
 
355
373
  def __getitem__(self, key: str) -> typing.Any:
374
+ # If this key has been deserialized (for mutable types), we need to handle serialization
375
+ if hasattr(self, "_attr_to_rest_field"):
376
+ cache_attr = f"_deserialized_{key}"
377
+ if hasattr(self, cache_attr):
378
+ rf = _get_rest_field(getattr(self, "_attr_to_rest_field"), key)
379
+ if rf:
380
+ value = self._data.get(key)
381
+ if isinstance(value, (dict, list, set)):
382
+ # For mutable types, serialize and return
383
+ # But also update _data with serialized form and clear flag
384
+ # so mutations via this returned value affect _data
385
+ serialized = _serialize(value, rf._format)
386
+ # If serialized form is same type (no transformation needed),
387
+ # return _data directly so mutations work
388
+ if isinstance(serialized, type(value)) and serialized == value:
389
+ return self._data.get(key)
390
+ # Otherwise return serialized copy and clear flag
391
+ try:
392
+ object.__delattr__(self, cache_attr)
393
+ except AttributeError:
394
+ pass
395
+ # Store serialized form back
396
+ self._data[key] = serialized
397
+ return serialized
356
398
  return self._data.__getitem__(key)
357
399
 
358
400
  def __setitem__(self, key: str, value: typing.Any) -> None:
401
+ # Clear any cached deserialized value when setting through dictionary access
402
+ cache_attr = f"_deserialized_{key}"
403
+ try:
404
+ object.__delattr__(self, cache_attr)
405
+ except AttributeError:
406
+ pass
359
407
  self._data.__setitem__(key, value)
360
408
 
361
409
  def __delitem__(self, key: str) -> None:
@@ -483,6 +531,8 @@ def _is_model(obj: typing.Any) -> bool:
483
531
 
484
532
  def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-many-return-statements
485
533
  if isinstance(o, list):
534
+ if format in _ARRAY_ENCODE_MAPPING and all(isinstance(x, str) for x in o):
535
+ return _ARRAY_ENCODE_MAPPING[format].join(o)
486
536
  return [_serialize(x, format) for x in o]
487
537
  if isinstance(o, dict):
488
538
  return {k: _serialize(v, format) for k, v in o.items()}
@@ -758,6 +808,14 @@ def _deserialize_multiple_sequence(
758
808
  return type(obj)(_deserialize(deserializer, entry, module) for entry, deserializer in zip(obj, entry_deserializers))
759
809
 
760
810
 
811
+ def _is_array_encoded_deserializer(deserializer: functools.partial) -> bool:
812
+ return (
813
+ isinstance(deserializer, functools.partial)
814
+ and isinstance(deserializer.args[0], functools.partial)
815
+ and deserializer.args[0].func == _deserialize_array_encoded # pylint: disable=comparison-with-callable
816
+ )
817
+
818
+
761
819
  def _deserialize_sequence(
762
820
  deserializer: typing.Optional[typing.Callable],
763
821
  module: typing.Optional[str],
@@ -767,6 +825,19 @@ def _deserialize_sequence(
767
825
  return obj
768
826
  if isinstance(obj, ET.Element):
769
827
  obj = list(obj)
828
+
829
+ # encoded string may be deserialized to sequence
830
+ if isinstance(obj, str) and isinstance(deserializer, functools.partial):
831
+ # for list[str]
832
+ if _is_array_encoded_deserializer(deserializer):
833
+ return deserializer(obj)
834
+
835
+ # for list[Union[...]]
836
+ if isinstance(deserializer.args[0], list):
837
+ for sub_deserializer in deserializer.args[0]:
838
+ if _is_array_encoded_deserializer(sub_deserializer):
839
+ return sub_deserializer(obj)
840
+
770
841
  return type(obj)(_deserialize(deserializer, entry, module) for entry in obj)
771
842
 
772
843
 
@@ -817,16 +888,16 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur
817
888
 
818
889
  # is it optional?
819
890
  try:
820
- if any(a for a in annotation.__args__ if a == type(None)): # pyright: ignore
891
+ if any(a is _NONE_TYPE for a in annotation.__args__): # pyright: ignore
821
892
  if len(annotation.__args__) <= 2: # pyright: ignore
822
893
  if_obj_deserializer = _get_deserialize_callable_from_annotation(
823
- next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore
894
+ next(a for a in annotation.__args__ if a is not _NONE_TYPE), module, rf # pyright: ignore
824
895
  )
825
896
 
826
897
  return functools.partial(_deserialize_with_optional, if_obj_deserializer)
827
898
  # the type is Optional[Union[...]], we need to remove the None type from the Union
828
899
  annotation_copy = copy.copy(annotation)
829
- annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a != type(None)] # pyright: ignore
900
+ annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a is not _NONE_TYPE] # pyright: ignore
830
901
  return _get_deserialize_callable_from_annotation(annotation_copy, module, rf)
831
902
  except AttributeError:
832
903
  pass
@@ -952,7 +1023,7 @@ def _failsafe_deserialize(
952
1023
  ) -> typing.Any:
953
1024
  try:
954
1025
  return _deserialize(deserializer, response.json(), module, rf, format)
955
- except DeserializationError:
1026
+ except Exception: # pylint: disable=broad-except
956
1027
  _LOGGER.warning(
957
1028
  "Ran into a deserialization error. Ignoring since this is failsafe deserialization", exc_info=True
958
1029
  )
@@ -965,7 +1036,7 @@ def _failsafe_deserialize_xml(
965
1036
  ) -> typing.Any:
966
1037
  try:
967
1038
  return _deserialize_xml(deserializer, response.text())
968
- except DeserializationError:
1039
+ except Exception: # pylint: disable=broad-except
969
1040
  _LOGGER.warning(
970
1041
  "Ran into a deserialization error. Ignoring since this is failsafe deserialization", exc_info=True
971
1042
  )
@@ -998,7 +1069,11 @@ class _RestField:
998
1069
 
999
1070
  @property
1000
1071
  def _class_type(self) -> typing.Any:
1001
- return getattr(self._type, "args", [None])[0]
1072
+ result = getattr(self._type, "args", [None])[0]
1073
+ # type may be wrapped by nested functools.partial so we need to check for that
1074
+ if isinstance(result, functools.partial):
1075
+ return getattr(result, "args", [None])[0]
1076
+ return result
1002
1077
 
1003
1078
  @property
1004
1079
  def _rest_name(self) -> str:
@@ -1009,14 +1084,37 @@ class _RestField:
1009
1084
  def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin
1010
1085
  # by this point, type and rest_name will have a value bc we default
1011
1086
  # them in __new__ of the Model class
1012
- item = obj.get(self._rest_name)
1087
+ # Use _data.get() directly to avoid triggering __getitem__ which clears the cache
1088
+ item = obj._data.get(self._rest_name)
1013
1089
  if item is None:
1014
1090
  return item
1015
1091
  if self._is_model:
1016
1092
  return item
1017
- return _deserialize(self._type, _serialize(item, self._format), rf=self)
1093
+
1094
+ # For mutable types, we want mutations to directly affect _data
1095
+ # Check if we've already deserialized this value
1096
+ cache_attr = f"_deserialized_{self._rest_name}"
1097
+ if hasattr(obj, cache_attr):
1098
+ # Return the value from _data directly (it's been deserialized in place)
1099
+ return obj._data.get(self._rest_name)
1100
+
1101
+ deserialized = _deserialize(self._type, _serialize(item, self._format), rf=self)
1102
+
1103
+ # For mutable types, store the deserialized value back in _data
1104
+ # so mutations directly affect _data
1105
+ if isinstance(deserialized, (dict, list, set)):
1106
+ obj._data[self._rest_name] = deserialized
1107
+ object.__setattr__(obj, cache_attr, True) # Mark as deserialized
1108
+ return deserialized
1109
+
1110
+ return deserialized
1018
1111
 
1019
1112
  def __set__(self, obj: Model, value) -> None:
1113
+ # Clear the cached deserialized object when setting a new value
1114
+ cache_attr = f"_deserialized_{self._rest_name}"
1115
+ if hasattr(obj, cache_attr):
1116
+ object.__delattr__(obj, cache_attr)
1117
+
1020
1118
  if value is None:
1021
1119
  # we want to wipe out entries if users set attr to None
1022
1120
  try:
@@ -1184,7 +1282,7 @@ def _get_wrapped_element(
1184
1282
  _get_element(v, exclude_readonly, meta, wrapped_element)
1185
1283
  else:
1186
1284
  wrapped_element.text = _get_primitive_type_value(v)
1187
- return wrapped_element
1285
+ return wrapped_element # type: ignore[no-any-return]
1188
1286
 
1189
1287
 
1190
1288
  def _get_primitive_type_value(v) -> str:
@@ -1197,7 +1295,9 @@ def _get_primitive_type_value(v) -> str:
1197
1295
  return str(v)
1198
1296
 
1199
1297
 
1200
- def _create_xml_element(tag, prefix=None, ns=None):
1298
+ def _create_xml_element(
1299
+ tag: typing.Any, prefix: typing.Optional[str] = None, ns: typing.Optional[str] = None
1300
+ ) -> ET.Element:
1201
1301
  if prefix and ns:
1202
1302
  ET.register_namespace(prefix, ns)
1203
1303
  if ns:
@@ -821,13 +821,20 @@ class Serializer: # pylint: disable=too-many-public-methods
821
821
  :param str data_type: Type of object in the iterable.
822
822
  :rtype: str, int, float, bool
823
823
  :return: serialized object
824
+ :raises TypeError: raise if data_type is not one of str, int, float, bool.
824
825
  """
825
826
  custom_serializer = cls._get_custom_serializers(data_type, **kwargs)
826
827
  if custom_serializer:
827
828
  return custom_serializer(data)
828
829
  if data_type == "str":
829
830
  return cls.serialize_unicode(data)
830
- return eval(data_type)(data) # nosec # pylint: disable=eval-used
831
+ if data_type == "int":
832
+ return int(data)
833
+ if data_type == "float":
834
+ return float(data)
835
+ if data_type == "bool":
836
+ return bool(data)
837
+ raise TypeError("Unknown basic data type: {}".format(data_type))
831
838
 
832
839
  @classmethod
833
840
  def serialize_unicode(cls, data):
@@ -1757,7 +1764,7 @@ class Deserializer:
1757
1764
  :param str data_type: deserialization data type.
1758
1765
  :return: Deserialized basic type.
1759
1766
  :rtype: str, int, float or bool
1760
- :raises TypeError: if string format is not valid.
1767
+ :raises TypeError: if string format is not valid or data_type is not one of str, int, float, bool.
1761
1768
  """
1762
1769
  # If we're here, data is supposed to be a basic type.
1763
1770
  # If it's still an XML node, take the text
@@ -1783,7 +1790,11 @@ class Deserializer:
1783
1790
 
1784
1791
  if data_type == "str":
1785
1792
  return self.deserialize_unicode(attr)
1786
- return eval(data_type)(attr) # nosec # pylint: disable=eval-used
1793
+ if data_type == "int":
1794
+ return int(attr)
1795
+ if data_type == "float":
1796
+ return float(attr)
1797
+ raise TypeError("Unknown basic data type: {}".format(data_type))
1787
1798
 
1788
1799
  @staticmethod
1789
1800
  def deserialize_unicode(data):
@@ -49,9 +49,8 @@ def serialize_multipart_data_entry(data_entry: Any) -> Any:
49
49
 
50
50
  def prepare_multipart_form_data(
51
51
  body: Mapping[str, Any], multipart_fields: list[str], data_fields: list[str]
52
- ) -> tuple[list[FileType], dict[str, Any]]:
52
+ ) -> list[FileType]:
53
53
  files: list[FileType] = []
54
- data: dict[str, Any] = {}
55
54
  for multipart_field in multipart_fields:
56
55
  multipart_entry = body.get(multipart_field)
57
56
  if isinstance(multipart_entry, list):
@@ -59,9 +58,11 @@ def prepare_multipart_form_data(
59
58
  elif multipart_entry:
60
59
  files.append((multipart_field, multipart_entry))
61
60
 
61
+ # if files is empty, sdk core library can't handle multipart/form-data correctly, so
62
+ # we put data fields into files with filename as None to avoid that scenario.
62
63
  for data_field in data_fields:
63
64
  data_entry = body.get(data_field)
64
65
  if data_entry:
65
- data[data_field] = serialize_multipart_data_entry(data_entry)
66
+ files.append((data_field, str(serialize_multipart_data_entry(data_entry))))
66
67
 
67
- return files, data
68
+ return files
@@ -6,4 +6,4 @@
6
6
  # Changes may cause incorrect behavior and will be lost if the code is regenerated.
7
7
  # --------------------------------------------------------------------------
8
8
 
9
- VERSION = "1.0.0b2"
9
+ VERSION = "1.0.0b3"
@@ -27,7 +27,7 @@ class TranscriptionClient(_TranscriptionClientOperationsMixin):
27
27
  """TranscriptionClient.
28
28
 
29
29
  :param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
30
- `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_.
30
+ `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_).
31
31
  Required.
32
32
  :type endpoint: str
33
33
  :param credential: Credential used to authenticate requests to the service. Is either a key
@@ -24,7 +24,7 @@ class TranscriptionClientConfiguration: # pylint: disable=too-many-instance-att
24
24
  attributes.
25
25
 
26
26
  :param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
27
- `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_.
27
+ `https://westus.api.cognitive.microsoft.com <https://westus.api.cognitive.microsoft.com>`_).
28
28
  Required.
29
29
  :type endpoint: str
30
30
  :param credential: Credential used to authenticate requests to the service. Is either a key
@@ -90,12 +90,11 @@ class _TranscriptionClientOperationsMixin(
90
90
  _body = body.as_dict() if isinstance(body, _Model) else body
91
91
  _file_fields: list[str] = ["audio"]
92
92
  _data_fields: list[str] = ["definition"]
93
- _files, _data = prepare_multipart_form_data(_body, _file_fields, _data_fields)
93
+ _files = prepare_multipart_form_data(_body, _file_fields, _data_fields)
94
94
 
95
95
  _request = build_transcription_transcribe_request(
96
96
  api_version=self._config.api_version,
97
97
  files=_files,
98
- data=_data,
99
98
  headers=_headers,
100
99
  params=_params,
101
100
  )
@@ -12,7 +12,14 @@ from collections.abc import MutableMapping
12
12
  from typing import Any, Optional
13
13
  import json
14
14
  from azure.core.tracing.decorator_async import distributed_trace_async
15
- from azure.core.exceptions import map_error, HttpResponseError, ClientAuthenticationError, ResourceNotFoundError, ResourceExistsError, ResourceNotModifiedError
15
+ from azure.core.exceptions import (
16
+ map_error,
17
+ HttpResponseError,
18
+ ClientAuthenticationError,
19
+ ResourceNotFoundError,
20
+ ResourceExistsError,
21
+ ResourceNotModifiedError,
22
+ )
16
23
 
17
24
  from ... import models as _models
18
25
  from ..._utils.model_base import _deserialize, SdkJSONEncoder
@@ -91,7 +98,9 @@ class _TranscriptionClientOperationsMixin(_TranscriptionClientOperationsMixinGen
91
98
  }
92
99
  _request.url = self._client.format_url(_request.url, **path_format_arguments)
93
100
 
94
- pipeline_response = await self._client._pipeline.run(_request, stream=False, **kwargs) # pylint: disable=protected-access
101
+ pipeline_response = await self._client._pipeline.run( # pylint: disable=protected-access
102
+ _request, stream=False, **kwargs
103
+ )
95
104
  response = pipeline_response.http_response
96
105
 
97
106
  if response.status_code not in [200]:
@@ -18,6 +18,6 @@ class ProfanityFilterMode(str, Enum, metaclass=CaseInsensitiveEnumMeta):
18
18
  REMOVED = "Removed"
19
19
  """Remove profanity."""
20
20
  TAGS = "Tags"
21
- """Add "profanity" XML tags</Profanity>"""
21
+ """Add "profanity" XML tags</Profanity>."""
22
22
  MASKED = "Masked"
23
- """Mask the profanity with * except of the first letter, e.g., f***"""
23
+ """Mask the profanity with * except of the first letter, e.g., f***."""
@@ -100,7 +100,7 @@ class PhraseListProperties(_Model):
100
100
 
101
101
  :ivar phrases: List of phrases for recognition.
102
102
  :vartype phrases: list[str]
103
- :ivar biasing_weight: Biasing weight for phrase list (1.0 to 20.0).
103
+ :ivar biasing_weight: Biasing weight for phrase list (0.0-2.0).
104
104
  :vartype biasing_weight: float
105
105
  """
106
106
 
@@ -109,7 +109,7 @@ class PhraseListProperties(_Model):
109
109
  biasing_weight: Optional[float] = rest_field(
110
110
  name="biasingWeight", visibility=["read", "create", "update", "delete", "query"]
111
111
  )
112
- """Biasing weight for phrase list (1.0 to 20.0)."""
112
+ """Biasing weight for phrase list (0.0-2.0)."""
113
113
 
114
114
  @overload
115
115
  def __init__(
@@ -7,9 +7,54 @@
7
7
 
8
8
  Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
9
9
  """
10
+ from typing import Any, Optional
10
11
 
12
+ from ._models import EnhancedModeProperties as _EnhancedModeProperties
11
13
 
12
- __all__: list[str] = [] # Add all objects you want publicly available to users at this package level
14
+
15
+ class EnhancedModeProperties(_EnhancedModeProperties):
16
+ """Enhanced mode properties for transcription.
17
+
18
+ :ivar task: Task type for enhanced mode.
19
+ :vartype task: str
20
+ :ivar target_language: Target language for enhanced mode.
21
+ :vartype target_language: str
22
+ :ivar prompt: A list of user prompts.
23
+ :vartype prompt: list[str]
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ *,
29
+ task: Optional[str] = None,
30
+ target_language: Optional[str] = None,
31
+ prompt: Optional[list[str]] = None,
32
+ **kwargs: Any,
33
+ ) -> None:
34
+ super().__init__(task=task, target_language=target_language, prompt=prompt, **kwargs)
35
+ # Automatically set enabled=True if any enhanced mode properties are specified
36
+ # This is hidden from public API but sent to the server
37
+ self._enabled: Optional[bool] = None
38
+ if task is not None or target_language is not None or prompt is not None:
39
+ self._enabled = True
40
+
41
+ def as_dict(self, *, exclude_readonly: bool = False) -> dict[str, Any]:
42
+ """Return a dict that can be turned into json using json.dump.
43
+
44
+ :keyword bool exclude_readonly: Whether to remove the readonly properties.
45
+ :returns: A dict JSON compatible object
46
+ :rtype: dict
47
+ """
48
+ result = super().as_dict(exclude_readonly=exclude_readonly)
49
+ # Always include enabled in the request if it's set
50
+ if self._enabled is not None:
51
+ result["enabled"] = self._enabled
52
+ return result
53
+
54
+
55
+ __all__: list[str] = [
56
+ "EnhancedModeProperties"
57
+ ] # Add all objects you want publicly available to users at this package level
13
58
 
14
59
 
15
60
  def patch_sdk():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: azure-ai-transcription
3
- Version: 1.0.0b2
3
+ Version: 1.0.0b3
4
4
  Summary: Microsoft Corporation Azure AI Transcription Client Library for Python
5
5
  Author-email: Microsoft Corporation <azpysdkhelp@microsoft.com>
6
6
  License-Expression: MIT
@@ -19,7 +19,7 @@ Requires-Python: >=3.9
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
21
  Requires-Dist: isodate>=0.6.1
22
- Requires-Dist: azure-core>=1.35.0
22
+ Requires-Dist: azure-core>=1.37.0
23
23
  Requires-Dist: typing-extensions>=4.6.0
24
24
  Dynamic: license-file
25
25
 
@@ -174,10 +174,18 @@ from azure.ai.transcription.models import TranscriptionContent, TranscriptionOpt
174
174
 
175
175
  # Get configuration from environment variables
176
176
  endpoint = os.environ["AZURE_SPEECH_ENDPOINT"]
177
- api_key = os.environ["AZURE_SPEECH_API_KEY"]
177
+
178
+ # We recommend using role-based access control (RBAC) for production scenarios
179
+ api_key = os.environ.get("AZURE_SPEECH_API_KEY")
180
+ if api_key:
181
+ credential = AzureKeyCredential(api_key)
182
+ else:
183
+ from azure.identity import DefaultAzureCredential
184
+
185
+ credential = DefaultAzureCredential()
178
186
 
179
187
  # Create the transcription client
180
- client = TranscriptionClient(endpoint=endpoint, credential=AzureKeyCredential(api_key))
188
+ client = TranscriptionClient(endpoint=endpoint, credential=credential)
181
189
 
182
190
  # Path to your audio file
183
191
  import pathlib
@@ -222,10 +230,18 @@ from azure.ai.transcription.models import TranscriptionOptions
222
230
 
223
231
  # Get configuration from environment variables
224
232
  endpoint = os.environ["AZURE_SPEECH_ENDPOINT"]
225
- api_key = os.environ["AZURE_SPEECH_API_KEY"]
233
+
234
+ # We recommend using role-based access control (RBAC) for production scenarios
235
+ api_key = os.environ.get("AZURE_SPEECH_API_KEY")
236
+ if api_key:
237
+ credential = AzureKeyCredential(api_key)
238
+ else:
239
+ from azure.identity import DefaultAzureCredential
240
+
241
+ credential = DefaultAzureCredential()
226
242
 
227
243
  # Create the transcription client
228
- client = TranscriptionClient(endpoint=endpoint, credential=AzureKeyCredential(api_key))
244
+ client = TranscriptionClient(endpoint=endpoint, credential=credential)
229
245
 
230
246
  # URL to your audio file (must be publicly accessible)
231
247
  audio_url = "https://example.com/path/to/audio.wav"
@@ -263,31 +279,29 @@ from azure.ai.transcription.models import (
263
279
 
264
280
  # Get configuration from environment variables
265
281
  endpoint = os.environ["AZURE_SPEECH_ENDPOINT"]
266
- api_key = os.environ["AZURE_SPEECH_API_KEY"]
282
+
283
+ # We recommend using role-based access control (RBAC) for production scenarios
284
+ api_key = os.environ.get("AZURE_SPEECH_API_KEY")
285
+ if api_key:
286
+ credential = AzureKeyCredential(api_key)
287
+ else:
288
+ from azure.identity import DefaultAzureCredential
289
+
290
+ credential = DefaultAzureCredential()
267
291
 
268
292
  # Create the transcription client
269
- client = TranscriptionClient(endpoint=endpoint, credential=AzureKeyCredential(api_key))
293
+ client = TranscriptionClient(endpoint=endpoint, credential=credential)
270
294
 
271
295
  # Path to your audio file
272
- import pathlib
273
-
274
296
  audio_file_path = pathlib.Path(__file__).parent / "assets" / "audio.wav"
275
297
 
276
298
  # Open and read the audio file
277
299
  with open(audio_file_path, "rb") as audio_file:
278
- # Create enhanced mode properties
279
- # Enable enhanced mode for advanced processing capabilities
280
- enhanced_mode = EnhancedModeProperties(
281
- task="translation", # Specify the task type (e.g., "translation", "summarization")
282
- target_language="es-ES", # Target language for translation
283
- prompt=[
284
- "Translate the following audio to Spanish",
285
- "Focus on technical terminology",
286
- ], # Optional prompts to guide the enhanced mode
287
- )
300
+ # Enhanced mode is automatically enabled when task is specified
301
+ enhanced_mode = EnhancedModeProperties(task="transcribe")
288
302
 
289
303
  # Create transcription options with enhanced mode
290
- options = TranscriptionOptions(locales=["en-US"], enhanced_mode=enhanced_mode)
304
+ options = TranscriptionOptions(enhanced_mode=enhanced_mode)
291
305
 
292
306
  # Create the request content
293
307
  request_content = TranscriptionContent(definition=options, audio=audio_file)
@@ -296,14 +310,7 @@ with open(audio_file_path, "rb") as audio_file:
296
310
  result = client.transcribe(request_content)
297
311
 
298
312
  # Print the transcription result
299
- print("Transcription with enhanced mode:")
300
- print(f"{result.combined_phrases[0].text}")
301
-
302
- # Print individual phrases if available
303
- if result.phrases:
304
- print("\nDetailed phrases:")
305
- for phrase in result.phrases:
306
- print(f" [{phrase.offset_milliseconds}ms]: {phrase.text}")
313
+ print(result.combined_phrases[0].text)
307
314
  ```
308
315
 
309
316
  <!-- END SNIPPET -->
@@ -321,10 +328,18 @@ from azure.ai.transcription.models import TranscriptionContent, TranscriptionOpt
321
328
 
322
329
  # Get configuration from environment variables
323
330
  endpoint = os.environ["AZURE_SPEECH_ENDPOINT"]
324
- api_key = os.environ["AZURE_SPEECH_API_KEY"]
331
+
332
+ # We recommend using role-based access control (RBAC) for production scenarios
333
+ api_key = os.environ.get("AZURE_SPEECH_API_KEY")
334
+ if api_key:
335
+ credential = AzureKeyCredential(api_key)
336
+ else:
337
+ from azure.identity.aio import DefaultAzureCredential
338
+
339
+ credential = DefaultAzureCredential()
325
340
 
326
341
  # Create the transcription client
327
- async with TranscriptionClient(endpoint=endpoint, credential=AzureKeyCredential(api_key)) as client:
342
+ async with TranscriptionClient(endpoint=endpoint, credential=credential) as client:
328
343
  # Path to your audio file
329
344
  import pathlib
330
345
 
@@ -464,6 +479,16 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con
464
479
 
465
480
  # Release History
466
481
 
482
+ ## 1.0.0b3 (2026-02-04)
483
+
484
+ ### Features Added
485
+
486
+ - Enhanced Mode now automatically sets `enabled=True` when `task`, `target_language`, or `prompt` are specified
487
+
488
+ ### Bugs Fixed
489
+
490
+ - Fixed Enhanced Mode not being activated when using `EnhancedModeProperties` without explicitly setting `enabled=True`
491
+
467
492
  ## 1.0.0b2 (2025-12-19)
468
493
 
469
494
  ### Bugs Fixed
@@ -0,0 +1,29 @@
1
+ azure/ai/transcription/__init__.py,sha256=EeG1egQNXEo3TvGAR2l71hUVkL7pKO_TQV0HTvIEB58,1034
2
+ azure/ai/transcription/_client.py,sha256=4DixcxqIi4i12b-dePWmvmtmS5ynLvj0BK1LAKWjYuc,4732
3
+ azure/ai/transcription/_configuration.py,sha256=zXCfZAJkZRDmeeipDnLBpNuEHzZg_9TYQGej2YYcmiU,3957
4
+ azure/ai/transcription/_patch.py,sha256=bRmors9r9iYkR1NFjnMBYkj7OVhnGo-_rhjh67IMApE,824
5
+ azure/ai/transcription/_version.py,sha256=Asg_DLffMngVmD1Oq-HAuVt6cCjN85ZAwBkwSJDeSPk,486
6
+ azure/ai/transcription/py.typed,sha256=dcrsqJrcYfTX-ckLFJMTaj6mD8aDe2u0tkQG-ZYxnEg,26
7
+ azure/ai/transcription/_operations/__init__.py,sha256=eFL_D7LwlwgDmM6AnUcGEGlCDzEnviNC_3AMhFl0V7E,951
8
+ azure/ai/transcription/_operations/_operations.py,sha256=h5xiyk4EtmFAZwnyUIXyiN8Zyaxvou6_dx2OJRYPQLM,6219
9
+ azure/ai/transcription/_operations/_patch.py,sha256=xsgXg12Jn1w2N_jYn-LntBJGOK2ilaq3a9nb4QKXMAM,5253
10
+ azure/ai/transcription/_utils/__init__.py,sha256=nh5swTUwCBe3xsb9n60QMcuJ33d89Itwx7q9V-oDOUE,450
11
+ azure/ai/transcription/_utils/model_base.py,sha256=_gvNGFrsOn1ijmwkCN_Bwpi3NFEWElVCcBoODJ5ry_E,50190
12
+ azure/ai/transcription/_utils/serialization.py,sha256=swIoE4Jt5ZU2lWpsyfjw5hhbvTjVXDvFWFAi-LIRxbw,82386
13
+ azure/ai/transcription/_utils/utils.py,sha256=eOC03Dd-p46RWZWcF9Xy3qGBiAhY5XGgnI50bpuWi5s,2456
14
+ azure/ai/transcription/aio/__init__.py,sha256=837N-1lSBMBsb4KXhjkwKv0ZBrD_GJvlWkyPTNyMTY8,981
15
+ azure/ai/transcription/aio/_client.py,sha256=h-hTGjOiMQx0sZzaGNd-RxUzdFkAtUWzeKtrlJH3seM,4891
16
+ azure/ai/transcription/aio/_configuration.py,sha256=GZ5RBTx_yQuGKpUvydNpUtILuchtgNRr4rvJBV6qMrk,4014
17
+ azure/ai/transcription/aio/_patch.py,sha256=bRmors9r9iYkR1NFjnMBYkj7OVhnGo-_rhjh67IMApE,824
18
+ azure/ai/transcription/aio/_operations/__init__.py,sha256=eFL_D7LwlwgDmM6AnUcGEGlCDzEnviNC_3AMhFl0V7E,951
19
+ azure/ai/transcription/aio/_operations/_operations.py,sha256=4QFtHotyHcrM4SOqTNhhRCjTlfdM3MLPaNB2tziETu0,5566
20
+ azure/ai/transcription/aio/_operations/_patch.py,sha256=eXx5A7e_NgfrVCZPeGVD-bV8sRkOvtbryjgWrmN5o9A,5286
21
+ azure/ai/transcription/models/__init__.py,sha256=uMxxXYjdtGW9yodYZiwy2am437UU-ovgh8LgGDI5Hhc,1475
22
+ azure/ai/transcription/models/_enums.py,sha256=tLBH4nXjnH2TkM2jlR4GxapOJMojtwchwHv9_2jVO2c,923
23
+ azure/ai/transcription/models/_models.py,sha256=tGN15ABqX7cmN-raJQ7j0cqPlLUnwqPFOZQa_-Swlj8,18791
24
+ azure/ai/transcription/models/_patch.py,sha256=osT0tDiBrplag94iAXMapeAaQFIPi7ZiZduLzvtAgFQ,2474
25
+ azure_ai_transcription-1.0.0b3.dist-info/licenses/LICENSE,sha256=_VMkgdgo4ToLE8y1mOAjOKNhd0BnWoYu5r3BVBto6T0,1073
26
+ azure_ai_transcription-1.0.0b3.dist-info/METADATA,sha256=cTQdL3I9DdnujNCQJbnYTsIA8SuE3vavIr-y7BWlKOA,18834
27
+ azure_ai_transcription-1.0.0b3.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
28
+ azure_ai_transcription-1.0.0b3.dist-info/top_level.txt,sha256=S7DhWV9m80TBzAhOFjxDUiNbKszzoThbnrSz5MpbHSQ,6
29
+ azure_ai_transcription-1.0.0b3.dist-info/RECORD,,
@@ -1,29 +0,0 @@
1
- azure/ai/transcription/__init__.py,sha256=EeG1egQNXEo3TvGAR2l71hUVkL7pKO_TQV0HTvIEB58,1034
2
- azure/ai/transcription/_client.py,sha256=ZkmcLb6RXzwlK05JZWA3aebQwd8ZKAgqiSJBuoUQM1I,4731
3
- azure/ai/transcription/_configuration.py,sha256=CIRFAOFt8P5TdHEZa-ERIO-mu9z_8q3C-ybCQX3MQeQ,3956
4
- azure/ai/transcription/_patch.py,sha256=bRmors9r9iYkR1NFjnMBYkj7OVhnGo-_rhjh67IMApE,824
5
- azure/ai/transcription/_version.py,sha256=g637Xd9Uf23mTrNOKxXc_oX7Wi-Zaz6tfo5NYxUwOr0,486
6
- azure/ai/transcription/py.typed,sha256=dcrsqJrcYfTX-ckLFJMTaj6mD8aDe2u0tkQG-ZYxnEg,26
7
- azure/ai/transcription/_operations/__init__.py,sha256=eFL_D7LwlwgDmM6AnUcGEGlCDzEnviNC_3AMhFl0V7E,951
8
- azure/ai/transcription/_operations/_operations.py,sha256=9X8Kta71welA6YPwLombQbSH5b2G7TCZ-ofXlC9vcZU,6250
9
- azure/ai/transcription/_operations/_patch.py,sha256=gLMQTM_JpldQjpiZ_FLP8LfKxvdd5w2yNkPWC95YR5c,5202
10
- azure/ai/transcription/_utils/__init__.py,sha256=nh5swTUwCBe3xsb9n60QMcuJ33d89Itwx7q9V-oDOUE,450
11
- azure/ai/transcription/_utils/model_base.py,sha256=Qv1mr4gg-BarrjYBIVs8bJb5iJH79D-Ekthh1PPw1To,45555
12
- azure/ai/transcription/_utils/serialization.py,sha256=WrHETL6uaaDLnB7TVbe25huhlLDm3aWBGphIutnJcA4,81946
13
- azure/ai/transcription/_utils/utils.py,sha256=gB49FiUuAk96jBy7psn-BBlyKUlSNeRJCmgXbu8mf-8,2330
14
- azure/ai/transcription/aio/__init__.py,sha256=837N-1lSBMBsb4KXhjkwKv0ZBrD_GJvlWkyPTNyMTY8,981
15
- azure/ai/transcription/aio/_client.py,sha256=O55d0-FKcK6JzFnBhCWVPFIkwTUo9QaacLyAWPS7BQ4,4890
16
- azure/ai/transcription/aio/_configuration.py,sha256=geuVLsMNT1XS6VRyfFkFvjDIgIAV0EJatsWm_eTS3Vo,4013
17
- azure/ai/transcription/aio/_patch.py,sha256=bRmors9r9iYkR1NFjnMBYkj7OVhnGo-_rhjh67IMApE,824
18
- azure/ai/transcription/aio/_operations/__init__.py,sha256=eFL_D7LwlwgDmM6AnUcGEGlCDzEnviNC_3AMhFl0V7E,951
19
- azure/ai/transcription/aio/_operations/_operations.py,sha256=PD2EMCI-gfH_sJa5OH8lNZPUrm34hUSlryVrX3mNzAg,5597
20
- azure/ai/transcription/aio/_operations/_patch.py,sha256=gDr6RNer6lM15-voBXg8z7JMdAWm5xW9CXkzY3EZaWk,5235
21
- azure/ai/transcription/models/__init__.py,sha256=uMxxXYjdtGW9yodYZiwy2am437UU-ovgh8LgGDI5Hhc,1475
22
- azure/ai/transcription/models/_enums.py,sha256=QDGZWb4mRd59XLWdVtAwrbTbWYz9VR2zu5IdT2GSm3E,921
23
- azure/ai/transcription/models/_models.py,sha256=rOSC0AujNtYaQscm-P7kCq4WQz_eglkz175JezeIL4w,18799
24
- azure/ai/transcription/models/_patch.py,sha256=bRmors9r9iYkR1NFjnMBYkj7OVhnGo-_rhjh67IMApE,824
25
- azure_ai_transcription-1.0.0b2.dist-info/licenses/LICENSE,sha256=_VMkgdgo4ToLE8y1mOAjOKNhd0BnWoYu5r3BVBto6T0,1073
26
- azure_ai_transcription-1.0.0b2.dist-info/METADATA,sha256=iZf72IGhIau6gMD5afu0PlgM5NPqC6tUYO6D9GFvtgM,18288
27
- azure_ai_transcription-1.0.0b2.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
28
- azure_ai_transcription-1.0.0b2.dist-info/top_level.txt,sha256=S7DhWV9m80TBzAhOFjxDUiNbKszzoThbnrSz5MpbHSQ,6
29
- azure_ai_transcription-1.0.0b2.dist-info/RECORD,,