From 43fb6ac137f39f2f1dd9928bb478978753a12f8b Mon Sep 17 00:00:00 2001 From: azure-sdk Date: Wed, 12 Aug 2026 19:36:40 +0000 Subject: [PATCH 1/7] Configurations: 'specification/relationships/resource-manager/Microsoft.Relationships/Relationships/tspconfig.yaml', SDK Release Type: beta, and CommitSHA: '2831f359f052615c26675394fd3939cf6ca92a3b' in SpecRepo: 'https://github.com/Azure/azure-rest-api-specs' Pipeline run: https://dev.azure.com/azure-sdk/internal/_build/results?buildId=6693387 Refer to https://eng.ms/docs/products/azure-developer-experience/develop/sdk-release/sdk-release-prerequisites to prepare for SDK release. --- .../azure-mgmt-relationships/CHANGELOG.md | 4 + .../azure-mgmt-relationships/README.md | 6 +- .../azure-mgmt-relationships/_metadata.json | 11 +- .../azure-mgmt-relationships/api.md | 760 ++++++++++++++++++ .../azure-mgmt-relationships/api.metadata.yml | 3 + .../apiview-properties.json | 17 +- .../azure/mgmt/relationships/_client.py | 31 +- .../mgmt/relationships/_configuration.py | 16 +- .../mgmt/relationships/_utils/model_base.py | 603 ++++++++++++-- .../relationships/_utils/serialization.py | 144 +++- .../azure/mgmt/relationships/_validation.py | 66 ++ .../azure/mgmt/relationships/_version.py | 2 +- .../azure/mgmt/relationships/aio/_client.py | 31 +- .../mgmt/relationships/aio/_configuration.py | 16 +- .../relationships/aio/operations/__init__.py | 2 + .../aio/operations/_operations.py | 502 +++++++++++- .../mgmt/relationships/models/__init__.py | 8 +- .../mgmt/relationships/models/_models.py | 157 +++- .../mgmt/relationships/operations/__init__.py | 2 + .../relationships/operations/_operations.py | 618 +++++++++++++- .../azure/mgmt/relationships/types.py | 238 ++++++ ...ns_relationships_list_by_resource_group.py | 42 + ...ains_relationships_list_by_subscription.py | 40 + ...dency_of_relationships_create_or_update.py | 3 +- .../dependency_of_relationships_delete.py | 3 +- .../dependency_of_relationships_get.py | 3 +- ...endency_of_relationships_list_by_parent.py | 43 + .../operations_list_maximum_set_gen.py | 3 +- ...p_member_relationships_create_or_update.py | 7 +- ...rvice_group_member_relationships_delete.py | 3 +- .../service_group_member_relationships_get.py | 3 +- ...oup_member_relationships_list_by_parent.py | 43 + ..._mgmt_contains_relationships_operations.py | 37 + ...contains_relationships_operations_async.py | 38 + ..._dependency_of_relationships_operations.py | 14 +- ...dency_of_relationships_operations_async.py | 14 +- ...e_group_member_relationships_operations.py | 16 +- ...p_member_relationships_operations_async.py | 16 +- .../azure-mgmt-relationships/pyproject.toml | 4 +- .../tsp-location.yaml | 4 +- 40 files changed, 3345 insertions(+), 228 deletions(-) create mode 100644 sdk/relationships/azure-mgmt-relationships/api.md create mode 100644 sdk/relationships/azure-mgmt-relationships/api.metadata.yml create mode 100644 sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_validation.py create mode 100644 sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/types.py create mode 100644 sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_resource_group.py create mode 100644 sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_subscription.py create mode 100644 sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_list_by_parent.py create mode 100644 sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_list_by_parent.py create mode 100644 sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations.py create mode 100644 sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations_async.py diff --git a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md index d494ccd59503..2e639130132c 100644 --- a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md +++ b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History +## 1.0.0b2 (2026-08-12) + +tool can't generate changelog for this release, please update manually. + ## 1.0.0b1 (2026-04-02) ### Other Changes diff --git a/sdk/relationships/azure-mgmt-relationships/README.md b/sdk/relationships/azure-mgmt-relationships/README.md index 960d6f593f0f..4803ec1ec3bf 100644 --- a/sdk/relationships/azure-mgmt-relationships/README.md +++ b/sdk/relationships/azure-mgmt-relationships/README.md @@ -1,7 +1,7 @@ # Microsoft Azure SDK for Python This is the Microsoft Azure Relationships Management Client Library. -This package has been tested with Python 3.9+. +This package has been tested with Python 3.10+. For a more complete view of Azure libraries, see the [azure sdk python release](https://aka.ms/azsdk/python/all). ## _Disclaimer_ @@ -12,7 +12,7 @@ _Azure SDK Python packages support for Python 2.7 has ended 01 January 2022. For ### Prerequisites -- Python 3.9+ is required to use this package. +- Python 3.10+ is required to use this package. - [Azure subscription](https://azure.microsoft.com/free/) ### Install the package @@ -24,7 +24,7 @@ pip install azure-identity ### Authentication -By default, [Azure Active Directory](https://aka.ms/awps/aad) token authentication depends on correct configuration of the following environment variables. +By default, [Microsoft Entra](https://learn.microsoft.com/entra/fundamentals/what-is-entra) token authentication depends on correct configuration of the following environment variables. - `AZURE_CLIENT_ID` for Azure client ID. - `AZURE_TENANT_ID` for Azure tenant ID. diff --git a/sdk/relationships/azure-mgmt-relationships/_metadata.json b/sdk/relationships/azure-mgmt-relationships/_metadata.json index 533c754c49f8..1e0785129ed5 100644 --- a/sdk/relationships/azure-mgmt-relationships/_metadata.json +++ b/sdk/relationships/azure-mgmt-relationships/_metadata.json @@ -1,10 +1,11 @@ { - "apiVersion": "2023-09-01-preview", + "apiVersion": "2026-03-01-preview", "apiVersions": { - "Microsoft.Relationships": "2023-09-01-preview" + "Microsoft.Relationships": "2026-03-01-preview" }, - "commit": "fe03e53383d9c9c97ec22a65abd1d8c18e401abe", + "commit": "2831f359f052615c26675394fd3939cf6ca92a3b", "repository_url": "https://github.com/Azure/azure-rest-api-specs", - "typespec_src": "specification/relationships/Relationships.Management", - "emitterVersion": "0.61.2" + "typespec_src": "specification/relationships/resource-manager/Microsoft.Relationships/Relationships", + "emitterVersion": "0.63.3", + "httpClientPythonVersion": "^0.35.1" } \ No newline at end of file diff --git a/sdk/relationships/azure-mgmt-relationships/api.md b/sdk/relationships/azure-mgmt-relationships/api.md new file mode 100644 index 000000000000..6baa9330ddab --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/api.md @@ -0,0 +1,760 @@ +```py +namespace azure.mgmt.relationships + + class azure.mgmt.relationships.RelationshipsMgmtClient: implements ContextManager + contains_relationships: ContainsRelationshipsOperations + dependency_of_relationships: DependencyOfRelationshipsOperations + operations: Operations + service_group_member_relationships: ServiceGroupMemberRelationshipsOperations + + def __init__( + self, + credential: TokenCredential, + subscription_id: str, + base_url: Optional[str] = None, + *, + api_version: str = ..., + cloud_setting: Optional[AzureClouds] = ..., + polling_interval: Optional[int] = ..., + **kwargs: Any + ) -> None: ... + + def close(self) -> None: ... + + def send_request( + self, + request: HttpRequest, + *, + stream: bool = False, + **kwargs: Any + ) -> HttpResponse: ... + + +namespace azure.mgmt.relationships.aio + + class azure.mgmt.relationships.aio.RelationshipsMgmtClient: implements AsyncContextManager + contains_relationships: ContainsRelationshipsOperations + dependency_of_relationships: DependencyOfRelationshipsOperations + operations: Operations + service_group_member_relationships: ServiceGroupMemberRelationshipsOperations + + def __init__( + self, + credential: AsyncTokenCredential, + subscription_id: str, + base_url: Optional[str] = None, + *, + api_version: str = ..., + cloud_setting: Optional[AzureClouds] = ..., + polling_interval: Optional[int] = ..., + **kwargs: Any + ) -> None: ... + + async def close(self) -> None: ... + + def send_request( + self, + request: HttpRequest, + *, + stream: bool = False, + **kwargs: Any + ) -> Awaitable[AsyncHttpResponse]: ... + + +namespace azure.mgmt.relationships.aio.operations + + class azure.mgmt.relationships.aio.operations.ContainsRelationshipsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'subscription_id', 'resource_group_name', 'filter', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_resource_group( + self, + resource_group_name: str, + *, + filter: Optional[str] = ..., + **kwargs: Any + ) -> AsyncItemPaged[ContainsRelationship]: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'subscription_id', 'filter', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_subscription( + self, + *, + filter: Optional[str] = ..., + **kwargs: Any + ) -> AsyncItemPaged[ContainsRelationship]: ... + + + class azure.mgmt.relationships.aio.operations.DependencyOfRelationshipsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: DependencyOfRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[DependencyOfRelationship]: ... + + @overload + async def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: DependencyOfRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[DependencyOfRelationship]: ... + + @overload + async def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[DependencyOfRelationship]: ... + + @distributed_trace_async + async def begin_delete( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> AsyncLROPoller[None]: ... + + @distributed_trace_async + async def get( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> DependencyOfRelationship: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'resource_uri', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_parent( + self, + resource_uri: str, + **kwargs: Any + ) -> AsyncItemPaged[DependencyOfRelationship]: ... + + + class azure.mgmt.relationships.aio.operations.Operations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace + def list(self, **kwargs: Any) -> AsyncItemPaged[Operation]: ... + + + class azure.mgmt.relationships.aio.operations.ServiceGroupMemberRelationshipsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + async def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: ServiceGroupMemberRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[ServiceGroupMemberRelationship]: ... + + @overload + async def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: ServiceGroupMemberRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[ServiceGroupMemberRelationship]: ... + + @overload + async def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[ServiceGroupMemberRelationship]: ... + + @distributed_trace_async + async def begin_delete( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> AsyncLROPoller[None]: ... + + @distributed_trace_async + async def get( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> ServiceGroupMemberRelationship: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'resource_uri', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_parent( + self, + resource_uri: str, + **kwargs: Any + ) -> AsyncItemPaged[ServiceGroupMemberRelationship]: ... + + +namespace azure.mgmt.relationships.models + + class azure.mgmt.relationships.models.ActionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + INTERNAL = "Internal" + + + class azure.mgmt.relationships.models.ContainsRelationship(ExtensionResource): + id: str + name: str + properties: Optional[ContainsRelationshipProperties] + system_data: SystemData + type: str + + @overload + def __init__( + self, + *, + properties: Optional[ContainsRelationshipProperties] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.mgmt.relationships.models.ContainsRelationshipProperties(_Model): + metadata: Optional[RelationshipMetadata] + origin_information: Optional[RelationshipOriginInformation] + provisioning_state: Optional[Union[str, ProvisioningState]] + source_id: Optional[str] + target_id: str + target_tenant: Optional[str] + + + class azure.mgmt.relationships.models.CreatedByType(str, Enum, metaclass=CaseInsensitiveEnumMeta): + APPLICATION = "Application" + KEY = "Key" + MANAGED_IDENTITY = "ManagedIdentity" + USER = "User" + + + class azure.mgmt.relationships.models.DependencyOfRelationship(ExtensionResource): + id: str + name: str + properties: Optional[DependencyOfRelationshipProperties] + system_data: SystemData + type: str + + @overload + def __init__( + self, + *, + properties: Optional[DependencyOfRelationshipProperties] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.mgmt.relationships.models.DependencyOfRelationshipProperties(_Model): + metadata: Optional[RelationshipMetadata] + origin_information: Optional[RelationshipOriginInformation] + provisioning_state: Optional[Union[str, ProvisioningState]] + source_id: Optional[str] + target_id: str + target_tenant: Optional[str] + + @overload + def __init__( + self, + *, + target_id: str, + target_tenant: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.mgmt.relationships.models.ErrorAdditionalInfo(_Model): + info: Optional[Any] + type: Optional[str] + + + class azure.mgmt.relationships.models.ErrorDetail(_Model): + additional_info: Optional[list[ErrorAdditionalInfo]] + code: Optional[str] + details: Optional[list[ErrorDetail]] + message: Optional[str] + target: Optional[str] + + + class azure.mgmt.relationships.models.ErrorResponse(_Model): + error: Optional[ErrorDetail] + + @overload + def __init__( + self, + *, + error: Optional[ErrorDetail] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.mgmt.relationships.models.ExtensionResource(Resource): + id: str + name: str + system_data: SystemData + type: str + + + class azure.mgmt.relationships.models.Operation(_Model): + action_type: Optional[Union[str, ActionType]] + display: Optional[OperationDisplay] + is_data_action: Optional[bool] + name: Optional[str] + origin: Optional[Union[str, Origin]] + + @overload + def __init__( + self, + *, + display: Optional[OperationDisplay] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.mgmt.relationships.models.OperationDisplay(_Model): + description: Optional[str] + operation: Optional[str] + provider: Optional[str] + resource: Optional[str] + + + class azure.mgmt.relationships.models.Origin(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SYSTEM = "system" + USER = "user" + USER_SYSTEM = "user,system" + + + class azure.mgmt.relationships.models.ProvisioningState(str, Enum, metaclass=CaseInsensitiveEnumMeta): + ACCEPTED = "Accepted" + CANCELED = "Canceled" + DELETING = "Deleting" + FAILED = "Failed" + PROVISIONING = "Provisioning" + SUCCEEDED = "Succeeded" + UPDATING = "Updating" + + + class azure.mgmt.relationships.models.RelationshipMetadata(_Model): + source_type: str + target_type: str + + + class azure.mgmt.relationships.models.RelationshipOriginInformation(_Model): + discovery_engine: Optional[str] + relationship_origin_type: Union[str, RelationshipOrigins] + + + class azure.mgmt.relationships.models.RelationshipOrigins(str, Enum, metaclass=CaseInsensitiveEnumMeta): + SERVICE_EXPLICITLY_CREATED = "ServiceExplicitlyCreated" + SYSTEM_DISCOVERED_BY_RULE = "SystemDiscoveredByRule" + USER_DISCOVERED_BY_RULE = "UserDiscoveredByRule" + USER_EXPLICITLY_CREATED = "UserExplicitlyCreated" + + + class azure.mgmt.relationships.models.Resource(_Model): + id: Optional[str] + name: Optional[str] + system_data: Optional[SystemData] + type: Optional[str] + + + class azure.mgmt.relationships.models.ServiceGroupMemberRelationship(ExtensionResource): + id: str + name: str + properties: Optional[ServiceGroupMemberRelationshipPropertiesV2] + system_data: SystemData + type: str + + @overload + def __init__( + self, + *, + properties: Optional[ServiceGroupMemberRelationshipPropertiesV2] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.mgmt.relationships.models.ServiceGroupMemberRelationshipPropertiesV2(_Model): + metadata: Optional[RelationshipMetadata] + origin_information: Optional[RelationshipOriginInformation] + provisioning_state: Optional[Union[str, ProvisioningState]] + source_id: str + source_tenant: Optional[str] + target_id: Optional[str] + + @overload + def __init__( + self, + *, + source_id: str, + source_tenant: Optional[str] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + + class azure.mgmt.relationships.models.SystemData(_Model): + created_at: Optional[datetime] + created_by: Optional[str] + created_by_type: Optional[Union[str, CreatedByType]] + last_modified_at: Optional[datetime] + last_modified_by: Optional[str] + last_modified_by_type: Optional[Union[str, CreatedByType]] + + @overload + def __init__( + self, + *, + created_at: Optional[datetime] = ..., + created_by: Optional[str] = ..., + created_by_type: Optional[Union[str, CreatedByType]] = ..., + last_modified_at: Optional[datetime] = ..., + last_modified_by: Optional[str] = ..., + last_modified_by_type: Optional[Union[str, CreatedByType]] = ... + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: ... + + +namespace azure.mgmt.relationships.operations + + class azure.mgmt.relationships.operations.ContainsRelationshipsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'subscription_id', 'resource_group_name', 'filter', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_resource_group( + self, + resource_group_name: str, + *, + filter: Optional[str] = ..., + **kwargs: Any + ) -> ItemPaged[ContainsRelationship]: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'subscription_id', 'filter', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_subscription( + self, + *, + filter: Optional[str] = ..., + **kwargs: Any + ) -> ItemPaged[ContainsRelationship]: ... + + + class azure.mgmt.relationships.operations.DependencyOfRelationshipsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: DependencyOfRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[DependencyOfRelationship]: ... + + @overload + def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: DependencyOfRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[DependencyOfRelationship]: ... + + @overload + def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[DependencyOfRelationship]: ... + + @distributed_trace + def begin_delete( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> LROPoller[None]: ... + + @distributed_trace + def get( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> DependencyOfRelationship: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'resource_uri', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_parent( + self, + resource_uri: str, + **kwargs: Any + ) -> ItemPaged[DependencyOfRelationship]: ... + + + class azure.mgmt.relationships.operations.Operations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @distributed_trace + def list(self, **kwargs: Any) -> ItemPaged[Operation]: ... + + + class azure.mgmt.relationships.operations.ServiceGroupMemberRelationshipsOperations: + + def __init__( + self, + *args, + **kwargs + ) -> None: ... + + @overload + def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: ServiceGroupMemberRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[ServiceGroupMemberRelationship]: ... + + @overload + def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: ServiceGroupMemberRelationship, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[ServiceGroupMemberRelationship]: ... + + @overload + def begin_create_or_update( + self, + resource_uri: str, + name: str, + resource: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[ServiceGroupMemberRelationship]: ... + + @distributed_trace + def begin_delete( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> LROPoller[None]: ... + + @distributed_trace + def get( + self, + resource_uri: str, + name: str, + **kwargs: Any + ) -> ServiceGroupMemberRelationship: ... + + @distributed_trace + @api_version_validation(method_added_on='2026-03-01-preview', params_added_on={'2026-03-01-preview': ['api_version', 'resource_uri', 'accept']}, api_versions_list=['2026-03-01-preview']) + def list_by_parent( + self, + resource_uri: str, + **kwargs: Any + ) -> ItemPaged[ServiceGroupMemberRelationship]: ... + + +namespace azure.mgmt.relationships.types + + class azure.mgmt.relationships.types.DependencyOfRelationship(ExtensionResource): + key "id": str + key "name": str + key "properties": ForwardRef('DependencyOfRelationshipProperties', module='types') + key "systemData": ForwardRef('SystemData', module='types') + key "type": str + id: str + name: str + properties: DependencyOfRelationshipProperties + systemData: SystemData + type: str + + + class azure.mgmt.relationships.types.DependencyOfRelationshipProperties(TypedDict, total=False): + key "metadata": ForwardRef('RelationshipMetadata', module='types') + key "originInformation": ForwardRef('RelationshipOriginInformation', module='types') + key "provisioningState": Union[str, ProvisioningState] + key "sourceId": str + key "targetId": Required[str] + key "targetTenant": str + metadata: RelationshipMetadata + originInformation: RelationshipOriginInformation + provisioningState: Union[str, ProvisioningState] + sourceId: str + targetId: str + targetTenant: str + + + class azure.mgmt.relationships.types.ExtensionResource(Resource): + key "id": str + key "name": str + key "systemData": ForwardRef('SystemData', module='types') + key "type": str + id: str + name: str + systemData: SystemData + type: str + + + class azure.mgmt.relationships.types.RelationshipMetadata(TypedDict, total=False): + key "sourceType": Required[str] + key "targetType": Required[str] + sourceType: str + targetType: str + + + class azure.mgmt.relationships.types.RelationshipOriginInformation(TypedDict, total=False): + key "discoveryEngine": str + key "relationshipOriginType": Required[Union[str, RelationshipOrigins]] + discoveryEngine: str + relationshipOriginType: Union[str, RelationshipOrigins] + + + class azure.mgmt.relationships.types.Resource(TypedDict, total=False): + key "id": str + key "name": str + key "systemData": ForwardRef('SystemData', module='types') + key "type": str + id: str + name: str + systemData: SystemData + type: str + + + class azure.mgmt.relationships.types.ServiceGroupMemberRelationship(ExtensionResource): + key "id": str + key "name": str + key "properties": ForwardRef('ServiceGroupMemberRelationshipPropertiesV2', module='types') + key "systemData": ForwardRef('SystemData', module='types') + key "type": str + id: str + name: str + properties: ServiceGroupMemberRelationshipPropertiesV2 + systemData: SystemData + type: str + + + class azure.mgmt.relationships.types.ServiceGroupMemberRelationshipPropertiesV2(TypedDict, total=False): + key "metadata": ForwardRef('RelationshipMetadata', module='types') + key "originInformation": ForwardRef('RelationshipOriginInformation', module='types') + key "provisioningState": Union[str, ProvisioningState] + key "sourceId": Required[str] + key "sourceTenant": str + key "targetId": str + metadata: RelationshipMetadata + originInformation: RelationshipOriginInformation + provisioningState: Union[str, ProvisioningState] + sourceId: str + sourceTenant: str + targetId: str + + + class azure.mgmt.relationships.types.SystemData(TypedDict, total=False): + key "createdAt": str + key "createdBy": str + key "createdByType": Union[str, CreatedByType] + key "lastModifiedAt": str + key "lastModifiedBy": str + key "lastModifiedByType": Union[str, CreatedByType] + createdAt: str + createdBy: str + createdByType: Union[str, CreatedByType] + lastModifiedAt: str + lastModifiedBy: str + lastModifiedByType: Union[str, CreatedByType] + + +``` \ No newline at end of file diff --git a/sdk/relationships/azure-mgmt-relationships/api.metadata.yml b/sdk/relationships/azure-mgmt-relationships/api.metadata.yml new file mode 100644 index 000000000000..eb054ab4e7be --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/api.metadata.yml @@ -0,0 +1,3 @@ +apiMdSha256: 83f01bd830ca48b14b79e8aee234209989049d47ddc88959b504c1ce3cfc9d55 +parserVersion: 0.3.31 +pythonVersion: 3.13.14 diff --git a/sdk/relationships/azure-mgmt-relationships/apiview-properties.json b/sdk/relationships/azure-mgmt-relationships/apiview-properties.json index 1397d9d9e4cc..1df81f090b85 100644 --- a/sdk/relationships/azure-mgmt-relationships/apiview-properties.json +++ b/sdk/relationships/azure-mgmt-relationships/apiview-properties.json @@ -3,6 +3,8 @@ "CrossLanguageDefinitionId": { "azure.mgmt.relationships.models.Resource": "Azure.ResourceManager.CommonTypes.Resource", "azure.mgmt.relationships.models.ExtensionResource": "Azure.ResourceManager.CommonTypes.ExtensionResource", + "azure.mgmt.relationships.models.ContainsRelationship": "Microsoft.Relationships.ContainsRelationship", + "azure.mgmt.relationships.models.ContainsRelationshipProperties": "Microsoft.Relationships.ContainsRelationshipProperties", "azure.mgmt.relationships.models.DependencyOfRelationship": "Microsoft.Relationships.DependencyOfRelationship", "azure.mgmt.relationships.models.DependencyOfRelationshipProperties": "Microsoft.Relationships.DependencyOfRelationshipProperties", "azure.mgmt.relationships.models.ErrorAdditionalInfo": "Azure.ResourceManager.CommonTypes.ErrorAdditionalInfo", @@ -13,7 +15,7 @@ "azure.mgmt.relationships.models.RelationshipMetadata": "Microsoft.Relationships.RelationshipMetadata", "azure.mgmt.relationships.models.RelationshipOriginInformation": "Microsoft.Relationships.RelationshipOriginInformation", "azure.mgmt.relationships.models.ServiceGroupMemberRelationship": "Microsoft.Relationships.ServiceGroupMemberRelationship", - "azure.mgmt.relationships.models.ServiceGroupMemberRelationshipProperties": "Microsoft.Relationships.ServiceGroupMemberRelationshipProperties", + "azure.mgmt.relationships.models.ServiceGroupMemberRelationshipPropertiesV2": "Microsoft.Relationships.ServiceGroupMemberRelationshipPropertiesV2", "azure.mgmt.relationships.models.SystemData": "Azure.ResourceManager.CommonTypes.SystemData", "azure.mgmt.relationships.models.Origin": "Azure.ResourceManager.CommonTypes.Origin", "azure.mgmt.relationships.models.ActionType": "Azure.ResourceManager.CommonTypes.ActionType", @@ -28,11 +30,20 @@ "azure.mgmt.relationships.aio.operations.DependencyOfRelationshipsOperations.get": "Microsoft.Relationships.DependencyOfRelationships.get", "azure.mgmt.relationships.operations.DependencyOfRelationshipsOperations.begin_delete": "Microsoft.Relationships.DependencyOfRelationships.delete", "azure.mgmt.relationships.aio.operations.DependencyOfRelationshipsOperations.begin_delete": "Microsoft.Relationships.DependencyOfRelationships.delete", + "azure.mgmt.relationships.operations.DependencyOfRelationshipsOperations.list_by_parent": "Microsoft.Relationships.DependencyOfRelationships.listByParent", + "azure.mgmt.relationships.aio.operations.DependencyOfRelationshipsOperations.list_by_parent": "Microsoft.Relationships.DependencyOfRelationships.listByParent", "azure.mgmt.relationships.operations.ServiceGroupMemberRelationshipsOperations.begin_create_or_update": "Microsoft.Relationships.ServiceGroupMemberRelationships.createOrUpdate", "azure.mgmt.relationships.aio.operations.ServiceGroupMemberRelationshipsOperations.begin_create_or_update": "Microsoft.Relationships.ServiceGroupMemberRelationships.createOrUpdate", "azure.mgmt.relationships.operations.ServiceGroupMemberRelationshipsOperations.get": "Microsoft.Relationships.ServiceGroupMemberRelationships.get", "azure.mgmt.relationships.aio.operations.ServiceGroupMemberRelationshipsOperations.get": "Microsoft.Relationships.ServiceGroupMemberRelationships.get", "azure.mgmt.relationships.operations.ServiceGroupMemberRelationshipsOperations.begin_delete": "Microsoft.Relationships.ServiceGroupMemberRelationships.delete", - "azure.mgmt.relationships.aio.operations.ServiceGroupMemberRelationshipsOperations.begin_delete": "Microsoft.Relationships.ServiceGroupMemberRelationships.delete" - } + "azure.mgmt.relationships.aio.operations.ServiceGroupMemberRelationshipsOperations.begin_delete": "Microsoft.Relationships.ServiceGroupMemberRelationships.delete", + "azure.mgmt.relationships.operations.ServiceGroupMemberRelationshipsOperations.list_by_parent": "Microsoft.Relationships.ServiceGroupMemberRelationships.listByParent", + "azure.mgmt.relationships.aio.operations.ServiceGroupMemberRelationshipsOperations.list_by_parent": "Microsoft.Relationships.ServiceGroupMemberRelationships.listByParent", + "azure.mgmt.relationships.operations.ContainsRelationshipsOperations.list_by_subscription": "Microsoft.Relationships.ContainsRelationships.listBySubscription", + "azure.mgmt.relationships.aio.operations.ContainsRelationshipsOperations.list_by_subscription": "Microsoft.Relationships.ContainsRelationships.listBySubscription", + "azure.mgmt.relationships.operations.ContainsRelationshipsOperations.list_by_resource_group": "Microsoft.Relationships.ContainsRelationships.listByResourceGroup", + "azure.mgmt.relationships.aio.operations.ContainsRelationshipsOperations.list_by_resource_group": "Microsoft.Relationships.ContainsRelationships.listByResourceGroup" + }, + "CrossLanguageVersion": "5fecff0ecbaa" } \ No newline at end of file diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_client.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_client.py index 8e3a4c1c89ee..8cd8065416ee 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_client.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_client.py @@ -7,8 +7,8 @@ # -------------------------------------------------------------------------- from copy import deepcopy +import sys from typing import Any, Optional, TYPE_CHECKING, cast -from typing_extensions import Self from azure.core.pipeline import policies from azure.core.rest import HttpRequest, HttpResponse @@ -19,14 +19,24 @@ from ._configuration import RelationshipsMgmtClientConfiguration from ._utils.serialization import Deserializer, Serializer -from .operations import DependencyOfRelationshipsOperations, Operations, ServiceGroupMemberRelationshipsOperations +from .operations import ( + ContainsRelationshipsOperations, + DependencyOfRelationshipsOperations, + Operations, + ServiceGroupMemberRelationshipsOperations, +) + +if sys.version_info >= (3, 11): + from typing import Self +else: + from typing_extensions import Self # type: ignore if TYPE_CHECKING: from azure.core import AzureClouds from azure.core.credentials import TokenCredential -class RelationshipsMgmtClient: +class RelationshipsMgmtClient: # pylint: disable=docstring-keyword-should-match-keyword-only """Microsoft.Relationships Resource Provider management API. :ivar operations: Operations operations @@ -37,16 +47,22 @@ class RelationshipsMgmtClient: :ivar service_group_member_relationships: ServiceGroupMemberRelationshipsOperations operations :vartype service_group_member_relationships: azure.mgmt.relationships.operations.ServiceGroupMemberRelationshipsOperations + :ivar contains_relationships: ContainsRelationshipsOperations operations + :vartype contains_relationships: + azure.mgmt.relationships.operations.ContainsRelationshipsOperations :param credential: Credential used to authenticate requests to the service. Required. :type credential: ~azure.core.credentials.TokenCredential + :param subscription_id: The ID of the target subscription. The value must be an UUID. Required. + :type subscription_id: str :param base_url: Service host. Default value is None. :type base_url: str :keyword cloud_setting: The cloud setting for which to get the ARM endpoint. Default value is None. :paramtype cloud_setting: ~azure.core.AzureClouds :keyword api_version: The API version to use for this operation. Known values are - "2023-09-01-preview". Default value is "2023-09-01-preview". Note that overriding this default - value may result in unsupported behavior. + "2026-03-01-preview" and None. Default value is None. If not set, the operation's default API + version will be used. Note that overriding this default value may result in unsupported + behavior. :paramtype api_version: str :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. @@ -55,6 +71,7 @@ class RelationshipsMgmtClient: def __init__( self, credential: "TokenCredential", + subscription_id: str, base_url: Optional[str] = None, *, cloud_setting: Optional["AzureClouds"] = None, @@ -68,6 +85,7 @@ def __init__( credential_scopes = kwargs.pop("credential_scopes", _endpoints["credential_scopes"]) self._config = RelationshipsMgmtClientConfiguration( credential=credential, + subscription_id=subscription_id, base_url=cast(str, base_url), cloud_setting=cloud_setting, credential_scopes=credential_scopes, @@ -104,6 +122,9 @@ def __init__( self.service_group_member_relationships = ServiceGroupMemberRelationshipsOperations( self._client, self._config, self._serialize, self._deserialize ) + self.contains_relationships = ContainsRelationshipsOperations( + self._client, self._config, self._serialize, self._deserialize + ) def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: """Runs the network request through the client's chained policies. diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_configuration.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_configuration.py index 49c556ae670f..f99e596340f5 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_configuration.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_configuration.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -18,7 +19,7 @@ from azure.core.credentials import TokenCredential -class RelationshipsMgmtClientConfiguration: # pylint: disable=too-many-instance-attributes +class RelationshipsMgmtClientConfiguration: # pylint: disable=too-many-instance-attributes,docstring-keyword-should-match-keyword-only """Configuration for RelationshipsMgmtClient. Note that all parameters used to create this instance are saved as instance @@ -26,30 +27,37 @@ class RelationshipsMgmtClientConfiguration: # pylint: disable=too-many-instance :param credential: Credential used to authenticate requests to the service. Required. :type credential: ~azure.core.credentials.TokenCredential + :param subscription_id: The ID of the target subscription. The value must be an UUID. Required. + :type subscription_id: str :param base_url: Service host. Default value is "https://management.azure.com". :type base_url: str :param cloud_setting: The cloud setting for which to get the ARM endpoint. Default value is None. :type cloud_setting: ~azure.core.AzureClouds :keyword api_version: The API version to use for this operation. Known values are - "2023-09-01-preview". Default value is "2023-09-01-preview". Note that overriding this default - value may result in unsupported behavior. + "2026-03-01-preview" and None. Default value is None. If not set, the operation's default API + version will be used. Note that overriding this default value may result in unsupported + behavior. :paramtype api_version: str """ def __init__( self, credential: "TokenCredential", + subscription_id: str, base_url: str = "https://management.azure.com", cloud_setting: Optional["AzureClouds"] = None, **kwargs: Any ) -> None: - api_version: str = kwargs.pop("api_version", "2023-09-01-preview") + api_version: str = kwargs.pop("api_version", "2026-03-01-preview") if credential is None: raise ValueError("Parameter 'credential' must not be None.") + if subscription_id is None: + raise ValueError("Parameter 'subscription_id' must not be None.") self.credential = credential + self.subscription_id = subscription_id self.base_url = base_url self.cloud_setting = cloud_setting self.api_version = api_version diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/model_base.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/model_base.py index 7b7f8ba67b53..35d5fc024978 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/model_base.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/model_base.py @@ -23,14 +23,19 @@ from json import JSONEncoder import xml.etree.ElementTree as ET from collections.abc import MutableMapping -from typing_extensions import Self import isodate from azure.core.exceptions import DeserializationError from azure.core import CaseInsensitiveEnumMeta from azure.core.pipeline import PipelineResponse from azure.core.serialization import _Null + from azure.core.rest import HttpResponse +if sys.version_info >= (3, 11): + from typing import Self +else: + from typing_extensions import Self + _LOGGER = logging.getLogger(__name__) __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"] @@ -104,6 +109,29 @@ def _serialize_bytes(o, format: typing.Optional[str] = None) -> str: return encoded +def _serialize_duration(td: timedelta, format: typing.Optional[str] = None): + """Serialize a timedelta to its wire representation. + + For the ``seconds``/``milliseconds`` encodings the value is converted to a + numeric value, otherwise it falls back to an ISO 8601 duration string. + + :param timedelta td: The timedelta to serialize. + :param str format: The duration encoding format. + :rtype: int or float or str + :return: serialized duration + """ + seconds = td.total_seconds() + if format == "duration-seconds-int": + return int(seconds) + if format == "duration-seconds-float": + return seconds + if format == "duration-milliseconds-int": + return int(seconds * 1000) + if format == "duration-milliseconds-float": + return seconds * 1000 + return _timedelta_as_isostr(td) + + def _serialize_datetime(o, format: typing.Optional[str] = None): if hasattr(o, "year") and hasattr(o, "hour"): if format == "rfc7231": @@ -130,7 +158,15 @@ def _is_readonly(p): class SdkJSONEncoder(JSONEncoder): - """A JSON encoder that's capable of serializing datetime objects and bytes.""" + """A JSON encoder that's capable of serializing datetime objects and bytes. + + :param args: Additional positional arguments passed to the base ``JSONEncoder``. + :type args: typing.Any + :keyword exclude_readonly: Whether to exclude readonly properties. Defaults to False. + :paramtype exclude_readonly: bool + :keyword format: The format to use for serialization. Defaults to None. + :paramtype format: typing.Optional[str] + """ def __init__(self, *args, exclude_readonly: bool = False, format: typing.Optional[str] = None, **kwargs): super().__init__(*args, **kwargs) @@ -296,6 +332,12 @@ def _deserialize_duration(attr): return isodate.parse_duration(attr) +def _deserialize_duration_numeric(attr, unit): + if isinstance(attr, timedelta): + return attr + return timedelta(**{unit: float(attr)}) + + def _deserialize_decimal(attr): if isinstance(attr, decimal.Decimal): return attr @@ -308,6 +350,12 @@ def _deserialize_int_as_str(attr): return int(attr) +def _deserialize_bool_as_str(attr): + if isinstance(attr, bool): + return attr + return attr.lower() == "true" + + _DESERIALIZE_MAPPING = { datetime: _deserialize_datetime, date: _deserialize_date, @@ -325,12 +373,18 @@ def _deserialize_int_as_str(attr): "unix-timestamp": _deserialize_datetime_unix_timestamp, "base64": _deserialize_bytes, "base64url": _deserialize_bytes_base64, + "duration-seconds-int": functools.partial(_deserialize_duration_numeric, unit="seconds"), + "duration-seconds-float": functools.partial(_deserialize_duration_numeric, unit="seconds"), + "duration-milliseconds-int": functools.partial(_deserialize_duration_numeric, unit="milliseconds"), + "duration-milliseconds-float": functools.partial(_deserialize_duration_numeric, unit="milliseconds"), } def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = None): if annotation is int and rf and rf._format == "str": return _deserialize_int_as_str + if annotation is bool and rf and rf._format == "str": + return _deserialize_bool_as_str if annotation is str and rf and rf._format in _ARRAY_ENCODE_MAPPING: return functools.partial(_deserialize_array_encoded, _ARRAY_ENCODE_MAPPING[rf._format]) if rf and rf._format: @@ -420,21 +474,21 @@ def __ne__(self, other: typing.Any) -> bool: def keys(self) -> typing.KeysView[str]: """ - :returns: a set-like object providing a view on D's keys + :returns: a set-like object providing a view on the mapping's keys :rtype: ~typing.KeysView """ return self._data.keys() def values(self) -> typing.ValuesView[typing.Any]: """ - :returns: an object providing a view on D's values + :returns: an object providing a view on the mapping's values :rtype: ~typing.ValuesView """ return self._data.values() def items(self) -> typing.ItemsView[str, typing.Any]: """ - :returns: set-like object providing a view on D's items + :returns: a set-like object providing a view on the mapping's items :rtype: ~typing.ItemsView """ return self._data.items() @@ -444,7 +498,7 @@ def get(self, key: str, default: typing.Any = None) -> typing.Any: Get the value for key if key is in the dictionary, else default. :param str key: The key to look up. :param any default: The value to return if key is not in the dictionary. Defaults to None - :returns: D[k] if k in D, else d. + :returns: The value for key if key is in the dictionary, else default. :rtype: any """ try: @@ -479,19 +533,19 @@ def popitem(self) -> tuple[str, typing.Any]: Removes and returns some (key, value) pair :returns: The (key, value) pair. :rtype: tuple - :raises KeyError: if D is empty. + :raises KeyError: if the dictionary is empty. """ return self._data.popitem() def clear(self) -> None: """ - Remove all items from D. + Remove all items from the dictionary. """ self._data.clear() def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: # pylint: disable=arguments-differ """ - Updates D from mapping/iterable E and F. + Update the dictionary from a mapping or an iterable of key-value pairs. :param any args: Either a mapping object or an iterable of key-value pairs. """ self._data.update(*args, **kwargs) @@ -504,10 +558,11 @@ def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... # pylint def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any: """ - Same as calling D.get(k, d), and setting D[k]=d if k not found + Return the value for key if key is in the dictionary; otherwise set the key to + default and return default. :param str key: The key to look up. :param any default: The value to set if key is not in the dictionary - :returns: D[k] if k in D, else d. + :returns: The value for key if key is in the dictionary, else default. :rtype: any """ if default is _UNSET: @@ -559,7 +614,7 @@ def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-m pass # Last, try datetime.timedelta try: - return _timedelta_as_isostr(o) + return _serialize_duration(o, format) except AttributeError: # This will be raised when it hits value.total_seconds in the method above pass @@ -585,6 +640,239 @@ def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typin return _serialize(value, rf._format) +# ============================================================================ +# Fast-path scalar deserializer functions for rest_field(deserializer=...) +# These are referenced from rest_field declarations to bypass the generic +# _deserialize -> _deserialize_with_callable chain. +# Only simple/primitive types — no models or container types. +# ============================================================================ + + +def _xml_deser_str(value): + if isinstance(value, ET.Element): + return value.text or "" + return str(value) if value is not None else None + + +def _xml_deser_int(value): + if isinstance(value, ET.Element): + return int(value.text) if value.text else None + return int(value) if value is not None else None + + +def _xml_deser_float(value): + if isinstance(value, ET.Element): + return float(value.text) if value.text else None + return float(value) if value is not None else None + + +def _xml_deser_bool(value): + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + if text in (True, False): + return text + return text.lower() == "true" + + +# pylint: disable=docstring-missing-param +def _xml_deser_bytes(value): + """Deserialize bytes from XML (base64).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_bytes(text) + + +def _xml_deser_bytes_base64url(value): + """Deserialize bytes from XML (base64url).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_bytes_base64(text) + + +def _xml_deser_datetime(value): + """Deserialize a datetime from XML (ISO 8601 / rfc3339).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_datetime(text) + + +def _xml_deser_datetime_rfc7231(value): + """Deserialize a datetime from XML (RFC7231 format).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_datetime_rfc7231(text) + + +def _xml_deser_datetime_unix_timestamp(value): + """Deserialize a datetime from XML (Unix timestamp).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_datetime_unix_timestamp(float(text)) + + +def _xml_deser_date(value): + """Deserialize a date from XML (ISO 8601).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_date(text) + + +def _xml_deser_time(value): + """Deserialize a time from XML (ISO 8601).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_time(text) + + +def _xml_deser_duration(value): + """Deserialize a timedelta from XML (ISO 8601 duration).""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_duration(text) + + +def _xml_deser_decimal(value): + """Deserialize a Decimal from XML.""" + if isinstance(value, ET.Element): + text = value.text + else: + text = value + if text is None: + return None + return _deserialize_decimal(text) + + +def _xml_deser_enum_or_str(enum_cls, value): + """Deserialize a Union[EnumType, str] from XML.""" + text = value.text if isinstance(value, ET.Element) else value + if text is None: + return None + try: + return enum_cls(text) + except ValueError: + return text + + +def _extract_xml_model_type(rf_type): + """Extract the concrete Model class from a resolved rf._type partial chain. + + Unwraps ``Optional[Model]`` and ``_deserialize_model(Model, ...)`` + wrappers. Only handles Model and Optional[Model] — other composite + types (List, Dict, Union, etc.) return None and fall through to the + generic ``_deserialize`` path at runtime. + """ + if rf_type is None: + return None + if isinstance(rf_type, type) and _is_model(rf_type): + return rf_type + if not isinstance(rf_type, functools.partial): + return None + func = rf_type.func + args = rf_type.args + if func is _deserialize_with_optional and args: + return _extract_xml_model_type(args[0]) + if func is _deserialize_model and args: + cls = args[0] + return cls if isinstance(cls, type) and _is_model(cls) else None + return None + + +def _build_xml_field_plan( # pylint: disable=docstring-missing-return, docstring-missing-rtype, unused-variable + cls, attr_to_rest_field: dict +) -> list: + """Build a precomputed XML field plan for fast _init_from_xml iteration. + + Called once per model class in __new__. Returns a list of tuples: + (rest_name, xml_name, kind, deser, rf_type, is_optional, items_name) + + kind: 0=wrapped, 1=attribute, 2=unwrapped, 3=text + + For Model and Optional[Model] fields that lack a scalar + ``_deserializer``, this function precomputes the Model class as the + deserializer so ``_init_from_xml`` can call ``ModelClass(element)`` + directly instead of going through the expensive + ``_get_deserialize_callable_from_annotation`` chain at runtime. + """ + model_meta = getattr(cls, "_xml", {}) + model_ns = model_meta.get("ns") or model_meta.get("namespace") + plan = [] + + for rf in attr_to_rest_field.values(): + prop_meta = getattr(rf, "_xml", {}) + deser = rf._deserializer + + 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 + + is_optional = rf._is_optional + + # For Model / Optional[Model] fields without a scalar deserializer, + # precompute the Model class as the deserializer. + if deser is None and rf._type is not None: + model_cls = _extract_xml_model_type(rf._type) + if model_cls is not None: + deser = model_cls + + if prop_meta.get("attribute", False): + plan.append((rf._rest_name, xml_name, 1, deser, rf._type, is_optional, None)) + elif prop_meta.get("unwrapped", False): + items_name = prop_meta.get("itemsName") + if items_name: + items_ns = prop_meta.get("itemsNs") + if items_ns is not None: + xml_ns = items_ns + if xml_ns: + items_name = "{" + xml_ns + "}" + items_name + else: + items_name = xml_name + plan.append((rf._rest_name, xml_name, 2, deser, rf._type, is_optional, items_name)) + elif prop_meta.get("text", False): + plan.append((rf._rest_name, xml_name, 3, deser, rf._type, is_optional, None)) + else: + plan.append((rf._rest_name, xml_name, 0, deser, rf._type, is_optional, None)) + + return plan + + +# pylint: enable=docstring-missing-param class Model(_MyMutableMapping): _is_model = True # label whether current class's _attr_to_rest_field has been calculated @@ -595,62 +883,10 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: class_name = self.__class__.__name__ if len(args) > 1: raise TypeError(f"{class_name}.__init__() takes 2 positional arguments but {len(args) + 1} were given") - dict_to_pass = { - rest_field._rest_name: rest_field._default - 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 + dict_to_pass: dict[str, typing.Any] = {} + 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()} @@ -667,8 +903,117 @@ def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: if v is not None } ) + # Apply client default values for fields the caller didn't set so that + # defaults are part of `_data` and therefore included during serialization. + for rf in self._attr_to_rest_field.values(): + if rf._default is _UNSET: + continue + if rf._rest_name in dict_to_pass: + continue + dict_to_pass[rf._rest_name] = _create_value(rf, rf._default) super().__init__(dict_to_pass) + def _init_from_xml( # pylint: disable=too-many-branches, too-many-statements + 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] = {} + existed_attr_keys: list[str] = [] + + field_plan = getattr(self, "_xml_field_plan", None) + if field_plan: + for rest_name, xml_name, kind, deser, rf_type, is_optional, items_name in field_plan: + if kind == 0: # wrapped element (most common) + item = element.find(xml_name) + if item is not None: + existed_attr_keys.append(xml_name) + if deser: + result[rest_name] = deser(item) + else: + result[rest_name] = _deserialize(rf_type, item) + elif kind == 1: # attribute + attr_val = element.get(xml_name) + if attr_val is not None: + existed_attr_keys.append(xml_name) + if deser: + result[rest_name] = deser(attr_val) + else: + result[rest_name] = attr_val + elif kind == 2: # unwrapped array + items = element.findall(items_name) # pyright: ignore + if len(items) > 0: + existed_attr_keys.append(items_name) + if deser: + result[rest_name] = deser(items) + else: + result[rest_name] = _deserialize(rf_type, items) + elif not is_optional: + existed_attr_keys.append(items_name) + result[rest_name] = [] + elif kind == 3: # text + if element.text is not None: + if deser: + result[rest_name] = deser(element.text) + else: + result[rest_name] = element.text + else: + 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 = _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): + _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 + 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__) @@ -693,6 +1038,9 @@ def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> Self: if not rf._rest_name_input: rf._rest_name_input = attr cls._attr_to_rest_field: dict[str, _RestField] = dict(attr_to_rest_field.items()) + # Build XML field plan for fast _init_from_xml (only for XML models) + if getattr(cls, "_xml", None): + cls._xml_field_plan = _build_xml_field_plan(cls, attr_to_rest_field) cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}") return super().__new__(cls) @@ -721,7 +1069,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 @@ -1067,6 +1415,7 @@ def __init__( format: typing.Optional[str] = None, is_multipart_file_input: bool = False, xml: typing.Optional[dict[str, typing.Any]] = None, + deserializer: typing.Optional[typing.Callable] = None, ): self._type = type self._rest_name_input = name @@ -1079,6 +1428,7 @@ def __init__( self._format = format self._is_multipart_file_input = is_multipart_file_input self._xml = xml if xml is not None else {} + self._deserializer = deserializer @property def _class_type(self) -> typing.Any: @@ -1098,7 +1448,10 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin # by this point, type and rest_name will have a value bc we default # them in __new__ of the Model class # Use _data.get() directly to avoid triggering __getitem__ which clears the cache - item = obj._data.get(self._rest_name) + item = obj._data.get(self._rest_name, _UNSET) + if item is _UNSET: + # Field not set by user; return the client default if one exists, otherwise None + return self._default if self._default is not _UNSET else None if item is None: return item if self._is_model: @@ -1111,7 +1464,11 @@ def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin # Return the value from _data directly (it's been deserialized in place) return obj._data.get(self._rest_name) - deserialized = _deserialize(self._type, _serialize(item, self._format), rf=self) + # Fast path: use _deserializer directly (avoids _serialize/_deserialize chain) + if self._deserializer: + deserialized = self._deserializer(item) + else: + deserialized = _deserialize(self._type, _serialize(item, self._format), rf=self) # For mutable types, store the deserialized value back in _data # so mutations directly affect _data @@ -1157,6 +1514,7 @@ def rest_field( format: typing.Optional[str] = None, is_multipart_file_input: bool = False, xml: typing.Optional[dict[str, typing.Any]] = None, + deserializer: typing.Optional[typing.Callable] = None, ) -> typing.Any: return _RestField( name=name, @@ -1166,6 +1524,7 @@ def rest_field( format=format, is_multipart_file_input=is_multipart_file_input, xml=xml, + deserializer=deserializer, ) @@ -1190,6 +1549,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 +1610,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 +1641,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 +1655,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 +1664,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 +1672,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 +1681,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 +1702,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 +1725,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) @@ -1323,6 +1758,8 @@ def _deserialize_xml( value: str, ) -> typing.Any: element = ET.fromstring(value) # nosec + if _is_model(deserializer): + return deserializer._deserialize(element, []) return _deserialize(deserializer, element) diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/serialization.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/serialization.py index 81ec1de5922b..ae08f9d89f74 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/serialization.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_utils/serialization.py @@ -39,11 +39,15 @@ import xml.etree.ElementTree as ET import isodate # type: ignore -from typing_extensions import Self from azure.core.exceptions import DeserializationError, SerializationError from azure.core.serialization import NULL as CoreNull +if sys.version_info >= (3, 11): + from typing import Self +else: + from typing_extensions import Self + _BOM = codecs.BOM_UTF8.decode(encoding="utf-8") JSON = MutableMapping[str, Any] @@ -476,7 +480,11 @@ def _decode_attribute_map_key(key): class Serializer: # pylint: disable=too-many-public-methods - """Request object model serializer.""" + """Request object model serializer. + + :param classes: Mapping of model names to model types, used to resolve models during serialization. + :type classes: typing.Optional[typing.Mapping[str, type]] + """ basic_types = {str: "str", int: "int", bool: "bool", float: "float"} @@ -516,6 +524,10 @@ def __init__(self, classes: Optional[Mapping[str, type]] = None) -> None: "rfc-1123": Serializer.serialize_rfc, "unix-time": Serializer.serialize_unix, "duration": Serializer.serialize_duration, + "duration-seconds-int": Serializer.serialize_duration_seconds_int, + "duration-seconds-float": Serializer.serialize_duration_seconds_float, + "duration-milliseconds-int": Serializer.serialize_duration_milliseconds_int, + "duration-milliseconds-float": Serializer.serialize_duration_milliseconds_float, "date": Serializer.serialize_date, "time": Serializer.serialize_time, "decimal": Serializer.serialize_decimal, @@ -1105,6 +1117,61 @@ def serialize_duration(attr, **kwargs): # pylint: disable=unused-argument attr = isodate.parse_duration(attr) return isodate.duration_isoformat(attr) + @staticmethod + def _serialize_duration_numeric(attr, scale, as_int): + """Serialize a TimeDelta into a numeric value scaled to the wire unit. + + :param TimeDelta attr: Object to be serialized. + :param int scale: Multiplier applied to total seconds (1 for seconds, 1000 for milliseconds). + :param bool as_int: Whether to truncate the result to an int. + :rtype: int or float + :return: serialized duration + """ + if isinstance(attr, str): + attr = isodate.parse_duration(attr) + value = attr.total_seconds() * scale if isinstance(attr, datetime.timedelta) else attr + return int(value) if as_int else float(value) + + @staticmethod + def serialize_duration_seconds_int(attr, **kwargs): # pylint: disable=unused-argument + """Serialize TimeDelta object into an integer number of seconds. + + :param TimeDelta attr: Object to be serialized. + :rtype: int + :return: serialized duration + """ + return Serializer._serialize_duration_numeric(attr, 1, True) + + @staticmethod + def serialize_duration_seconds_float(attr, **kwargs): # pylint: disable=unused-argument + """Serialize TimeDelta object into a floating point number of seconds. + + :param TimeDelta attr: Object to be serialized. + :rtype: float + :return: serialized duration + """ + return Serializer._serialize_duration_numeric(attr, 1, False) + + @staticmethod + def serialize_duration_milliseconds_int(attr, **kwargs): # pylint: disable=unused-argument + """Serialize TimeDelta object into an integer number of milliseconds. + + :param TimeDelta attr: Object to be serialized. + :rtype: int + :return: serialized duration + """ + return Serializer._serialize_duration_numeric(attr, 1000, True) + + @staticmethod + def serialize_duration_milliseconds_float(attr, **kwargs): # pylint: disable=unused-argument + """Serialize TimeDelta object into a floating point number of milliseconds. + + :param TimeDelta attr: Object to be serialized. + :rtype: float + :return: serialized duration + """ + return Serializer._serialize_duration_numeric(attr, 1000, False) + @staticmethod def serialize_rfc(attr, **kwargs): # pylint: disable=unused-argument """Serialize Datetime object into RFC-1123 formatted string. @@ -1377,6 +1444,10 @@ def __init__(self, classes: Optional[Mapping[str, type]] = None) -> None: "rfc-1123": Deserializer.deserialize_rfc, "unix-time": Deserializer.deserialize_unix, "duration": Deserializer.deserialize_duration, + "duration-seconds-int": Deserializer.deserialize_duration_seconds, + "duration-seconds-float": Deserializer.deserialize_duration_seconds, + "duration-milliseconds-int": Deserializer.deserialize_duration_milliseconds, + "duration-milliseconds-float": Deserializer.deserialize_duration_milliseconds, "date": Deserializer.deserialize_date, "time": Deserializer.deserialize_time, "decimal": Deserializer.deserialize_decimal, @@ -1389,6 +1460,10 @@ def __init__(self, classes: Optional[Mapping[str, type]] = None) -> None: } self.deserialize_expected_types = { "duration": (isodate.Duration, datetime.timedelta), + "duration-seconds-int": (isodate.Duration, datetime.timedelta), + "duration-seconds-float": (isodate.Duration, datetime.timedelta), + "duration-milliseconds-int": (isodate.Duration, datetime.timedelta), + "duration-milliseconds-float": (isodate.Duration, datetime.timedelta), "iso-8601": (datetime.datetime), } self.dependencies: dict[str, type] = dict(classes) if classes else {} @@ -1401,7 +1476,7 @@ def __init__(self, classes: Optional[Mapping[str, type]] = None) -> None: # Otherwise, result are unexpected self.additional_properties_detection = True - def __call__(self, target_obj, response_data, content_type=None): + def __call__(self, target_obj, response_data, content_type=None): # pylint: disable=too-many-return-statements """Call the deserializer to process a REST response. :param str target_obj: Target data type to deserialize to. @@ -1411,6 +1486,27 @@ def __call__(self, target_obj, response_data, content_type=None): :return: Deserialized object. :rtype: object """ + # Fast path for header deserialization: response_data is a plain str or None + # and target_obj is a simple scalar type. This avoids the expensive + # _unpack_content → _deserialize → _classify_target → deserialize_data chain. + if response_data is None: + return None + if target_obj == "str" and isinstance(response_data, str): + return response_data + if isinstance(response_data, str): + if target_obj == "int": + return int(response_data) + if target_obj == "bool": + if response_data in ("true", "1", "True"): + return True + if response_data in ("false", "0", "False"): + return False + return bool(response_data) + if target_obj == "rfc-1123": + return Deserializer.deserialize_rfc(response_data) + if target_obj == "bytearray": + return Deserializer.deserialize_bytearray(response_data) + data = self._unpack_content(response_data, content_type) return self._deserialize(target_obj, data) @@ -1929,6 +2025,48 @@ def deserialize_duration(attr): raise DeserializationError(msg) from err return duration + @staticmethod + def _deserialize_duration_numeric(attr, unit): + """Deserialize a numeric duration value into a TimeDelta object. + + :param float attr: response value to be deserialized. + :param str unit: The wire unit, used as the ``timedelta`` keyword + (``"seconds"`` or ``"milliseconds"``). + :return: Deserialized duration + :rtype: TimeDelta + :raises DeserializationError: if value is invalid. + """ + if isinstance(attr, ET.Element): + attr = attr.text + try: + duration = datetime.timedelta(**{unit: float(attr)}) # type: ignore + except (ValueError, OverflowError, TypeError) as err: + msg = "Cannot deserialize duration object." + raise DeserializationError(msg) from err + return duration + + @staticmethod + def deserialize_duration_seconds(attr): + """Deserialize a numeric number of seconds into a TimeDelta object. + + :param float attr: response value to be deserialized. + :return: Deserialized duration + :rtype: TimeDelta + :raises DeserializationError: if value is invalid. + """ + return Deserializer._deserialize_duration_numeric(attr, "seconds") + + @staticmethod + def deserialize_duration_milliseconds(attr): + """Deserialize a numeric number of milliseconds into a TimeDelta object. + + :param float attr: response value to be deserialized. + :return: Deserialized duration + :rtype: TimeDelta + :raises DeserializationError: if value is invalid. + """ + return Deserializer._deserialize_duration_numeric(attr, "milliseconds") + @staticmethod def deserialize_date(attr): """Deserialize ISO-8601 formatted string into Date object. diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_validation.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_validation.py new file mode 100644 index 000000000000..f5af3a4eb8a2 --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_validation.py @@ -0,0 +1,66 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import functools + + +def api_version_validation(**kwargs): + params_added_on = kwargs.pop("params_added_on", {}) + method_added_on = kwargs.pop("method_added_on", "") + api_versions_list = kwargs.pop("api_versions_list", []) + + def _index_with_default(value: str, default: int = -1) -> int: + """Get the index of value in lst, or return default if not found. + + :param value: The value to search for in the api_versions_list. + :type value: str + :param default: The default value to return if the value is not found. + :type default: int + :return: The index of the value in the list, or the default value if not found. + :rtype: int + """ + try: + return api_versions_list.index(value) + except ValueError: + return default + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + # this assumes the client has an _api_version attribute + client = args[0] + client_api_version = client._config.api_version # pylint: disable=protected-access + except AttributeError: + return func(*args, **kwargs) + + if _index_with_default(method_added_on) > _index_with_default(client_api_version): + raise ValueError( + f"'{func.__name__}' is not available in API version " + f"{client_api_version}. Pass service API version {method_added_on} or newer to your client." + ) + + unsupported = { + parameter: api_version + for api_version, parameters in params_added_on.items() + for parameter in parameters + if parameter in kwargs and _index_with_default(api_version) > _index_with_default(client_api_version) + } + if unsupported: + raise ValueError( + "".join( + [ + f"'{param}' is not available in API version {client_api_version}. " + f"Use service API version {version} or newer.\n" + for param, version in unsupported.items() + ] + ) + ) + return func(*args, **kwargs) + + return wrapper + + return decorator diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_version.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_version.py index be71c81bd282..bbcd28b4aa67 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_version.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/_version.py @@ -6,4 +6,4 @@ # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -VERSION = "1.0.0b1" +VERSION = "1.0.0b2" diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_client.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_client.py index 6f5740cec155..d21ba023182a 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_client.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_client.py @@ -7,8 +7,8 @@ # -------------------------------------------------------------------------- from copy import deepcopy +import sys from typing import Any, Awaitable, Optional, TYPE_CHECKING, cast -from typing_extensions import Self from azure.core.pipeline import policies from azure.core.rest import AsyncHttpResponse, HttpRequest @@ -19,14 +19,24 @@ from .._utils.serialization import Deserializer, Serializer from ._configuration import RelationshipsMgmtClientConfiguration -from .operations import DependencyOfRelationshipsOperations, Operations, ServiceGroupMemberRelationshipsOperations +from .operations import ( + ContainsRelationshipsOperations, + DependencyOfRelationshipsOperations, + Operations, + ServiceGroupMemberRelationshipsOperations, +) + +if sys.version_info >= (3, 11): + from typing import Self +else: + from typing_extensions import Self # type: ignore if TYPE_CHECKING: from azure.core import AzureClouds from azure.core.credentials_async import AsyncTokenCredential -class RelationshipsMgmtClient: +class RelationshipsMgmtClient: # pylint: disable=docstring-keyword-should-match-keyword-only """Microsoft.Relationships Resource Provider management API. :ivar operations: Operations operations @@ -37,16 +47,22 @@ class RelationshipsMgmtClient: :ivar service_group_member_relationships: ServiceGroupMemberRelationshipsOperations operations :vartype service_group_member_relationships: azure.mgmt.relationships.aio.operations.ServiceGroupMemberRelationshipsOperations + :ivar contains_relationships: ContainsRelationshipsOperations operations + :vartype contains_relationships: + azure.mgmt.relationships.aio.operations.ContainsRelationshipsOperations :param credential: Credential used to authenticate requests to the service. Required. :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :param subscription_id: The ID of the target subscription. The value must be an UUID. Required. + :type subscription_id: str :param base_url: Service host. Default value is None. :type base_url: str :keyword cloud_setting: The cloud setting for which to get the ARM endpoint. Default value is None. :paramtype cloud_setting: ~azure.core.AzureClouds :keyword api_version: The API version to use for this operation. Known values are - "2023-09-01-preview". Default value is "2023-09-01-preview". Note that overriding this default - value may result in unsupported behavior. + "2026-03-01-preview" and None. Default value is None. If not set, the operation's default API + version will be used. Note that overriding this default value may result in unsupported + behavior. :paramtype api_version: str :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. @@ -55,6 +71,7 @@ class RelationshipsMgmtClient: def __init__( self, credential: "AsyncTokenCredential", + subscription_id: str, base_url: Optional[str] = None, *, cloud_setting: Optional["AzureClouds"] = None, @@ -68,6 +85,7 @@ def __init__( credential_scopes = kwargs.pop("credential_scopes", _endpoints["credential_scopes"]) self._config = RelationshipsMgmtClientConfiguration( credential=credential, + subscription_id=subscription_id, base_url=cast(str, base_url), cloud_setting=cloud_setting, credential_scopes=credential_scopes, @@ -106,6 +124,9 @@ def __init__( self.service_group_member_relationships = ServiceGroupMemberRelationshipsOperations( self._client, self._config, self._serialize, self._deserialize ) + self.contains_relationships = ContainsRelationshipsOperations( + self._client, self._config, self._serialize, self._deserialize + ) def send_request( self, request: HttpRequest, *, stream: bool = False, **kwargs: Any diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_configuration.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_configuration.py index 0f766d7864fa..8cb2cb489cde 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_configuration.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/_configuration.py @@ -1,3 +1,4 @@ +# pylint: disable=line-too-long,useless-suppression # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -18,7 +19,7 @@ from azure.core.credentials_async import AsyncTokenCredential -class RelationshipsMgmtClientConfiguration: # pylint: disable=too-many-instance-attributes +class RelationshipsMgmtClientConfiguration: # pylint: disable=too-many-instance-attributes,docstring-keyword-should-match-keyword-only """Configuration for RelationshipsMgmtClient. Note that all parameters used to create this instance are saved as instance @@ -26,30 +27,37 @@ class RelationshipsMgmtClientConfiguration: # pylint: disable=too-many-instance :param credential: Credential used to authenticate requests to the service. Required. :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :param subscription_id: The ID of the target subscription. The value must be an UUID. Required. + :type subscription_id: str :param base_url: Service host. Default value is "https://management.azure.com". :type base_url: str :param cloud_setting: The cloud setting for which to get the ARM endpoint. Default value is None. :type cloud_setting: ~azure.core.AzureClouds :keyword api_version: The API version to use for this operation. Known values are - "2023-09-01-preview". Default value is "2023-09-01-preview". Note that overriding this default - value may result in unsupported behavior. + "2026-03-01-preview" and None. Default value is None. If not set, the operation's default API + version will be used. Note that overriding this default value may result in unsupported + behavior. :paramtype api_version: str """ def __init__( self, credential: "AsyncTokenCredential", + subscription_id: str, base_url: str = "https://management.azure.com", cloud_setting: Optional["AzureClouds"] = None, **kwargs: Any ) -> None: - api_version: str = kwargs.pop("api_version", "2023-09-01-preview") + api_version: str = kwargs.pop("api_version", "2026-03-01-preview") if credential is None: raise ValueError("Parameter 'credential' must not be None.") + if subscription_id is None: + raise ValueError("Parameter 'subscription_id' must not be None.") self.credential = credential + self.subscription_id = subscription_id self.base_url = base_url self.cloud_setting = cloud_setting self.api_version = api_version diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/__init__.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/__init__.py index 4d82f2aaa938..b82f5c6828f9 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/__init__.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/__init__.py @@ -15,6 +15,7 @@ from ._operations import Operations # type: ignore from ._operations import DependencyOfRelationshipsOperations # type: ignore from ._operations import ServiceGroupMemberRelationshipsOperations # type: ignore +from ._operations import ContainsRelationshipsOperations # type: ignore from ._patch import __all__ as _patch_all from ._patch import * @@ -24,6 +25,7 @@ "Operations", "DependencyOfRelationshipsOperations", "ServiceGroupMemberRelationshipsOperations", + "ContainsRelationshipsOperations", ] __all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore _patch_sdk() diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/_operations.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/_operations.py index 94caeaf05b91..1eeac7fde899 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/_operations.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/aio/operations/_operations.py @@ -33,27 +33,31 @@ from azure.mgmt.core.exceptions import ARMErrorFormat from azure.mgmt.core.polling.async_arm_polling import AsyncARMPolling -from ... import models as _models +from ... import models as _models, types as _types from ..._utils.model_base import SdkJSONEncoder, _deserialize, _failsafe_deserialize from ..._utils.serialization import Deserializer, Serializer +from ..._validation import api_version_validation from ...operations._operations import ( + build_contains_relationships_list_by_resource_group_request, + build_contains_relationships_list_by_subscription_request, build_dependency_of_relationships_create_or_update_request, build_dependency_of_relationships_delete_request, build_dependency_of_relationships_get_request, + build_dependency_of_relationships_list_by_parent_request, build_operations_list_request, build_service_group_member_relationships_create_or_update_request, build_service_group_member_relationships_delete_request, build_service_group_member_relationships_get_request, + build_service_group_member_relationships_list_by_parent_request, ) from .._configuration import RelationshipsMgmtClientConfiguration T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, dict[str, Any]], Any]] -JSON = MutableMapping[str, Any] List = list -class Operations: +class Operations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. @@ -117,7 +121,10 @@ def prepare_request(next_link=None): ) _next_request_params["api-version"] = self._config.api_version _request = HttpRequest( - "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, ) path_format_arguments = { "endpoint": self._serialize.url( @@ -160,7 +167,7 @@ async def get_next(next_link=None): return AsyncItemPaged(get_next, extract_data) -class DependencyOfRelationshipsOperations: +class DependencyOfRelationshipsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. @@ -181,7 +188,7 @@ async def _create_or_update_initial( self, resource_uri: str, name: str, - resource: Union[_models.DependencyOfRelationship, JSON, IO[bytes]], + resource: Union[_models.DependencyOfRelationship, _types.DependencyOfRelationship, IO[bytes]], **kwargs: Any ) -> AsyncIterator[bytes]: error_map: MutableMapping = { @@ -284,7 +291,13 @@ async def begin_create_or_update( @overload async def begin_create_or_update( - self, resource_uri: str, name: str, resource: JSON, *, content_type: str = "application/json", **kwargs: Any + self, + resource_uri: str, + name: str, + resource: _types.DependencyOfRelationship, + *, + content_type: str = "application/json", + **kwargs: Any ) -> AsyncLROPoller[_models.DependencyOfRelationship]: """Create a DependencyOfRelationship. @@ -294,7 +307,7 @@ async def begin_create_or_update( :param name: Name of dependencyOf relationship. Required. :type name: str :param resource: Resource create parameters. Required. - :type resource: JSON + :type resource: ~azure.mgmt.relationships.types.DependencyOfRelationship :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -339,7 +352,7 @@ async def begin_create_or_update( self, resource_uri: str, name: str, - resource: Union[_models.DependencyOfRelationship, JSON, IO[bytes]], + resource: Union[_models.DependencyOfRelationship, _types.DependencyOfRelationship, IO[bytes]], **kwargs: Any ) -> AsyncLROPoller[_models.DependencyOfRelationship]: """Create a DependencyOfRelationship. @@ -349,9 +362,10 @@ async def begin_create_or_update( :type resource_uri: str :param name: Name of dependencyOf relationship. Required. :type name: str - :param resource: Resource create parameters. Is one of the following types: - DependencyOfRelationship, JSON, IO[bytes] Required. - :type resource: ~azure.mgmt.relationships.models.DependencyOfRelationship or JSON or IO[bytes] + :param resource: Resource create parameters. Is either a DependencyOfRelationship type or a + IO[bytes] type. Required. + :type resource: ~azure.mgmt.relationships.models.DependencyOfRelationship or + ~azure.mgmt.relationships.types.DependencyOfRelationship or IO[bytes] :return: An instance of AsyncLROPoller that returns DependencyOfRelationship. The DependencyOfRelationship is compatible with MutableMapping :rtype: @@ -590,8 +604,110 @@ def get_long_running_output(pipeline_response): # pylint: disable=inconsistent- ) return AsyncLROPoller[None](self._client, raw_result, get_long_running_output, polling_method) # type: ignore + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={"2026-03-01-preview": ["api_version", "resource_uri", "accept"]}, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_parent(self, resource_uri: str, **kwargs: Any) -> AsyncItemPaged["_models.DependencyOfRelationship"]: + """List DependencyOfRelationship resources by parent. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource. + Required. + :type resource_uri: str + :return: An iterator like instance of DependencyOfRelationship + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.relationships.models.DependencyOfRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DependencyOfRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_dependency_of_relationships_list_by_parent_request( + resource_uri=resource_uri, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DependencyOfRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) -class ServiceGroupMemberRelationshipsOperations: # pylint: disable=name-too-long + +class ServiceGroupMemberRelationshipsOperations: # pylint: disable=docstring-missing-param,name-too-long """ .. warning:: **DO NOT** instantiate this class directly. @@ -612,7 +728,7 @@ async def _create_or_update_initial( self, resource_uri: str, name: str, - resource: Union[_models.ServiceGroupMemberRelationship, JSON, IO[bytes]], + resource: Union[_models.ServiceGroupMemberRelationship, _types.ServiceGroupMemberRelationship, IO[bytes]], **kwargs: Any ) -> AsyncIterator[bytes]: error_map: MutableMapping = { @@ -715,7 +831,13 @@ async def begin_create_or_update( @overload async def begin_create_or_update( - self, resource_uri: str, name: str, resource: JSON, *, content_type: str = "application/json", **kwargs: Any + self, + resource_uri: str, + name: str, + resource: _types.ServiceGroupMemberRelationship, + *, + content_type: str = "application/json", + **kwargs: Any ) -> AsyncLROPoller[_models.ServiceGroupMemberRelationship]: """Create a ServiceGroupMemberRelationship. @@ -725,7 +847,7 @@ async def begin_create_or_update( :param name: Name of ServiceGroupMember relationship. Required. :type name: str :param resource: Resource create parameters. Required. - :type resource: JSON + :type resource: ~azure.mgmt.relationships.types.ServiceGroupMemberRelationship :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -770,7 +892,7 @@ async def begin_create_or_update( self, resource_uri: str, name: str, - resource: Union[_models.ServiceGroupMemberRelationship, JSON, IO[bytes]], + resource: Union[_models.ServiceGroupMemberRelationship, _types.ServiceGroupMemberRelationship, IO[bytes]], **kwargs: Any ) -> AsyncLROPoller[_models.ServiceGroupMemberRelationship]: """Create a ServiceGroupMemberRelationship. @@ -780,10 +902,10 @@ async def begin_create_or_update( :type resource_uri: str :param name: Name of ServiceGroupMember relationship. Required. :type name: str - :param resource: Resource create parameters. Is one of the following types: - ServiceGroupMemberRelationship, JSON, IO[bytes] Required. - :type resource: ~azure.mgmt.relationships.models.ServiceGroupMemberRelationship or JSON or - IO[bytes] + :param resource: Resource create parameters. Is either a ServiceGroupMemberRelationship type or + a IO[bytes] type. Required. + :type resource: ~azure.mgmt.relationships.models.ServiceGroupMemberRelationship or + ~azure.mgmt.relationships.types.ServiceGroupMemberRelationship or IO[bytes] :return: An instance of AsyncLROPoller that returns ServiceGroupMemberRelationship. The ServiceGroupMemberRelationship is compatible with MutableMapping :rtype: @@ -1021,3 +1143,341 @@ def get_long_running_output(pipeline_response): # pylint: disable=inconsistent- deserialization_callback=get_long_running_output, ) return AsyncLROPoller[None](self._client, raw_result, get_long_running_output, polling_method) # type: ignore + + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={"2026-03-01-preview": ["api_version", "resource_uri", "accept"]}, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_parent( + self, resource_uri: str, **kwargs: Any + ) -> AsyncItemPaged["_models.ServiceGroupMemberRelationship"]: + """List ServiceGroupMemberRelationship resources by parent. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource. + Required. + :type resource_uri: str + :return: An iterator like instance of ServiceGroupMemberRelationship + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.relationships.models.ServiceGroupMemberRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ServiceGroupMemberRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_service_group_member_relationships_list_by_parent_request( + resource_uri=resource_uri, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ServiceGroupMemberRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + +class ContainsRelationshipsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.mgmt.relationships.aio.RelationshipsMgmtClient`'s + :attr:`contains_relationships` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: RelationshipsMgmtClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={"2026-03-01-preview": ["api_version", "subscription_id", "filter", "accept"]}, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_subscription( + self, *, filter: Optional[str] = None, **kwargs: Any + ) -> AsyncItemPaged["_models.ContainsRelationship"]: + """List ContainsRelationship resources by subscription ID. + + :keyword filter: Filters the results by target resource type. Example: + properties.metadata.targetType eq 'Microsoft.Compute/virtualMachines'. Default value is None. + :paramtype filter: str + :return: An iterator like instance of ContainsRelationship + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.relationships.models.ContainsRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ContainsRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_contains_relationships_list_by_subscription_request( + subscription_id=self._config.subscription_id, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ContainsRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={ + "2026-03-01-preview": ["api_version", "subscription_id", "resource_group_name", "filter", "accept"] + }, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_resource_group( + self, resource_group_name: str, *, filter: Optional[str] = None, **kwargs: Any + ) -> AsyncItemPaged["_models.ContainsRelationship"]: + """List ContainsRelationship resources by resource group. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + Required. + :type resource_group_name: str + :keyword filter: Filters the results by target resource type. Example: + properties.metadata.targetType eq 'Microsoft.Compute/virtualMachines'. Default value is None. + :paramtype filter: str + :return: An iterator like instance of ContainsRelationship + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.relationships.models.ContainsRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ContainsRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_contains_relationships_list_by_resource_group_request( + resource_group_name=resource_group_name, + subscription_id=self._config.subscription_id, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ContainsRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/__init__.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/__init__.py index c069003b4624..fe48032b9d57 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/__init__.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/__init__.py @@ -14,6 +14,8 @@ from ._models import ( # type: ignore + ContainsRelationship, + ContainsRelationshipProperties, DependencyOfRelationship, DependencyOfRelationshipProperties, ErrorAdditionalInfo, @@ -26,7 +28,7 @@ RelationshipOriginInformation, Resource, ServiceGroupMemberRelationship, - ServiceGroupMemberRelationshipProperties, + ServiceGroupMemberRelationshipPropertiesV2, SystemData, ) @@ -42,6 +44,8 @@ from ._patch import patch_sdk as _patch_sdk __all__ = [ + "ContainsRelationship", + "ContainsRelationshipProperties", "DependencyOfRelationship", "DependencyOfRelationshipProperties", "ErrorAdditionalInfo", @@ -54,7 +58,7 @@ "RelationshipOriginInformation", "Resource", "ServiceGroupMemberRelationship", - "ServiceGroupMemberRelationshipProperties", + "ServiceGroupMemberRelationshipPropertiesV2", "SystemData", "ActionType", "CreatedByType", diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/_models.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/_models.py index 9161dc241f07..2c0b39475cec 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/_models.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/models/_models.py @@ -62,7 +62,85 @@ class ExtensionResource(Resource): """ -class DependencyOfRelationship(ExtensionResource): +class ContainsRelationship(ExtensionResource): # pylint: disable=docstring-keyword-should-match-keyword-only + """Defines a contains relationship resource. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :ivar system_data: Azure Resource Manager metadata containing createdBy and modifiedBy + information. + :vartype system_data: ~azure.mgmt.relationships.models.SystemData + :ivar properties: The resource-specific properties for this resource. + :vartype properties: ~azure.mgmt.relationships.models.ContainsRelationshipProperties + """ + + properties: Optional["_models.ContainsRelationshipProperties"] = rest_field( + visibility=["read", "create", "update", "delete", "query"] + ) + """The resource-specific properties for this resource.""" + + @overload + def __init__( + self, + *, + properties: Optional["_models.ContainsRelationshipProperties"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class ContainsRelationshipProperties(_Model): + """contains relationship properties. + + :ivar source_id: The relationship source resource id. Must be a subscription or resource group. + :vartype source_id: str + :ivar target_id: The relationship target resource id. Required. + :vartype target_id: str + :ivar target_tenant: The relationship target tenant id. + :vartype target_tenant: str + :ivar origin_information: Information about the origin of the relationship. + :vartype origin_information: ~azure.mgmt.relationships.models.RelationshipOriginInformation + :ivar metadata: Metadata about the relationship. + :vartype metadata: ~azure.mgmt.relationships.models.RelationshipMetadata + :ivar provisioning_state: The provisioning state of the relationship. Known values are: + "Succeeded", "Failed", "Canceled", "Provisioning", "Updating", "Deleting", and "Accepted". + :vartype provisioning_state: str or ~azure.mgmt.relationships.models.ProvisioningState + """ + + source_id: Optional[str] = rest_field(name="sourceId", visibility=["read"]) + """The relationship source resource id. Must be a subscription or resource group.""" + target_id: str = rest_field(name="targetId", visibility=["read"]) + """The relationship target resource id. Required.""" + target_tenant: Optional[str] = rest_field(name="targetTenant", visibility=["read"]) + """The relationship target tenant id.""" + origin_information: Optional["_models.RelationshipOriginInformation"] = rest_field( + name="originInformation", visibility=["read"] + ) + """Information about the origin of the relationship.""" + metadata: Optional["_models.RelationshipMetadata"] = rest_field(visibility=["read"]) + """Metadata about the relationship.""" + provisioning_state: Optional[Union[str, "_models.ProvisioningState"]] = rest_field( + name="provisioningState", visibility=["read"] + ) + """The provisioning state of the relationship. Known values are: \"Succeeded\", \"Failed\", + \"Canceled\", \"Provisioning\", \"Updating\", \"Deleting\", and \"Accepted\".""" + + +class DependencyOfRelationship(ExtensionResource): # pylint: disable=docstring-keyword-should-match-keyword-only """Defines a dependencyOf relationship resource. :ivar id: Fully qualified resource ID for the resource. Ex - @@ -103,38 +181,38 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class DependencyOfRelationshipProperties(_Model): +class DependencyOfRelationshipProperties(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """dependencyOf relationship properties. - :ivar source_id: The relationship source resource id. Required. + :ivar source_id: The relationship source resource id. :vartype source_id: str :ivar target_id: The relationship target resource id. Required. :vartype target_id: str :ivar target_tenant: The relationship target tenant id. :vartype target_tenant: str - :ivar origin_information: Information about the origin of the relationship. Required. + :ivar origin_information: Information about the origin of the relationship. :vartype origin_information: ~azure.mgmt.relationships.models.RelationshipOriginInformation - :ivar metadata: Metadata about the relationship. Required. + :ivar metadata: Metadata about the relationship. :vartype metadata: ~azure.mgmt.relationships.models.RelationshipMetadata :ivar provisioning_state: The provisioning state of the relationship. Known values are: "Succeeded", "Failed", "Canceled", "Provisioning", "Updating", "Deleting", and "Accepted". :vartype provisioning_state: str or ~azure.mgmt.relationships.models.ProvisioningState """ - source_id: str = rest_field(name="sourceId", visibility=["read"]) - """The relationship source resource id. Required.""" + source_id: Optional[str] = rest_field(name="sourceId", visibility=["read"]) + """The relationship source resource id.""" target_id: str = rest_field(name="targetId", visibility=["read", "create", "update", "delete", "query"]) """The relationship target resource id. Required.""" target_tenant: Optional[str] = rest_field( name="targetTenant", visibility=["read", "create", "update", "delete", "query"] ) """The relationship target tenant id.""" - origin_information: "_models.RelationshipOriginInformation" = rest_field( + origin_information: Optional["_models.RelationshipOriginInformation"] = rest_field( name="originInformation", visibility=["read"] ) - """Information about the origin of the relationship. Required.""" - metadata: "_models.RelationshipMetadata" = rest_field(visibility=["read"]) - """Metadata about the relationship. Required.""" + """Information about the origin of the relationship.""" + metadata: Optional["_models.RelationshipMetadata"] = rest_field(visibility=["read"]) + """Metadata about the relationship.""" provisioning_state: Optional[Union[str, "_models.ProvisioningState"]] = rest_field( name="provisioningState", visibility=["read"] ) @@ -204,7 +282,7 @@ class ErrorDetail(_Model): """The error additional info.""" -class ErrorResponse(_Model): +class ErrorResponse(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Error response. :ivar error: The error object. @@ -232,7 +310,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class Operation(_Model): +class Operation(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """REST API Operation. :ivar name: The name of the operation, as per Resource-Based Access Control (RBAC). Examples: @@ -356,7 +434,7 @@ class RelationshipOriginInformation(_Model): """The name of the discovery engine that created the relationship.""" -class ServiceGroupMemberRelationship(ExtensionResource): +class ServiceGroupMemberRelationship(ExtensionResource): # pylint: disable=docstring-keyword-should-match-keyword-only """Defines a ServiceGroupMember relationship resource. :ivar id: Fully qualified resource ID for the resource. Ex - @@ -371,10 +449,11 @@ class ServiceGroupMemberRelationship(ExtensionResource): information. :vartype system_data: ~azure.mgmt.relationships.models.SystemData :ivar properties: The resource-specific properties for this resource. - :vartype properties: ~azure.mgmt.relationships.models.ServiceGroupMemberRelationshipProperties + :vartype properties: + ~azure.mgmt.relationships.models.ServiceGroupMemberRelationshipPropertiesV2 """ - properties: Optional["_models.ServiceGroupMemberRelationshipProperties"] = rest_field( + properties: Optional["_models.ServiceGroupMemberRelationshipPropertiesV2"] = rest_field( visibility=["read", "create", "update", "delete", "query"] ) """The resource-specific properties for this resource.""" @@ -383,7 +462,7 @@ class ServiceGroupMemberRelationship(ExtensionResource): def __init__( self, *, - properties: Optional["_models.ServiceGroupMemberRelationshipProperties"] = None, + properties: Optional["_models.ServiceGroupMemberRelationshipPropertiesV2"] = None, ) -> None: ... @overload @@ -397,38 +476,40 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class ServiceGroupMemberRelationshipProperties(_Model): +class ServiceGroupMemberRelationshipPropertiesV2( + _Model +): # pylint: disable=name-too-long,docstring-keyword-should-match-keyword-only """ServiceGroupMember relationship properties. - :ivar source_id: The relationship source resource id. Required. + :ivar source_id: The relationship source resource id. Must be a service group. Required. :vartype source_id: str - :ivar target_id: The relationship target resource id. Required. + :ivar target_id: The relationship target resource id. Server-derived from the scoped resource. :vartype target_id: str - :ivar target_tenant: The relationship target tenant id. - :vartype target_tenant: str - :ivar origin_information: Information about the origin of the relationship. Required. + :ivar source_tenant: The relationship source tenant id. + :vartype source_tenant: str + :ivar origin_information: Information about the origin of the relationship. :vartype origin_information: ~azure.mgmt.relationships.models.RelationshipOriginInformation - :ivar metadata: Metadata about the relationship. Required. + :ivar metadata: Metadata about the relationship. :vartype metadata: ~azure.mgmt.relationships.models.RelationshipMetadata :ivar provisioning_state: The provisioning state of the relationship. Known values are: "Succeeded", "Failed", "Canceled", "Provisioning", "Updating", "Deleting", and "Accepted". :vartype provisioning_state: str or ~azure.mgmt.relationships.models.ProvisioningState """ - source_id: str = rest_field(name="sourceId", visibility=["read"]) - """The relationship source resource id. Required.""" - target_id: str = rest_field(name="targetId", visibility=["read", "create", "update", "delete", "query"]) - """The relationship target resource id. Required.""" - target_tenant: Optional[str] = rest_field( - name="targetTenant", visibility=["read", "create", "update", "delete", "query"] + source_id: str = rest_field(name="sourceId", visibility=["read", "create", "update", "delete", "query"]) + """The relationship source resource id. Must be a service group. Required.""" + target_id: Optional[str] = rest_field(name="targetId", visibility=["read"]) + """The relationship target resource id. Server-derived from the scoped resource.""" + source_tenant: Optional[str] = rest_field( + name="sourceTenant", visibility=["read", "create", "update", "delete", "query"] ) - """The relationship target tenant id.""" - origin_information: "_models.RelationshipOriginInformation" = rest_field( + """The relationship source tenant id.""" + origin_information: Optional["_models.RelationshipOriginInformation"] = rest_field( name="originInformation", visibility=["read"] ) - """Information about the origin of the relationship. Required.""" - metadata: "_models.RelationshipMetadata" = rest_field(visibility=["read"]) - """Metadata about the relationship. Required.""" + """Information about the origin of the relationship.""" + metadata: Optional["_models.RelationshipMetadata"] = rest_field(visibility=["read"]) + """Metadata about the relationship.""" provisioning_state: Optional[Union[str, "_models.ProvisioningState"]] = rest_field( name="provisioningState", visibility=["read"] ) @@ -439,8 +520,8 @@ class ServiceGroupMemberRelationshipProperties(_Model): def __init__( self, *, - target_id: str, - target_tenant: Optional[str] = None, + source_id: str, + source_tenant: Optional[str] = None, ) -> None: ... @overload @@ -454,7 +535,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) -class SystemData(_Model): +class SystemData(_Model): # pylint: disable=docstring-keyword-should-match-keyword-only """Metadata pertaining to creation and last modification of the resource. :ivar created_by: The identity that created the resource. diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/__init__.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/__init__.py index 4d82f2aaa938..b82f5c6828f9 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/__init__.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/__init__.py @@ -15,6 +15,7 @@ from ._operations import Operations # type: ignore from ._operations import DependencyOfRelationshipsOperations # type: ignore from ._operations import ServiceGroupMemberRelationshipsOperations # type: ignore +from ._operations import ContainsRelationshipsOperations # type: ignore from ._patch import __all__ as _patch_all from ._patch import * @@ -24,6 +25,7 @@ "Operations", "DependencyOfRelationshipsOperations", "ServiceGroupMemberRelationshipsOperations", + "ContainsRelationshipsOperations", ] __all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore _patch_sdk() diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/_operations.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/_operations.py index 0c94dbd91fc9..934aaa94857e 100644 --- a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/_operations.py +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/operations/_operations.py @@ -32,14 +32,14 @@ from azure.mgmt.core.exceptions import ARMErrorFormat from azure.mgmt.core.polling.arm_polling import ARMPolling -from .. import models as _models +from .. import models as _models, types as _types from .._configuration import RelationshipsMgmtClientConfiguration from .._utils.model_base import SdkJSONEncoder, _deserialize, _failsafe_deserialize from .._utils.serialization import Deserializer, Serializer +from .._validation import api_version_validation T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, dict[str, Any]], Any]] -JSON = MutableMapping[str, Any] List = list _SERIALIZER = Serializer() @@ -50,7 +50,7 @@ def build_operations_list_request(**kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-09-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -72,7 +72,7 @@ def build_dependency_of_relationships_create_or_update_request( # pylint: disab _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-09-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -101,7 +101,7 @@ def build_dependency_of_relationships_get_request( # pylint: disable=name-too-l _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-09-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -127,7 +127,7 @@ def build_dependency_of_relationships_delete_request( # pylint: disable=name-to ) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-09-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) # Construct URL _url = "/{resourceUri}/providers/Microsoft.Relationships/dependencyOf/{name}" path_format_arguments = { @@ -143,6 +143,32 @@ def build_dependency_of_relationships_delete_request( # pylint: disable=name-to return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) +def build_dependency_of_relationships_list_by_parent_request( # pylint: disable=name-too-long + resource_uri: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/{resourceUri}/providers/Microsoft.Relationships/dependencyOf" + path_format_arguments = { + "resourceUri": _SERIALIZER.url("resource_uri", resource_uri, "str", skip_quote=True), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + def build_service_group_member_relationships_create_or_update_request( # pylint: disable=name-too-long resource_uri: str, name: str, **kwargs: Any ) -> HttpRequest: @@ -150,7 +176,7 @@ def build_service_group_member_relationships_create_or_update_request( # pylint _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-09-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -179,7 +205,7 @@ def build_service_group_member_relationships_get_request( # pylint: disable=nam _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-09-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) accept = _headers.pop("Accept", "application/json") # Construct URL @@ -205,7 +231,7 @@ def build_service_group_member_relationships_delete_request( # pylint: disable= ) -> HttpRequest: _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2023-09-01-preview")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) # Construct URL _url = "/{resourceUri}/providers/Microsoft.Relationships/serviceGroupMember/{name}" path_format_arguments = { @@ -221,7 +247,92 @@ def build_service_group_member_relationships_delete_request( # pylint: disable= return HttpRequest(method="DELETE", url=_url, params=_params, **kwargs) -class Operations: +def build_service_group_member_relationships_list_by_parent_request( # pylint: disable=name-too-long + resource_uri: str, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/{resourceUri}/providers/Microsoft.Relationships/serviceGroupMember" + path_format_arguments = { + "resourceUri": _SERIALIZER.url("resource_uri", resource_uri, "str", skip_quote=True), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_contains_relationships_list_by_subscription_request( # pylint: disable=name-too-long + subscription_id: str, *, filter: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/subscriptions/{subscriptionId}/providers/Microsoft.Relationships/contains" + path_format_arguments = { + "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if filter is not None: + _params["$filter"] = _SERIALIZER.query("filter", filter, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_contains_relationships_list_by_resource_group_request( # pylint: disable=name-too-long + resource_group_name: str, subscription_id: str, *, filter: Optional[str] = None, **kwargs: Any +) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2026-03-01-preview")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = ( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Relationships/contains" + ) + path_format_arguments = { + "subscriptionId": _SERIALIZER.url("subscription_id", subscription_id, "str"), + "resourceGroupName": _SERIALIZER.url("resource_group_name", resource_group_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore + + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if filter is not None: + _params["$filter"] = _SERIALIZER.query("filter", filter, "str") + + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +class Operations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. @@ -285,7 +396,10 @@ def prepare_request(next_link=None): ) _next_request_params["api-version"] = self._config.api_version _request = HttpRequest( - "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, ) path_format_arguments = { "endpoint": self._serialize.url( @@ -328,7 +442,7 @@ def get_next(next_link=None): return ItemPaged(get_next, extract_data) -class DependencyOfRelationshipsOperations: +class DependencyOfRelationshipsOperations: # pylint: disable=docstring-missing-param """ .. warning:: **DO NOT** instantiate this class directly. @@ -349,7 +463,7 @@ def _create_or_update_initial( self, resource_uri: str, name: str, - resource: Union[_models.DependencyOfRelationship, JSON, IO[bytes]], + resource: Union[_models.DependencyOfRelationship, _types.DependencyOfRelationship, IO[bytes]], **kwargs: Any ) -> Iterator[bytes]: error_map: MutableMapping = { @@ -452,7 +566,13 @@ def begin_create_or_update( @overload def begin_create_or_update( - self, resource_uri: str, name: str, resource: JSON, *, content_type: str = "application/json", **kwargs: Any + self, + resource_uri: str, + name: str, + resource: _types.DependencyOfRelationship, + *, + content_type: str = "application/json", + **kwargs: Any ) -> LROPoller[_models.DependencyOfRelationship]: """Create a DependencyOfRelationship. @@ -462,7 +582,7 @@ def begin_create_or_update( :param name: Name of dependencyOf relationship. Required. :type name: str :param resource: Resource create parameters. Required. - :type resource: JSON + :type resource: ~azure.mgmt.relationships.types.DependencyOfRelationship :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -507,7 +627,7 @@ def begin_create_or_update( self, resource_uri: str, name: str, - resource: Union[_models.DependencyOfRelationship, JSON, IO[bytes]], + resource: Union[_models.DependencyOfRelationship, _types.DependencyOfRelationship, IO[bytes]], **kwargs: Any ) -> LROPoller[_models.DependencyOfRelationship]: """Create a DependencyOfRelationship. @@ -517,9 +637,10 @@ def begin_create_or_update( :type resource_uri: str :param name: Name of dependencyOf relationship. Required. :type name: str - :param resource: Resource create parameters. Is one of the following types: - DependencyOfRelationship, JSON, IO[bytes] Required. - :type resource: ~azure.mgmt.relationships.models.DependencyOfRelationship or JSON or IO[bytes] + :param resource: Resource create parameters. Is either a DependencyOfRelationship type or a + IO[bytes] type. Required. + :type resource: ~azure.mgmt.relationships.models.DependencyOfRelationship or + ~azure.mgmt.relationships.types.DependencyOfRelationship or IO[bytes] :return: An instance of LROPoller that returns DependencyOfRelationship. The DependencyOfRelationship is compatible with MutableMapping :rtype: @@ -758,8 +879,109 @@ def get_long_running_output(pipeline_response): # pylint: disable=inconsistent- ) return LROPoller[None](self._client, raw_result, get_long_running_output, polling_method) # type: ignore + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={"2026-03-01-preview": ["api_version", "resource_uri", "accept"]}, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_parent(self, resource_uri: str, **kwargs: Any) -> ItemPaged["_models.DependencyOfRelationship"]: + """List DependencyOfRelationship resources by parent. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource. + Required. + :type resource_uri: str + :return: An iterator like instance of DependencyOfRelationship + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.relationships.models.DependencyOfRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.DependencyOfRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) -class ServiceGroupMemberRelationshipsOperations: # pylint: disable=name-too-long + def prepare_request(next_link=None): + if not next_link: + + _request = build_dependency_of_relationships_list_by_parent_request( + resource_uri=resource_uri, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.DependencyOfRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class ServiceGroupMemberRelationshipsOperations: # pylint: disable=docstring-missing-param,name-too-long """ .. warning:: **DO NOT** instantiate this class directly. @@ -780,7 +1002,7 @@ def _create_or_update_initial( self, resource_uri: str, name: str, - resource: Union[_models.ServiceGroupMemberRelationship, JSON, IO[bytes]], + resource: Union[_models.ServiceGroupMemberRelationship, _types.ServiceGroupMemberRelationship, IO[bytes]], **kwargs: Any ) -> Iterator[bytes]: error_map: MutableMapping = { @@ -883,7 +1105,13 @@ def begin_create_or_update( @overload def begin_create_or_update( - self, resource_uri: str, name: str, resource: JSON, *, content_type: str = "application/json", **kwargs: Any + self, + resource_uri: str, + name: str, + resource: _types.ServiceGroupMemberRelationship, + *, + content_type: str = "application/json", + **kwargs: Any ) -> LROPoller[_models.ServiceGroupMemberRelationship]: """Create a ServiceGroupMemberRelationship. @@ -893,7 +1121,7 @@ def begin_create_or_update( :param name: Name of ServiceGroupMember relationship. Required. :type name: str :param resource: Resource create parameters. Required. - :type resource: JSON + :type resource: ~azure.mgmt.relationships.types.ServiceGroupMemberRelationship :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str @@ -938,7 +1166,7 @@ def begin_create_or_update( self, resource_uri: str, name: str, - resource: Union[_models.ServiceGroupMemberRelationship, JSON, IO[bytes]], + resource: Union[_models.ServiceGroupMemberRelationship, _types.ServiceGroupMemberRelationship, IO[bytes]], **kwargs: Any ) -> LROPoller[_models.ServiceGroupMemberRelationship]: """Create a ServiceGroupMemberRelationship. @@ -948,10 +1176,10 @@ def begin_create_or_update( :type resource_uri: str :param name: Name of ServiceGroupMember relationship. Required. :type name: str - :param resource: Resource create parameters. Is one of the following types: - ServiceGroupMemberRelationship, JSON, IO[bytes] Required. - :type resource: ~azure.mgmt.relationships.models.ServiceGroupMemberRelationship or JSON or - IO[bytes] + :param resource: Resource create parameters. Is either a ServiceGroupMemberRelationship type or + a IO[bytes] type. Required. + :type resource: ~azure.mgmt.relationships.models.ServiceGroupMemberRelationship or + ~azure.mgmt.relationships.types.ServiceGroupMemberRelationship or IO[bytes] :return: An instance of LROPoller that returns ServiceGroupMemberRelationship. The ServiceGroupMemberRelationship is compatible with MutableMapping :rtype: @@ -1189,3 +1417,337 @@ def get_long_running_output(pipeline_response): # pylint: disable=inconsistent- deserialization_callback=get_long_running_output, ) return LROPoller[None](self._client, raw_result, get_long_running_output, polling_method) # type: ignore + + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={"2026-03-01-preview": ["api_version", "resource_uri", "accept"]}, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_parent(self, resource_uri: str, **kwargs: Any) -> ItemPaged["_models.ServiceGroupMemberRelationship"]: + """List ServiceGroupMemberRelationship resources by parent. + + :param resource_uri: The fully qualified Azure Resource manager identifier of the resource. + Required. + :type resource_uri: str + :return: An iterator like instance of ServiceGroupMemberRelationship + :rtype: + ~azure.core.paging.ItemPaged[~azure.mgmt.relationships.models.ServiceGroupMemberRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ServiceGroupMemberRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_service_group_member_relationships_list_by_parent_request( + resource_uri=resource_uri, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ServiceGroupMemberRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class ContainsRelationshipsOperations: # pylint: disable=docstring-missing-param + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.mgmt.relationships.RelationshipsMgmtClient`'s + :attr:`contains_relationships` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: RelationshipsMgmtClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={"2026-03-01-preview": ["api_version", "subscription_id", "filter", "accept"]}, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_subscription( + self, *, filter: Optional[str] = None, **kwargs: Any + ) -> ItemPaged["_models.ContainsRelationship"]: + """List ContainsRelationship resources by subscription ID. + + :keyword filter: Filters the results by target resource type. Example: + properties.metadata.targetType eq 'Microsoft.Compute/virtualMachines'. Default value is None. + :paramtype filter: str + :return: An iterator like instance of ContainsRelationship + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.relationships.models.ContainsRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ContainsRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_contains_relationships_list_by_subscription_request( + subscription_id=self._config.subscription_id, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ContainsRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + @distributed_trace + @api_version_validation( + method_added_on="2026-03-01-preview", + params_added_on={ + "2026-03-01-preview": ["api_version", "subscription_id", "resource_group_name", "filter", "accept"] + }, + api_versions_list=["2026-03-01-preview"], + ) + def list_by_resource_group( + self, resource_group_name: str, *, filter: Optional[str] = None, **kwargs: Any + ) -> ItemPaged["_models.ContainsRelationship"]: + """List ContainsRelationship resources by resource group. + + :param resource_group_name: The name of the resource group. The name is case insensitive. + Required. + :type resource_group_name: str + :keyword filter: Filters the results by target resource type. Example: + properties.metadata.targetType eq 'Microsoft.Compute/virtualMachines'. Default value is None. + :paramtype filter: str + :return: An iterator like instance of ContainsRelationship + :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.relationships.models.ContainsRelationship] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.ContainsRelationship]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_contains_relationships_list_by_resource_group_request( + resource_group_name=resource_group_name, + subscription_id=self._config.subscription_id, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", + urllib.parse.urljoin(next_link, _parsed_next_link.path), + headers=_headers, + params=_next_request_params, + ) + path_format_arguments = { + "endpoint": self._serialize.url( + "self._config.base_url", self._config.base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize( + List[_models.ContainsRelationship], + deserialized.get("value", []), + ) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize( + _models.ErrorResponse, + response, + ) + raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat) + + return pipeline_response + + return ItemPaged(get_next, extract_data) diff --git a/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/types.py b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/types.py new file mode 100644 index 000000000000..00b05f44a1ff --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/azure/mgmt/relationships/types.py @@ -0,0 +1,238 @@ +# pylint: disable=line-too-long,useless-suppression +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING, Union +from typing_extensions import Required, TypedDict + +if TYPE_CHECKING: + from .models import CreatedByType, ProvisioningState, RelationshipOrigins + + +class Resource(TypedDict, total=False): + """Resource. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :ivar systemData: Azure Resource Manager metadata containing createdBy and modifiedBy + information. + :vartype systemData: "SystemData" + """ + + id: str + """Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}.""" + name: str + """The name of the resource.""" + type: str + """The type of the resource. E.g. \"Microsoft.Compute/virtualMachines\" or + \"Microsoft.Storage/storageAccounts\".""" + systemData: "SystemData" + """Azure Resource Manager metadata containing createdBy and modifiedBy information.""" + + +class ExtensionResource(Resource): + """The base extension resource. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :ivar systemData: Azure Resource Manager metadata containing createdBy and modifiedBy + information. + :vartype systemData: "SystemData" + """ + + +class DependencyOfRelationship(ExtensionResource): + """Defines a dependencyOf relationship resource. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :ivar systemData: Azure Resource Manager metadata containing createdBy and modifiedBy + information. + :vartype systemData: "SystemData" + :ivar properties: The resource-specific properties for this resource. + :vartype properties: "DependencyOfRelationshipProperties" + """ + + properties: "DependencyOfRelationshipProperties" + """The resource-specific properties for this resource.""" + + +class DependencyOfRelationshipProperties(TypedDict, total=False): + """dependencyOf relationship properties. + + :ivar sourceId: The relationship source resource id. + :vartype sourceId: str + :ivar targetId: The relationship target resource id. Required. + :vartype targetId: str + :ivar targetTenant: The relationship target tenant id. + :vartype targetTenant: str + :ivar originInformation: Information about the origin of the relationship. + :vartype originInformation: "RelationshipOriginInformation" + :ivar metadata: Metadata about the relationship. + :vartype metadata: "RelationshipMetadata" + :ivar provisioningState: The provisioning state of the relationship. Known values are: + "Succeeded", "Failed", "Canceled", "Provisioning", "Updating", "Deleting", and "Accepted". + :vartype provisioningState: Union[str, "ProvisioningState"] + """ + + sourceId: str + """The relationship source resource id.""" + targetId: Required[str] + """The relationship target resource id. Required.""" + targetTenant: str + """The relationship target tenant id.""" + originInformation: "RelationshipOriginInformation" + """Information about the origin of the relationship.""" + metadata: "RelationshipMetadata" + """Metadata about the relationship.""" + provisioningState: Union[str, "ProvisioningState"] + """The provisioning state of the relationship. Known values are: \"Succeeded\", \"Failed\", + \"Canceled\", \"Provisioning\", \"Updating\", \"Deleting\", and \"Accepted\".""" + + +class RelationshipMetadata(TypedDict, total=False): + """Provides information about the relationship properties. + + :ivar sourceType: The type of the relationship source resource. Required. + :vartype sourceType: str + :ivar targetType: The type of the relationship target resource. Required. + :vartype targetType: str + """ + + sourceType: Required[str] + """The type of the relationship source resource. Required.""" + targetType: Required[str] + """The type of the relationship target resource. Required.""" + + +class RelationshipOriginInformation(TypedDict, total=False): + """Provides information about the origin of a relationship. + + :ivar relationshipOriginType: Identifies the origin type of the relationship. Required. Known + values are: "ServiceExplicitlyCreated", "SystemDiscoveredByRule", "UserExplicitlyCreated", and + "UserDiscoveredByRule". + :vartype relationshipOriginType: Union[str, "RelationshipOrigins"] + :ivar discoveryEngine: The name of the discovery engine that created the relationship. + :vartype discoveryEngine: str + """ + + relationshipOriginType: Required[Union[str, "RelationshipOrigins"]] + """Identifies the origin type of the relationship. Required. Known values are: + \"ServiceExplicitlyCreated\", \"SystemDiscoveredByRule\", \"UserExplicitlyCreated\", and + \"UserDiscoveredByRule\".""" + discoveryEngine: str + """The name of the discovery engine that created the relationship.""" + + +class ServiceGroupMemberRelationship(ExtensionResource): + """Defines a ServiceGroupMember relationship resource. + + :ivar id: Fully qualified resource ID for the resource. Ex - + /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}. + :vartype id: str + :ivar name: The name of the resource. + :vartype name: str + :ivar type: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or + "Microsoft.Storage/storageAccounts". + :vartype type: str + :ivar systemData: Azure Resource Manager metadata containing createdBy and modifiedBy + information. + :vartype systemData: "SystemData" + :ivar properties: The resource-specific properties for this resource. + :vartype properties: "ServiceGroupMemberRelationshipPropertiesV2" + """ + + properties: "ServiceGroupMemberRelationshipPropertiesV2" + """The resource-specific properties for this resource.""" + + +class ServiceGroupMemberRelationshipPropertiesV2(TypedDict, total=False): # pylint: disable=name-too-long + """ServiceGroupMember relationship properties. + + :ivar sourceId: The relationship source resource id. Must be a service group. Required. + :vartype sourceId: str + :ivar targetId: The relationship target resource id. Server-derived from the scoped resource. + :vartype targetId: str + :ivar sourceTenant: The relationship source tenant id. + :vartype sourceTenant: str + :ivar originInformation: Information about the origin of the relationship. + :vartype originInformation: "RelationshipOriginInformation" + :ivar metadata: Metadata about the relationship. + :vartype metadata: "RelationshipMetadata" + :ivar provisioningState: The provisioning state of the relationship. Known values are: + "Succeeded", "Failed", "Canceled", "Provisioning", "Updating", "Deleting", and "Accepted". + :vartype provisioningState: Union[str, "ProvisioningState"] + """ + + sourceId: Required[str] + """The relationship source resource id. Must be a service group. Required.""" + targetId: str + """The relationship target resource id. Server-derived from the scoped resource.""" + sourceTenant: str + """The relationship source tenant id.""" + originInformation: "RelationshipOriginInformation" + """Information about the origin of the relationship.""" + metadata: "RelationshipMetadata" + """Metadata about the relationship.""" + provisioningState: Union[str, "ProvisioningState"] + """The provisioning state of the relationship. Known values are: \"Succeeded\", \"Failed\", + \"Canceled\", \"Provisioning\", \"Updating\", \"Deleting\", and \"Accepted\".""" + + +class SystemData(TypedDict, total=False): + """Metadata pertaining to creation and last modification of the resource. + + :ivar createdBy: The identity that created the resource. + :vartype createdBy: str + :ivar createdByType: The type of identity that created the resource. Known values are: "User", + "Application", "ManagedIdentity", and "Key". + :vartype createdByType: Union[str, "CreatedByType"] + :ivar createdAt: The timestamp of resource creation (UTC). + :vartype createdAt: str + :ivar lastModifiedBy: The identity that last modified the resource. + :vartype lastModifiedBy: str + :ivar lastModifiedByType: The type of identity that last modified the resource. Known values + are: "User", "Application", "ManagedIdentity", and "Key". + :vartype lastModifiedByType: Union[str, "CreatedByType"] + :ivar lastModifiedAt: The timestamp of resource last modification (UTC). + :vartype lastModifiedAt: str + """ + + createdBy: str + """The identity that created the resource.""" + createdByType: Union[str, "CreatedByType"] + """The type of identity that created the resource. Known values are: \"User\", \"Application\", + \"ManagedIdentity\", and \"Key\".""" + createdAt: str + """The timestamp of resource creation (UTC).""" + lastModifiedBy: str + """The identity that last modified the resource.""" + lastModifiedByType: Union[str, "CreatedByType"] + """The type of identity that last modified the resource. Known values are: \"User\", + \"Application\", \"ManagedIdentity\", and \"Key\".""" + lastModifiedAt: str + """The timestamp of resource last modification (UTC).""" diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_resource_group.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_resource_group.py new file mode 100644 index 000000000000..2f9a8fddc4af --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_resource_group.py @@ -0,0 +1,42 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from azure.identity import DefaultAzureCredential + +from azure.mgmt.relationships import RelationshipsMgmtClient + +""" +# PREREQUISITES + pip install azure-identity + pip install azure-mgmt-relationships +# USAGE + python contains_relationships_list_by_resource_group.py + + Before run the sample, please set the values of the client ID, tenant ID and client secret + of the AAD application as environment variables: AZURE_CLIENT_ID, AZURE_TENANT_ID, + AZURE_CLIENT_SECRET. For more info about how to get the value, please see: + https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal +""" + + +def main(): + client = RelationshipsMgmtClient( + credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", + ) + + response = client.contains_relationships.list_by_resource_group( + resource_group_name="testrg", + ) + for item in response: + print(item) + + +# x-ms-original-file: 2026-03-01-preview/ContainsRelationships_ListByResourceGroup.json +if __name__ == "__main__": + main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_subscription.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_subscription.py new file mode 100644 index 000000000000..ce5160db2cf4 --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/contains_relationships_list_by_subscription.py @@ -0,0 +1,40 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from azure.identity import DefaultAzureCredential + +from azure.mgmt.relationships import RelationshipsMgmtClient + +""" +# PREREQUISITES + pip install azure-identity + pip install azure-mgmt-relationships +# USAGE + python contains_relationships_list_by_subscription.py + + Before run the sample, please set the values of the client ID, tenant ID and client secret + of the AAD application as environment variables: AZURE_CLIENT_ID, AZURE_TENANT_ID, + AZURE_CLIENT_SECRET. For more info about how to get the value, please see: + https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal +""" + + +def main(): + client = RelationshipsMgmtClient( + credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", + ) + + response = client.contains_relationships.list_by_subscription() + for item in response: + print(item) + + +# x-ms-original-file: 2026-03-01-preview/ContainsRelationships_ListBySubscription.json +if __name__ == "__main__": + main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_create_or_update.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_create_or_update.py index 67b101683aef..f29abbb62ae8 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_create_or_update.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_create_or_update.py @@ -28,6 +28,7 @@ def main(): client = RelationshipsMgmtClient( credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", ) response = client.dependency_of_relationships.begin_create_or_update( @@ -43,6 +44,6 @@ def main(): print(response) -# x-ms-original-file: 2023-09-01-preview/DependencyOfRelationships_CreateOrUpdate.json +# x-ms-original-file: 2026-03-01-preview/DependencyOfRelationships_CreateOrUpdate.json if __name__ == "__main__": main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_delete.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_delete.py index 2bb12e49658c..5b4edfe28fc9 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_delete.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_delete.py @@ -28,6 +28,7 @@ def main(): client = RelationshipsMgmtClient( credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", ) client.dependency_of_relationships.begin_delete( @@ -36,6 +37,6 @@ def main(): ).result() -# x-ms-original-file: 2023-09-01-preview/DependencyOfRelationships_Delete.json +# x-ms-original-file: 2026-03-01-preview/DependencyOfRelationships_Delete.json if __name__ == "__main__": main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_get.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_get.py index 3fec65904fed..6245442e473f 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_get.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_get.py @@ -28,6 +28,7 @@ def main(): client = RelationshipsMgmtClient( credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", ) response = client.dependency_of_relationships.get( @@ -37,6 +38,6 @@ def main(): print(response) -# x-ms-original-file: 2023-09-01-preview/DependencyOfRelationships_Get.json +# x-ms-original-file: 2026-03-01-preview/DependencyOfRelationships_Get.json if __name__ == "__main__": main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_list_by_parent.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_list_by_parent.py new file mode 100644 index 000000000000..6346a5e23b88 --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/dependency_of_relationships_list_by_parent.py @@ -0,0 +1,43 @@ +# pylint: disable=line-too-long,useless-suppression +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from azure.identity import DefaultAzureCredential + +from azure.mgmt.relationships import RelationshipsMgmtClient + +""" +# PREREQUISITES + pip install azure-identity + pip install azure-mgmt-relationships +# USAGE + python dependency_of_relationships_list_by_parent.py + + Before run the sample, please set the values of the client ID, tenant ID and client secret + of the AAD application as environment variables: AZURE_CLIENT_ID, AZURE_TENANT_ID, + AZURE_CLIENT_SECRET. For more info about how to get the value, please see: + https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal +""" + + +def main(): + client = RelationshipsMgmtClient( + credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", + ) + + response = client.dependency_of_relationships.list_by_parent( + resource_uri="subscriptions/a925f2f7-5c63-4b7b-8799-25a5f97bc3b2/resourceGroups/testrg/providers/Microsoft.DocumentDb/databaseAccounts/test-db-account", + ) + for item in response: + print(item) + + +# x-ms-original-file: 2026-03-01-preview/DependencyOfRelationships_ListByParent.json +if __name__ == "__main__": + main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/operations_list_maximum_set_gen.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/operations_list_maximum_set_gen.py index 02d0b189a267..8d0bdf04f87a 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_samples/operations_list_maximum_set_gen.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/operations_list_maximum_set_gen.py @@ -27,6 +27,7 @@ def main(): client = RelationshipsMgmtClient( credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", ) response = client.operations.list() @@ -34,6 +35,6 @@ def main(): print(item) -# x-ms-original-file: 2023-09-01-preview/Operations_List_MaximumSet_Gen.json +# x-ms-original-file: 2026-03-01-preview/Operations_List_MaximumSet_Gen.json if __name__ == "__main__": main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_create_or_update.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_create_or_update.py index b53a2714fb11..5eb583ff2b1a 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_create_or_update.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_create_or_update.py @@ -28,6 +28,7 @@ def main(): client = RelationshipsMgmtClient( credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", ) response = client.service_group_member_relationships.begin_create_or_update( @@ -35,14 +36,14 @@ def main(): name="sg1", resource={ "properties": { - "targetId": "/providers/Microsoft.Management/serviceGroups/sg1", - "targetTenant": "72f988bf-86f1-41af-91ab-2d7cd011db47", + "sourceId": "/providers/Microsoft.Management/serviceGroups/sg1", + "sourceTenant": "72f988bf-86f1-41af-91ab-2d7cd011db47", } }, ).result() print(response) -# x-ms-original-file: 2023-09-01-preview/ServiceGroupMemberRelationships_CreateOrUpdate.json +# x-ms-original-file: 2026-03-01-preview/ServiceGroupMemberRelationships_CreateOrUpdate.json if __name__ == "__main__": main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_delete.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_delete.py index 3bf5027416c2..61ebeeb9d855 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_delete.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_delete.py @@ -28,6 +28,7 @@ def main(): client = RelationshipsMgmtClient( credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", ) client.service_group_member_relationships.begin_delete( @@ -36,6 +37,6 @@ def main(): ).result() -# x-ms-original-file: 2023-09-01-preview/ServiceGroupMemberRelationships_Delete.json +# x-ms-original-file: 2026-03-01-preview/ServiceGroupMemberRelationships_Delete.json if __name__ == "__main__": main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_get.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_get.py index dc25dce618a8..bf91056171cd 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_get.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_get.py @@ -28,6 +28,7 @@ def main(): client = RelationshipsMgmtClient( credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", ) response = client.service_group_member_relationships.get( @@ -37,6 +38,6 @@ def main(): print(response) -# x-ms-original-file: 2023-09-01-preview/ServiceGroupMemberRelationships_Get.json +# x-ms-original-file: 2026-03-01-preview/ServiceGroupMemberRelationships_Get.json if __name__ == "__main__": main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_list_by_parent.py b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_list_by_parent.py new file mode 100644 index 000000000000..89ce11caa312 --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/generated_samples/service_group_member_relationships_list_by_parent.py @@ -0,0 +1,43 @@ +# pylint: disable=line-too-long,useless-suppression +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from azure.identity import DefaultAzureCredential + +from azure.mgmt.relationships import RelationshipsMgmtClient + +""" +# PREREQUISITES + pip install azure-identity + pip install azure-mgmt-relationships +# USAGE + python service_group_member_relationships_list_by_parent.py + + Before run the sample, please set the values of the client ID, tenant ID and client secret + of the AAD application as environment variables: AZURE_CLIENT_ID, AZURE_TENANT_ID, + AZURE_CLIENT_SECRET. For more info about how to get the value, please see: + https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal +""" + + +def main(): + client = RelationshipsMgmtClient( + credential=DefaultAzureCredential(), + subscription_id="SUBSCRIPTION_ID", + ) + + response = client.service_group_member_relationships.list_by_parent( + resource_uri="subscriptions/a925f2f7-5c63-4b7b-8799-25a5f97bc3b2/resourceGroups/testrg/providers/Microsoft.DocumentDb/databaseAccounts/test-db-account", + ) + for item in response: + print(item) + + +# x-ms-original-file: 2026-03-01-preview/ServiceGroupMemberRelationships_ListByParent.json +if __name__ == "__main__": + main() diff --git a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations.py b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations.py new file mode 100644 index 000000000000..1ae0c7f9b226 --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations.py @@ -0,0 +1,37 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import pytest +from azure.mgmt.relationships import RelationshipsMgmtClient + +from devtools_testutils import AzureMgmtRecordedTestCase, RandomNameResourceGroupPreparer, recorded_by_proxy + +AZURE_LOCATION = "eastus" + + +@pytest.mark.skip("you may need to update the auto-generated test case before run it") +class TestRelationshipsMgmtContainsRelationshipsOperations(AzureMgmtRecordedTestCase): + def setup_method(self, method): + self.client = self.create_mgmt_client(RelationshipsMgmtClient) + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy + def test_contains_relationships_list_by_subscription(self, resource_group): + response = self.client.contains_relationships.list_by_subscription() + result = [r for r in response] + # please add some check logic here by yourself + # ... + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy + def test_contains_relationships_list_by_resource_group(self, resource_group): + response = self.client.contains_relationships.list_by_resource_group( + resource_group_name=resource_group.name, + ) + result = [r for r in response] + # please add some check logic here by yourself + # ... diff --git a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations_async.py b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations_async.py new file mode 100644 index 000000000000..76a14bd7a1a1 --- /dev/null +++ b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_contains_relationships_operations_async.py @@ -0,0 +1,38 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import pytest +from azure.mgmt.relationships.aio import RelationshipsMgmtClient + +from devtools_testutils import AzureMgmtRecordedTestCase, RandomNameResourceGroupPreparer +from devtools_testutils.aio import recorded_by_proxy_async + +AZURE_LOCATION = "eastus" + + +@pytest.mark.skip("you may need to update the auto-generated test case before run it") +class TestRelationshipsMgmtContainsRelationshipsOperationsAsync(AzureMgmtRecordedTestCase): + def setup_method(self, method): + self.client = self.create_mgmt_client(RelationshipsMgmtClient, is_async=True) + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy_async + async def test_contains_relationships_list_by_subscription(self, resource_group): + response = self.client.contains_relationships.list_by_subscription() + result = [r async for r in response] + # please add some check logic here by yourself + # ... + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy_async + async def test_contains_relationships_list_by_resource_group(self, resource_group): + response = self.client.contains_relationships.list_by_resource_group( + resource_group_name=resource_group.name, + ) + result = [r async for r in response] + # please add some check logic here by yourself + # ... diff --git a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations.py b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations.py index d7322c6393e8..2724337bbb14 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations.py @@ -28,11 +28,11 @@ def test_dependency_of_relationships_begin_create_or_update(self, resource_group "id": "str", "name": "str", "properties": { + "targetId": "str", "metadata": {"sourceType": "str", "targetType": "str"}, "originInformation": {"relationshipOriginType": "str", "discoveryEngine": "str"}, - "sourceId": "str", - "targetId": "str", "provisioningState": "str", + "sourceId": "str", "targetTenant": "str", }, "systemData": { @@ -71,3 +71,13 @@ def test_dependency_of_relationships_begin_delete(self, resource_group): # please add some check logic here by yourself # ... + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy + def test_dependency_of_relationships_list_by_parent(self, resource_group): + response = self.client.dependency_of_relationships.list_by_parent( + resource_uri="str", + ) + result = [r for r in response] + # please add some check logic here by yourself + # ... diff --git a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations_async.py b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations_async.py index 3f96425c479a..b309216c5260 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations_async.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_dependency_of_relationships_operations_async.py @@ -30,11 +30,11 @@ async def test_dependency_of_relationships_begin_create_or_update(self, resource "id": "str", "name": "str", "properties": { + "targetId": "str", "metadata": {"sourceType": "str", "targetType": "str"}, "originInformation": {"relationshipOriginType": "str", "discoveryEngine": "str"}, - "sourceId": "str", - "targetId": "str", "provisioningState": "str", + "sourceId": "str", "targetTenant": "str", }, "systemData": { @@ -76,3 +76,13 @@ async def test_dependency_of_relationships_begin_delete(self, resource_group): # please add some check logic here by yourself # ... + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy_async + async def test_dependency_of_relationships_list_by_parent(self, resource_group): + response = self.client.dependency_of_relationships.list_by_parent( + resource_uri="str", + ) + result = [r async for r in response] + # please add some check logic here by yourself + # ... diff --git a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations.py b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations.py index 07f92c1ac8e3..d744ca8be8bb 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations.py @@ -28,12 +28,12 @@ def test_service_group_member_relationships_begin_create_or_update(self, resourc "id": "str", "name": "str", "properties": { + "sourceId": "str", "metadata": {"sourceType": "str", "targetType": "str"}, "originInformation": {"relationshipOriginType": "str", "discoveryEngine": "str"}, - "sourceId": "str", - "targetId": "str", "provisioningState": "str", - "targetTenant": "str", + "sourceTenant": "str", + "targetId": "str", }, "systemData": { "createdAt": "2020-02-20 00:00:00", @@ -71,3 +71,13 @@ def test_service_group_member_relationships_begin_delete(self, resource_group): # please add some check logic here by yourself # ... + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy + def test_service_group_member_relationships_list_by_parent(self, resource_group): + response = self.client.service_group_member_relationships.list_by_parent( + resource_uri="str", + ) + result = [r for r in response] + # please add some check logic here by yourself + # ... diff --git a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations_async.py b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations_async.py index 244636efea8f..fda79ca8f236 100644 --- a/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations_async.py +++ b/sdk/relationships/azure-mgmt-relationships/generated_tests/test_relationships_mgmt_service_group_member_relationships_operations_async.py @@ -30,12 +30,12 @@ async def test_service_group_member_relationships_begin_create_or_update(self, r "id": "str", "name": "str", "properties": { + "sourceId": "str", "metadata": {"sourceType": "str", "targetType": "str"}, "originInformation": {"relationshipOriginType": "str", "discoveryEngine": "str"}, - "sourceId": "str", - "targetId": "str", "provisioningState": "str", - "targetTenant": "str", + "sourceTenant": "str", + "targetId": "str", }, "systemData": { "createdAt": "2020-02-20 00:00:00", @@ -76,3 +76,13 @@ async def test_service_group_member_relationships_begin_delete(self, resource_gr # please add some check logic here by yourself # ... + + @RandomNameResourceGroupPreparer(location=AZURE_LOCATION) + @recorded_by_proxy_async + async def test_service_group_member_relationships_list_by_parent(self, resource_group): + response = self.client.service_group_member_relationships.list_by_parent( + resource_uri="str", + ) + result = [r async for r in response] + # please add some check logic here by yourself + # ... diff --git a/sdk/relationships/azure-mgmt-relationships/pyproject.toml b/sdk/relationships/azure-mgmt-relationships/pyproject.toml index 53254807c54c..191c354967ad 100644 --- a/sdk/relationships/azure-mgmt-relationships/pyproject.toml +++ b/sdk/relationships/azure-mgmt-relationships/pyproject.toml @@ -17,13 +17,13 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] -requires-python = ">=3.9" +requires-python = ">=3.10" keywords = [ "azure", "azure sdk", diff --git a/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml b/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml index 7b861564e60a..0aa19b525bb4 100644 --- a/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml +++ b/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml @@ -1,4 +1,4 @@ -directory: specification/relationships/Relationships.Management -commit: fe03e53383d9c9c97ec22a65abd1d8c18e401abe +directory: specification/relationships/resource-manager/Microsoft.Relationships/Relationships +commit: 2831f359f052615c26675394fd3939cf6ca92a3b repo: Azure/azure-rest-api-specs additionalDirectories: From 97040fdd5441b05389ddd8abb785d67482df1266 Mon Sep 17 00:00:00 2001 From: ChenxiJiang333 Date: Thu, 13 Aug 2026 10:32:50 +0800 Subject: [PATCH 2/7] update --- sdk/relationships/azure-mgmt-relationships/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md index 2e639130132c..80eccf8c1048 100644 --- a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md +++ b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md @@ -2,7 +2,9 @@ ## 1.0.0b2 (2026-08-12) -tool can't generate changelog for this release, please update manually. +### Other Changes + + - Regular release ## 1.0.0b1 (2026-04-02) From 28ab53d8eb637ce71b5a1cde12d2844e90d45c41 Mon Sep 17 00:00:00 2001 From: ChenxiJiang333 <119990644+ChenxiJiang333@users.noreply.github.com> Date: Thu, 13 Aug 2026 11:34:39 +0800 Subject: [PATCH 3/7] Update pyproject.toml --- sdk/relationships/azure-mgmt-relationships/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/relationships/azure-mgmt-relationships/pyproject.toml b/sdk/relationships/azure-mgmt-relationships/pyproject.toml index 191c354967ad..d9cfdd7f2d0a 100644 --- a/sdk/relationships/azure-mgmt-relationships/pyproject.toml +++ b/sdk/relationships/azure-mgmt-relationships/pyproject.toml @@ -79,7 +79,6 @@ package_pprint_name = "Relationships Management" package_doc_id = "" is_stable = false is_arm = true -no_sub = true need_msrestazure = false need_azuremgmtcore = true sample_link = "" From 7e91812b3cefbd70f94bea037ec6d827fe5c1e5d Mon Sep 17 00:00:00 2001 From: azure-sdk Date: Thu, 13 Aug 2026 03:44:56 +0000 Subject: [PATCH 4/7] Configurations: 'specification/relationships/resource-manager/Microsoft.Relationships/Relationships/tspconfig.yaml', SDK Release Type: beta, and CommitSHA: 'ad48a6c4c835ed1a4242ff178cdeb32a74c5c6a3' in SpecRepo: 'https://github.com/Azure/azure-rest-api-specs' Pipeline run: https://dev.azure.com/azure-sdk/internal/_build/results?buildId=6696107 Refer to https://eng.ms/docs/products/azure-developer-experience/develop/sdk-release/sdk-release-prerequisites to prepare for SDK release. --- sdk/relationships/azure-mgmt-relationships/CHANGELOG.md | 6 ++---- sdk/relationships/azure-mgmt-relationships/README.md | 6 +++++- sdk/relationships/azure-mgmt-relationships/_metadata.json | 2 +- .../azure-mgmt-relationships/tsp-location.yaml | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md index 80eccf8c1048..093176acb821 100644 --- a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md +++ b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md @@ -1,10 +1,8 @@ # Release History -## 1.0.0b2 (2026-08-12) +## 1.0.0b2 (2026-08-13) -### Other Changes - - - Regular release +tool can't generate changelog for this release, please update manually. ## 1.0.0b1 (2026-04-02) diff --git a/sdk/relationships/azure-mgmt-relationships/README.md b/sdk/relationships/azure-mgmt-relationships/README.md index 4803ec1ec3bf..bf23c4e54e04 100644 --- a/sdk/relationships/azure-mgmt-relationships/README.md +++ b/sdk/relationships/azure-mgmt-relationships/README.md @@ -30,13 +30,17 @@ By default, [Microsoft Entra](https://learn.microsoft.com/entra/fundamentals/wha - `AZURE_TENANT_ID` for Azure tenant ID. - `AZURE_CLIENT_SECRET` for Azure client secret. +In addition, Azure subscription ID can be configured via environment variable `AZURE_SUBSCRIPTION_ID`. + With above configuration, client can be authenticated by following code: ```python from azure.identity import DefaultAzureCredential from azure.mgmt.relationships import RelationshipsMgmtClient +import os -client = RelationshipsMgmtClient(credential=DefaultAzureCredential()) +sub_id = os.getenv("AZURE_SUBSCRIPTION_ID") +client = RelationshipsMgmtClient(credential=DefaultAzureCredential(), subscription_id=sub_id) ``` ## Examples diff --git a/sdk/relationships/azure-mgmt-relationships/_metadata.json b/sdk/relationships/azure-mgmt-relationships/_metadata.json index 1e0785129ed5..7cd39f068485 100644 --- a/sdk/relationships/azure-mgmt-relationships/_metadata.json +++ b/sdk/relationships/azure-mgmt-relationships/_metadata.json @@ -3,7 +3,7 @@ "apiVersions": { "Microsoft.Relationships": "2026-03-01-preview" }, - "commit": "2831f359f052615c26675394fd3939cf6ca92a3b", + "commit": "ad48a6c4c835ed1a4242ff178cdeb32a74c5c6a3", "repository_url": "https://github.com/Azure/azure-rest-api-specs", "typespec_src": "specification/relationships/resource-manager/Microsoft.Relationships/Relationships", "emitterVersion": "0.63.3", diff --git a/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml b/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml index 0aa19b525bb4..01d7cf85fbea 100644 --- a/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml +++ b/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml @@ -1,4 +1,4 @@ directory: specification/relationships/resource-manager/Microsoft.Relationships/Relationships -commit: 2831f359f052615c26675394fd3939cf6ca92a3b +commit: ad48a6c4c835ed1a4242ff178cdeb32a74c5c6a3 repo: Azure/azure-rest-api-specs additionalDirectories: From 8098d74472741fe147fe046f388e1f3ab55d14ae Mon Sep 17 00:00:00 2001 From: ChenxiJiang333 Date: Thu, 13 Aug 2026 11:49:37 +0800 Subject: [PATCH 5/7] update Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1ad075a4-44e8-4fea-b342-0dbe2f0d3035 --- sdk/relationships/azure-mgmt-relationships/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md index 093176acb821..719a25130203 100644 --- a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md +++ b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md @@ -2,7 +2,9 @@ ## 1.0.0b2 (2026-08-13) -tool can't generate changelog for this release, please update manually. +### Other Changes + + - Regular release ## 1.0.0b1 (2026-04-02) From a3e368e7bb649b80128c84c6288b3dab43c0dfdb Mon Sep 17 00:00:00 2001 From: azure-sdk Date: Thu, 13 Aug 2026 06:36:19 +0000 Subject: [PATCH 6/7] Configurations: 'specification/relationships/resource-manager/Microsoft.Relationships/Relationships/tspconfig.yaml', SDK Release Type: beta, and CommitSHA: 'e9b8d33567e9422a09711667279fe178fada51a1' in SpecRepo: 'https://github.com/Azure/azure-rest-api-specs' Pipeline run: https://dev.azure.com/azure-sdk/internal/_build/results?buildId=6696817 Refer to https://eng.ms/docs/products/azure-developer-experience/develop/sdk-release/sdk-release-prerequisites to prepare for SDK release. --- sdk/relationships/azure-mgmt-relationships/CHANGELOG.md | 4 +--- sdk/relationships/azure-mgmt-relationships/_metadata.json | 2 +- .../azure-mgmt-relationships/apiview-properties.json | 2 +- sdk/relationships/azure-mgmt-relationships/tsp-location.yaml | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md index 719a25130203..093176acb821 100644 --- a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md +++ b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md @@ -2,9 +2,7 @@ ## 1.0.0b2 (2026-08-13) -### Other Changes - - - Regular release +tool can't generate changelog for this release, please update manually. ## 1.0.0b1 (2026-04-02) diff --git a/sdk/relationships/azure-mgmt-relationships/_metadata.json b/sdk/relationships/azure-mgmt-relationships/_metadata.json index 7cd39f068485..ed9f2e64d7a8 100644 --- a/sdk/relationships/azure-mgmt-relationships/_metadata.json +++ b/sdk/relationships/azure-mgmt-relationships/_metadata.json @@ -3,7 +3,7 @@ "apiVersions": { "Microsoft.Relationships": "2026-03-01-preview" }, - "commit": "ad48a6c4c835ed1a4242ff178cdeb32a74c5c6a3", + "commit": "e9b8d33567e9422a09711667279fe178fada51a1", "repository_url": "https://github.com/Azure/azure-rest-api-specs", "typespec_src": "specification/relationships/resource-manager/Microsoft.Relationships/Relationships", "emitterVersion": "0.63.3", diff --git a/sdk/relationships/azure-mgmt-relationships/apiview-properties.json b/sdk/relationships/azure-mgmt-relationships/apiview-properties.json index 1df81f090b85..70db765684b2 100644 --- a/sdk/relationships/azure-mgmt-relationships/apiview-properties.json +++ b/sdk/relationships/azure-mgmt-relationships/apiview-properties.json @@ -45,5 +45,5 @@ "azure.mgmt.relationships.operations.ContainsRelationshipsOperations.list_by_resource_group": "Microsoft.Relationships.ContainsRelationships.listByResourceGroup", "azure.mgmt.relationships.aio.operations.ContainsRelationshipsOperations.list_by_resource_group": "Microsoft.Relationships.ContainsRelationships.listByResourceGroup" }, - "CrossLanguageVersion": "5fecff0ecbaa" + "CrossLanguageVersion": "d30af55609b3" } \ No newline at end of file diff --git a/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml b/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml index 01d7cf85fbea..63fcbc4299cd 100644 --- a/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml +++ b/sdk/relationships/azure-mgmt-relationships/tsp-location.yaml @@ -1,4 +1,4 @@ directory: specification/relationships/resource-manager/Microsoft.Relationships/Relationships -commit: ad48a6c4c835ed1a4242ff178cdeb32a74c5c6a3 +commit: e9b8d33567e9422a09711667279fe178fada51a1 repo: Azure/azure-rest-api-specs additionalDirectories: From 1d7f68e61312212e7e711badeac54c8aeb5caf78 Mon Sep 17 00:00:00 2001 From: azure-sdk Date: Thu, 13 Aug 2026 07:01:51 +0000 Subject: [PATCH 7/7] Configurations: 'specification/relationships/resource-manager/Microsoft.Relationships/Relationships/tspconfig.yaml', SDK Release Type: beta, and CommitSHA: 'e9b8d33567e9422a09711667279fe178fada51a1' in SpecRepo: 'https://github.com/Azure/azure-rest-api-specs' Pipeline run: https://dev.azure.com/azure-sdk/internal/_build/results?buildId=6696942 Refer to https://eng.ms/docs/products/azure-developer-experience/develop/sdk-release/sdk-release-prerequisites to prepare for SDK release. --- .../azure-mgmt-relationships/CHANGELOG.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md index 093176acb821..07f5ca8b0ae6 100644 --- a/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md +++ b/sdk/relationships/azure-mgmt-relationships/CHANGELOG.md @@ -2,7 +2,20 @@ ## 1.0.0b2 (2026-08-13) -tool can't generate changelog for this release, please update manually. +### Features Added + + - Client `RelationshipsMgmtClient` added operation group `contains_relationships` + - Added model `ContainsRelationship` + - Added model `ContainsRelationshipProperties` + - Added model `ServiceGroupMemberRelationshipPropertiesV2` + - Model `DependencyOfRelationshipsOperations` added method `list_by_parent` + - Model `ServiceGroupMemberRelationshipsOperations` added method `list_by_parent` + - Added operation group `ContainsRelationshipsOperations` + +### Breaking Changes + + - Method `RelationshipsMgmtClient.__init__` inserted a `positional_or_keyword` parameter `subscription_id` + - Deleted or renamed model `ServiceGroupMemberRelationshipProperties` ## 1.0.0b1 (2026-04-02)