Skip to content

Commit 3ba12f6

Browse files
committed
Update radiology insights SDK from local TypeSpec - Add new custom model inference method and fix compatibility issues
- Added begin_infer_from_custom_model_id method to both sync and async clients - Fixed import compatibility for collections.abc.MutableMapping with fallback - Fixed classmethod call issue in model_base.py with pylint disable - Updated version to 1.2.0b1 for beta release - Updated setup.py to use proper package namespace resolution - Fixed operation mixin class names and imports - Added APIView properties for new inference method
1 parent 27ed0de commit 3ba12f6

File tree

10 files changed

+494
-30
lines changed

10 files changed

+494
-30
lines changed

sdk/healthinsights/azure-healthinsights-radiologyinsights/apiview-properties.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@
8383
"azure.healthinsights.radiologyinsights.models.ScoringAndAssessmentCategoryType": "AzureHealthInsights.ScoringAndAssessmentCategoryType",
8484
"azure.healthinsights.radiologyinsights.models.JobStatus": "AzureHealthInsights.JobStatus",
8585
"azure.healthinsights.radiologyinsights.RadiologyInsightsClient.begin_infer_radiology_insights": "ClientForAzureHealthInsights.RadiologyInsightsClient.inferRadiologyInsights",
86-
"azure.healthinsights.radiologyinsights.aio.RadiologyInsightsClient.begin_infer_radiology_insights": "ClientForAzureHealthInsights.RadiologyInsightsClient.inferRadiologyInsights"
86+
"azure.healthinsights.radiologyinsights.aio.RadiologyInsightsClient.begin_infer_radiology_insights": "ClientForAzureHealthInsights.RadiologyInsightsClient.inferRadiologyInsights",
87+
"azure.healthinsights.radiologyinsights.RadiologyInsightsClient.begin_infer_from_custom_model_id": "ClientForAzureHealthInsights.RadiologyInsightsClient.inferFromCustomModelId",
88+
"azure.healthinsights.radiologyinsights.aio.RadiologyInsightsClient.begin_infer_from_custom_model_id": "ClientForAzureHealthInsights.RadiologyInsightsClient.inferFromCustomModelId"
8789
}
8890
}

sdk/healthinsights/azure-healthinsights-radiologyinsights/azure/healthinsights/radiologyinsights/_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
from azure.core.rest import HttpRequest, HttpResponse
1717

1818
from ._configuration import RadiologyInsightsClientConfiguration
19-
from ._operations import RadiologyInsightsClientOperationsMixin
19+
from ._operations._operations import _RadiologyInsightsClientOperationsMixin
2020
from ._utils.serialization import Deserializer, Serializer
2121

2222
if TYPE_CHECKING:
2323
from azure.core.credentials import TokenCredential
2424

2525

26-
class RadiologyInsightsClient(RadiologyInsightsClientOperationsMixin):
26+
class RadiologyInsightsClient(_RadiologyInsightsClientOperationsMixin):
2727
"""RadiologyInsightsClient.
2828
2929
:param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:

sdk/healthinsights/azure-healthinsights-radiologyinsights/azure/healthinsights/radiologyinsights/_operations/__init__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,11 @@
1212
if TYPE_CHECKING:
1313
from ._patch import * # pylint: disable=unused-wildcard-import
1414

15-
from ._operations import RadiologyInsightsClientOperationsMixin # type: ignore
1615

1716
from ._patch import __all__ as _patch_all
1817
from ._patch import *
1918
from ._patch import patch_sdk as _patch_sdk
2019

21-
__all__ = [
22-
"RadiologyInsightsClientOperationsMixin",
23-
]
20+
__all__ = []
2421
__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore
2522
_patch_sdk()

sdk/healthinsights/azure-healthinsights-radiologyinsights/azure/healthinsights/radiologyinsights/_operations/_operations.py

Lines changed: 250 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
# Code generated by Microsoft (R) Python Code Generator.
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
8-
from collections.abc import MutableMapping
8+
try:
9+
from collections.abc import MutableMapping
10+
except ImportError:
11+
from collections import MutableMapping # pylint: disable=deprecated-class
912
from io import IOBase
1013
import json
1114
from typing import Any, Callable, Dict, IO, Iterator, List, Optional, TypeVar, Union, cast, overload
@@ -35,6 +38,7 @@
3538
from .._utils.utils import ClientMixinABC
3639

3740
JSON = MutableMapping[str, Any]
41+
_Unset: Any = object()
3842
T = TypeVar("T")
3943
ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
4044

@@ -73,7 +77,31 @@ def build_radiology_insights_infer_radiology_insights_request( # pylint: disabl
7377
return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs)
7478

7579

76-
class RadiologyInsightsClientOperationsMixin(
80+
def build_radiology_insights_infer_from_custom_model_id_request( # pylint: disable=name-too-long
81+
**kwargs: Any,
82+
) -> HttpRequest:
83+
_headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
84+
_params = case_insensitive_dict(kwargs.pop("params", {}) or {})
85+
86+
content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
87+
api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-10-01"))
88+
accept = _headers.pop("Accept", "application/json")
89+
90+
# Construct URL
91+
_url = "/radiology-insights/custom"
92+
93+
# Construct parameters
94+
_params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")
95+
96+
# Construct headers
97+
if content_type is not None:
98+
_headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str")
99+
_headers["Accept"] = _SERIALIZER.header("accept", accept, "str")
100+
101+
return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)
102+
103+
104+
class _RadiologyInsightsClientOperationsMixin(
77105
ClientMixinABC[PipelineClient[HttpRequest, HttpResponse], RadiologyInsightsClientConfiguration]
78106
):
79107

@@ -83,7 +111,7 @@ def _infer_radiology_insights_initial(
83111
resource: Union[_models.RadiologyInsightsJob, JSON, IO[bytes]],
84112
*,
85113
expand: Optional[List[str]] = None,
86-
**kwargs: Any
114+
**kwargs: Any,
87115
) -> Iterator[bytes]:
88116
error_map: MutableMapping = {
89117
401: ClientAuthenticationError,
@@ -155,7 +183,7 @@ def begin_infer_radiology_insights(
155183
*,
156184
expand: Optional[List[str]] = None,
157185
content_type: str = "application/json",
158-
**kwargs: Any
186+
**kwargs: Any,
159187
) -> LROPoller[_models.RadiologyInsightsJob]:
160188
"""Create Radiology Insights job.
161189
@@ -185,7 +213,7 @@ def begin_infer_radiology_insights(
185213
*,
186214
expand: Optional[List[str]] = None,
187215
content_type: str = "application/json",
188-
**kwargs: Any
216+
**kwargs: Any,
189217
) -> LROPoller[_models.RadiologyInsightsJob]:
190218
"""Create Radiology Insights job.
191219
@@ -215,7 +243,7 @@ def begin_infer_radiology_insights(
215243
*,
216244
expand: Optional[List[str]] = None,
217245
content_type: str = "application/json",
218-
**kwargs: Any
246+
**kwargs: Any,
219247
) -> LROPoller[_models.RadiologyInsightsJob]:
220248
"""Create Radiology Insights job.
221249
@@ -244,7 +272,7 @@ def begin_infer_radiology_insights(
244272
resource: Union[_models.RadiologyInsightsJob, JSON, IO[bytes]],
245273
*,
246274
expand: Optional[List[str]] = None,
247-
**kwargs: Any
275+
**kwargs: Any,
248276
) -> LROPoller[_models.RadiologyInsightsJob]:
249277
"""Create Radiology Insights job.
250278
@@ -281,7 +309,7 @@ def begin_infer_radiology_insights(
281309
cls=lambda x, y, z: x,
282310
headers=_headers,
283311
params=_params,
284-
**kwargs
312+
**kwargs,
285313
)
286314
raw_result.http_response.read() # type: ignore
287315
kwargs.pop("error_map", None)
@@ -321,3 +349,217 @@ def get_long_running_output(pipeline_response):
321349
return LROPoller[_models.RadiologyInsightsJob](
322350
self._client, raw_result, get_long_running_output, polling_method # type: ignore
323351
)
352+
353+
def _infer_from_custom_model_id_initial(
354+
self,
355+
body: Union[JSON, IO[bytes]] = _Unset,
356+
*,
357+
inference_data: _models.RadiologyInsightsData = _Unset,
358+
id: Optional[List[str]] = None,
359+
**kwargs: Any,
360+
) -> Iterator[bytes]:
361+
error_map: MutableMapping = {
362+
401: ClientAuthenticationError,
363+
404: ResourceNotFoundError,
364+
409: ResourceExistsError,
365+
304: ResourceNotModifiedError,
366+
}
367+
error_map.update(kwargs.pop("error_map", {}) or {})
368+
369+
_headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
370+
_params = kwargs.pop("params", {}) or {}
371+
372+
content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
373+
cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None)
374+
375+
if body is _Unset:
376+
if inference_data is _Unset:
377+
raise TypeError("missing required argument: inference_data")
378+
body = {"id": id, "inferenceData": inference_data}
379+
body = {k: v for k, v in body.items() if v is not None}
380+
content_type = content_type or "application/json"
381+
_content = None
382+
if isinstance(body, (IOBase, bytes)):
383+
_content = body
384+
else:
385+
_content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore
386+
387+
_request = build_radiology_insights_infer_from_custom_model_id_request(
388+
content_type=content_type,
389+
api_version=self._config.api_version,
390+
content=_content,
391+
headers=_headers,
392+
params=_params,
393+
)
394+
path_format_arguments = {
395+
"endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
396+
}
397+
_request.url = self._client.format_url(_request.url, **path_format_arguments)
398+
399+
_stream = True
400+
pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access
401+
_request, stream=_stream, **kwargs
402+
)
403+
404+
response = pipeline_response.http_response
405+
406+
if response.status_code not in [202]:
407+
try:
408+
response.read() # Load the body in memory and close the socket
409+
except (StreamConsumedError, StreamClosedError):
410+
pass
411+
map_error(status_code=response.status_code, response=response, error_map=error_map)
412+
raise HttpResponseError(response=response)
413+
414+
response_headers = {}
415+
response_headers["Operation-Location"] = self._deserialize("str", response.headers.get("Operation-Location"))
416+
417+
deserialized = response.iter_bytes()
418+
419+
if cls:
420+
return cls(pipeline_response, deserialized, response_headers) # type: ignore
421+
422+
return deserialized # type: ignore
423+
424+
@overload
425+
def begin_infer_from_custom_model_id(
426+
self,
427+
*,
428+
inference_data: _models.RadiologyInsightsData,
429+
content_type: str = "application/json",
430+
id: Optional[List[str]] = None,
431+
**kwargs: Any,
432+
) -> LROPoller[_models.RadiologyInsightsInferenceResult]:
433+
"""Infer radiology insights using a custom model.
434+
435+
:keyword inference_data: Contains the list of patients, and configuration data. Required.
436+
:paramtype inference_data: ~azure.healthinsights.radiologyinsights.models.RadiologyInsightsData
437+
:keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
438+
Default value is "application/json".
439+
:paramtype content_type: str
440+
:keyword id: Models to be used for inference. If this is not specified, the model will use the
441+
default model for inference. Default value is None.
442+
:paramtype id: list[str]
443+
:return: An instance of LROPoller that returns RadiologyInsightsInferenceResult. The
444+
RadiologyInsightsInferenceResult is compatible with MutableMapping
445+
:rtype:
446+
~azure.core.polling.LROPoller[~azure.healthinsights.radiologyinsights.models.RadiologyInsightsInferenceResult]
447+
:raises ~azure.core.exceptions.HttpResponseError:
448+
"""
449+
450+
@overload
451+
def begin_infer_from_custom_model_id(
452+
self, body: JSON, *, content_type: str = "application/json", **kwargs: Any
453+
) -> LROPoller[_models.RadiologyInsightsInferenceResult]:
454+
"""Infer radiology insights using a custom model.
455+
456+
:param body: Required.
457+
:type body: JSON
458+
:keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
459+
Default value is "application/json".
460+
:paramtype content_type: str
461+
:return: An instance of LROPoller that returns RadiologyInsightsInferenceResult. The
462+
RadiologyInsightsInferenceResult is compatible with MutableMapping
463+
:rtype:
464+
~azure.core.polling.LROPoller[~azure.healthinsights.radiologyinsights.models.RadiologyInsightsInferenceResult]
465+
:raises ~azure.core.exceptions.HttpResponseError:
466+
"""
467+
468+
@overload
469+
def begin_infer_from_custom_model_id(
470+
self, body: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
471+
) -> LROPoller[_models.RadiologyInsightsInferenceResult]:
472+
"""Infer radiology insights using a custom model.
473+
474+
:param body: Required.
475+
:type body: IO[bytes]
476+
:keyword content_type: Body Parameter content-type. Content type parameter for binary body.
477+
Default value is "application/json".
478+
:paramtype content_type: str
479+
:return: An instance of LROPoller that returns RadiologyInsightsInferenceResult. The
480+
RadiologyInsightsInferenceResult is compatible with MutableMapping
481+
:rtype:
482+
~azure.core.polling.LROPoller[~azure.healthinsights.radiologyinsights.models.RadiologyInsightsInferenceResult]
483+
:raises ~azure.core.exceptions.HttpResponseError:
484+
"""
485+
486+
@distributed_trace
487+
def begin_infer_from_custom_model_id(
488+
self,
489+
body: Union[JSON, IO[bytes]] = _Unset,
490+
*,
491+
inference_data: _models.RadiologyInsightsData = _Unset,
492+
id: Optional[List[str]] = None,
493+
**kwargs: Any,
494+
) -> LROPoller[_models.RadiologyInsightsInferenceResult]:
495+
"""Infer radiology insights using a custom model.
496+
497+
:param body: Is either a JSON type or a IO[bytes] type. Required.
498+
:type body: JSON or IO[bytes]
499+
:keyword inference_data: Contains the list of patients, and configuration data. Required.
500+
:paramtype inference_data: ~azure.healthinsights.radiologyinsights.models.RadiologyInsightsData
501+
:keyword id: Models to be used for inference. If this is not specified, the model will use the
502+
default model for inference. Default value is None.
503+
:paramtype id: list[str]
504+
:return: An instance of LROPoller that returns RadiologyInsightsInferenceResult. The
505+
RadiologyInsightsInferenceResult is compatible with MutableMapping
506+
:rtype:
507+
~azure.core.polling.LROPoller[~azure.healthinsights.radiologyinsights.models.RadiologyInsightsInferenceResult]
508+
:raises ~azure.core.exceptions.HttpResponseError:
509+
"""
510+
_headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
511+
_params = kwargs.pop("params", {}) or {}
512+
513+
content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
514+
cls: ClsType[_models.RadiologyInsightsInferenceResult] = kwargs.pop("cls", None)
515+
polling: Union[bool, PollingMethod] = kwargs.pop("polling", True)
516+
lro_delay = kwargs.pop("polling_interval", self._config.polling_interval)
517+
cont_token: Optional[str] = kwargs.pop("continuation_token", None)
518+
if cont_token is None:
519+
raw_result = self._infer_from_custom_model_id_initial(
520+
body=body,
521+
inference_data=inference_data,
522+
id=id,
523+
content_type=content_type,
524+
cls=lambda x, y, z: x,
525+
headers=_headers,
526+
params=_params,
527+
**kwargs,
528+
)
529+
raw_result.http_response.read() # type: ignore
530+
kwargs.pop("error_map", None)
531+
532+
def get_long_running_output(pipeline_response):
533+
response_headers = {}
534+
response = pipeline_response.http_response
535+
response_headers["Operation-Location"] = self._deserialize(
536+
"str", response.headers.get("Operation-Location")
537+
)
538+
539+
deserialized = _deserialize(_models.RadiologyInsightsInferenceResult, response.json().get("result", {}))
540+
if cls:
541+
return cls(pipeline_response, deserialized, response_headers) # type: ignore
542+
return deserialized
543+
544+
path_format_arguments = {
545+
"endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
546+
}
547+
548+
if polling is True:
549+
polling_method: PollingMethod = cast(
550+
PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs)
551+
)
552+
elif polling is False:
553+
polling_method = cast(PollingMethod, NoPolling())
554+
else:
555+
polling_method = polling
556+
if cont_token:
557+
return LROPoller[_models.RadiologyInsightsInferenceResult].from_continuation_token(
558+
polling_method=polling_method,
559+
continuation_token=cont_token,
560+
client=self._client,
561+
deserialization_callback=get_long_running_output,
562+
)
563+
return LROPoller[_models.RadiologyInsightsInferenceResult](
564+
self._client, raw_result, get_long_running_output, polling_method # type: ignore
565+
)

sdk/healthinsights/azure-healthinsights-radiologyinsights/azure/healthinsights/radiologyinsights/_utils/model_base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
from datetime import datetime, date, time, timedelta, timezone
2323
from json import JSONEncoder
2424
import xml.etree.ElementTree as ET
25-
from collections.abc import MutableMapping
25+
try:
26+
from collections.abc import MutableMapping
27+
except ImportError:
28+
from collections import MutableMapping # pylint: disable=deprecated-class
2629
from typing_extensions import Self
2730
import isodate
2831
from azure.core.exceptions import DeserializationError
@@ -641,7 +644,7 @@ def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> Self:
641644
cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items())
642645
cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}")
643646

644-
return super().__new__(cls)
647+
return super().__new__(cls) # pylint: disable=no-value-for-parameter
645648

646649
def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None:
647650
for base in cls.__bases__:

sdk/healthinsights/azure-healthinsights-radiologyinsights/azure/healthinsights/radiologyinsights/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
88

9-
VERSION = "1.1.0"
9+
VERSION = "1.2.0b1"

0 commit comments

Comments
 (0)