Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ce483f1
client bugfix
mrm9084 Jun 22, 2026
b919e61
Auto gen, exposed endpoints and basic tests
mrm9084 Jun 22, 2026
01b095f
Updating tests, added samples
mrm9084 Jun 23, 2026
d762028
Update README.md
mrm9084 Jun 23, 2026
5c9807b
Labels endpoint
mrm9084 Jun 23, 2026
61b1c99
fixes
mrm9084 Jun 23, 2026
bff7b4c
pylint fixes
mrm9084 Jun 24, 2026
34a120a
mypy fixes
mrm9084 Jun 24, 2026
a077685
Merge branch 'main' into FFEndpoint
mrm9084 Jun 25, 2026
fc722ea
Split Clients
mrm9084 Jul 2, 2026
ed03caf
pipeline fixes
mrm9084 Jul 7, 2026
444cab1
Updating label usage
mrm9084 Jul 15, 2026
e2ba71c
Update _models.py
mrm9084 Jul 16, 2026
509976f
review comments
mrm9084 Jul 20, 2026
f534f6b
PageBasedEtagFF
mrm9084 Jul 21, 2026
16737c7
page based etag ff samples and tests
mrm9084 Jul 21, 2026
2907d04
Load feature flags from the dedicated feature flag resource endpoint …
yuanqu72 Jul 22, 2026
0e66fca
Rename to enhanced feature flag terminology, fix id/name schema bug, …
yuanqu72 Jul 29, 2026
177c154
Wire FeatureFlagSelector into feature flag loading, add samples, and …
yuanqu72 Jul 30, 2026
c383fba
Trim redundant comments and rewrite README enhanced feature flag sect…
yuanqu72 Jul 30, 2026
198846a
Trim redundant docstring in test_configuration_client_manager.py
yuanqu72 Jul 30, 2026
969c15c
Update ENHANCED_FEATURE_FLAG_TAG from EnhancedFF to EnhFF
yuanqu72 Jul 30, 2026
3a11cd2
Fix feature flag selector type checking to support sets and reset enh…
yuanqu72 Jul 31, 2026
33fdc6b
Fix enhanced feature flag schema mapping, selector type narrowing, as…
yuanqu72 Jul 31, 2026
a621f9e
Reload both feature flag sources on change and validate JSON variant …
yuanqu72 Aug 19, 2026
22a3b31
Merge appconfig-ff-endpoint-preview and fix enhanced feature flag fil…
yuanqu72 Aug 19, 2026
85ef03c
Fix pre-PR static checks; add filter parameter JSON fallback-to-strin…
yuanqu72 Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# Release History

## 2.5.1 (Unreleased)
## 2.6.0b1 (Unreleased)

### Features Added

- Feature flags created via the dedicated feature flag resource endpoint (`FeatureFlagClient`/`FeatureFlag` in `azure-appconfiguration`) are now loaded automatically alongside key-value based feature flags whenever `feature_flag_enabled=True`. Both kinds are merged into the same `feature_management.feature_flags` list, with resource-based feature flags taking precedence over key-value based ones when they share the same name. No new `load()` options are required to opt in, and existing `feature_flag_selectors` filter both kinds.

### Breaking Changes

- Raised the minimum supported Python version to 3.10, matching the minimum required by `azure-appconfiguration>=1.10.0b1`. Dropped support for Python 3.7, 3.8, and 3.9.

### Bugs Fixed

- Fixed a resource leak where replica clients that were no longer part of the auto-failover set were not closed during client refresh.
Expand All @@ -17,6 +21,7 @@
### Other Changes

- Bumped minimum dependency on `azure-core` to `>=1.31.0`.
- Bumped minimum dependency on `azure-appconfiguration` to `>=1.10.0b1` for `FeatureFlagClient`/`FeatureFlag` support.

## 2.5.0 (2026-05-22)

Expand Down
72 changes: 72 additions & 0 deletions sdk/appconfiguration/azure-appconfiguration-provider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,72 @@ config = load(

<!-- END SNIPPET -->

### Loading Enhanced Feature Flags

Feature flags can also be created using the dedicated feature flag endpoint (via `FeatureFlagClient`/`FeatureFlag` in `azure-appconfiguration`), instead of as key-value configuration settings. These are referred to as enhanced feature flags. No additional `load()` options are required to load them — it happens automatically whenever `feature_flag_enabled=True`, and they are merged into the same `feature_management.feature_flags` list as key-value based feature flags, with enhanced feature flags taking precedence when both share the same name.

<!-- SNIPPET:enhanced_feature_flag_sample.enhanced_feature_flag_loading -->

```python
from azure.appconfiguration.provider import load

# Feature flags loaded from the enhanced feature flag endpoint are merged into the same
# feature_management.feature_flags list as key-value based feature flags.
config = load(endpoint=endpoint, credential=credential, feature_flag_enabled=True, **kwargs)
feature_flags = config["feature_management"]["feature_flags"]
enhanced_flag_beta = next(flag for flag in feature_flags if flag.get("id") == "EnhancedFeatureBeta")
print(enhanced_flag_beta["enabled"])
```

<!-- END SNIPPET -->

`FeatureFlagSelector` is the dedicated selector type for filtering enhanced feature flags by name, label, or tags, and is the recommended way to select enhanced feature flags.

<!-- SNIPPET:enhanced_feature_flag_sample.enhanced_feature_flag_selector_with_feature_flag_selector -->

```python
from azure.appconfiguration.provider import load, FeatureFlagSelector

# FeatureFlagSelector is the dedicated selector type for filtering enhanced feature flags.
config = load(
endpoint=endpoint,
credential=credential,
feature_flag_enabled=True,
feature_flag_selectors=[FeatureFlagSelector(name_filter="Enhanced*")],
**kwargs,
)
feature_flags = config["feature_management"]["feature_flags"]
enhanced_flag_beta = next(flag for flag in feature_flags if flag.get("id") == "EnhancedFeatureBeta")
print(enhanced_flag_beta["enabled"])
```

<!-- END SNIPPET -->

The same `SettingSelector` used to filter key-value based feature flags also filters enhanced feature flags, by name, label, or tags. A list of `feature_flag_selectors` must contain either `SettingSelector` or `FeatureFlagSelector` instances, but not both. Note that selectors with a `snapshot_name` are not currently supported for enhanced feature flags and are skipped when loading them.

<!-- SNIPPET:enhanced_feature_flag_sample.enhanced_feature_flag_selector -->

```python
from azure.appconfiguration.provider import load, SettingSelector

# The same SettingSelector used to filter key-value based feature flags also filters enhanced feature
# flags, by name/label/tags.
config = load(
endpoint=endpoint,
credential=credential,
feature_flag_enabled=True,
feature_flag_selectors=[SettingSelector(key_filter="Enhanced*")],
**kwargs,
)
feature_flags = config["feature_management"]["feature_flags"]
enhanced_flag_beta = next(flag for flag in feature_flags if flag.get("id") == "EnhancedFeatureBeta")
print(enhanced_flag_beta["enabled"])
```

<!-- END SNIPPET -->

Existing customers using key-value based feature flags do not need to make any code changes to benefit from this feature. If enhanced feature flags are created in the same App Configuration store, the provider will automatically load and merge them alongside the existing key-value based feature flags whenever `feature_flag_enabled=True`.

## JSON Content Type

Configuration settings with a JSON content type (e.g., `application/json`) are automatically deserialized into their corresponding Python objects when loaded by the provider.
Expand Down Expand Up @@ -469,6 +535,12 @@ This library uses the standard [logging](https://docs.python.org/3/library/loggi
* **Configuration not refreshing** — Make sure you are calling `config.refresh()` periodically (e.g., before each request in a web app). The provider does not auto-refresh in the background.
* **Startup failures** — If the store is unreachable during startup, the provider will retry until `startup_timeout` (default 100 seconds) is exceeded. Increase this value if your store is expected to have high latency.

## Testing

(This content is for `azure-appconfiguration-provider` package developer only)

See [tests/tests.md](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/appconfiguration/azure-appconfiguration-provider/tests/tests.md) for instructions on running unit and integration tests, working with recordings, and setting up environment variables for local testing.

## Next steps

Check out our Django and Flask examples to see how to use the provider in a web application.
Expand Down
19 changes: 15 additions & 4 deletions sdk/appconfiguration/azure-appconfiguration-provider/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace azure.appconfiguration.provider
*,
feature_flag_enabled: bool = False,
feature_flag_refresh_enabled: bool = False,
feature_flag_selectors: Optional[List[SettingSelector]] = ...,
feature_flag_selectors: Optional[Union[List[SettingSelector], List[FeatureFlagSelector]]] = ...,
key_vault_options: Optional[AzureAppConfigurationKeyVaultOptions] = ...,
keyvault_client_configs: Optional[Mapping[str, JSON]] = ...,
keyvault_credential: Optional[TokenCredential] = ...,
Expand All @@ -31,7 +31,7 @@ namespace azure.appconfiguration.provider
connection_string: str,
feature_flag_enabled: bool = False,
feature_flag_refresh_enabled: bool = False,
feature_flag_selectors: Optional[List[SettingSelector]] = ...,
feature_flag_selectors: Optional[Union[List[SettingSelector], List[FeatureFlagSelector]]] = ...,
key_vault_options: Optional[AzureAppConfigurationKeyVaultOptions] = ...,
keyvault_client_configs: Optional[Mapping[str, JSON]] = ...,
keyvault_credential: Optional[TokenCredential] = ...,
Expand Down Expand Up @@ -68,6 +68,17 @@ namespace azure.appconfiguration.provider
def refresh(self, **kwargs) -> None: ...


class azure.appconfiguration.provider.FeatureFlagSelector:

def __init__(
self,
*,
label_filter: Optional[str] = NULL_CHAR,
name_filter: Optional[str] = ...,
tag_filters: Optional[List[str]] = ...
): ...


class azure.appconfiguration.provider.SettingSelector:

def __init__(
Expand All @@ -94,7 +105,7 @@ namespace azure.appconfiguration.provider.aio
*,
feature_flag_enabled: bool = False,
feature_flag_refresh_enabled: bool = False,
feature_flag_selectors: Optional[List[SettingSelector]] = ...,
feature_flag_selectors: Optional[Union[List[SettingSelector], List[FeatureFlagSelector]]] = ...,
key_vault_options: Optional[AzureAppConfigurationKeyVaultOptions] = ...,
keyvault_client_configs: Optional[Mapping[str, JSON]] = ...,
keyvault_credential: Optional[AsyncTokenCredential] = ...,
Expand All @@ -117,7 +128,7 @@ namespace azure.appconfiguration.provider.aio
connection_string: str,
feature_flag_enabled: bool = False,
feature_flag_refresh_enabled: bool = False,
feature_flag_selectors: Optional[List[SettingSelector]] = ...,
feature_flag_selectors: Optional[Union[List[SettingSelector], List[FeatureFlagSelector]]] = ...,
key_vault_options: Optional[AzureAppConfigurationKeyVaultOptions] = ...,
keyvault_client_configs: Optional[Mapping[str, JSON]] = ...,
keyvault_credential: Optional[AsyncTokenCredential] = ...,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "python",
"TagPrefix": "python/appconfiguration/azure-appconfiguration-provider",
"Tag": "python/appconfiguration/azure-appconfiguration-provider_34a63910b7"
"Tag": "python/appconfiguration/azure-appconfiguration-provider_b61dbba519"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ._azureappconfigurationprovider import AzureAppConfigurationProvider
from ._models import (
AzureAppConfigurationKeyVaultOptions,
FeatureFlagSelector,
SettingSelector,
WatchKey,
)
Expand All @@ -18,6 +19,7 @@
"load",
"AzureAppConfigurationProvider",
"AzureAppConfigurationKeyVaultOptions",
"FeatureFlagSelector",
Comment thread
yuanqu72 marked this conversation as resolved.
"SettingSelector",
"WatchKey",
]
Loading
Loading