From 5dd10b7411b841edb36f9a505263959ddd3baae7 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Wed, 21 Jan 2026 16:36:42 -0800 Subject: [PATCH 01/11] Fixing/Adding samples --- .../samples/async_snapshot_sample.py | 96 ++++++++++++++++--- .../samples/snapshot_sample.py | 84 +++++++++++++--- .../samples/hello_world_entra_id_sample.py | 70 ++++++++++++++ .../hello_world_sample_entra_id_and_bleu.py | 11 +-- 4 files changed, 228 insertions(+), 33 deletions(-) create mode 100644 sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py index 413010a5b789..1c24412cf422 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py @@ -7,48 +7,114 @@ import asyncio from azure.appconfiguration.provider.aio import load from azure.appconfiguration.provider import SettingSelector -from sample_utilities import get_client_modifications +from azure.appconfiguration.aio import AzureAppConfigurationClient +from azure.appconfiguration import ConfigurationSettingsFilter, ConfigurationSetting, FeatureFlagConfigurationSetting +from sample_utilities import get_authority, get_credential, get_client_modifications import os +import uuid async def main(): + endpoint = os.environ.get("APPCONFIGURATION_ENDPOINT_STRING") + authority = get_authority(endpoint) + credential = get_credential(authority, is_async=True) kwargs = get_client_modifications() - connection_string = os.environ["APPCONFIGURATION_CONNECTION_STRING"] - # Loading configuration settings from a snapshot - # Note: The snapshot must already exist in your App Configuration store - snapshot_name = "my-snapshot-name" + # Step 1: Create a snapshot + # First, we'll create some configuration settings and then create a snapshot containing them + async with AzureAppConfigurationClient(endpoint, credential) as client: + # Create sample configuration settings (these will be included in the snapshot) + sample_settings = [ + ConfigurationSetting(key="app/settings/message", value="Hello from snapshot!"), + ConfigurationSetting(key="app/settings/fontSize", value="14"), + ConfigurationSetting(key="app/settings/backgroundColor", value="#FFFFFF"), + ] + + # Create a feature flag (also included in the snapshot) + sample_feature_flag = FeatureFlagConfigurationSetting( + feature_id="Beta", + enabled=True, + description="Beta feature flag from snapshot sample", + ) + + # Override settings with "prod" label (used in mixed selects, not in snapshot) + override_settings = [ + ConfigurationSetting(key="override.message", value="Production override!", label="prod"), + ConfigurationSetting(key="override.fontSize", value="16", label="prod"), + ] + + print("Creating sample configuration settings...") + for setting in sample_settings: + await client.set_configuration_setting(setting) + print(f" Created: {setting.key} = {setting.value}") + + # Create the feature flag + await client.set_configuration_setting(sample_feature_flag) + print(f" Created feature flag: {sample_feature_flag.feature_id} = {sample_feature_flag.enabled}") + + for setting in override_settings: + await client.set_configuration_setting(setting) + print(f" Created: {setting.key} = {setting.value} (label: {setting.label})") + + # Generate a unique snapshot name + snapshot_name = f"sample-snapshot-{uuid.uuid4().hex[:8]}" + + # Create snapshot with filters for app settings and feature flags (retention_period=3600 seconds = 1 hour) + snapshot_filters = [ + ConfigurationSettingsFilter(key="app/*"), + ConfigurationSettingsFilter(key=".appconfig.featureflag/*"), + ] + + try: + poller = await client.begin_create_snapshot( + name=snapshot_name, filters=snapshot_filters, retention_period=3600 + ) + created_snapshot = await poller.result() + print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") + except Exception as e: + print(f"Error creating snapshot: {e}") + print("Make sure you have configuration settings with keys starting with 'app/' in your store.") + raise + + # Step 2: Loading configuration settings from the snapshot snapshot_selects = [SettingSelector(snapshot_name=snapshot_name)] - config = await load(connection_string=connection_string, selects=snapshot_selects, **kwargs) + config = await load(endpoint=endpoint, credential=credential, selects=snapshot_selects, **kwargs) print("Configuration settings from snapshot:") for key, value in config.items(): print(f"{key}: {value}") + await config.close() - # You can also combine snapshot-based selectors with regular selectors - # The snapshot settings and filtered settings will be merged, with later selectors taking precedence + # Step 3: Combine snapshot with regular selectors (later selectors take precedence) mixed_selects = [ SettingSelector(snapshot_name=snapshot_name), # Load all settings from snapshot SettingSelector(key_filter="override.*", label_filter="prod"), # Also load specific override settings ] - config_mixed = await load(connection_string=connection_string, selects=mixed_selects, **kwargs) + config_mixed = await load(endpoint=endpoint, credential=credential, selects=mixed_selects, **kwargs) print("\nMixed configuration (snapshot + filtered settings):") for key, value in config_mixed.items(): print(f"{key}: {value}") + await config_mixed.close() - # Loading feature flags from a snapshot - # To load feature flags from a snapshot, include the snapshot selector in the 'selects' parameter and set feature_flag_enabled=True. + # Step 4: Load feature flags from the snapshot (requires feature_flag_enabled=True) feature_flag_selects = [SettingSelector(snapshot_name=snapshot_name)] config_with_flags = await load( - connection_string=connection_string, + endpoint=endpoint, + credential=credential, selects=feature_flag_selects, feature_flag_enabled=True, **kwargs, ) - print( - f"\nConfiguration includes feature flags: {any(key.startswith('.appconfig.featureflag/') for key in config_with_flags.keys())}" - ) + + print(f"\nFeature flags loaded: {'feature_management' in config_with_flags}") + if "feature_management" in config_with_flags: + feature_flags = config_with_flags["feature_management"].get("feature_flags", []) + for flag in feature_flags: + print(f" {flag['id']}: enabled={flag['enabled']}") + + await config_with_flags.close() + await credential.close() if __name__ == "__main__": diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index 5222879e5431..9bcbc3076b5b 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -5,20 +5,80 @@ # ------------------------------------------------------------------------- from azure.appconfiguration.provider import load, SettingSelector +from azure.appconfiguration import ( + AzureAppConfigurationClient, + ConfigurationSettingsFilter, + ConfigurationSnapshot, + ConfigurationSetting, + FeatureFlagConfigurationSetting, +) from sample_utilities import get_authority, get_credential, get_client_modifications import os +import uuid endpoint = os.environ.get("APPCONFIGURATION_ENDPOINT_STRING") authority = get_authority(endpoint) credential = get_credential(authority) kwargs = get_client_modifications() -# Connecting to Azure App Configuration using AAD -config = load(endpoint=endpoint, credential=credential, **kwargs) +# Step 1: Create a snapshot +# First, we'll create some configuration settings and then create a snapshot containing them +client = AzureAppConfigurationClient(endpoint, credential) + + +# Create sample configuration settings (these will be included in the snapshot) +sample_settings = [ + ConfigurationSetting(key="app/settings/message", value="Hello from snapshot!"), + ConfigurationSetting(key="app/settings/fontSize", value="14"), + ConfigurationSetting(key="app/settings/backgroundColor", value="#FFFFFF"), +] + +# Create a feature flag (also included in the snapshot) +sample_feature_flag = FeatureFlagConfigurationSetting( + feature_id="Beta", + enabled=True, + description="Beta feature flag from snapshot sample", +) + +# Override settings with "prod" label (used in mixed selects, not in snapshot) +override_settings = [ + ConfigurationSetting(key="override.message", value="Production override!", label="prod"), + ConfigurationSetting(key="override.fontSize", value="16", label="prod"), +] + +print("Creating sample configuration settings...") +for setting in sample_settings: + # client.set_configuration_setting(setting) + print(f" Created: {setting.key} = {setting.value}") + +# Create the feature flag +# client.set_configuration_setting(sample_feature_flag) +print(f" Created feature flag: {sample_feature_flag.feature_id} = {sample_feature_flag.enabled}") + +for setting in override_settings: + # client.set_configuration_setting(setting) + print(f" Created: {setting.key} = {setting.value} (label: {setting.label})") + +# Generate a unique snapshot name +snapshot_name = f"sample-snapshot-{uuid.uuid4().hex[:8]}" -# Loading configuration settings from a snapshot -# Note: The snapshot must already exist in your App Configuration store -snapshot_name = "my-snapshot-name" +# Create snapshot with filters for app settings and feature flags (retention_period=3600 seconds = 1 hour) +snapshot_filters = [ + ConfigurationSettingsFilter(key="app/*"), + ConfigurationSettingsFilter(key=".appconfig.featureflag/*"), +] + +try: + created_snapshot = client.begin_create_snapshot( + name=snapshot_name, filters=snapshot_filters, retention_period=3600 + ).result() + print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") +except Exception as e: + print(f"Error creating snapshot: {e}") + print("Make sure you have configuration settings with keys starting with 'app/' in your store.") + raise + +# Step 2: Loading configuration settings from the snapshot snapshot_selects = [SettingSelector(snapshot_name=snapshot_name)] config = load(endpoint=endpoint, credential=credential, selects=snapshot_selects, **kwargs) @@ -26,8 +86,7 @@ for key, value in config.items(): print(f"{key}: {value}") -# You can also combine snapshot-based selectors with regular selectors -# The snapshot settings and filtered settings will be merged, with later selectors taking precedence +# Step 3: Combine snapshot with regular selectors (later selectors take precedence) mixed_selects = [ SettingSelector(snapshot_name=snapshot_name), # Load all settings from snapshot SettingSelector(key_filter="override.*", label_filter="prod"), # Also load specific override settings @@ -38,8 +97,7 @@ for key, value in config_mixed.items(): print(f"{key}: {value}") -# Loading feature flags from a snapshot -# To load feature flags from a snapshot, include the snapshot selector in the `selects` parameter and set `feature_flag_enabled=True`. +# Step 4: Load feature flags from the snapshot (requires feature_flag_enabled=True) feature_flag_selects = [SettingSelector(snapshot_name=snapshot_name)] config_with_flags = load( endpoint=endpoint, @@ -49,6 +107,8 @@ **kwargs, ) -print( - f"\nConfiguration includes feature flags: {any(key.startswith('.appconfig.featureflag/') for key in config_with_flags.keys())}" -) +print(f"\nFeature flags loaded: {'feature_management' in config_with_flags}") +if "feature_management" in config_with_flags: + feature_flags = config_with_flags["feature_management"].get("feature_flags", []) + for flag in feature_flags: + print(f" {flag['id']}: enabled={flag['enabled']}") diff --git a/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py b/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py new file mode 100644 index 000000000000..213b281e1047 --- /dev/null +++ b/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py @@ -0,0 +1,70 @@ +# 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. +# -------------------------------------------------------------------------- + +""" +FILE: hello_world_sample.py + +DESCRIPTION: + This sample demos how to add/update/retrieve/delete configuration settings synchronously. + +USAGE: python hello_world_sample.py + + Set the environment variables with your own values before running the sample: + 1) APPCONFIGURATION_CONNECTION_STRING: Connection String used to access the Azure App Configuration. +""" +import os +from azure.appconfiguration import AzureAppConfigurationClient +from azure.identity import DefaultAzureCredential +from azure.appconfiguration import ConfigurationSetting + + +def main(): + # [START create_app_config_client] + + ENDPOINT = os.environ["APPCONFIGURATION_ENDPOINT"] + credential = DefaultAzureCredential() + # Create app config client + client = AzureAppConfigurationClient(base_url=ENDPOINT, credential=credential) + # [END create_app_config_client] + + print("Add new configuration setting") + # [START create_config_setting] + config_setting = ConfigurationSetting( + key="MyKey", label="MyLabel", value="my value", content_type="my content type", tags={"my tag": "my tag value"} + ) + added_config_setting = client.add_configuration_setting(config_setting) + # [END create_config_setting] + print("New configuration setting:") + print(added_config_setting) + print("") + + print("Set configuration setting") + # [START set_config_setting] + added_config_setting.value = "new value" + added_config_setting.content_type = "new content type" + updated_config_setting = client.set_configuration_setting(added_config_setting) + # [END set_config_setting] + print(updated_config_setting) + print("") + + print("Get configuration setting") + # [START get_config_setting] + fetched_config_setting = client.get_configuration_setting(key="MyKey", label="MyLabel") + # [END get_config_setting] + print("Fetched configuration setting:") + print(fetched_config_setting) + print("") + + print("Delete configuration setting") + # [START delete_config_setting] + client.delete_configuration_setting(key="MyKey", label="MyLabel") + # [END delete_config_setting] + + +if __name__ == "__main__": + main() diff --git a/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_sample_entra_id_and_bleu.py b/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_sample_entra_id_and_bleu.py index 420b650193e2..ad91cf88cd2b 100644 --- a/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_sample_entra_id_and_bleu.py +++ b/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_sample_entra_id_and_bleu.py @@ -23,7 +23,7 @@ 4) AZURE_CLIENT_SECRET: Your application client secret For Azure Bleu (French Sovereign Cloud): - - Use credential_scopes: ["https://appconfig.sovcloud-api.fr/.default"] + - Use audience: ["https://appconfig.sovcloud-api.fr/"] DefaultAzureCredential will attempt multiple authentication methods: - Environment variables (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET) @@ -33,21 +33,20 @@ - Azure PowerShell - Interactive browser """ +import os +from azure.appconfiguration import AzureAppConfigurationClient +from azure.identity import DefaultAzureCredential from azure.appconfiguration import ConfigurationSetting def main(): # [START create_app_config_client_entra_id] - import os - from azure.appconfiguration import AzureAppConfigurationClient - from azure.identity import DefaultAzureCredential - ENDPOINT = os.environ["APPCONFIGURATION_ENDPOINT"] # Create app config client with Entra ID authentication credential = DefaultAzureCredential() client = AzureAppConfigurationClient( - base_url=ENDPOINT, credential=credential, credential_scopes=["https://appconfig.sovcloud-api.fr/.default"] + base_url=ENDPOINT, credential=credential, audience="https://appconfig.sovcloud-api.fr/" ) # [END create_app_config_client_entra_id] From c0d9269feb348fb84b2a4feba4918c2e34f2368d Mon Sep 17 00:00:00 2001 From: Matthew Metcalf Date: Thu, 22 Jan 2026 09:01:59 -0800 Subject: [PATCH 02/11] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../azure-appconfiguration-provider/samples/snapshot_sample.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index 9bcbc3076b5b..21dbd261c998 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -52,7 +52,7 @@ print(f" Created: {setting.key} = {setting.value}") # Create the feature flag -# client.set_configuration_setting(sample_feature_flag) +client.set_configuration_setting(sample_feature_flag) print(f" Created feature flag: {sample_feature_flag.feature_id} = {sample_feature_flag.enabled}") for setting in override_settings: From 62f3f790c7036e692960c6fa94209007314022c7 Mon Sep 17 00:00:00 2001 From: Matthew Metcalf Date: Thu, 22 Jan 2026 09:02:13 -0800 Subject: [PATCH 03/11] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../samples/snapshot_sample.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index 21dbd261c998..6cf21a37f51f 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -48,7 +48,7 @@ print("Creating sample configuration settings...") for setting in sample_settings: - # client.set_configuration_setting(setting) + client.set_configuration_setting(setting) print(f" Created: {setting.key} = {setting.value}") # Create the feature flag @@ -56,7 +56,7 @@ print(f" Created feature flag: {sample_feature_flag.feature_id} = {sample_feature_flag.enabled}") for setting in override_settings: - # client.set_configuration_setting(setting) + client.set_configuration_setting(setting) print(f" Created: {setting.key} = {setting.value} (label: {setting.label})") # Generate a unique snapshot name From 06c56b23dc1062152020fa188139781b3e8c74a9 Mon Sep 17 00:00:00 2001 From: Matthew Metcalf Date: Thu, 22 Jan 2026 09:02:35 -0800 Subject: [PATCH 04/11] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../samples/hello_world_entra_id_sample.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py b/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py index 213b281e1047..e539d26ddea1 100644 --- a/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration/samples/hello_world_entra_id_sample.py @@ -7,12 +7,12 @@ # -------------------------------------------------------------------------- """ -FILE: hello_world_sample.py +FILE: hello_world_entra_id_sample.py DESCRIPTION: This sample demos how to add/update/retrieve/delete configuration settings synchronously. -USAGE: python hello_world_sample.py +USAGE: python hello_world_entra_id_sample.py Set the environment variables with your own values before running the sample: 1) APPCONFIGURATION_CONNECTION_STRING: Connection String used to access the Azure App Configuration. From 91dc37f0af53ae517c017fce44177544b920135b Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 22 Jan 2026 10:36:41 -0800 Subject: [PATCH 05/11] Update README.md --- .../azure-appconfiguration/README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sdk/appconfiguration/azure-appconfiguration/README.md b/sdk/appconfiguration/azure-appconfiguration/README.md index 4b59281924b0..1ba482518ad6 100644 --- a/sdk/appconfiguration/azure-appconfiguration/README.md +++ b/sdk/appconfiguration/azure-appconfiguration/README.md @@ -71,7 +71,7 @@ client = AzureAppConfigurationClient.from_connection_string(CONNECTION_STRING) -#### Use AAD token +#### Use Entra ID token Here we demonstrate using [DefaultAzureCredential][default_cred_ref] to authenticate as a service principal. However, [AzureAppConfigurationClient][configuration_client_class] @@ -79,6 +79,18 @@ accepts any [azure-identity][azure_identity] credential. See the [azure-identity][azure_identity] documentation for more information about other credentials. + + +```python + + ENDPOINT = os.environ["APPCONFIGURATION_ENDPOINT"] + credential = DefaultAzureCredential() + # Create app config client + client = AzureAppConfigurationClient(base_url=ENDPOINT, credential=credential) +``` + + + ##### Create a service principal (optional) This [Azure CLI][azure_cli] snippet shows how to create a new service principal. Before using it, replace "your-application-name" with From 37ce3940b98b91311304cbba47cf2fdc99bdf91f Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 22 Jan 2026 11:22:49 -0800 Subject: [PATCH 06/11] removing fail as we create the keys --- .../samples/async_snapshot_sample.py | 15 +++++---------- .../samples/snapshot_sample.py | 14 +++++--------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py index 1c24412cf422..34d0bc0026d8 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py @@ -65,16 +65,11 @@ async def main(): ConfigurationSettingsFilter(key=".appconfig.featureflag/*"), ] - try: - poller = await client.begin_create_snapshot( - name=snapshot_name, filters=snapshot_filters, retention_period=3600 - ) - created_snapshot = await poller.result() - print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") - except Exception as e: - print(f"Error creating snapshot: {e}") - print("Make sure you have configuration settings with keys starting with 'app/' in your store.") - raise + poller = await client.begin_create_snapshot( + name=snapshot_name, filters=snapshot_filters, retention_period=3600 + ) + created_snapshot = await poller.result() + print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") # Step 2: Loading configuration settings from the snapshot snapshot_selects = [SettingSelector(snapshot_name=snapshot_name)] diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index 6cf21a37f51f..48c2f83e3d62 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -68,15 +68,11 @@ ConfigurationSettingsFilter(key=".appconfig.featureflag/*"), ] -try: - created_snapshot = client.begin_create_snapshot( - name=snapshot_name, filters=snapshot_filters, retention_period=3600 - ).result() - print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") -except Exception as e: - print(f"Error creating snapshot: {e}") - print("Make sure you have configuration settings with keys starting with 'app/' in your store.") - raise +created_snapshot = client.begin_create_snapshot( + name=snapshot_name, filters=snapshot_filters, retention_period=3600 +).result() +print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") + # Step 2: Loading configuration settings from the snapshot snapshot_selects = [SettingSelector(snapshot_name=snapshot_name)] From ed79dedbc61d77764f6e0accfa7e3b78f0afca5d Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 22 Jan 2026 12:04:28 -0800 Subject: [PATCH 07/11] fixing test mypy issue --- .../samples/async_snapshot_sample.py | 10 +++++++--- .../samples/snapshot_sample.py | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py index 34d0bc0026d8..ab30141574a0 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py @@ -7,9 +7,13 @@ import asyncio from azure.appconfiguration.provider.aio import load from azure.appconfiguration.provider import SettingSelector -from azure.appconfiguration.aio import AzureAppConfigurationClient -from azure.appconfiguration import ConfigurationSettingsFilter, ConfigurationSetting, FeatureFlagConfigurationSetting -from sample_utilities import get_authority, get_credential, get_client_modifications +from azure.appconfiguration.aio import AzureAppConfigurationClient # type:ignore +from azure.appconfiguration import ( # type:ignore + ConfigurationSettingsFilter, + ConfigurationSetting, + FeatureFlagConfigurationSetting, +) +from azure.identity.aio import DefaultAzureCredential import os import uuid diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index 48c2f83e3d62..5ad1cc826be6 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -5,7 +5,7 @@ # ------------------------------------------------------------------------- from azure.appconfiguration.provider import load, SettingSelector -from azure.appconfiguration import ( +from azure.appconfiguration import ( # type:ignore AzureAppConfigurationClient, ConfigurationSettingsFilter, ConfigurationSnapshot, From 9a3d0d45c7ff3c0187619a7fe1868497cc70a086 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 22 Jan 2026 15:05:20 -0800 Subject: [PATCH 08/11] update tests --- .../azure-appconfiguration-provider/assets.json | 2 +- sdk/appconfiguration/azure-appconfiguration/assets.json | 2 +- .../tests/test_azure_appconfiguration_client.py | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/assets.json b/sdk/appconfiguration/azure-appconfiguration-provider/assets.json index c09c492b8eda..b612cb2b1b0f 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/assets.json +++ b/sdk/appconfiguration/azure-appconfiguration-provider/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/appconfiguration/azure-appconfiguration-provider", - "Tag": "python/appconfiguration/azure-appconfiguration-provider_32bd63579a" + "Tag": "python/appconfiguration/azure-appconfiguration-provider_3e69808293" } diff --git a/sdk/appconfiguration/azure-appconfiguration/assets.json b/sdk/appconfiguration/azure-appconfiguration/assets.json index 3d5f769f30fe..dc13685404d8 100644 --- a/sdk/appconfiguration/azure-appconfiguration/assets.json +++ b/sdk/appconfiguration/azure-appconfiguration/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/appconfiguration/azure-appconfiguration", - "Tag": "python/appconfiguration/azure-appconfiguration_7b8ff3a790" + "Tag": "python/appconfiguration/azure-appconfiguration_e031d16e39" } diff --git a/sdk/appconfiguration/azure-appconfiguration/tests/test_azure_appconfiguration_client.py b/sdk/appconfiguration/azure-appconfiguration/tests/test_azure_appconfiguration_client.py index cb73966af567..d52458ab630f 100644 --- a/sdk/appconfiguration/azure-appconfiguration/tests/test_azure_appconfiguration_client.py +++ b/sdk/appconfiguration/azure-appconfiguration/tests/test_azure_appconfiguration_client.py @@ -1067,7 +1067,8 @@ def test_list_snapshots(self, appconfiguration_connection_string, **kwargs): set_custom_default_matcher(compare_bodies=False, excluded_headers="x-ms-content-sha256,x-ms-date") self.set_up(appconfiguration_connection_string) - result = self.client.list_snapshots() + # Only list "ready" snapshots to avoid counting archived snapshots that may expire during test runs + result = self.client.list_snapshots(status=["ready"]) initial_snapshots = len(list(result)) variables = kwargs.pop("variables", {}) @@ -1085,7 +1086,7 @@ def test_list_snapshots(self, appconfiguration_connection_string, **kwargs): created_snapshot2 = response2.result() assert created_snapshot2.status == "ready" - result = self.client.list_snapshots() + result = self.client.list_snapshots(status=["ready"]) assert len(list(result)) == initial_snapshots + 2 self.tear_down() From f7acc2f31174eafff7ee147ae5163e34d3d42842 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 22 Jan 2026 16:25:44 -0800 Subject: [PATCH 09/11] fixing sample --- .../samples/async_snapshot_sample.py | 108 +++++++++--------- .../samples/snapshot_sample.py | 13 +-- 2 files changed, 58 insertions(+), 63 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py index ab30141574a0..979164182b0c 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py @@ -19,65 +19,63 @@ async def main(): - endpoint = os.environ.get("APPCONFIGURATION_ENDPOINT_STRING") - authority = get_authority(endpoint) - credential = get_credential(authority, is_async=True) - kwargs = get_client_modifications() + endpoint = os.environ["APPCONFIGURATION_ENDPOINT_STRING"] + credential = DefaultAzureCredential() # Step 1: Create a snapshot # First, we'll create some configuration settings and then create a snapshot containing them - async with AzureAppConfigurationClient(endpoint, credential) as client: - # Create sample configuration settings (these will be included in the snapshot) - sample_settings = [ - ConfigurationSetting(key="app/settings/message", value="Hello from snapshot!"), - ConfigurationSetting(key="app/settings/fontSize", value="14"), - ConfigurationSetting(key="app/settings/backgroundColor", value="#FFFFFF"), - ] - - # Create a feature flag (also included in the snapshot) - sample_feature_flag = FeatureFlagConfigurationSetting( - feature_id="Beta", - enabled=True, - description="Beta feature flag from snapshot sample", - ) - - # Override settings with "prod" label (used in mixed selects, not in snapshot) - override_settings = [ - ConfigurationSetting(key="override.message", value="Production override!", label="prod"), - ConfigurationSetting(key="override.fontSize", value="16", label="prod"), - ] - - print("Creating sample configuration settings...") - for setting in sample_settings: - await client.set_configuration_setting(setting) - print(f" Created: {setting.key} = {setting.value}") - - # Create the feature flag - await client.set_configuration_setting(sample_feature_flag) - print(f" Created feature flag: {sample_feature_flag.feature_id} = {sample_feature_flag.enabled}") - - for setting in override_settings: - await client.set_configuration_setting(setting) - print(f" Created: {setting.key} = {setting.value} (label: {setting.label})") - - # Generate a unique snapshot name - snapshot_name = f"sample-snapshot-{uuid.uuid4().hex[:8]}" - - # Create snapshot with filters for app settings and feature flags (retention_period=3600 seconds = 1 hour) - snapshot_filters = [ - ConfigurationSettingsFilter(key="app/*"), - ConfigurationSettingsFilter(key=".appconfig.featureflag/*"), - ] - - poller = await client.begin_create_snapshot( - name=snapshot_name, filters=snapshot_filters, retention_period=3600 - ) - created_snapshot = await poller.result() - print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") + client = AzureAppConfigurationClient(endpoint, credential) + # Create sample configuration settings (these will be included in the snapshot) + sample_settings = [ + ConfigurationSetting(key="app/settings/message", value="Hello from snapshot!"), + ConfigurationSetting(key="app/settings/fontSize", value="14"), + ConfigurationSetting(key="app/settings/backgroundColor", value="#FFFFFF"), + ] + + # Create a feature flag (also included in the snapshot) + sample_feature_flag = FeatureFlagConfigurationSetting( + feature_id="Beta", + enabled=True, + description="Beta feature flag from snapshot sample", + ) + + # Override settings with "prod" label (used in mixed selects, not in snapshot) + override_settings = [ + ConfigurationSetting(key="override.message", value="Production override!", label="prod"), + ConfigurationSetting(key="override.fontSize", value="16", label="prod"), + ] + + print("Creating sample configuration settings...") + for setting in sample_settings: + await client.set_configuration_setting(setting) + print(f" Created: {setting.key} = {setting.value}") + + # Create the feature flag + await client.set_configuration_setting(sample_feature_flag) + print(f" Created feature flag: {sample_feature_flag.feature_id} = {sample_feature_flag.enabled}") + + for setting in override_settings: + await client.set_configuration_setting(setting) + print(f" Created: {setting.key} = {setting.value} (label: {setting.label})") + + # Generate a unique snapshot name + snapshot_name = f"sample-snapshot-{uuid.uuid4().hex[:8]}" + + # Create snapshot with filters for app settings and feature flags (retention_period=3600 seconds = 1 hour) + snapshot_filters = [ + ConfigurationSettingsFilter(key="app/*"), + ConfigurationSettingsFilter(key=".appconfig.featureflag/*"), + ] + + poller = await client.begin_create_snapshot( + name=snapshot_name, filters=snapshot_filters, retention_period=3600 + ) + created_snapshot = await poller.result() + print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") # Step 2: Loading configuration settings from the snapshot snapshot_selects = [SettingSelector(snapshot_name=snapshot_name)] - config = await load(endpoint=endpoint, credential=credential, selects=snapshot_selects, **kwargs) + config = await load(endpoint=endpoint, credential=credential, selects=snapshot_selects) print("Configuration settings from snapshot:") for key, value in config.items(): @@ -89,7 +87,7 @@ async def main(): SettingSelector(snapshot_name=snapshot_name), # Load all settings from snapshot SettingSelector(key_filter="override.*", label_filter="prod"), # Also load specific override settings ] - config_mixed = await load(endpoint=endpoint, credential=credential, selects=mixed_selects, **kwargs) + config_mixed = await load(endpoint=endpoint, credential=credential, selects=mixed_selects) print("\nMixed configuration (snapshot + filtered settings):") for key, value in config_mixed.items(): @@ -103,7 +101,6 @@ async def main(): credential=credential, selects=feature_flag_selects, feature_flag_enabled=True, - **kwargs, ) print(f"\nFeature flags loaded: {'feature_management' in config_with_flags}") @@ -112,6 +109,7 @@ async def main(): for flag in feature_flags: print(f" {flag['id']}: enabled={flag['enabled']}") + await client.close() await config_with_flags.close() await credential.close() diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index 5ad1cc826be6..b42d24fca5dd 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -12,14 +12,12 @@ ConfigurationSetting, FeatureFlagConfigurationSetting, ) -from sample_utilities import get_authority, get_credential, get_client_modifications +from azure.identity import DefaultAzureCredential import os import uuid -endpoint = os.environ.get("APPCONFIGURATION_ENDPOINT_STRING") -authority = get_authority(endpoint) -credential = get_credential(authority) -kwargs = get_client_modifications() +endpoint = os.environ["APPCONFIGURATION_ENDPOINT_STRING"] +credential = DefaultAzureCredential() # Step 1: Create a snapshot # First, we'll create some configuration settings and then create a snapshot containing them @@ -76,7 +74,7 @@ # Step 2: Loading configuration settings from the snapshot snapshot_selects = [SettingSelector(snapshot_name=snapshot_name)] -config = load(endpoint=endpoint, credential=credential, selects=snapshot_selects, **kwargs) +config = load(endpoint=endpoint, credential=credential, selects=snapshot_selects) print("Configuration settings from snapshot:") for key, value in config.items(): @@ -87,7 +85,7 @@ SettingSelector(snapshot_name=snapshot_name), # Load all settings from snapshot SettingSelector(key_filter="override.*", label_filter="prod"), # Also load specific override settings ] -config_mixed = load(endpoint=endpoint, credential=credential, selects=mixed_selects, **kwargs) +config_mixed = load(endpoint=endpoint, credential=credential, selects=mixed_selects) print("\nMixed configuration (snapshot + filtered settings):") for key, value in config_mixed.items(): @@ -100,7 +98,6 @@ credential=credential, selects=feature_flag_selects, feature_flag_enabled=True, - **kwargs, ) print(f"\nFeature flags loaded: {'feature_management' in config_with_flags}") From 24d4f1748ebd1a2539638868703ed5c68ad043c4 Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Thu, 22 Jan 2026 16:58:06 -0800 Subject: [PATCH 10/11] format fixes --- .../samples/async_snapshot_sample.py | 4 +--- .../samples/snapshot_sample.py | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py index 979164182b0c..281061b14b46 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/async_snapshot_sample.py @@ -67,9 +67,7 @@ async def main(): ConfigurationSettingsFilter(key=".appconfig.featureflag/*"), ] - poller = await client.begin_create_snapshot( - name=snapshot_name, filters=snapshot_filters, retention_period=3600 - ) + poller = await client.begin_create_snapshot(name=snapshot_name, filters=snapshot_filters, retention_period=3600) created_snapshot = await poller.result() print(f"Created snapshot: {created_snapshot.name} with status: {created_snapshot.status}") diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index b42d24fca5dd..26c5bb99cf93 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -12,11 +12,7 @@ ConfigurationSetting, FeatureFlagConfigurationSetting, ) -from azure.identity import DefaultAzureCredential -import os -import uuid - -endpoint = os.environ["APPCONFIGURATION_ENDPOINT_STRING"] += os.environ["APPCONFIGURATION_ENDPOINT_STRING"] credential = DefaultAzureCredential() # Step 1: Create a snapshot From 68230d87564e94702b310f681aa9b9879d7ac72e Mon Sep 17 00:00:00 2001 From: Matt Metcalf Date: Fri, 23 Jan 2026 09:32:57 -0800 Subject: [PATCH 11/11] Fixing sample + disable one live test --- .../samples/snapshot_sample.py | 7 +++++-- .../tests/aio/test_async_snapshots.py | 1 + .../tests/test_snapshots.py | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py index 26c5bb99cf93..2f0b650ad74b 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/samples/snapshot_sample.py @@ -3,7 +3,9 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # ------------------------------------------------------------------------- - +import os +import uuid +from azure.identity import DefaultAzureCredential from azure.appconfiguration.provider import load, SettingSelector from azure.appconfiguration import ( # type:ignore AzureAppConfigurationClient, @@ -12,7 +14,8 @@ ConfigurationSetting, FeatureFlagConfigurationSetting, ) -= os.environ["APPCONFIGURATION_ENDPOINT_STRING"] + +endpoint = os.environ["APPCONFIGURATION_ENDPOINT_STRING"] credential = DefaultAzureCredential() # Step 1: Create a snapshot diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/tests/aio/test_async_snapshots.py b/sdk/appconfiguration/azure-appconfiguration-provider/tests/aio/test_async_snapshots.py index 50ae76f0bc1c..926542d82872 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/tests/aio/test_async_snapshots.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/tests/aio/test_async_snapshots.py @@ -168,6 +168,7 @@ async def test_snapshot_selector_parameter_validation_in_provider(self, appconfi feature_flag_selectors=[SettingSelector(snapshot_name="test-snapshot")], ) + @pytest.mark.live_test_only # Needed to fix an azure core dependency compatibility issue @app_config_decorator_async @recorded_by_proxy_async async def test_create_snapshot_and_load_provider(self, appconfiguration_connection_string, **kwargs): diff --git a/sdk/appconfiguration/azure-appconfiguration-provider/tests/test_snapshots.py b/sdk/appconfiguration/azure-appconfiguration-provider/tests/test_snapshots.py index 11865016978d..3a31c3ac874c 100644 --- a/sdk/appconfiguration/azure-appconfiguration-provider/tests/test_snapshots.py +++ b/sdk/appconfiguration/azure-appconfiguration-provider/tests/test_snapshots.py @@ -166,6 +166,7 @@ def test_snapshot_selector_parameter_validation_in_provider(self, appconfigurati feature_flag_selectors=[SettingSelector(snapshot_name="test-snapshot")], ) + @pytest.mark.live_test_only # Needed to fix an azure core dependency compatibility issue @app_config_decorator @recorded_by_proxy def test_create_snapshot_and_load_provider(self, appconfiguration_connection_string, **kwargs):