Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-azure-keyvault-administration
for openSUSE:Factory checked in at 2026-07-14 13:48:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-azure-keyvault-administration (Old)
and
/work/SRC/openSUSE:Factory/.python-azure-keyvault-administration.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-azure-keyvault-administration"
Tue Jul 14 13:48:50 2026 rev:16 rq:1365370 version:4.8.0~b2
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-azure-keyvault-administration/python-azure-keyvault-administration.changes
2026-07-08 17:40:55.910659810 +0200
+++
/work/SRC/openSUSE:Factory/.python-azure-keyvault-administration.new.1991/python-azure-keyvault-administration.changes
2026-07-14 13:49:22.405833356 +0200
@@ -1,0 +2,8 @@
+Fri Jul 10 07:51:36 UTC 2026 - John Paul Adrian Glaubitz
<[email protected]>
+
+- New upstream release
+ + Version 4.8.0b2
+ + For detailed information about changes see the
+ CHANGELOG.md file provided with this package
+
+-------------------------------------------------------------------
Old:
----
azure_keyvault_administration-4.8.0b1.tar.gz
New:
----
azure_keyvault_administration-4.8.0b2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-azure-keyvault-administration.spec ++++++
--- /var/tmp/diff_new_pack.p0496d/_old 2026-07-14 13:49:23.125857972 +0200
+++ /var/tmp/diff_new_pack.p0496d/_new 2026-07-14 13:49:23.133858245 +0200
@@ -16,11 +16,11 @@
#
-%define realversion 4.8.0b1
+%define realversion 4.8.0b2
%{?sle15_python_module_pythons}
Name: python-azure-keyvault-administration
-Version: 4.8.0~b1
+Version: 4.8.0~b2
Release: 0
Summary: Microsoft Azure Key Vault Administration Client Library for
Python
License: MIT
++++++ azure_keyvault_administration-4.8.0b1.tar.gz ->
azure_keyvault_administration-4.8.0b2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_keyvault_administration-4.8.0b1/CHANGELOG.md
new/azure_keyvault_administration-4.8.0b2/CHANGELOG.md
--- old/azure_keyvault_administration-4.8.0b1/CHANGELOG.md 2026-05-29
18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/CHANGELOG.md 2026-07-08
14:56:42.000000000 +0200
@@ -1,5 +1,11 @@
# Release History
+## 4.8.0b2 (2026-07-08)
+
+### Bugs Fixed
+
+- Fixed a replay bug in challenge authentication policy. The original request
is now stored at the request level instead of the client level.
[#47742](https://github.com/Azure/azure-sdk-for-python/pull/47742)
+
## 4.8.0b1 (2026-05-29)
### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_keyvault_administration-4.8.0b1/PKG-INFO
new/azure_keyvault_administration-4.8.0b2/PKG-INFO
--- old/azure_keyvault_administration-4.8.0b1/PKG-INFO 2026-05-29
18:29:01.517442200 +0200
+++ new/azure_keyvault_administration-4.8.0b2/PKG-INFO 2026-07-08
14:57:40.448423400 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: azure-keyvault-administration
-Version: 4.8.0b1
+Version: 4.8.0b2
Summary: Microsoft Corporation Key Vault Administration Client Library for
Python
Home-page: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk
Author: Microsoft Corporation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_keyvault_administration-4.8.0b1/api.md
new/azure_keyvault_administration-4.8.0b2/api.md
--- old/azure_keyvault_administration-4.8.0b1/api.md 1970-01-01
01:00:00.000000000 +0100
+++ new/azure_keyvault_administration-4.8.0b2/api.md 2026-07-08
14:56:42.000000000 +0200
@@ -0,0 +1,758 @@
+```py
+namespace azure.keyvault.administration
+
+ class azure.keyvault.administration.ApiVersion(str, Enum,
metaclass=CaseInsensitiveEnumMeta):
+ V2025_07_01 = "2025-07-01"
+ V2026_01_01_PREVIEW = "2026-01-01-preview"
+ V7_2 = "7.2"
+ V7_3 = "7.3"
+ V7_4 = "7.4"
+ V7_5 = "7.5"
+ V7_6 = "7.6"
+
+
+ class
azure.keyvault.administration.KeyVaultAccessControlClient(KeyVaultClientBase):
implements ContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: TokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ def close(self) -> None: ...
+
+ @distributed_trace
+ def create_role_assignment(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ definition_id: str,
+ principal_id: str,
+ *,
+ name: Optional[Union[str, UUID]] = ...,
+ **kwargs: Any
+ ) -> KeyVaultRoleAssignment: ...
+
+ @distributed_trace
+ def delete_role_assignment(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> None: ...
+
+ @distributed_trace
+ def delete_role_definition(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> None: ...
+
+ @distributed_trace
+ def get_role_assignment(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> KeyVaultRoleAssignment: ...
+
+ @distributed_trace
+ def get_role_definition(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> KeyVaultRoleDefinition: ...
+
+ @distributed_trace
+ def list_role_assignments(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ **kwargs: Any
+ ) -> ItemPaged[KeyVaultRoleAssignment]: ...
+
+ @distributed_trace
+ def list_role_definitions(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ **kwargs: Any
+ ) -> ItemPaged[KeyVaultRoleDefinition]: ...
+
+ @distributed_trace
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> HttpResponse: ...
+
+ @distributed_trace
+ def set_role_definition(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ *,
+ assignable_scopes: Optional[List[Union[str,
KeyVaultRoleScope]]] = ...,
+ description: Optional[str] = ...,
+ name: Optional[Union[str, UUID]] = ...,
+ permissions: Optional[List[KeyVaultPermission]] = ...,
+ role_name: Optional[str] = ...,
+ **kwargs: Any
+ ) -> KeyVaultRoleDefinition: ...
+
+
+ class
azure.keyvault.administration.KeyVaultBackupClient(KeyVaultClientBase):
implements ContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: TokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ @overload
+ def begin_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> LROPoller[KeyVaultBackupResult]: ...
+
+ @overload
+ def begin_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> LROPoller[KeyVaultBackupResult]: ...
+
+ @overload
+ def begin_pre_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> LROPoller[None]: ...
+
+ @overload
+ def begin_pre_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> LROPoller[None]: ...
+
+ @overload
+ def begin_pre_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> LROPoller[None]: ...
+
+ @overload
+ def begin_pre_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> LROPoller[None]: ...
+
+ @overload
+ def begin_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ key_name: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> LROPoller[None]: ...
+
+ @overload
+ def begin_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ key_name: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> LROPoller[None]: ...
+
+ def close(self) -> None: ...
+
+ @distributed_trace
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> HttpResponse: ...
+
+
+ class azure.keyvault.administration.KeyVaultBackupResult:
+ folder_url: str
+
+ def __init__(self, **kwargs: Any) -> None: ...
+
+
+ class azure.keyvault.administration.KeyVaultDataAction(str, Enum,
metaclass=CaseInsensitiveEnumMeta):
+ BACKUP_HSM_KEYS = "Microsoft.KeyVault/managedHsm/keys/backup/action"
+ CREATE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/create"
+ DECRYPT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/decrypt/action"
+ DELETE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/delete"
+ DELETE_ROLE_ASSIGNMENT =
"Microsoft.KeyVault/managedHsm/roleAssignments/delete/action"
+ DELETE_ROLE_DEFINITION =
"Microsoft.KeyVault/managedHsm/roleDefinitions/delete/action"
+ DOWNLOAD_HSM_SECURITY_DOMAIN =
"Microsoft.KeyVault/managedHsm/securitydomain/download/action"
+ DOWNLOAD_HSM_SECURITY_DOMAIN_STATUS =
"Microsoft.KeyVault/managedHsm/securitydomain/download/read"
+ ENCRYPT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/encrypt/action"
+ EXPORT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/export/action"
+ GET_ROLE_ASSIGNMENT =
"Microsoft.KeyVault/managedHsm/roleAssignments/read/action"
+ IMPORT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/import/action"
+ PURGE_DELETED_HSM_KEY =
"Microsoft.KeyVault/managedHsm/keys/deletedKeys/delete"
+ RANDOM_NUMBERS_GENERATE = "Microsoft.KeyVault/managedHsm/rng/action"
+ READ_DELETED_HSM_KEY =
"Microsoft.KeyVault/managedHsm/keys/deletedKeys/read/action"
+ READ_HSM_BACKUP_STATUS =
"Microsoft.KeyVault/managedHsm/backup/status/action"
+ READ_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/read/action"
+ READ_HSM_RESTORE_STATUS =
"Microsoft.KeyVault/managedHsm/restore/status/action"
+ READ_HSM_SECURITY_DOMAIN_STATUS =
"Microsoft.KeyVault/managedHsm/securitydomain/upload/read"
+ READ_HSM_SECURITY_DOMAIN_TRANSFER_KEY =
"Microsoft.KeyVault/managedHsm/securitydomain/transferkey/read"
+ READ_ROLE_DEFINITION =
"Microsoft.KeyVault/managedHsm/roleDefinitions/read/action"
+ RECOVER_DELETED_HSM_KEY =
"Microsoft.KeyVault/managedHsm/keys/deletedKeys/recover/action"
+ RELEASE_KEY = "Microsoft.KeyVault/managedHsm/keys/release/action"
+ RESTORE_HSM_KEYS = "Microsoft.KeyVault/managedHsm/keys/restore/action"
+ SIGN_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/sign/action"
+ START_HSM_BACKUP = "Microsoft.KeyVault/managedHsm/backup/start/action"
+ START_HSM_RESTORE =
"Microsoft.KeyVault/managedHsm/restore/start/action"
+ UNWRAP_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/unwrap/action"
+ UPLOAD_HSM_SECURITY_DOMAIN =
"Microsoft.KeyVault/managedHsm/securitydomain/upload/action"
+ VERIFY_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/verify/action"
+ WRAP_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/wrap/action"
+ WRITE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/write/action"
+ WRITE_ROLE_ASSIGNMENT =
"Microsoft.KeyVault/managedHsm/roleAssignments/write/action"
+ WRITE_ROLE_DEFINITION =
"Microsoft.KeyVault/managedHsm/roleDefinitions/write/action"
+
+
+ class azure.keyvault.administration.KeyVaultEkmClient(KeyVaultClientBase):
implements ContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: TokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ @distributed_trace
+ def check_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmProxyInfo:
...
+
+ def close(self) -> None: ...
+
+ @distributed_trace
+ def create_ekm_connection(
+ self,
+ connection: KeyVaultEkmConnection,
+ **kwargs: Any
+ ) -> KeyVaultEkmConnection: ...
+
+ @distributed_trace
+ def delete_ekm_connection(self, **kwargs: Any) ->
KeyVaultEkmConnection: ...
+
+ @distributed_trace
+ def get_ekm_certificate(self, **kwargs: Any) ->
KeyVaultEkmProxyClientCertificateInfo: ...
+
+ @distributed_trace
+ def get_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmConnection:
...
+
+ @distributed_trace
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> HttpResponse: ...
+
+ @distributed_trace
+ def update_ekm_connection(
+ self,
+ connection: KeyVaultEkmConnection,
+ **kwargs: Any
+ ) -> KeyVaultEkmConnection: ...
+
+
+ class azure.keyvault.administration.KeyVaultEkmConnection:
+ host: str
+ path_prefix: Union[str, None]
+ server_ca_certificates: list[bytes]
+ server_subject_common_name: Union[str, None]
+
+ def __init__(
+ self,
+ host: str,
+ server_ca_certificates: List[bytes],
+ *,
+ path_prefix: Optional[str] = ...,
+ server_subject_common_name: Optional[str] = ...
+ ) -> None: ...
+
+ def __repr__(self) -> str: ...
+
+
+ class azure.keyvault.administration.KeyVaultEkmProxyClientCertificateInfo:
+ ca_certificates: Union[list[bytes], None]
+ subject_common_name: Union[str, None]
+
+ def __init__(self, **kwargs: Any) -> None: ...
+
+ def __repr__(self) -> str: ...
+
+
+ class azure.keyvault.administration.KeyVaultEkmProxyInfo:
+ api_version: Union[str, None]
+ ekm_product: Union[str, None]
+ ekm_vendor: Union[str, None]
+ proxy_name: Union[str, None]
+ proxy_vendor: Union[str, None]
+
+ def __init__(self, **kwargs: Any) -> None: ...
+
+ def __repr__(self) -> str: ...
+
+
+ class azure.keyvault.administration.KeyVaultPermission:
+ actions: list[str]
+ data_actions: list[str]
+ not_actions: list[str]
+ not_data_actions: list[str]
+
+ def __init__(self, **kwargs: Any) -> None: ...
+
+
+ class azure.keyvault.administration.KeyVaultRoleAssignment:
+ name: str
+ properties: KeyVaultRoleAssignmentProperties
+ role_assignment_id: str
+ type: str
+
+ def __init__(self, **kwargs: Any) -> None: ...
+
+ def __repr__(self) -> str: ...
+
+
+ class azure.keyvault.administration.KeyVaultRoleAssignmentProperties:
+ principal_id: str
+ role_definition_id: str
+ scope: str
+
+ def __init__(self, **kwargs: Any) -> None: ...
+
+ def __repr__(self) -> str: ...
+
+
+ class azure.keyvault.administration.KeyVaultRoleDefinition:
+ assignable_scopes: list[str]
+ description: str
+ id: str
+ name: str
+ permissions: list[KeyVaultPermission]
+ role_name: str
+ role_type: str
+ type: str
+
+ def __init__(self, **kwargs: Any) -> None: ...
+
+ def __repr__(self) -> str: ...
+
+
+ class azure.keyvault.administration.KeyVaultRoleScope(str, Enum,
metaclass=CaseInsensitiveEnumMeta):
+ GLOBAL = "/"
+ KEYS = "/keys"
+
+
+ class azure.keyvault.administration.KeyVaultSetting:
+ name: str
+ setting_type: Union[str, KeyVaultSettingType, None]
+ value: str
+
+ def __init__(
+ self,
+ name: str,
+ value: Union[str, bool],
+ setting_type: Optional[Union[str, KeyVaultSettingType]] =
None,
+ **kwargs
+ ) -> None: ...
+
+ def getboolean(self) -> bool: ...
+
+
+ class azure.keyvault.administration.KeyVaultSettingType(str, Enum,
metaclass=CaseInsensitiveEnumMeta):
+ BOOLEAN = "boolean"
+
+
+ class
azure.keyvault.administration.KeyVaultSettingsClient(KeyVaultClientBase):
implements ContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: TokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ def close(self) -> None: ...
+
+ @distributed_trace
+ def get_setting(
+ self,
+ name: str,
+ **kwargs: Any
+ ) -> KeyVaultSetting: ...
+
+ @distributed_trace
+ def list_settings(self, **kwargs: Any) -> ItemPaged[KeyVaultSetting]:
...
+
+ @distributed_trace
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> HttpResponse: ...
+
+ @distributed_trace
+ def update_setting(
+ self,
+ setting: KeyVaultSetting,
+ **kwargs: Any
+ ) -> KeyVaultSetting: ...
+
+
+namespace azure.keyvault.administration.aio
+
+ class
azure.keyvault.administration.aio.KeyVaultAccessControlClient(AsyncKeyVaultClientBase):
implements AsyncContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: AsyncTokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ async def close(self) -> None: ...
+
+ @distributed_trace_async
+ async def create_role_assignment(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ definition_id: str,
+ principal_id: str,
+ *,
+ name: Optional[Union[str, UUID]] = ...,
+ **kwargs: Any
+ ) -> KeyVaultRoleAssignment: ...
+
+ @distributed_trace_async
+ async def delete_role_assignment(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> None: ...
+
+ @distributed_trace_async
+ async def delete_role_definition(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> None: ...
+
+ @distributed_trace_async
+ async def get_role_assignment(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> KeyVaultRoleAssignment: ...
+
+ @distributed_trace_async
+ async def get_role_definition(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ name: Union[str, UUID],
+ **kwargs: Any
+ ) -> KeyVaultRoleDefinition: ...
+
+ @distributed_trace
+ def list_role_assignments(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ **kwargs: Any
+ ) -> AsyncItemPaged[KeyVaultRoleAssignment]: ...
+
+ @distributed_trace
+ def list_role_definitions(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ **kwargs: Any
+ ) -> AsyncItemPaged[KeyVaultRoleDefinition]: ...
+
+ @distributed_trace_async
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> Awaitable[AsyncHttpResponse]: ...
+
+ @distributed_trace_async
+ async def set_role_definition(
+ self,
+ scope: Union[str, KeyVaultRoleScope],
+ *,
+ assignable_scopes: Optional[List[Union[str,
KeyVaultRoleScope]]] = ...,
+ description: Optional[str] = ...,
+ name: Optional[Union[str, UUID]] = ...,
+ permissions: Optional[List[KeyVaultPermission]] = ...,
+ role_name: Optional[str] = ...,
+ **kwargs: Any
+ ) -> KeyVaultRoleDefinition: ...
+
+
+ class
azure.keyvault.administration.aio.KeyVaultBackupClient(AsyncKeyVaultClientBase):
implements AsyncContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: AsyncTokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ @overload
+ async def begin_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> AsyncLROPoller[KeyVaultBackupResult]: ...
+
+ @overload
+ async def begin_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> AsyncLROPoller[KeyVaultBackupResult]: ...
+
+ @overload
+ async def begin_pre_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> AsyncLROPoller[None]: ...
+
+ @overload
+ async def begin_pre_backup(
+ self,
+ blob_storage_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> AsyncLROPoller[None]: ...
+
+ @overload
+ async def begin_pre_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> AsyncLROPoller[None]: ...
+
+ @overload
+ async def begin_pre_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> AsyncLROPoller[None]: ...
+
+ @overload
+ async def begin_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ key_name: Optional[str] = ...,
+ use_managed_identity: Literal[True],
+ **kwargs: Any
+ ) -> AsyncLROPoller[None]: ...
+
+ @overload
+ async def begin_restore(
+ self,
+ folder_url: str,
+ *,
+ continuation_token: Optional[str] = ...,
+ key_name: Optional[str] = ...,
+ sas_token: str,
+ **kwargs: Any
+ ) -> AsyncLROPoller[None]: ...
+
+ async def close(self) -> None: ...
+
+ @distributed_trace_async
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> Awaitable[AsyncHttpResponse]: ...
+
+
+ class
azure.keyvault.administration.aio.KeyVaultEkmClient(AsyncKeyVaultClientBase):
implements AsyncContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: AsyncTokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ @distributed_trace_async
+ async def check_ekm_connection(self, **kwargs: Any) ->
KeyVaultEkmProxyInfo: ...
+
+ async def close(self) -> None: ...
+
+ @distributed_trace_async
+ async def create_ekm_connection(
+ self,
+ connection: KeyVaultEkmConnection,
+ **kwargs: Any
+ ) -> KeyVaultEkmConnection: ...
+
+ @distributed_trace_async
+ async def delete_ekm_connection(self, **kwargs: Any) ->
KeyVaultEkmConnection: ...
+
+ @distributed_trace_async
+ async def get_ekm_certificate(self, **kwargs: Any) ->
KeyVaultEkmProxyClientCertificateInfo: ...
+
+ @distributed_trace_async
+ async def get_ekm_connection(self, **kwargs: Any) ->
KeyVaultEkmConnection: ...
+
+ @distributed_trace_async
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> Awaitable[AsyncHttpResponse]: ...
+
+ @distributed_trace_async
+ async def update_ekm_connection(
+ self,
+ connection: KeyVaultEkmConnection,
+ **kwargs: Any
+ ) -> KeyVaultEkmConnection: ...
+
+
+ class
azure.keyvault.administration.aio.KeyVaultSettingsClient(AsyncKeyVaultClientBase):
implements AsyncContextManager
+ property vault_url: str # Read-only
+
+ def __init__(
+ self,
+ vault_url: str,
+ credential: AsyncTokenCredential,
+ *,
+ api_version: Union[ApiVersion, str] = ...,
+ verify_challenge_resource: Optional[bool] = ...,
+ **kwargs: Any
+ ) -> None: ...
+
+ async def close(self) -> None: ...
+
+ @distributed_trace_async
+ async def get_setting(
+ self,
+ name: str,
+ **kwargs: Any
+ ) -> KeyVaultSetting: ...
+
+ @distributed_trace
+ def list_settings(self, **kwargs: Any) ->
AsyncItemPaged[KeyVaultSetting]: ...
+
+ @distributed_trace_async
+ def send_request(
+ self,
+ request: HttpRequest,
+ *,
+ stream: bool = False,
+ **kwargs: Any
+ ) -> Awaitable[AsyncHttpResponse]: ...
+
+ @distributed_trace_async
+ async def update_setting(
+ self,
+ setting: KeyVaultSetting,
+ **kwargs: Any
+ ) -> KeyVaultSetting: ...
+
+
+```
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
---
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
2026-05-29 18:27:52.000000000 +0200
+++
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/async_challenge_auth_policy.py
2026-07-08 14:56:42.000000000 +0200
@@ -30,7 +30,7 @@
from .http_challenge import HttpChallenge
from . import http_challenge_cache as ChallengeCache
-from .challenge_auth_policy import _enforce_tls, _has_claims, _update_challenge
+from .challenge_auth_policy import _enforce_tls, _has_claims,
_update_challenge, _REQUEST_COPY_KEY
if sys.version_info < (3, 9):
from typing import Awaitable
@@ -80,7 +80,6 @@
self._credential: AsyncTokenProvider = credential
self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None
self._verify_challenge_resource =
kwargs.pop("verify_challenge_resource", True)
- self._request_copy: Optional[HttpRequest] = None
async def send(self, request: PipelineRequest[HttpRequest]) ->
PipelineResponse[HttpRequest, AsyncHttpResponse]:
"""Authorize request with a bearer token and send it to the next
policy.
@@ -171,8 +170,10 @@
# saving it for later. Key Vault will reject the request as
unauthorized and respond with a challenge.
# on_challenge will parse that challenge, use the original request
including the body, authorize the
# request, and tell super to send it again.
- if request.http_request.content:
- self._request_copy = request.http_request
+ # The original request is stashed on the request's context
(per-request), so it cannot leak into a later
+ # request made by the same client. Don't overwrite a previously
stashed copy if this is a retry.
+ if request.http_request.content and _REQUEST_COPY_KEY not in
request.context:
+ request.context[_REQUEST_COPY_KEY] = request.http_request
bodiless_request = HttpRequest(
method=request.http_request.method,
url=request.http_request.url,
@@ -214,9 +215,10 @@
"See https://aka.ms/azsdk/blog/vault-uri for more
information."
)
- # If we had created a request copy in on_request, use it now to send
along the original body content
- if self._request_copy:
- request.http_request = self._request_copy
+ # If we stashed the original request in on_request, use it now to send
along the original body content
+ request_copy = request.context.get(_REQUEST_COPY_KEY)
+ if request_copy:
+ request.http_request = request_copy
# The tenant parsed from AD FS challenges is "adfs"; we don't actually
need a tenant for AD FS authentication
# For AD FS we skip cross-tenant authentication per
https://github.com/Azure/azure-sdk-for-python/issues/28648
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/challenge_auth_policy.py
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/challenge_auth_policy.py
---
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_internal/challenge_auth_policy.py
2026-05-29 18:27:52.000000000 +0200
+++
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_internal/challenge_auth_policy.py
2026-07-08 14:56:42.000000000 +0200
@@ -36,6 +36,12 @@
from . import http_challenge_cache as ChallengeCache
+# Key under which the original request is stashed on the per-request pipeline
context during the challenge flow.
+# Storing this per-request (rather than on the policy instance) prevents the
body of one request from leaking into a
+# subsequent request made by the same client.
+_REQUEST_COPY_KEY = "key_vault_request_copy"
+
+
def _enforce_tls(request: PipelineRequest) -> None:
if not request.http_request.url.lower().startswith("https"):
raise ServiceRequestError(
@@ -93,7 +99,6 @@
self._credential: TokenProvider = credential
self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None
self._verify_challenge_resource =
kwargs.pop("verify_challenge_resource", True)
- self._request_copy: Optional[HttpRequest] = None
def send(self, request: PipelineRequest[HttpRequest]) ->
PipelineResponse[HttpRequest, HttpResponse]:
"""Authorize request with a bearer token and send it to the next
policy.
@@ -184,8 +189,10 @@
# saving it for later. Key Vault will reject the request as
unauthorized and respond with a challenge.
# on_challenge will parse that challenge, use the original request
including the body, authorize the
# request, and tell super to send it again.
- if request.http_request.content:
- self._request_copy = request.http_request
+ # The original request is stashed on the request's context
(per-request), so it cannot leak into a later
+ # request made by the same client. Don't overwrite a previously
stashed copy if this is a retry.
+ if request.http_request.content and _REQUEST_COPY_KEY not in
request.context:
+ request.context[_REQUEST_COPY_KEY] = request.http_request
bodiless_request = HttpRequest(
method=request.http_request.method,
url=request.http_request.url,
@@ -227,9 +234,10 @@
"See https://aka.ms/azsdk/blog/vault-uri for more
information."
)
- # If we had created a request copy in on_request, use it now to send
along the original body content
- if self._request_copy:
- request.http_request = self._request_copy
+ # If we stashed the original request in on_request, use it now to send
along the original body content
+ request_copy = request.context.get(_REQUEST_COPY_KEY)
+ if request_copy:
+ request.http_request = request_copy
# The tenant parsed from AD FS challenges is "adfs"; we don't actually
need a tenant for AD FS authentication
# For AD FS we skip cross-tenant authentication per
https://github.com/Azure/azure-sdk-for-python/issues/28648
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_version.py
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_version.py
---
old/azure_keyvault_administration-4.8.0b1/azure/keyvault/administration/_version.py
2026-05-29 18:27:52.000000000 +0200
+++
new/azure_keyvault_administration-4.8.0b2/azure/keyvault/administration/_version.py
2026-07-08 14:56:42.000000000 +0200
@@ -3,4 +3,4 @@
# Licensed under the MIT License.
# ------------------------------------
-VERSION = "4.8.0b1"
+VERSION = "4.8.0b2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/PKG-INFO
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/PKG-INFO
---
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/PKG-INFO
2026-05-29 18:29:01.000000000 +0200
+++
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/PKG-INFO
2026-07-08 14:57:40.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: azure-keyvault-administration
-Version: 4.8.0b1
+Version: 4.8.0b2
Summary: Microsoft Corporation Key Vault Administration Client Library for
Python
Home-page: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk
Author: Microsoft Corporation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/SOURCES.txt
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/SOURCES.txt
---
old/azure_keyvault_administration-4.8.0b1/azure_keyvault_administration.egg-info/SOURCES.txt
2026-05-29 18:29:01.000000000 +0200
+++
new/azure_keyvault_administration-4.8.0b2/azure_keyvault_administration.egg-info/SOURCES.txt
2026-07-08 14:57:40.000000000 +0200
@@ -3,6 +3,7 @@
MANIFEST.in
README.md
TROUBLESHOOTING.md
+api.md
pyproject.toml
setup.py
azure/__init__.py
@@ -78,6 +79,7 @@
tests/test_access_control_async.py
tests/test_backup_client.py
tests/test_backup_client_async.py
+tests/test_challenge_auth.py
tests/test_ekm_client.py
tests/test_ekm_client_async.py
tests/test_examples_administration.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/tests/conftest.py
new/azure_keyvault_administration-4.8.0b2/tests/conftest.py
--- old/azure_keyvault_administration-4.8.0b1/tests/conftest.py 2026-05-29
18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/tests/conftest.py 2026-07-08
14:56:42.000000000 +0200
@@ -14,6 +14,7 @@
add_uri_regex_sanitizer,
is_live,
remove_batch_sanitizers,
+ set_custom_default_matcher,
)
os.environ["PYTHONHASHSEED"] = "0"
@@ -21,6 +22,7 @@
@pytest.fixture(scope="session", autouse=True)
def add_sanitizers(test_proxy):
+ set_custom_default_matcher(compare_bodies=False,
ignore_query_ordering=True, ignored_headers="Accept")
azure_keyvault_url = os.getenv("AZURE_KEYVAULT_URL",
"https://Sanitized.vault.azure.net")
azure_keyvault_url = azure_keyvault_url.rstrip("/")
keyvault_tenant_id = os.getenv("KEYVAULT_TENANT_ID", "keyvault_tenant_id")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client.py
new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client.py
--- old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client.py
2026-05-29 18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client.py
2026-07-08 14:56:42.000000000 +0200
@@ -93,7 +93,6 @@
@KeyVaultBackupClientPreparer()
@recorded_by_proxy
def test_selective_key_restore(self, client, **kwargs):
- set_bodiless_matcher()
# create a key to selectively restore
managed_hsm_url = kwargs.pop("managed_hsm_url")
key_client = self.create_key_client(managed_hsm_url)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client_async.py
new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client_async.py
--- old/azure_keyvault_administration-4.8.0b1/tests/test_backup_client_async.py
2026-05-29 18:27:52.000000000 +0200
+++ new/azure_keyvault_administration-4.8.0b2/tests/test_backup_client_async.py
2026-07-08 14:56:42.000000000 +0200
@@ -94,7 +94,6 @@
@KeyVaultBackupClientPreparer()
@recorded_by_proxy_async
async def test_selective_key_restore(self, client, **kwargs):
- set_bodiless_matcher()
# create a key to selectively restore
managed_hsm_url = kwargs.pop("managed_hsm_url")
key_client = self.create_key_client(managed_hsm_url, is_async=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_keyvault_administration-4.8.0b1/tests/test_challenge_auth.py
new/azure_keyvault_administration-4.8.0b2/tests/test_challenge_auth.py
--- old/azure_keyvault_administration-4.8.0b1/tests/test_challenge_auth.py
1970-01-01 01:00:00.000000000 +0100
+++ new/azure_keyvault_administration-4.8.0b2/tests/test_challenge_auth.py
2026-07-08 14:56:42.000000000 +0200
@@ -0,0 +1,190 @@
+# ------------------------------------
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+# ------------------------------------
+"""
+Tests for the HTTP challenge authentication implementation.
+"""
+
+import functools
+import time
+from unittest.mock import Mock
+from uuid import uuid4
+
+import pytest
+from azure.core.credentials import AccessToken, AccessTokenInfo
+from azure.core.pipeline import AsyncPipeline, Pipeline
+from azure.core.rest import HttpRequest
+from azure.keyvault.administration._internal import ChallengeAuthPolicy,
HttpChallengeCache
+from azure.keyvault.administration._internal.async_challenge_auth_policy
import AsyncChallengeAuthPolicy
+
+TOKEN_TYPES = [AccessToken, AccessTokenInfo]
+
+
+def empty_challenge_cache(fn):
+ @functools.wraps(fn)
+ def wrapper(**kwargs):
+ HttpChallengeCache.clear()
+ assert len(HttpChallengeCache._cache) == 0
+ return fn(**kwargs)
+
+ return wrapper
+
+
+def async_empty_challenge_cache(fn):
+ @functools.wraps(fn)
+ async def wrapper(**kwargs):
+ HttpChallengeCache.clear()
+ assert len(HttpChallengeCache._cache) == 0
+ return await fn(**kwargs)
+
+ return wrapper
+
+
+def get_random_url():
+ """The challenge cache is keyed on URLs. Random URLs defend against tests
interfering with each other."""
+
+ return f"https://{uuid4()}.vault.azure.net/{uuid4()}".replace("-", "")
+
+
+@empty_challenge_cache
[email protected]("token_type", TOKEN_TYPES)
+def test_request_body_not_reused_across_requests(token_type):
+ """A request's body must not leak into a later request made by the same
client.
+
+ Regression test for the replay bug: the original request used to be
stashed on the policy instance and was
+ never cleared, so a subsequent bodiless request (e.g. a polling GET during
a backup/restore operation) that
+ triggered its own challenge would have the earlier request's body (and
method/URL) replayed onto it. The copy
+ is now stored per-request on the pipeline context, so it cannot leak
across requests. See
+ https://github.com/Azure/azure-sdk-for-python/pull/47742.
+ """
+
+ expected_token = "expected_token"
+ first_content = b"a duck"
+ first_url = get_random_url()
+ second_url = get_random_url()
+ challenge = Mock(
+ status_code=401,
+ headers={
+ "WWW-Authenticate": 'Bearer
authorization="https://authority.net/tenant", resource=https://vault.azure.net'
+ },
+ )
+
+ class Requests:
+ count = 0
+
+ def send(request):
+ Requests.count += 1
+ if Requests.count == 1:
+ # first request (POST with body): the body is stripped to elicit a
challenge
+ assert not request.body
+ assert request.headers["Content-Length"] == "0"
+ return challenge
+ elif Requests.count == 2:
+ # first request is retried with its original body and authorization
+ assert request.body == first_content
+ assert expected_token in request.headers["Authorization"]
+ return Mock(status_code=200)
+ elif Requests.count == 3:
+ # second request (bodiless GET): elicits its own challenge and
must have no body
+ assert not request.body
+ return challenge
+ elif Requests.count == 4:
+ # second request is retried: it must remain a bodiless GET, i.e.
the first request's body and
+ # method/URL must NOT be replayed onto it
+ assert not request.body
+ assert request.method == "GET"
+ assert request.url == second_url
+ assert expected_token in request.headers["Authorization"]
+ return Mock(status_code=200)
+ raise ValueError("unexpected request")
+
+ def get_token(*_, **__):
+ return token_type(expected_token, time.time() + 3600)
+
+ if token_type == AccessToken:
+ credential = Mock(spec_set=["get_token"],
get_token=Mock(wraps=get_token))
+ else:
+ credential = Mock(spec_set=["get_token_info"],
get_token_info=Mock(wraps=get_token))
+
+ # a single policy instance handles both requests; the fix prevents state
from one request leaking into the next
+ policy = ChallengeAuthPolicy(credential=credential)
+ pipeline = Pipeline(policies=[policy], transport=Mock(send=send))
+
+ first_request = HttpRequest("POST", first_url)
+ first_request.set_bytes_body(first_content)
+ pipeline.run(first_request)
+
+ pipeline.run(HttpRequest("GET", second_url))
+
+
[email protected]
+@async_empty_challenge_cache
[email protected]("token_type", TOKEN_TYPES)
+async def test_request_body_not_reused_across_requests_async(token_type):
+ """A request's body must not leak into a later request made by the same
client (async).
+
+ Regression test for the replay bug: the original request used to be
stashed on the policy instance and was
+ never cleared, so a subsequent bodiless request (e.g. a polling GET during
a backup/restore operation) that
+ triggered its own challenge would have the earlier request's body (and
method/URL) replayed onto it. The copy
+ is now stored per-request on the pipeline context, so it cannot leak
across requests. See
+ https://github.com/Azure/azure-sdk-for-python/pull/47742.
+ """
+
+ expected_token = "expected_token"
+ first_content = b"a duck"
+ first_url = get_random_url()
+ second_url = get_random_url()
+ challenge = Mock(
+ status_code=401,
+ headers={
+ "WWW-Authenticate": 'Bearer
authorization="https://authority.net/tenant", resource=https://vault.azure.net'
+ },
+ )
+
+ class Requests:
+ count = 0
+
+ async def send(request):
+ Requests.count += 1
+ if Requests.count == 1:
+ # first request (POST with body): the body is stripped to elicit a
challenge
+ assert not request.body
+ assert request.headers["Content-Length"] == "0"
+ return challenge
+ elif Requests.count == 2:
+ # first request is retried with its original body and authorization
+ assert request.body == first_content
+ assert expected_token in request.headers["Authorization"]
+ return Mock(status_code=200)
+ elif Requests.count == 3:
+ # second request (bodiless GET): elicits its own challenge and
must have no body
+ assert not request.body
+ return challenge
+ elif Requests.count == 4:
+ # second request is retried: it must remain a bodiless GET, i.e.
the first request's body and
+ # method/URL must NOT be replayed onto it
+ assert not request.body
+ assert request.method == "GET"
+ assert request.url == second_url
+ assert expected_token in request.headers["Authorization"]
+ return Mock(status_code=200)
+ raise ValueError("unexpected request")
+
+ async def get_token(*_, **__):
+ return token_type(expected_token, time.time() + 3600)
+
+ if token_type == AccessToken:
+ credential = Mock(spec_set=["get_token"],
get_token=Mock(wraps=get_token))
+ else:
+ credential = Mock(spec_set=["get_token_info"],
get_token_info=Mock(wraps=get_token))
+
+ # a single policy instance handles both requests; the fix prevents state
from one request leaking into the next
+ policy = AsyncChallengeAuthPolicy(credential=credential)
+ pipeline = AsyncPipeline(policies=[policy], transport=Mock(send=send))
+
+ first_request = HttpRequest("POST", first_url)
+ first_request.set_bytes_body(first_content)
+ await pipeline.run(first_request)
+
+ await pipeline.run(HttpRequest("GET", second_url))