Skip to main content

Python

The topaz-sdk package bridges Python test code and local development applications to the Topaz emulator.

SymbolPurpose
AzureLocalCredentialTokenCredential implementation that generates tokens accepted by Topaz
ManagedIdentityLocalCredentialTokenCredential that emulates a managed identity principal
GLOBAL_ADMIN_IDThe built-in superadmin object ID constant
TopazArmClientHTTP client for Topaz-specific management operations
TopazResourceHelpersStatic helpers that return endpoint URIs and connection strings
Port constantsNamed constants for every Topaz service port

Installation

pip install topaz-sdk

AzureLocalCredential

The primary TokenCredential for use with any Azure SDK client that calls Topaz. It generates a short-lived JWT locally — no network call is made — that Topaz's auth layer accepts as a valid Entra ID token.

Equivalent to Topaz.Identity.AzureLocalCredential in C#.

from topaz_sdk import AzureLocalCredential, GLOBAL_ADMIN_ID

credential = AzureLocalCredential(GLOBAL_ADMIN_ID)

Constructor

AzureLocalCredential(object_id: str, preferred_username: str | None = None)
ParameterTypeDescription
object_idstrThe principal object ID embedded in the token. Use GLOBAL_ADMIN_ID ("00000000-0000-0000-0000-000000000000") to bypass RBAC checks, or a specific UUID to represent a named principal.
preferred_usernamestr | NoneOptional UPN injected into the token as the preferred_username claim. Useful for tests that inspect the caller's identity.

This credential is compatible with every Azure SDK client that accepts a TokenCredentialSecretClient, BlobServiceClient, QueueServiceClient, TableServiceClient, and the azure-mgmt-* management clients.

from azure.mgmt.resource import ResourceManagementClient
from topaz_sdk import AzureLocalCredential, GLOBAL_ADMIN_ID, DEFAULT_RESOURCE_MANAGER_PORT

base_url = f"https://topaz.local.dev:{DEFAULT_RESOURCE_MANAGER_PORT}"
credential = AzureLocalCredential(GLOBAL_ADMIN_ID)

client = ResourceManagementClient(
credential=credential,
subscription_id="<subscription-id>",
base_url=base_url,
credential_scopes=[base_url + "/.default"],
)

ManagedIdentityLocalCredential

A TokenCredential that emulates a call made by a user-assigned or system-assigned managed identity. Use this when your production code authenticates via ManagedIdentityCredential and you want to exercise that path locally.

Equivalent to Topaz.Identity.ManagedIdentityLocalCredential in C#.

from topaz_sdk import ManagedIdentityLocalCredential

credential = ManagedIdentityLocalCredential(principal_id="<managed-identity-principal-id>")

Constructor

ManagedIdentityLocalCredential(principal_id: str)
ParameterTypeDescription
principal_idstrUUID of the managed identity resource created in Topaz.

GLOBAL_ADMIN_ID

GLOBAL_ADMIN_ID: str = "00000000-0000-0000-0000-000000000000"

The built-in superadmin object ID. Pass it to AzureLocalCredential to act as a principal with full access to all resources, bypassing all RBAC checks. Use this in test fixtures where you need unrestricted access.


TopazArmClient

A thin HTTP client for Topaz-specific management operations not covered by azure-mgmt-resource — primarily subscription lifecycle, management group hierarchy, and scoped role assignments needed to set up test fixtures.

Equivalent to Topaz.ResourceManager.TopazArmClient in C#.

SSL verification is controlled automatically via the REQUESTS_CA_BUNDLE environment variable. Set it to the path of the Topaz TLS certificate before running your scripts or tests.

from topaz_sdk import AzureLocalCredential, GLOBAL_ADMIN_ID, TopazArmClient

with TopazArmClient(AzureLocalCredential(GLOBAL_ADMIN_ID)) as client:
client.create_subscription("e0000001-0000-0000-0000-000000000001", "dev-subscription")

Constructor

TopazArmClient(credential: AzureLocalCredential)

TopazArmClient implements the context-manager protocol (__enter__ / __exit__) and closes the underlying requests.Session on exit. Use it with with statements or call .close() manually in test teardown.

Subscriptions

MethodReturnsDescription
create_subscription(subscription_id, subscription_name)NoneCreates a subscription in Topaz.
delete_subscription(subscription_id)NoneDeletes a subscription. Silently succeeds if not found.
update_subscription(subscription_id, subscription_name, tags)NoneUpdates the display name and/or tags of an existing subscription.
cancel_subscription(subscription_id)NoneCancels (disables) a subscription.
enable_subscription(subscription_id)NoneRe-enables a previously cancelled subscription.

Resource Groups

MethodReturnsDescription
create_resource_group(subscription_id, resource_group_name, location)NoneCreates or updates a resource group. location defaults to "westeurope".
delete_resource_group(subscription_id, resource_group_name)NoneDeletes a resource group. Silently succeeds if not found.

Key Vault

MethodReturnsDescription
purge_key_vault(subscription_id, key_vault_name, location)NonePurges a soft-deleted Key Vault so a vault with the same name can be re-created. location defaults to "westeurope".

Management Groups

MethodReturnsDescription
create_management_group(group_id, display_name)NoneCreates a management group at the tenant root.
create_management_group_with_parent(group_id, display_name, parent_id)NoneCreates a management group nested under an existing parent group.
get_management_group(group_id)dictReturns the management group resource as a dict.
get_descendants(group_id)dictReturns the list of descendants (child groups and subscriptions) of a management group.
get_entities()dictReturns all entities (management groups and subscriptions) visible to the caller. Follows @nextLink pagination automatically.
associate_subscription_with_management_group(group_id, subscription_id)dictAssociates a subscription with a management group.
disassociate_subscription_from_management_group(group_id, subscription_id)NoneRemoves the association between a subscription and a management group.
get_subscription_under_management_group(group_id, subscription_id)dictReturns the subscription resource as seen from a management group scope.

Hierarchy Settings

MethodReturnsDescription
create_or_update_hierarchy_settings(group_id, require_authorization_for_group_creation, default_management_group)dictCreates or fully replaces hierarchy settings for a management group.
update_hierarchy_settings(group_id, require_authorization_for_group_creation, default_management_group)dictPartially updates hierarchy settings (PATCH semantics).
get_hierarchy_settings(group_id)dictReturns current hierarchy settings for a management group.
list_hierarchy_settings(group_id)dictReturns all hierarchy settings objects for a management group.
delete_hierarchy_settings(group_id)NoneDeletes hierarchy settings for a management group.

Role Assignments

MethodReturnsDescription
create_management_group_role_assignment(management_group_id, assignment_name, principal_id, role_definition_id)NoneCreates a role assignment at management-group scope.
create_resource_group_role_assignment(subscription_id, resource_group_name, assignment_name, principal_id, role_definition_id)NoneCreates a role assignment scoped to a resource group.
create_resource_role_assignment(subscription_id, resource_group_name, provider_namespace, resource_type, resource_name, assignment_name, principal_id, role_definition_id)NoneCreates a role assignment scoped to a single resource.

Health

MethodReturnsDescription
check_ready()boolReturns True when the Topaz host is running and responding. Uses the unauthenticated GET /health endpoint. Useful for readiness polling in test fixtures.

TopazResourceHelpers

A static class that generates service endpoint URIs and connection strings for every emulated Azure service. Use these instead of building strings by hand to ensure port numbers and hostname formats stay consistent with Topaz's DNS conventions.

from topaz_sdk import TopazResourceHelpers

vault_url = TopazResourceHelpers.get_key_vault_endpoint("my-vault")
conn_str = TopazResourceHelpers.get_storage_connection_string("myaccount", account_key)
MethodReturnsDescription
get_key_vault_endpoint(vault_name)strReturns the data-plane URI for a Key Vault (e.g. https://my-vault.vault.topaz.local.dev:8898). Pass to SecretClient, KeyClient, or CertificateClient.
get_blob_service_uri(storage_account_name)strReturns the Blob service HTTPS URI (e.g. https://myaccount.blob.storage.topaz.local.dev:8891/).
get_queue_service_uri(storage_account_name)strReturns the Queue service HTTPS URI.
get_table_service_uri(storage_account_name)strReturns the Table service HTTPS URI.
get_storage_connection_string(storage_account_name, account_key)strReturns a full DefaultEndpointsProtocol=… connection string covering Blob, Queue, and Table Storage. Pass to BlobServiceClient, QueueServiceClient, or TableServiceClient constructors that accept a connection string.
get_service_bus_connection_string(namespace_name)strReturns an AMQP connection string for a Service Bus namespace (UseDevelopmentEmulator=true).
get_service_bus_connection_string_with_tls(namespace_name)strReturns an AMQPS (port 5671) connection string — use with MassTransit or clients that require TLS.
get_service_bus_connection_string_for_management(namespace_name)strReturns a connection string for Service Bus management-plane operations.
get_event_hub_connection_string(namespace_name)strReturns an AMQP connection string for an Event Hub namespace (UseDevelopmentEmulator=true).
get_container_registry_login_server(registry_name)strReturns the host:port login server string for a Container Registry instance (e.g. myregistry.cr.topaz.local.dev:8892).
get_web_site_default_host_name(site_name)strReturns the default hostname for an App Service site.

Port constants

All port constants are importable directly from topaz_sdk.

ConstantPortService
DEFAULT_RESOURCE_MANAGER_PORT8899ARM / Resource Manager
DEFAULT_KEY_VAULT_PORT8898Key Vault
DEFAULT_BLOB_STORAGE_PORT8891Blob Storage
DEFAULT_TABLE_STORAGE_PORT8890Table Storage
DEFAULT_QUEUE_STORAGE_PORT8893Queue Storage
DEFAULT_FILE_STORAGE_PORT8894File Storage
DEFAULT_EVENT_HUB_PORT8897Event Hub (HTTP)
DEFAULT_EVENT_HUB_AMQP_PORT8888Event Hub (AMQP)
DEFAULT_SERVICE_BUS_AMQP_PORT8889Service Bus (AMQP)
ADDITIONAL_SERVICE_BUS_PORT8887Service Bus (management)
AMQP_TLS_CONNECTION_PORT5671AMQP over TLS
CONTAINER_REGISTRY_PORT8892Container Registry

Complete example

The following snippet shows a common test fixture pattern: create a credential, provision a subscription and resource group, then work with Key Vault secrets and Table Storage.

import os
import uuid

from azure.data.tables import TableServiceClient
from azure.keyvault.secrets import SecretClient
from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.mgmt.keyvault.models import Sku, VaultCreateOrUpdateParameters, VaultProperties
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.resource.resources.models import ResourceGroup
from azure.mgmt.storage import StorageManagementClient
from azure.mgmt.storage.models import Kind, StorageAccountCreateParameters
from azure.mgmt.storage.models import Sku as StorageSku

from topaz_sdk import (
GLOBAL_ADMIN_ID,
DEFAULT_RESOURCE_MANAGER_PORT,
AzureLocalCredential,
TopazArmClient,
TopazResourceHelpers,
)

SUBSCRIPTION_ID = "e0000001-0000-0000-0000-000000000001"
BASE_URL = f"https://topaz.local.dev:{DEFAULT_RESOURCE_MANAGER_PORT}"
CREDENTIAL_SCOPE = f"{BASE_URL}/.default"

def mgmt_kwargs(subscription_id: str) -> dict:
return {
"credential": AzureLocalCredential(GLOBAL_ADMIN_ID),
"subscription_id": subscription_id,
"base_url": BASE_URL,
"credential_scopes": [CREDENTIAL_SCOPE],
}

# ── Subscription (Topaz-specific management client) ───────────────────────────
with TopazArmClient(AzureLocalCredential(GLOBAL_ADMIN_ID)) as client:
client.delete_subscription(SUBSCRIPTION_ID) # clean slate on re-runs
client.create_subscription(SUBSCRIPTION_ID, "dev-subscription")

# ── Resource group (standard azure-mgmt-resource client) ─────────────────────
rm = ResourceManagementClient(**mgmt_kwargs(SUBSCRIPTION_ID))
rm.resource_groups.create_or_update("rg-example", ResourceGroup(location="westeurope"))

# ── Key Vault (control plane + data plane) ───────────────────────────────────
kv_mgmt = KeyVaultManagementClient(**mgmt_kwargs(SUBSCRIPTION_ID))
kv_mgmt.vaults.begin_create_or_update(
"rg-example", "my-vault",
VaultCreateOrUpdateParameters(
location="westeurope",
properties=VaultProperties(
tenant_id=str(uuid.UUID(int=0)),
sku=Sku(family="A", name="standard"),
),
),
).result()

secret_client = SecretClient(
vault_url=TopazResourceHelpers.get_key_vault_endpoint("my-vault"),
credential=AzureLocalCredential(GLOBAL_ADMIN_ID),
verify_challenge_resource=False, # required for Topaz custom domain
)
secret_client.set_secret("db-password", "s3cr3t")
print(secret_client.get_secret("db-password").value) # → s3cr3t

# ── Storage account + Table Storage ──────────────────────────────────────────
st_mgmt = StorageManagementClient(**mgmt_kwargs(SUBSCRIPTION_ID))
st_mgmt.storage_accounts.begin_create(
"rg-example", "myaccount",
StorageAccountCreateParameters(
sku=StorageSku(name="Standard_LRS"),
kind=Kind.STORAGE_V2,
location="westeurope",
),
).result()

keys = st_mgmt.storage_accounts.list_keys("rg-example", "myaccount")
# azure-mgmt-storage >= 21: StorageAccountListKeysResult is a MutableMapping
account_key = keys["keys"][0]["value"]

table_service = TableServiceClient.from_connection_string(
TopazResourceHelpers.get_storage_connection_string("myaccount", account_key)
)
table_service.create_table_if_not_exists("employees")
table_service.get_table_client("employees").create_entity({
"PartitionKey": "Engineering",
"RowKey": uuid.uuid4().hex, # hex avoids hyphens, which Topaz's regex rejects
"Name": "Alice",
})
TLS certificate

Set REQUESTS_CA_BUNDLE to the path of the Topaz TLS certificate before running your script or test suite:

export REQUESTS_CA_BUNDLE=/path/to/topaz.crt
python3 my_script.py

Full certificate setup guide: https://topaz.thecloudtheory.com/docs/intro/

Star on GitHub