diff --git a/sdk/batch/azure-batch/CHANGELOG.md b/sdk/batch/azure-batch/CHANGELOG.md index 32f84aaef17f..c39c95213585 100644 --- a/sdk/batch/azure-batch/CHANGELOG.md +++ b/sdk/batch/azure-batch/CHANGELOG.md @@ -4,7 +4,52 @@ ### Other Changes -- This is the GA release of the features introduced in the 15.0.0 and 15.1.0 beta versions, including LRO support, job-level FIFO scheduling, CMK support on pools, IPv6 support, metadata security protocol support, IP tag support, and confidential VM enhancements. No additional changes were made from the last beta release. +- This is the GA release of the features introduced in the 15.0.0 and 15.1.0 beta versions, including LRO support, job-level FIFO scheduling, CMK support on pools, IPv6 support, metadata security protocol support, IP tag support, and confidential VM enhancements. + +### Breaking Changes + +- Renamed `BatchNodeUserUpdateOptions` to `BatchNodeUserReplaceOptions`. +- Renamed `OutputFileUploadConfig` to `OutputFileUploadConfiguration`. + +- Removed Models: + - Removed `AuthenticationTokenSettings` + +- NameSpace changed `azure.batch.models._models`: + - `BatchJobTerminateOptions` + - `BatchNodeDeallocateOptions` + - `BatchNodeRebootOptions` + - `BatchNodeReimageOptions` + +- Removed Enums: + - Removed `BatchAccessScope` + +- NameSpace changed `azure.batch.models._enums`: + - `BatchNodeDeallocateOption` + - `BatchNodeRebootKind` + - `BatchNodeReimageOption` + +- Renamed public methods: + - `list_sub_tasks` -> `list_subtasks` + - `get_task_file` -> `download_task_file` + - `get_node_file` -> `download_node_file` + +- Renamed parameters across all operation methods: + - `timeout` -> `service_timeout` + - `ocpdate` -> `ocp_date` + - `starttime` -> `start_time` + - `endtime` -> `end_time` + - `concurrencies` -> `max_concurrency` + +- Renamed properties in models: + - `e_tag` -> `etag` in `BatchJob`, `BatchJobSchedule`, `BatchPool`, `BatchTask`, and `BatchTaskCreateResult` + - `values_property` -> `error_values` in `AutoScaleRunError`, `BatchError`, and `ResizeError` + - `values_property` -> `result_values` in `CollectionResult` + - `values_property` -> `task_values` in `BatchTaskGroup` + - `avg_memory_gi_b` -> `avg_memory_gib`, `peak_memory_gi_b` -> `peak_memory_gib`, `avg_disk_gi_b` -> `avg_disk_gib`, `peak_disk_gi_b` -> `peak_disk_gib`, `disk_read_gi_b` -> `disk_read_gib`, `disk_write_gi_b` -> `disk_write_gib`, `network_read_gi_b` -> `network_read_gib`, `network_write_gi_b` -> `network_write_gib` in `BatchPoolResourceStatistics` + +- Removed Properties: + - Removed `authentication_token_settings` from `BatchJobManagerTask`, `BatchStartTask`, and `BatchTask` + - Removed `access` from `AuthenticationTokenSettings` ## 15.1.0b3 (2026-02-05) diff --git a/sdk/batch/azure-batch/apiview-properties.json b/sdk/batch/azure-batch/apiview-properties.json index 70cce5480f62..7a3c4effe06b 100644 --- a/sdk/batch/azure-batch/apiview-properties.json +++ b/sdk/batch/azure-batch/apiview-properties.json @@ -128,7 +128,7 @@ "azure.batch.models.OutputFile": "Azure.Batch.OutputFile", "azure.batch.models.OutputFileBlobContainerDestination": "Azure.Batch.OutputFileBlobContainerDestination", "azure.batch.models.OutputFileDestination": "Azure.Batch.OutputFileDestination", - "azure.batch.models.OutputFileUploadConfig": "Azure.Batch.OutputFileUploadConfig", + "azure.batch.models.OutputFileUploadConfiguration": "Azure.Batch.OutputFileUploadConfig", "azure.batch.models.OutputFileUploadHeader": "Azure.Batch.OutputFileUploadHeader", "azure.batch.models.ProxyAgentSettings": "Azure.Batch.ProxyAgentSettings", "azure.batch.models.RecentBatchJob": "Azure.Batch.RecentBatchJob", @@ -269,16 +269,16 @@ "azure.batch.aio.BatchClient.get_task": "Client.BatchClient.getTask", "azure.batch.BatchClient.replace_task": "Client.BatchClient.replaceTask", "azure.batch.aio.BatchClient.replace_task": "Client.BatchClient.replaceTask", - "azure.batch.BatchClient.list_sub_tasks": "Client.BatchClient.listSubTasks", - "azure.batch.aio.BatchClient.list_sub_tasks": "Client.BatchClient.listSubTasks", + "azure.batch.BatchClient.list_subtasks": "Client.BatchClient.listSubTasks", + "azure.batch.aio.BatchClient.list_subtasks": "Client.BatchClient.listSubTasks", "azure.batch.BatchClient.terminate_task": "Client.BatchClient.terminateTask", "azure.batch.aio.BatchClient.terminate_task": "Client.BatchClient.terminateTask", "azure.batch.BatchClient.reactivate_task": "Client.BatchClient.reactivateTask", "azure.batch.aio.BatchClient.reactivate_task": "Client.BatchClient.reactivateTask", "azure.batch.BatchClient.delete_task_file": "Client.BatchClient.deleteTaskFile", "azure.batch.aio.BatchClient.delete_task_file": "Client.BatchClient.deleteTaskFile", - "azure.batch.BatchClient.get_task_file": "Client.BatchClient.getTaskFile", - "azure.batch.aio.BatchClient.get_task_file": "Client.BatchClient.getTaskFile", + "azure.batch.BatchClient.download_task_file": "Client.BatchClient.getTaskFile", + "azure.batch.aio.BatchClient.download_task_file": "Client.BatchClient.getTaskFile", "azure.batch.BatchClient.list_task_files": "Client.BatchClient.listTaskFiles", "azure.batch.aio.BatchClient.list_task_files": "Client.BatchClient.listTaskFiles", "azure.batch.BatchClient.create_node_user": "Client.BatchClient.createNodeUser", @@ -305,8 +305,8 @@ "azure.batch.aio.BatchClient.list_node_extensions": "Client.BatchClient.listNodeExtensions", "azure.batch.BatchClient.delete_node_file": "Client.BatchClient.deleteNodeFile", "azure.batch.aio.BatchClient.delete_node_file": "Client.BatchClient.deleteNodeFile", - "azure.batch.BatchClient.get_node_file": "Client.BatchClient.getNodeFile", - "azure.batch.aio.BatchClient.get_node_file": "Client.BatchClient.getNodeFile", + "azure.batch.BatchClient.download_node_file": "Client.BatchClient.getNodeFile", + "azure.batch.aio.BatchClient.download_node_file": "Client.BatchClient.getNodeFile", "azure.batch.BatchClient.list_node_files": "Client.BatchClient.listNodeFiles", "azure.batch.aio.BatchClient.list_node_files": "Client.BatchClient.listNodeFiles" } diff --git a/sdk/batch/azure-batch/azure/batch/_model_base.py b/sdk/batch/azure-batch/azure/batch/_model_base.py index 228610c1f0c6..22d62109bb8a 100644 --- a/sdk/batch/azure-batch/azure/batch/_model_base.py +++ b/sdk/batch/azure-batch/azure/batch/_model_base.py @@ -821,16 +821,16 @@ def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-retur # is it optional? try: - if any(a for a in annotation.__args__ if a == type(None)): # pyright: ignore + if any(a for a in annotation.__args__ if a == type(None)): # pyright: ignore # pylint: disable=unidiomatic-typecheck if len(annotation.__args__) <= 2: # pyright: ignore if_obj_deserializer = _get_deserialize_callable_from_annotation( - next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore + next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore # pylint: disable=unidiomatic-typecheck ) return functools.partial(_deserialize_with_optional, if_obj_deserializer) # the type is Optional[Union[...]], we need to remove the None type from the Union annotation_copy = copy.copy(annotation) - annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a != type(None)] # pyright: ignore + annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a != type(None)] # pyright: ignore # pylint: disable=unidiomatic-typecheck return _get_deserialize_callable_from_annotation(annotation_copy, module, rf) except AttributeError: pass diff --git a/sdk/batch/azure-batch/azure/batch/_operations/_operations.py b/sdk/batch/azure-batch/azure/batch/_operations/_operations.py index 3342ed4ee5eb..6790090607eb 100644 --- a/sdk/batch/azure-batch/azure/batch/_operations/_operations.py +++ b/sdk/batch/azure-batch/azure/batch/_operations/_operations.py @@ -1968,7 +1968,7 @@ def build_batch_replace_task_request( return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_batch_list_sub_tasks_request( +def build_batch_list_subtasks_request( job_id: str, task_id: str, *, @@ -2139,7 +2139,7 @@ def build_batch_delete_task_file_request( return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) -def build_batch_get_task_file_request( +def build_batch_download_task_file_request( job_id: str, task_id: str, file_path: str, @@ -2862,7 +2862,7 @@ def build_batch_delete_node_file_request( return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) -def build_batch_get_node_file_request( +def build_batch_download_node_file_request( pool_id: str, node_id: str, file_path: str, @@ -8245,7 +8245,7 @@ def replace_task( # pylint: disable=inconsistent-return-statements return cls(pipeline_response, None, response_headers) # type: ignore @distributed_trace - def list_sub_tasks( + def list_subtasks( self, job_id: str, task_id: str, @@ -8293,7 +8293,7 @@ def list_sub_tasks( def prepare_request(next_link=None): if not next_link: - _request = build_batch_list_sub_tasks_request( + _request = build_batch_list_subtasks_request( job_id=job_id, task_id=task_id, service_timeout=service_timeout, @@ -8684,7 +8684,7 @@ def delete_task_file( # pylint: disable=inconsistent-return-statements return cls(pipeline_response, None, response_headers) # type: ignore @distributed_trace - def get_task_file( + def download_task_file( self, job_id: str, task_id: str, @@ -8744,7 +8744,7 @@ def get_task_file( cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_batch_get_task_file_request( + _request = build_batch_download_task_file_request( job_id=job_id, task_id=task_id, file_path=file_path, @@ -10631,7 +10631,7 @@ def delete_node_file( # pylint: disable=inconsistent-return-statements return cls(pipeline_response, None, response_headers) # type: ignore @distributed_trace - def get_node_file( + def download_node_file( self, pool_id: str, node_id: str, @@ -10691,7 +10691,7 @@ def get_node_file( cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_batch_get_node_file_request( + _request = build_batch_download_node_file_request( pool_id=pool_id, node_id=node_id, file_path=file_path, diff --git a/sdk/batch/azure-batch/azure/batch/_operations/_patch.py b/sdk/batch/azure-batch/azure/batch/_operations/_patch.py index beb011291b3f..df6e89143bc7 100644 --- a/sdk/batch/azure-batch/azure/batch/_operations/_patch.py +++ b/sdk/batch/azure-batch/azure/batch/_operations/_patch.py @@ -135,7 +135,13 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = DeleteJobPollingMethod(self, pipeline_response, None, job_id, polling_interval) + polling_method = DeleteJobPollingMethod( + client=self, + initial_response=pipeline_response, + deserialization_callback=None, + job_id=job_id, + polling_interval=polling_interval, + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -217,7 +223,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = DisableJobPollingMethod(self, pipeline_response, None, job_id, polling_interval) + polling_method = DisableJobPollingMethod( + self, pipeline_response, None, job_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -292,7 +300,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = EnableJobPollingMethod(self, pipeline_response, None, job_id, polling_interval) + polling_method = EnableJobPollingMethod( + self, pipeline_response, None, job_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -367,7 +377,7 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ) polling_method = DeleteJobSchedulePollingMethod( - self, pipeline_response, None, job_schedule_id, polling_interval + self, pipeline_response, None, job_schedule_id, polling_interval=polling_interval ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @@ -450,7 +460,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = DeletePoolPollingMethod(self, pipeline_response, None, pool_id, polling_interval) + polling_method = DeletePoolPollingMethod( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -506,7 +518,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = DeallocateNodePollingMethod(self, pipeline_response, None, pool_id, node_id, polling_interval) + polling_method = DeallocateNodePollingMethod( + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -562,7 +576,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = RebootNodePollingMethod(self, pipeline_response, None, pool_id, node_id, polling_interval) + polling_method = RebootNodePollingMethod( + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -622,7 +638,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = ReimageNodePollingMethod(self, pipeline_response, None, pool_id, node_id, polling_interval) + polling_method = ReimageNodePollingMethod( + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -699,7 +717,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = RemoveNodePollingMethod(self, pipeline_response, None, pool_id, polling_interval) + polling_method = RemoveNodePollingMethod( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -780,7 +800,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = ResizePoolPollingMethod(self, pipeline_response, None, pool_id, polling_interval) + polling_method = ResizePoolPollingMethod( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -832,7 +854,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = StartNodePollingMethod(self, pipeline_response, None, pool_id, node_id, polling_interval) + polling_method = StartNodePollingMethod( + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -909,7 +933,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = StopPoolResizePollingMethod(self, pipeline_response, None, pool_id, polling_interval) + polling_method = StopPoolResizePollingMethod( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -994,7 +1020,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = TerminateJobPollingMethod(self, pipeline_response, None, job_id, polling_interval) + polling_method = TerminateJobPollingMethod( + self, pipeline_response, None, job_id, polling_interval=polling_interval + ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -1070,7 +1098,7 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ) polling_method = TerminateJobSchedulePollingMethod( - self, pipeline_response, None, job_schedule_id, polling_interval + self, pipeline_response, None, job_schedule_id, polling_interval=polling_interval ) return LROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @@ -1081,7 +1109,7 @@ def create_tasks( job_id: str, task_collection: List[_models.BatchTaskCreateOptions], *, - max_concurrency: int = 0, + max_concurrency: Optional[int] = None, service_timeout: Optional[int] = None, ocp_date: Optional[datetime.datetime] = None, **kwargs: Any @@ -1161,7 +1189,7 @@ def create_tasks( return _models.BatchCreateTaskCollectionResult(result_values=submitted_tasks) @distributed_trace - def get_node_file( + def download_node_file( self, pool_id: str, node_id: str, @@ -1218,7 +1246,7 @@ def get_node_file( } ) kwargs["stream"] = True - return super().get_node_file(*args, **kwargs) + return super().download_node_file(*args, **kwargs) @distributed_trace def get_node_file_properties( @@ -1357,7 +1385,7 @@ def cls(_pipeline_response, _json_response, headers): return get_response @distributed_trace - def get_task_file( + def download_task_file( self, job_id: str, task_id: str, @@ -1415,7 +1443,7 @@ def get_task_file( } ) kwargs["stream"] = True - return super().get_task_file(*args, **kwargs) + return super().download_task_file(*args, **kwargs) def patch_sdk(): diff --git a/sdk/batch/azure-batch/azure/batch/_operations/_polling.py b/sdk/batch/azure-batch/azure/batch/_operations/_polling.py index aa87b22a6747..f50080380564 100644 --- a/sdk/batch/azure-batch/azure/batch/_operations/_polling.py +++ b/sdk/batch/azure-batch/azure/batch/_operations/_polling.py @@ -29,6 +29,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -103,6 +104,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -177,6 +179,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -251,6 +254,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_schedule_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -319,6 +323,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -393,6 +398,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -471,6 +477,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -547,6 +554,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -623,6 +631,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -699,6 +708,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -775,6 +785,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -851,6 +862,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -927,6 +939,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): self._client = client @@ -1001,6 +1014,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_schedule_id: str, + *, polling_interval: int = 5, ): self._client = client diff --git a/sdk/batch/azure-batch/azure/batch/_utils/model_base.py b/sdk/batch/azure-batch/azure/batch/_utils/model_base.py index 7b7f8ba67b53..db24930fdca9 100644 --- a/sdk/batch/azure-batch/azure/batch/_utils/model_base.py +++ b/sdk/batch/azure-batch/azure/batch/_utils/model_base.py @@ -600,57 +600,9 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: for rest_field in self._attr_to_rest_field.values() if rest_field._default is not _UNSET } - if args: # pylint: disable=too-many-nested-blocks + if args: if isinstance(args[0], ET.Element): - existed_attr_keys = [] - model_meta = getattr(self, "_xml", {}) - - for rf in self._attr_to_rest_field.values(): - prop_meta = getattr(rf, "_xml", {}) - xml_name = prop_meta.get("name", rf._rest_name) - xml_ns = prop_meta.get("ns", model_meta.get("ns", None)) - if xml_ns: - xml_name = "{" + xml_ns + "}" + xml_name - - # attribute - if prop_meta.get("attribute", False) and args[0].get(xml_name) is not None: - existed_attr_keys.append(xml_name) - dict_to_pass[rf._rest_name] = _deserialize(rf._type, args[0].get(xml_name)) - continue - - # unwrapped element is array - if prop_meta.get("unwrapped", False): - # unwrapped array could either use prop items meta/prop meta - if prop_meta.get("itemsName"): - xml_name = prop_meta.get("itemsName") - xml_ns = prop_meta.get("itemNs") - if xml_ns: - xml_name = "{" + xml_ns + "}" + xml_name - items = args[0].findall(xml_name) # pyright: ignore - if len(items) > 0: - existed_attr_keys.append(xml_name) - dict_to_pass[rf._rest_name] = _deserialize(rf._type, items) - elif not rf._is_optional: - existed_attr_keys.append(xml_name) - dict_to_pass[rf._rest_name] = [] - continue - - # text element is primitive type - if prop_meta.get("text", False): - if args[0].text is not None: - dict_to_pass[rf._rest_name] = _deserialize(rf._type, args[0].text) - continue - - # wrapped element could be normal property or array, it should only have one element - item = args[0].find(xml_name) - if item is not None: - existed_attr_keys.append(xml_name) - dict_to_pass[rf._rest_name] = _deserialize(rf._type, item) - - # rest thing is additional properties - for e in args[0]: - if e.tag not in existed_attr_keys: - dict_to_pass[e.tag] = _convert_element(e) + dict_to_pass.update(self._init_from_xml(args[0])) else: dict_to_pass.update( {k: _create_value(_get_rest_field(self._attr_to_rest_field, k), v) for k, v in args[0].items()} @@ -669,6 +621,69 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: ) super().__init__(dict_to_pass) + def _init_from_xml(self, element: ET.Element) -> dict[str, typing.Any]: + """Deserialize an XML element into a dict mapping rest field names to values. + + :param ET.Element element: The XML element to deserialize from. + :returns: A dictionary of rest_name to deserialized value pairs. + :rtype: dict + """ + result: dict[str, typing.Any] = {} + model_meta = getattr(self, "_xml", {}) + existed_attr_keys: list[str] = [] + + for rf in self._attr_to_rest_field.values(): + prop_meta = getattr(rf, "_xml", {}) + xml_name = prop_meta.get("name", rf._rest_name) + xml_ns = _resolve_xml_ns(prop_meta, model_meta) + if xml_ns: + xml_name = "{" + xml_ns + "}" + xml_name + + # attribute + if prop_meta.get("attribute", False) and element.get(xml_name) is not None: + existed_attr_keys.append(xml_name) + result[rf._rest_name] = _deserialize(rf._type, element.get(xml_name)) + continue + + # unwrapped element is array + if prop_meta.get("unwrapped", False): + # unwrapped array could either use prop items meta/prop meta + _items_name = prop_meta.get("itemsName") + if _items_name: + xml_name = _items_name + _items_ns = prop_meta.get("itemsNs") + if _items_ns is not None: + xml_ns = _items_ns + if xml_ns: + xml_name = "{" + xml_ns + "}" + xml_name + items = element.findall(xml_name) # pyright: ignore + if len(items) > 0: + existed_attr_keys.append(xml_name) + result[rf._rest_name] = _deserialize(rf._type, items) + elif not rf._is_optional: + existed_attr_keys.append(xml_name) + result[rf._rest_name] = [] + continue + + # text element is primitive type + if prop_meta.get("text", False): + if element.text is not None: + result[rf._rest_name] = _deserialize(rf._type, element.text) + continue + + # wrapped element could be normal property or array, it should only have one element + item = element.find(xml_name) + if item is not None: + existed_attr_keys.append(xml_name) + result[rf._rest_name] = _deserialize(rf._type, item) + + # rest thing is additional properties + for e in element: + if e.tag not in existed_attr_keys: + result[e.tag] = _convert_element(e) + + return result + def copy(self) -> "Model": return Model(self.__dict__) @@ -721,7 +736,7 @@ def _deserialize(cls, data, exist_discriminators): model_meta = getattr(cls, "_xml", {}) prop_meta = getattr(discriminator, "_xml", {}) xml_name = prop_meta.get("name", discriminator._rest_name) - xml_ns = prop_meta.get("ns", model_meta.get("ns", None)) + xml_ns = _resolve_xml_ns(prop_meta, model_meta) if xml_ns: xml_name = "{" + xml_ns + "}" + xml_name @@ -1190,6 +1205,56 @@ def serialize_xml(model: Model, exclude_readonly: bool = False) -> str: return ET.tostring(_get_element(model, exclude_readonly), encoding="unicode") # type: ignore +def _get_xml_ns(meta: dict[str, typing.Any]) -> typing.Optional[str]: + """Return the XML namespace from a metadata dict, checking both 'ns' (old-style) and 'namespace' (DPG) keys. + + :param dict meta: The metadata dictionary to extract namespace from. + :returns: The namespace string if 'ns' or 'namespace' key is present, None otherwise. + :rtype: str or None + """ + ns = meta.get("ns") + if ns is None: + ns = meta.get("namespace") + return ns + + +def _resolve_xml_ns( + prop_meta: dict[str, typing.Any], model_meta: typing.Optional[dict[str, typing.Any]] = None +) -> typing.Optional[str]: + """Resolve XML namespace for a property, falling back to model namespace when appropriate. + + Checks the property metadata first; if no namespace is found and the model does not declare + an explicit prefix, falls back to the model-level namespace. + + :param dict prop_meta: The property metadata dictionary. + :param dict model_meta: The model metadata dictionary, used as fallback. + :returns: The resolved namespace string, or None. + :rtype: str or None + """ + ns = _get_xml_ns(prop_meta) + if ns is None and model_meta is not None and not model_meta.get("prefix"): + ns = _get_xml_ns(model_meta) + return ns + + +def _set_xml_attribute(element: ET.Element, name: str, value: typing.Any, prop_meta: dict[str, typing.Any]) -> None: + """Set an XML attribute on an element, handling namespace prefix registration. + + :param ET.Element element: The element to set the attribute on. + :param str name: The default attribute name (wire name). + :param any value: The attribute value. + :param dict prop_meta: The property metadata dictionary. + """ + xml_name = prop_meta.get("name", name) + _attr_ns = _get_xml_ns(prop_meta) + if _attr_ns: + _attr_prefix = prop_meta.get("prefix") + if _attr_prefix: + _safe_register_namespace(_attr_prefix, _attr_ns) + xml_name = "{" + _attr_ns + "}" + xml_name + element.set(xml_name, _get_primitive_type_value(value)) + + def _get_element( o: typing.Any, exclude_readonly: bool = False, @@ -1201,10 +1266,16 @@ def _get_element( # if prop is a model, then use the prop element directly, else generate a wrapper of model if wrapped_element is None: + # When serializing as an array item (parent_meta is set), check if the parent has an + # explicit itemsName. This ensures correct element names for unwrapped arrays (where + # the element tag is the property/items name, not the model type name). + _items_name = parent_meta.get("itemsName") if parent_meta is not None else None + element_name = _items_name if _items_name else (model_meta.get("name") or o.__class__.__name__) + _model_ns = _get_xml_ns(model_meta) wrapped_element = _create_xml_element( - model_meta.get("name", o.__class__.__name__), + element_name, model_meta.get("prefix"), - model_meta.get("ns"), + _model_ns, ) readonly_props = [] @@ -1226,7 +1297,9 @@ def _get_element( # additional properties will not have rest field, use the wire name as xml name prop_meta = {"name": k} - # if no ns for prop, use model's + # Propagate model namespace to properties only for old-style "ns"-keyed models. + # DPG-generated models use the "namespace" key and explicitly declare namespace on + # each property that needs it, so propagation is intentionally skipped for them. if prop_meta.get("ns") is None and model_meta.get("ns"): prop_meta["ns"] = model_meta.get("ns") prop_meta["prefix"] = model_meta.get("prefix") @@ -1238,12 +1311,7 @@ def _get_element( # text could only set on primitive type wrapped_element.text = _get_primitive_type_value(v) elif prop_meta.get("attribute", False): - xml_name = prop_meta.get("name", k) - if prop_meta.get("ns"): - ET.register_namespace(prop_meta.get("prefix"), prop_meta.get("ns")) # pyright: ignore - xml_name = "{" + prop_meta.get("ns") + "}" + xml_name # pyright: ignore - # attribute should be primitive type - wrapped_element.set(xml_name, _get_primitive_type_value(v)) + _set_xml_attribute(wrapped_element, k, v, prop_meta) else: # other wrapped prop element wrapped_element.append(_get_wrapped_element(v, exclude_readonly, prop_meta)) @@ -1252,6 +1320,7 @@ def _get_element( return [_get_element(x, exclude_readonly, parent_meta) for x in o] # type: ignore if isinstance(o, dict): result = [] + _dict_ns = _get_xml_ns(parent_meta) if parent_meta else None for k, v in o.items(): result.append( _get_wrapped_element( @@ -1259,7 +1328,7 @@ def _get_element( exclude_readonly, { "name": k, - "ns": parent_meta.get("ns") if parent_meta else None, + "ns": _dict_ns, "prefix": parent_meta.get("prefix") if parent_meta else None, }, ) @@ -1268,13 +1337,16 @@ def _get_element( # primitive case need to create element based on parent_meta if parent_meta: + _items_ns = parent_meta.get("itemsNs") + if _items_ns is None: + _items_ns = _get_xml_ns(parent_meta) return _get_wrapped_element( o, exclude_readonly, { "name": parent_meta.get("itemsName", parent_meta.get("name")), "prefix": parent_meta.get("itemsPrefix", parent_meta.get("prefix")), - "ns": parent_meta.get("itemsNs", parent_meta.get("ns")), + "ns": _items_ns, }, ) @@ -1286,8 +1358,9 @@ def _get_wrapped_element( exclude_readonly: bool, meta: typing.Optional[dict[str, typing.Any]], ) -> ET.Element: + _meta_ns = _get_xml_ns(meta) if meta else None wrapped_element = _create_xml_element( - meta.get("name") if meta else None, meta.get("prefix") if meta else None, meta.get("ns") if meta else None + meta.get("name") if meta else None, meta.get("prefix") if meta else None, _meta_ns ) if isinstance(v, (dict, list)): wrapped_element.extend(_get_element(v, exclude_readonly, meta)) @@ -1308,11 +1381,29 @@ def _get_primitive_type_value(v) -> str: return str(v) +def _safe_register_namespace(prefix: str, ns: str) -> None: + """Register an XML namespace prefix, handling reserved prefix patterns. + + Some prefixes (e.g. 'ns2') match Python's reserved 'ns\\d+' pattern used for + auto-generated prefixes, causing register_namespace to raise ValueError. + Falls back to directly registering in the internal namespace map. + + :param str prefix: The namespace prefix to register. + :param str ns: The namespace URI. + """ + try: + ET.register_namespace(prefix, ns) + except ValueError: + _ns_map = getattr(ET, "_namespace_map", None) + if _ns_map is not None: + _ns_map[ns] = prefix + + def _create_xml_element( tag: typing.Any, prefix: typing.Optional[str] = None, ns: typing.Optional[str] = None ) -> ET.Element: if prefix and ns: - ET.register_namespace(prefix, ns) + _safe_register_namespace(prefix, ns) if ns: return ET.Element("{" + ns + "}" + tag) return ET.Element(tag) diff --git a/sdk/batch/azure-batch/azure/batch/aio/_operations/_operations.py b/sdk/batch/azure-batch/azure/batch/aio/_operations/_operations.py index 921be136fe1b..e204edcdd816 100644 --- a/sdk/batch/azure-batch/azure/batch/aio/_operations/_operations.py +++ b/sdk/batch/azure-batch/azure/batch/aio/_operations/_operations.py @@ -51,6 +51,8 @@ build_batch_disable_job_schedule_request, build_batch_disable_node_scheduling_request, build_batch_disable_pool_auto_scale_request, + build_batch_download_node_file_request, + build_batch_download_task_file_request, build_batch_enable_job_internal_request, build_batch_enable_job_schedule_request, build_batch_enable_node_scheduling_request, @@ -62,12 +64,10 @@ build_batch_get_job_task_counts_request, build_batch_get_node_extension_request, build_batch_get_node_file_properties_internal_request, - build_batch_get_node_file_request, build_batch_get_node_remote_login_settings_request, build_batch_get_node_request, build_batch_get_pool_request, build_batch_get_task_file_properties_internal_request, - build_batch_get_task_file_request, build_batch_get_task_request, build_batch_job_schedule_exists_request, build_batch_list_applications_request, @@ -81,7 +81,7 @@ build_batch_list_pool_node_counts_request, build_batch_list_pool_usage_metrics_request, build_batch_list_pools_request, - build_batch_list_sub_tasks_request, + build_batch_list_subtasks_request, build_batch_list_supported_images_request, build_batch_list_task_files_request, build_batch_list_tasks_request, @@ -5364,7 +5364,7 @@ async def replace_task( return cls(pipeline_response, None, response_headers) # type: ignore @distributed_trace - def list_sub_tasks( + def list_subtasks( self, job_id: str, task_id: str, @@ -5412,7 +5412,7 @@ def list_sub_tasks( def prepare_request(next_link=None): if not next_link: - _request = build_batch_list_sub_tasks_request( + _request = build_batch_list_subtasks_request( job_id=job_id, task_id=task_id, service_timeout=service_timeout, @@ -5803,7 +5803,7 @@ async def delete_task_file( return cls(pipeline_response, None, response_headers) # type: ignore @distributed_trace_async - async def get_task_file( + async def download_task_file( self, job_id: str, task_id: str, @@ -5863,7 +5863,7 @@ async def get_task_file( cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_batch_get_task_file_request( + _request = build_batch_download_task_file_request( job_id=job_id, task_id=task_id, file_path=file_path, @@ -7750,7 +7750,7 @@ async def delete_node_file( return cls(pipeline_response, None, response_headers) # type: ignore @distributed_trace_async - async def get_node_file( + async def download_node_file( self, pool_id: str, node_id: str, @@ -7810,7 +7810,7 @@ async def get_node_file( cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_batch_get_node_file_request( + _request = build_batch_download_node_file_request( pool_id=pool_id, node_id=node_id, file_path=file_path, diff --git a/sdk/batch/azure-batch/azure/batch/aio/_operations/_patch.py b/sdk/batch/azure-batch/azure/batch/aio/_operations/_patch.py index c06305d24412..f28ceee2301a 100644 --- a/sdk/batch/azure-batch/azure/batch/aio/_operations/_patch.py +++ b/sdk/batch/azure-batch/azure/batch/aio/_operations/_patch.py @@ -137,7 +137,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = DeleteJobPollingMethodAsync(self, pipeline_response, None, job_id, polling_interval) + polling_method = DeleteJobPollingMethodAsync( + self, pipeline_response, None, job_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -219,7 +221,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = DisableJobPollingMethodAsync(self, pipeline_response, None, job_id, polling_interval) + polling_method = DisableJobPollingMethodAsync( + self, pipeline_response, None, job_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -294,7 +298,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = EnableJobPollingMethodAsync(self, pipeline_response, None, job_id, polling_interval) + polling_method = EnableJobPollingMethodAsync( + self, pipeline_response, None, job_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -369,7 +375,7 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ) polling_method = DeleteJobSchedulePollingMethodAsync( - self, pipeline_response, None, job_schedule_id, polling_interval + self, pipeline_response, None, job_schedule_id, polling_interval=polling_interval ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @@ -452,7 +458,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = DeletePoolPollingMethodAsync(self, pipeline_response, None, pool_id, polling_interval) + polling_method = DeletePoolPollingMethodAsync( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -509,7 +517,7 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ) polling_method = DeallocateNodePollingMethodAsync( - self, pipeline_response, None, pool_id, node_id, polling_interval + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @@ -566,7 +574,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = RebootNodePollingMethodAsync(self, pipeline_response, None, pool_id, node_id, polling_interval) + polling_method = RebootNodePollingMethodAsync( + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -627,7 +637,7 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ) polling_method = ReimageNodePollingMethodAsync( - self, pipeline_response, None, pool_id, node_id, polling_interval + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @@ -705,7 +715,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = RemoveNodePollingMethodAsync(self, pipeline_response, None, pool_id, polling_interval) + polling_method = RemoveNodePollingMethodAsync( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -786,7 +798,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = ResizePoolPollingMethodAsync(self, pipeline_response, None, pool_id, polling_interval) + polling_method = ResizePoolPollingMethodAsync( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -838,7 +852,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = StartNodePollingMethodAsync(self, pipeline_response, None, pool_id, node_id, polling_interval) + polling_method = StartNodePollingMethodAsync( + self, pipeline_response, None, pool_id, node_id=node_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -915,7 +931,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = StopPoolResizePollingMethodAsync(self, pipeline_response, None, pool_id, polling_interval) + polling_method = StopPoolResizePollingMethodAsync( + self, pipeline_response, None, pool_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -1000,7 +1018,9 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ), ) - polling_method = TerminateJobPollingMethodAsync(self, pipeline_response, None, job_id, polling_interval) + polling_method = TerminateJobPollingMethodAsync( + self, pipeline_response, None, job_id, polling_interval=polling_interval + ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @distributed_trace @@ -1076,7 +1096,7 @@ def capture_pipeline_response(pipeline_response, _deserialized, _response_header ) polling_method = TerminateJobSchedulePollingMethodAsync( - self, pipeline_response, None, job_schedule_id, polling_interval + self, pipeline_response, None, job_schedule_id, polling_interval=polling_interval ) return AsyncLROPoller(self, pipeline_response, lambda _: None, polling_method, **kwargs) @@ -1087,7 +1107,7 @@ async def create_tasks( job_id: str, task_collection: List[_models.BatchTaskCreateOptions], *, - max_concurrency: int = 0, + max_concurrency: Optional[int] = None, service_timeout: Optional[int] = None, ocp_date: Optional[datetime.datetime] = None, **kwargs: Any @@ -1157,7 +1177,7 @@ async def create_tasks( return _models.BatchCreateTaskCollectionResult(result_values=submitted_tasks) @distributed_trace - async def get_node_file( + async def download_node_file( self, pool_id: str, node_id: str, @@ -1214,7 +1234,7 @@ async def get_node_file( } ) kwargs["stream"] = True - return await super().get_node_file(*args, **kwargs) + return await super().download_node_file(*args, **kwargs) @distributed_trace async def get_node_file_properties( @@ -1353,7 +1373,7 @@ def cls(_pipeline_response, _json_response, headers): return get_response @distributed_trace - async def get_task_file( + async def download_task_file( self, job_id: str, task_id: str, @@ -1411,7 +1431,7 @@ async def get_task_file( } ) kwargs["stream"] = True - return await super().get_task_file(*args, **kwargs) + return await super().download_task_file(*args, **kwargs) class _TaskWorkflowManager: diff --git a/sdk/batch/azure-batch/azure/batch/aio/_operations/_polling_async.py b/sdk/batch/azure-batch/azure/batch/aio/_operations/_polling_async.py index c1d3d8cc7ea9..f84a903fc7dc 100644 --- a/sdk/batch/azure-batch/azure/batch/aio/_operations/_polling_async.py +++ b/sdk/batch/azure-batch/azure/batch/aio/_operations/_polling_async.py @@ -30,6 +30,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): """Initialize the DeleteJobPollingMethodAsync. @@ -50,9 +51,9 @@ def __init__( :type deserialization_callback: Optional[Callable] :param job_id: The unique identifier of the job being deleted. :type job_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -126,6 +127,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): """Initialize the DisableJobPollingMethodAsync. @@ -146,9 +148,9 @@ def __init__( :type deserialization_callback: Optional[Callable] :param job_id: The unique identifier of the job being disabled. :type job_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -222,6 +224,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): """Initialize the EnableJobPollingMethodAsync. @@ -242,9 +245,9 @@ def __init__( :type deserialization_callback: Optional[Callable] :param job_id: The unique identifier of the job being enabled. :type job_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -318,6 +321,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_schedule_id: str, + *, polling_interval: int = 5, ): """Initialize the DeleteJobSchedulePollingMethodAsync. @@ -338,9 +342,9 @@ def __init__( :type deserialization_callback: Optional[Callable] :param job_schedule_id: The unique identifier of the job schedule being deleted. :type job_schedule_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -413,6 +417,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): """Initialize the DeletePoolPollingMethodAsync. @@ -433,9 +438,9 @@ def __init__( :type deserialization_callback: Optional[Callable] :param pool_id: The unique identifier of the pool being deleted. :type pool_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -509,6 +514,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -531,11 +537,11 @@ def __init__( :param pool_id: The unique identifier of the pool containing the node to be deallocated. :type pool_id: str - :param node_id: The unique identifier of the node to be deallocated. - :type node_id: str - :param polling_interval: The time interval in seconds between polling + :keyword node_id: The unique identifier of the node to be deallocated. + :paramtype node_id: str + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -612,6 +618,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -634,11 +641,11 @@ def __init__( :param pool_id: The unique identifier of the pool containing the node to be rebooted. :type pool_id: str - :param node_id: The unique identifier of the node to be rebooted. - :type node_id: str - :param polling_interval: The time interval in seconds between polling + :keyword node_id: The unique identifier of the node to be rebooted. + :paramtype node_id: str + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -713,6 +720,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -735,11 +743,11 @@ def __init__( :param pool_id: The unique identifier of the pool containing the node to be reimaged. :type pool_id: str - :param node_id: The unique identifier of the node to be reimaged. - :type node_id: str - :param polling_interval: The time interval in seconds between polling + :keyword node_id: The unique identifier of the node to be reimaged. + :paramtype node_id: str + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -814,6 +822,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): """Initialize the RemoveNodePollingMethodAsync. @@ -835,9 +844,9 @@ def __init__( :param pool_id: The unique identifier of the pool from which nodes are being removed. :type pool_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -913,6 +922,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): """Initialize the ResizePoolPollingMethodAsync. @@ -933,9 +943,9 @@ def __init__( :type deserialization_callback: Optional[Callable] :param pool_id: The unique identifier of the pool being resized. :type pool_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -1011,6 +1021,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, node_id: str, polling_interval: int = 5, ): @@ -1033,11 +1044,11 @@ def __init__( :param pool_id: The unique identifier of the pool containing the node to be started. :type pool_id: str - :param node_id: The unique identifier of the node to be started. - :type node_id: str - :param polling_interval: The time interval in seconds between polling + :keyword node_id: The unique identifier of the node to be started. + :paramtype node_id: str + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -1112,6 +1123,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], pool_id: str, + *, polling_interval: int = 5, ): """Initialize the StopPoolResizePollingMethodAsync. @@ -1133,9 +1145,9 @@ def __init__( :param pool_id: The unique identifier of the pool for which resize is being stopped. :type pool_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -1211,6 +1223,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_id: str, + *, polling_interval: int = 5, ): """Initialize the TerminateJobPollingMethodAsync. @@ -1231,9 +1244,9 @@ def __init__( :type deserialization_callback: Optional[Callable] :param job_id: The unique identifier of the job being terminated. :type job_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response @@ -1307,6 +1320,7 @@ def __init__( initial_response: PipelineResponse, deserialization_callback: Optional[Callable], job_schedule_id: str, + *, polling_interval: int = 5, ): """Initialize the TerminateJobSchedulePollingMethodAsync. @@ -1328,9 +1342,9 @@ def __init__( :param job_schedule_id: The unique identifier of the job schedule being terminated. :type job_schedule_id: str - :param polling_interval: The time interval in seconds between polling + :keyword polling_interval: The time interval in seconds between polling attempts. Defaults to 5 seconds. - :type polling_interval: int + :paramtype polling_interval: int """ self._client = client self._initial_response = initial_response diff --git a/sdk/batch/azure-batch/azure/batch/aio/_patch.py b/sdk/batch/azure-batch/azure/batch/aio/_patch.py index 4434e3c36878..0e143d513f25 100644 --- a/sdk/batch/azure-batch/azure/batch/aio/_patch.py +++ b/sdk/batch/azure-batch/azure/batch/aio/_patch.py @@ -9,7 +9,7 @@ from typing import Union -from azure.core.credentials import TokenCredential +from azure.core.credentials_async import AsyncTokenCredential from azure.core.credentials import AzureNamedKeyCredential from ._client import BatchClient as GenerateBatchClient @@ -30,13 +30,15 @@ class BatchClient(GenerateBatchClient): :type hub: str :param credentials: Credential needed for the client to connect to Azure. :type credentials: ~azure.identity.ClientSecretCredential, ~azure.core.credentials.AzureNamedKeyCredential, - or ~azure.identity.TokenCredentials + or ~azure.core.credentials_async.AsyncTokenCredential :keyword api_version: Api Version. The default value is "2021-10-01". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ - def __init__(self, endpoint: str, credential: Union[AzureNamedKeyCredential, TokenCredential], **kwargs) -> None: + def __init__( + self, endpoint: str, credential: Union[AzureNamedKeyCredential, AsyncTokenCredential], **kwargs + ) -> None: per_call_policies = kwargs.pop("per_call_policies", []) per_call_policies.append(BatchExceptionPolicy()) super().__init__( diff --git a/sdk/batch/azure-batch/azure/batch/models/__init__.py b/sdk/batch/azure-batch/azure/batch/models/__init__.py index 6d407dc35aac..5d61f090be5a 100644 --- a/sdk/batch/azure-batch/azure/batch/models/__init__.py +++ b/sdk/batch/azure-batch/azure/batch/models/__init__.py @@ -141,7 +141,7 @@ OutputFile, OutputFileBlobContainerDestination, OutputFileDestination, - OutputFileUploadConfig, + OutputFileUploadConfiguration, OutputFileUploadHeader, ProxyAgentSettings, RecentBatchJob, @@ -346,7 +346,7 @@ "OutputFile", "OutputFileBlobContainerDestination", "OutputFileDestination", - "OutputFileUploadConfig", + "OutputFileUploadConfiguration", "OutputFileUploadHeader", "ProxyAgentSettings", "RecentBatchJob", diff --git a/sdk/batch/azure-batch/azure/batch/models/_models.py b/sdk/batch/azure-batch/azure/batch/models/_models.py index 122d09360ae9..e28224578b5d 100644 --- a/sdk/batch/azure-batch/azure/batch/models/_models.py +++ b/sdk/batch/azure-batch/azure/batch/models/_models.py @@ -9864,7 +9864,7 @@ class OutputFile(_Model): :vartype destination: ~azure.batch.models.OutputFileDestination :ivar upload_options: Additional options for the upload operation, including under what conditions to perform the upload. Required. - :vartype upload_options: ~azure.batch.models.OutputFileUploadConfig + :vartype upload_options: ~azure.batch.models.OutputFileUploadConfiguration """ file_pattern: str = rest_field(name="filePattern", visibility=["read", "create", "update", "delete", "query"]) @@ -9886,7 +9886,7 @@ class OutputFile(_Model): visibility=["read", "create", "update", "delete", "query"] ) """The destination for the output file(s). Required.""" - upload_options: "_models.OutputFileUploadConfig" = rest_field( + upload_options: "_models.OutputFileUploadConfiguration" = rest_field( name="uploadOptions", visibility=["read", "create", "update", "delete", "query"] ) """Additional options for the upload operation, including under what conditions to perform the @@ -9898,7 +9898,7 @@ def __init__( *, file_pattern: str, destination: "_models.OutputFileDestination", - upload_options: "_models.OutputFileUploadConfig", + upload_options: "_models.OutputFileUploadConfiguration", ) -> None: ... @overload @@ -10014,7 +10014,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class OutputFileUploadConfig(_Model): +class OutputFileUploadConfiguration(_Model): """Options for an output file upload operation, including under what conditions to perform the upload. @@ -10917,8 +10917,10 @@ class VirtualMachineConfiguration(_Model): """This only applies to Images that contain the Windows operating system, and should only be used when you hold valid on-premises licenses for the Compute Nodes which will be deployed. If omitted, no on-premises licensing discount is - applied. Values are: Windows_Server (the on-premises license is for Windows - Server) and Windows_Client (the on-premises license is for Windows Client).""" + applied. Values are: + + Server. + Windows_Client - The on-premises license is for Windows Client.""" container_configuration: Optional["_models.BatchContainerConfiguration"] = rest_field( name="containerConfiguration", visibility=["read", "create", "update", "delete", "query"] ) diff --git a/sdk/batch/azure-batch/tests/test_batch.py b/sdk/batch/azure-batch/tests/test_batch.py index 8aa70f59f493..da4a589bbaf4 100644 --- a/sdk/batch/azure-batch/tests/test_batch.py +++ b/sdk/batch/azure-batch/tests/test_batch.py @@ -1032,7 +1032,7 @@ async def test_batch_files(self, client: BatchClient, **kwargs): # Test Get File from Batch Node file_length = 0 with io.BytesIO() as file_handle: - response = await wrap_file_result(client.get_node_file(batch_pool.name, node, only_files[1].name)) + response = await wrap_file_result(client.download_node_file(batch_pool.name, node, only_files[1].name)) for data in response: file_length += len(data) assert file_length == props.content_length @@ -1061,7 +1061,7 @@ async def test_batch_files(self, client: BatchClient, **kwargs): # Test Get File from Task file_length = 0 with io.BytesIO() as file_handle: - response = await wrap_file_result(client.get_task_file(batch_job.id, task_id, only_files[0].name)) + response = await wrap_file_result(client.download_task_file(batch_job.id, task_id, only_files[0].name)) for data in response: file_length += len(data) assert file_length == props.content_length @@ -1126,7 +1126,7 @@ async def test_batch_tasks(self, client: BatchClient, **kwargs): container_url=container_url, path="taskLogs/output.txt" ) ), - upload_options=models.OutputFileUploadConfig( + upload_options=models.OutputFileUploadConfiguration( upload_condition=models.OutputFileUploadCondition.TASK_COMPLETION ), ), @@ -1137,7 +1137,7 @@ async def test_batch_tasks(self, client: BatchClient, **kwargs): container_url=container_url, path="taskLogs/error.txt" ) ), - upload_options=models.OutputFileUploadConfig( + upload_options=models.OutputFileUploadConfiguration( upload_condition=models.OutputFileUploadCondition.TASK_FAILURE ), ), @@ -1242,7 +1242,7 @@ async def test_batch_tasks(self, client: BatchClient, **kwargs): # Test Get Subtasks # TODO: Test with actual subtasks - subtasks = list(await wrap_list_result(client.list_sub_tasks(batch_job.id, task_param.id))) + subtasks = list(await wrap_list_result(client.list_subtasks(batch_job.id, task_param.id))) assert isinstance(subtasks, Iterable) # Test Delete Task diff --git a/sdk/batch/azure-batch/tsp-location.yaml b/sdk/batch/azure-batch/tsp-location.yaml index be3da5c967d0..108066e5771d 100644 --- a/sdk/batch/azure-batch/tsp-location.yaml +++ b/sdk/batch/azure-batch/tsp-location.yaml @@ -1,4 +1,4 @@ directory: specification/batch/data-plane/Batch -commit: 7ffc2a029145d8b85a84e0ef0eddc1e21adf7027 +commit: 3cc80d86e8e1b8839fc2ea665e0fc6ee264f7c34 repo: Azure/azure-rest-api-specs additionalDirectories: