Microsoft Azure Subscription Management Client Library for Python
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Individual subscription lifecycle management including cancellation, renaming, enabling, and ownership transfer operations. These operations support the complete lifecycle of Azure subscriptions with long-running operation support for complex workflows.
Cancels an active subscription, which will disable all resources and services associated with the subscription.
def cancel(subscription_id: str, **kwargs) -> CanceledSubscriptionId:
"""
The operation to cancel a subscription.
Args:
subscription_id (str): The subscription ID to cancel
Returns:
CanceledSubscriptionId: Confirmation of cancellation with subscription ID
"""Usage Example:
from azure.identity import DefaultAzureCredential
from azure.mgmt.subscription import SubscriptionClient
credential = DefaultAzureCredential()
client = SubscriptionClient(credential)
subscription_id = "12345678-1234-1234-1234-123456789012"
try:
result = client.subscription.cancel(subscription_id)
print(f"Successfully canceled subscription: {result.value}")
# Verify the cancellation by checking subscription state
subscription = client.subscriptions.get(subscription_id)
print(f"New subscription state: {subscription.state}")
except Exception as e:
print(f"Failed to cancel subscription: {e}")Changes the display name of a subscription without affecting its ID or associated resources.
def rename(subscription_id: str, body: Union[SubscriptionName, IO], **kwargs) -> RenamedSubscriptionId:
"""
The operation to rename a subscription.
Args:
subscription_id (str): The subscription ID to rename
body (SubscriptionName): Object containing the new subscription name
Returns:
RenamedSubscriptionId: Confirmation of rename with subscription ID
"""Usage Example:
from azure.mgmt.subscription.models import SubscriptionName
subscription_id = "12345678-1234-1234-1234-123456789012"
new_name = "My Updated Subscription Name"
# Create the rename request
rename_request = SubscriptionName(subscription_name=new_name)
try:
result = client.subscription.rename(subscription_id, rename_request)
print(f"Successfully renamed subscription: {result.value}")
# Verify the rename by getting updated subscription details
subscription = client.subscriptions.get(subscription_id)
print(f"New display name: {subscription.display_name}")
except Exception as e:
print(f"Failed to rename subscription: {e}")Enables a disabled subscription, restoring access to its resources and services.
def enable(subscription_id: str, **kwargs) -> EnabledSubscriptionId:
"""
The operation to enable a subscription.
Args:
subscription_id (str): The subscription ID to enable
Returns:
EnabledSubscriptionId: Confirmation of enablement with subscription ID
"""Usage Example:
subscription_id = "12345678-1234-1234-1234-123456789012"
try:
result = client.subscription.enable(subscription_id)
print(f"Successfully enabled subscription: {result.value}")
# Verify the enablement by checking subscription state
subscription = client.subscriptions.get(subscription_id)
print(f"New subscription state: {subscription.state}")
except Exception as e:
print(f"Failed to enable subscription: {e}")Accepts ownership transfer of a subscription from another user or organization. This is a long-running operation that may take time to complete.
def begin_accept_ownership(subscription_id: str, body: Union[AcceptOwnershipRequest, IO], **kwargs) -> LROPoller[None]:
"""
Accept subscription ownership (Long Running Operation).
Args:
subscription_id (str): The subscription ID for ownership transfer
body (AcceptOwnershipRequest): Ownership acceptance request details
Returns:
LROPoller[None]: Long-running operation poller for monitoring progress
"""Usage Example:
from azure.mgmt.subscription.models import AcceptOwnershipRequest, AcceptOwnershipRequestProperties
subscription_id = "12345678-1234-1234-1234-123456789012"
# Create ownership acceptance request
properties = AcceptOwnershipRequestProperties(
display_name="My Transferred Subscription",
management_group_id="/providers/Microsoft.Management/managementGroups/my-mg",
tags={"Environment": "Production", "Owner": "MyTeam"}
)
ownership_request = AcceptOwnershipRequest(properties=properties)
try:
# Start the long-running operation
poller = client.subscription.begin_accept_ownership(subscription_id, ownership_request)
print("Ownership transfer initiated. Waiting for completion...")
# Wait for completion (this may take several minutes)
poller.wait()
if poller.done():
print("Ownership transfer completed successfully")
# Check the final status
status = client.subscription.accept_ownership_status(subscription_id)
print(f"Transfer status: {status.accept_ownership_state}")
print(f"New subscription ID: {status.subscription_id}")
else:
print("Ownership transfer still in progress")
except Exception as e:
print(f"Failed to accept ownership: {e}")Gets the current status of a subscription ownership transfer operation.
def accept_ownership_status(subscription_id: str, **kwargs) -> AcceptOwnershipStatusResponse:
"""
Accept subscription ownership status.
Args:
subscription_id (str): The subscription ID for ownership transfer
Returns:
AcceptOwnershipStatusResponse: Current status of ownership transfer
"""Usage Example:
subscription_id = "12345678-1234-1234-1234-123456789012"
try:
status = client.subscription.accept_ownership_status(subscription_id)
print(f"Ownership State: {status.accept_ownership_state}")
print(f"Provisioning State: {status.provisioning_state}")
print(f"Billing Owner: {status.billing_owner}")
print(f"Subscription Tenant ID: {status.subscription_tenant_id}")
if status.subscription_id:
print(f"New Subscription ID: {status.subscription_id}")
except Exception as e:
print(f"Failed to get ownership status: {e}")Common errors and scenarios when managing subscription lifecycle:
from azure.core.exceptions import HttpResponseError
def handle_subscription_operation_errors(operation_name: str, subscription_id: str, func, *args):
"""Generic error handler for subscription operations."""
try:
return func(*args)
except HttpResponseError as e:
if e.status_code == 404:
print(f"{operation_name}: Subscription {subscription_id} not found")
elif e.status_code == 403:
print(f"{operation_name}: Insufficient permissions for subscription {subscription_id}")
elif e.status_code == 409:
print(f"{operation_name}: Conflict - subscription may be in wrong state")
elif e.status_code == 400:
print(f"{operation_name}: Bad request - check parameters")
else:
print(f"{operation_name}: Error {e.status_code} - {e.message}")
raise
except Exception as e:
print(f"{operation_name}: Unexpected error - {e}")
raise
# Example usage
try:
result = handle_subscription_operation_errors(
"Cancel", subscription_id,
client.subscription.cancel, subscription_id
)
except Exception:
print("Operation failed")Working with long-running operations like ownership transfer:
import time
from azure.core.exceptions import HttpResponseError
def monitor_ownership_transfer(client, subscription_id, poller):
"""Monitor ownership transfer progress with status updates."""
while not poller.done():
try:
# Check current status
status = client.subscription.accept_ownership_status(subscription_id)
print(f"Current state: {status.accept_ownership_state}")
print(f"Provisioning state: {status.provisioning_state}")
# Wait before next check
time.sleep(30)
except HttpResponseError as e:
if e.status_code == 404:
print("Transfer request not found or completed")
break
else:
print(f"Error checking status: {e}")
except KeyboardInterrupt:
print("Monitoring interrupted. Transfer continues in background.")
break
return poller.done()class CanceledSubscriptionId:
"""Result of subscription cancellation."""
value: str # The subscription ID that was canceled
class RenamedSubscriptionId:
"""Result of subscription rename."""
value: str # The subscription ID that was renamed
class EnabledSubscriptionId:
"""Result of subscription enablement."""
value: str # The subscription ID that was enabled
class SubscriptionName:
"""Request object for subscription rename."""
subscription_name: str # New display name for the subscription
class AcceptOwnershipRequest:
"""Request object for accepting subscription ownership."""
properties: AcceptOwnershipRequestProperties # Ownership acceptance details
class AcceptOwnershipRequestProperties:
"""Properties for ownership acceptance request."""
display_name: str # New display name for the subscription (required)
management_group_id: str # Management group ID to place subscription under (optional)
tags: Dict[str, str] # Tags to apply to the subscription (optional)
class AcceptOwnershipStatusResponse:
"""Response containing ownership transfer status."""
subscription_id: str # Newly created subscription ID (if completed)
accept_ownership_state: Union[str, AcceptOwnership] # Current ownership state
provisioning_state: Union[str, Provisioning] # Current provisioning state
billing_owner: str # UPN of the billing owner
subscription_tenant_id: str # Tenant ID of the subscription
tags: Dict[str, str] # Applied tagsclass AcceptOwnership(str, Enum):
"""The accept ownership state of the resource."""
PENDING = "Pending"
COMPLETED = "Completed"
EXPIRED = "Expired"
class Provisioning(str, Enum):
"""The provisioning state of the resource."""
PENDING = "Pending"
ACCEPTED = "Accepted"
SUCCEEDED = "Succeeded"Install with Tessl CLI
npx tessl i tessl/pypi-azure-mgmt-subscription