Skip to content

Instantly share code, notes, and snippets.

@lmazuel
Last active April 29, 2025 22:40
Show Gist options
  • Save lmazuel/e80aa8f9f282892b4e629a5ac0274744 to your computer and use it in GitHub Desktop.
Save lmazuel/e80aa8f9f282892b4e629a5ac0274744 to your computer and use it in GitHub Desktop.
Mgmt resource refactorinng

Overview

azure-mgmt-resources is an interesting package that is consisteting of sub-folders:

image

But it also has a azure/mgmt/resources/__init__.py file that contains aliases to client, in order to avoid using the subnamespace:

from .managedapplications import ApplicationClient
from .deploymentscripts import DeploymentScriptsClient
from .features import FeatureClient
from .links import ManagementLinkClient
from .locks import ManagementLockClient
from .policy import PolicyClient
from .resources import ResourceManagementClient
from .subscriptions import SubscriptionClient
from .deploymentstacks import DeploymentStacksClient
from .databoundaries import DataBoundaryMgmtClient

__all__ = [
    "ApplicationClient",
    "DeploymentScriptsClient",
    "FeatureClient",
    "PolicyClient",
    "ManagementLinkClient",
    "ManagementLockClient",
    "ResourceManagementClient",
    "SubscriptionClient",
    "DeploymentStacksClient",
    "DataBoundaryMgmtClient",
]

To be clear, this was allowing people to import a client in two ways:

# Those two lines do the same thing
from azure.mgmt.resources import DeploymentScriptsClient
from azure.mgmt.resources.deploymentscripts import DeploymentScriptsClient

Approach to split azure-mgmt-resource

New package

New package should follow the 4 part name convention. Example: azure-mgmt-resources-deploymentscripts

This package should contain the folder azure/mgmt/resources/deploymentscripts in its entirety.

For azure-mgmt-resources

Remove the folder in question entirely.

For the __init__.py, in case someone was using the alias import, remove the import and add that code:

def _build_compat_message(client_name: str, packagee_namee: str) -> str:
   return f"""
{client_name} is no longer available in azure-mgmt-resources. Please use {package_name} instead.
You can import the client using `from {package_name.replace('-', '.')} import {client_name}
"""


def __getattr__(name: str):
    if name == DeploymentScriptsClient:
        raise ImportError(_build_compat_message("DeploymentScriptsClient", "azure-mgmt-resources-deploymentscripts")
    raise AttributeError(f"module 'azure.mgmt.resources' has no attribute {name}")

Breaking change analysis

  • Installing a new version of azure-mgmt-resources will break import of azure.mgmt.resources.xxxxxx Migration: Install the new package along, and things will work the same unchanged

  • Installing a new version of azure-mgmt-resources will break import of XXXClient from azure.mgmt.resources Migration: Install the new package along, and update your import to import XXXClient from azure.mgmt.resources.xxxxxx

  • Installing together an old azure-mgmt-resources will overwrite code. Migration: It should actually work fine, this is the same code shipped twice. TBH, I have no conncerns on people using a mix of old and new, people have shown they update all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment