From 02019c3964405209c1c7bf15458f72bfed8199ea Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 11:10:57 +0200 Subject: [PATCH 001/152] :arrow_up: Upgrade python-dateutil Resolves calling deprecated `datetime.utcfromtimestamp` method Signed-off-by: ff137 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d1395fcea8..3d47940686 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ pydid = "^0.5.1" pyjwt = "~2.9.0" pyld = "^2.0.4" pynacl = "~1.5.0" -python-dateutil = "~2.8.1" +python-dateutil = "^2.9.0" python-json-logger = "~2.0.7" pyyaml = "~6.0.2" qrcode = { version = ">=6.1,<7.0", extras = ["pil"] } From d8632ee2ce2a4ca2f0f5e21209ea277ebc3fd39d Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 11:14:27 +0200 Subject: [PATCH 002/152] :art: Rename class to resolve PytestCollectionWarning Signed-off-by: ff137 --- acapy_agent/didcomm_v2/tests/test_adapters.py | 6 +++--- acapy_agent/transport/tests/test_pack_format.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/acapy_agent/didcomm_v2/tests/test_adapters.py b/acapy_agent/didcomm_v2/tests/test_adapters.py index 61ba698a14..56d861bfcb 100644 --- a/acapy_agent/didcomm_v2/tests/test_adapters.py +++ b/acapy_agent/didcomm_v2/tests/test_adapters.py @@ -15,7 +15,7 @@ from ..adapters import ResolverAdapter, SecretsAdapter, SecretsAdapterError -class TestDIDResolver(BaseDIDResolver): +class MockDIDResolver(BaseDIDResolver): async def setup(self, context: InjectionContext): return await super().setup(context) @@ -26,7 +26,7 @@ async def resolve( self, profile, did, - sercive_accept=None, + service_accept=None, ): return {"did": did, "test": "didDoc"} @@ -46,7 +46,7 @@ async def asyncSetUp(self): self.test_did = "did:test:0" self.invalid_did = "this shouldn't work" resolver = DIDResolver() - resolver.register_resolver(TestDIDResolver()) + resolver.register_resolver(MockDIDResolver()) self.res_adapter = ResolverAdapter(profile=self.profile, resolver=resolver) async def test_resolver_adapter_resolve_did(self): diff --git a/acapy_agent/transport/tests/test_pack_format.py b/acapy_agent/transport/tests/test_pack_format.py index 06e6e9dfe3..058d054bf6 100644 --- a/acapy_agent/transport/tests/test_pack_format.py +++ b/acapy_agent/transport/tests/test_pack_format.py @@ -221,7 +221,7 @@ async def test_get_recipient_keys_fails(self): serializer.get_recipient_keys(json.dumps(enc_message)) -class TestDIDCommMessaging(DIDCommMessaging): +class MockDIDCommMessaging(DIDCommMessaging): def __init__( self, ): @@ -255,7 +255,7 @@ async def test_errors(self): message_json = json.dumps(message) async with self.profile.session() as session: session.context.injector.bind_instance( - DIDCommMessaging, TestDIDCommMessaging() + DIDCommMessaging, MockDIDCommMessaging() ) with self.assertRaises(WireFormatParseError) as context: await wire_format.parse_message(session, message_json) @@ -273,7 +273,7 @@ async def test_errors(self): async def test_fallback(self): serializer = V2PackWireFormat() - test_dm = TestDIDCommMessaging() + test_dm = MockDIDCommMessaging() test_dm.packaging.unpack = mock.AsyncMock(side_effect=CryptoServiceError()) async with self.profile.session() as session: session.context.injector.bind_instance(DIDCommMessaging, test_dm) @@ -289,7 +289,7 @@ async def test_fallback(self): async def test_encode(self): serializer = V2PackWireFormat() - test_dm = TestDIDCommMessaging() + test_dm = MockDIDCommMessaging() test_dm.pack = mock.AsyncMock( return_value=PackResult( message=self.test_message, target_services=mock.MagicMock() From 36e47ce152ece618a78adf6c72ecfc9804c0c8ae Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 11:25:23 +0200 Subject: [PATCH 003/152] :art: Replace deprecated `open_binary` method with `files` Signed-off-by: ff137 --- acapy_agent/config/logging/configurator.py | 2 +- acapy_agent/config/tests/test_logging.py | 59 +++++++++++++++++----- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/acapy_agent/config/logging/configurator.py b/acapy_agent/config/logging/configurator.py index 548508c0af..11763dca08 100644 --- a/acapy_agent/config/logging/configurator.py +++ b/acapy_agent/config/logging/configurator.py @@ -52,7 +52,7 @@ def load_resource(path: str, encoding: Optional[str] = None): else: # Package resource package, resource = components - bstream = resources.open_binary(package, resource) + bstream = resources.files(package).joinpath(resource).open("rb") if encoding: return io.TextIOWrapper(bstream, encoding=encoding) return bstream diff --git a/acapy_agent/config/tests/test_logging.py b/acapy_agent/config/tests/test_logging.py index 2e65770508..cf23074568 100644 --- a/acapy_agent/config/tests/test_logging.py +++ b/acapy_agent/config/tests/test_logging.py @@ -1,5 +1,5 @@ import contextlib -from io import StringIO +from io import BufferedReader, StringIO, TextIOWrapper from tempfile import NamedTemporaryFile from unittest import IsolatedAsyncioTestCase, mock @@ -110,24 +110,55 @@ def test_banner_did(self): def test_load_resource(self): # Testing local file access with mock.patch("builtins.open", mock.MagicMock()) as mock_open: - test_module.load_resource("abc", encoding="utf-8") + # First call succeeds + file_handle = mock.MagicMock(spec=TextIOWrapper) + mock_open.return_value = file_handle + result = test_module.load_resource("abc", encoding="utf-8") + mock_open.assert_called_once_with("abc", encoding="utf-8") + assert result == file_handle # Verify the returned file handle + + mock_open.reset_mock() + # Simulate IOError on second call mock_open.side_effect = IOError("insufficient privilege") # load_resource should absorb IOError - test_module.load_resource("abc", encoding="utf-8") + result = test_module.load_resource("abc", encoding="utf-8") + mock_open.assert_called_once_with("abc", encoding="utf-8") + assert result is None # Testing package resource access with encoding (text mode) - with mock.patch( - "importlib.resources.open_binary", mock.MagicMock() - ) as mock_open_binary, mock.patch( + with mock.patch("importlib.resources.files") as mock_files, mock.patch( "io.TextIOWrapper", mock.MagicMock() ) as mock_text_io_wrapper: - test_module.load_resource("abc:def", encoding="utf-8") - mock_open_binary.assert_called_once_with("abc", "def") - mock_text_io_wrapper.assert_called_once() + # Setup the mocks + mock_resource_path = mock.MagicMock() + mock_files.return_value.joinpath.return_value = mock_resource_path + mock_resource_handle = mock.MagicMock(spec=BufferedReader) + mock_resource_path.open.return_value = mock_resource_handle + mock_text_io_wrapper.return_value = mock.MagicMock(spec=TextIOWrapper) + + result = test_module.load_resource("abc:def", encoding="utf-8") + + # Assertions + mock_files.assert_called_once_with("abc") + mock_files.return_value.joinpath.assert_called_once_with("def") + mock_resource_path.open.assert_called_once_with("rb") + mock_text_io_wrapper.assert_called_once_with( + mock_resource_handle, encoding="utf-8" + ) + assert result is mock_text_io_wrapper.return_value # Testing package resource access without encoding (binary mode) - with mock.patch( - "importlib.resources.open_binary", mock.MagicMock() - ) as mock_open_binary: - test_module.load_resource("abc:def", encoding=None) - mock_open_binary.assert_called_once_with("abc", "def") + with mock.patch("importlib.resources.files") as mock_files: + # Setup the mocks + mock_resource_path = mock.MagicMock() + mock_files.return_value.joinpath.return_value = mock_resource_path + mock_resource_handle = mock.MagicMock(spec=BufferedReader) + mock_resource_path.open.return_value = mock_resource_handle + + result = test_module.load_resource("abc:def", encoding=None) + + # Assertions + mock_files.assert_called_once_with("abc") + mock_files.return_value.joinpath.assert_called_once_with("def") + mock_resource_path.open.assert_called_once_with("rb") + assert result == mock_resource_handle # Verify the returned binary stream From 573c2088d22e4e846bbb57840ae65d9cd7a72043 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 12:51:51 +0200 Subject: [PATCH 004/152] :art: Replace deprecated `scope` keyword with `loop_scope` Signed-off-by: ff137 --- acapy_agent/multitenant/admin/tests/test_routes.py | 4 ++-- .../v1_0/handlers/tests/test_response_handler.py | 10 +++++----- .../examples/tests/test_mediator_ping_agents.py | 14 +++++++------- demo/playground/examples/tests/test_ping_agents.py | 14 +++++++------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/acapy_agent/multitenant/admin/tests/test_routes.py b/acapy_agent/multitenant/admin/tests/test_routes.py index 87dcdde88d..2431e6f6d5 100644 --- a/acapy_agent/multitenant/admin/tests/test_routes.py +++ b/acapy_agent/multitenant/admin/tests/test_routes.py @@ -143,7 +143,7 @@ async def test_wallets_list_query(self): } ) - @pytest.mark.asyncio(scope="function") + @pytest.mark.asyncio(loop_scope="function") async def test_wallet_create_tenant_settings(self): body = { "wallet_name": "test", @@ -796,7 +796,7 @@ async def test_wallet_create_token_x(self): ) await test_module.wallet_create_token(self.request) - @pytest.mark.asyncio(scope="function") + @pytest.mark.asyncio(loop_scope="function") async def test_wallet_remove_managed(self): self.request.has_body = False self.request.match_info = {"wallet_id": "dummy"} diff --git a/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py b/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py index d177e2109f..87abd74791 100644 --- a/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py +++ b/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py @@ -75,7 +75,7 @@ async def asyncSetUp(self): did_doc_attach=self.did_doc_attach, ) - @pytest.mark.asyncio(scope="function") + @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") async def test_called(self, mock_didx_mgr): mock_didx_mgr.return_value.accept_response = mock.CoroutineMock() @@ -89,7 +89,7 @@ async def test_called(self, mock_didx_mgr): ) assert not responder.messages - @pytest.mark.asyncio(scope="function") + @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") async def test_called_auto_ping(self, mock_didx_mgr): self.ctx.update_settings({"auto_ping_connection": True}) @@ -107,7 +107,7 @@ async def test_called_auto_ping(self, mock_didx_mgr): result, _ = messages[0] assert isinstance(result, Ping) - @pytest.mark.asyncio(scope="function") + @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") @mock.patch.object(connection_target, "ConnectionTarget") async def test_problem_report(self, mock_conn_target, mock_didx_mgr): @@ -144,7 +144,7 @@ async def test_problem_report(self, mock_conn_target, mock_didx_mgr): ) assert target == {"target_list": [mock_conn_target]} - @pytest.mark.asyncio(scope="function") + @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") @mock.patch.object(connection_target, "ConnectionTarget") async def test_problem_report_did_doc( @@ -191,7 +191,7 @@ async def test_problem_report_did_doc( ) assert target == {"target_list": [mock_conn_target]} - @pytest.mark.asyncio(scope="function") + @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") @mock.patch.object(connection_target, "ConnectionTarget") async def test_problem_report_did_doc_no_conn_target( diff --git a/demo/playground/examples/tests/test_mediator_ping_agents.py b/demo/playground/examples/tests/test_mediator_ping_agents.py index d734dc14d7..7b1a1c4af5 100644 --- a/demo/playground/examples/tests/test_mediator_ping_agents.py +++ b/demo/playground/examples/tests/test_mediator_ping_agents.py @@ -16,21 +16,21 @@ logger.info("start testing mediated connections...") -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def faber(): """faber agent fixture.""" logger.info(f"faber = {FABER}") yield Agent(FABER) -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def alice(): """resolver agent fixture.""" logger.info(f"alice = {ALICE}") yield Agent(ALICE) -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def multi_one(): """resolver agent fixture.""" agent = Agent(MULTI) @@ -42,7 +42,7 @@ def multi_one(): yield agent -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def mediation_invite(): invitation_url = os.getenv("MEDIATOR_INVITATION_URL") logger.info(f"MEDIATOR_INVITATION_URL = {invitation_url}") @@ -97,7 +97,7 @@ def initialize_mediation(agent: Agent, invitation): return result -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def faber_mediator(faber, mediation_invite): logger.info("faber_mediator...") result = initialize_mediation(faber, mediation_invite) @@ -105,7 +105,7 @@ def faber_mediator(faber, mediation_invite): yield result -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def alice_mediator(alice, mediation_invite): logger.info("alice_mediator...") result = initialize_mediation(alice, mediation_invite) @@ -113,7 +113,7 @@ def alice_mediator(alice, mediation_invite): yield result -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def multi_one_mediator(multi_one, mediation_invite): logger.info("multi_one_mediator...") result = initialize_mediation(multi_one, mediation_invite) diff --git a/demo/playground/examples/tests/test_ping_agents.py b/demo/playground/examples/tests/test_ping_agents.py index 64cb4cdad1..13846181f8 100644 --- a/demo/playground/examples/tests/test_ping_agents.py +++ b/demo/playground/examples/tests/test_ping_agents.py @@ -11,19 +11,19 @@ from . import ALICE, FABER, MULTI, Agent, logger -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def faber(): """faber agent fixture.""" yield Agent(FABER) -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def alice(): """resolver agent fixture.""" yield Agent(ALICE) -@pytest.fixture(scope="session") +@pytest.fixture(loop_scope="session") def multi_one(): """resolver agent fixture.""" agent = Agent(MULTI) @@ -35,7 +35,7 @@ def multi_one(): yield agent -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(loop_scope="session", autouse=True) def alice_faber_connection(faber, alice): """Established connection filter.""" logger.info("faber create invitation to alice") @@ -48,7 +48,7 @@ def alice_faber_connection(faber, alice): return result -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(loop_scope="session", autouse=True) def faber_alice_connection(faber, alice): """Established connection filter.""" logger.info("alice create invitation to faber") @@ -61,7 +61,7 @@ def faber_alice_connection(faber, alice): return result -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(loop_scope="session", autouse=True) def alice_multi_one_connection(multi_one, alice): """Established connection filter.""" logger.info("multi_one create invitation to alice") @@ -74,7 +74,7 @@ def alice_multi_one_connection(multi_one, alice): return result -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(loop_scope="session", autouse=True) def multi_one_alice_connection(multi_one, alice): """Established connection filter.""" logger.info("alice create invitation to multi_one") From 70364a41388eeb6efb5c97d2b279e1bfe957e15b Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 12:59:48 +0200 Subject: [PATCH 005/152] :art: Filter Aries RFC 0160 DeprecationWarning in tests Signed-off-by: ff137 --- acapy_agent/core/tests/test_conductor.py | 1 + acapy_agent/protocols/connections/v1_0/tests/test_manager.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/acapy_agent/core/tests/test_conductor.py b/acapy_agent/core/tests/test_conductor.py index 4d3da3959b..875623deee 100644 --- a/acapy_agent/core/tests/test_conductor.py +++ b/acapy_agent/core/tests/test_conductor.py @@ -1186,6 +1186,7 @@ async def test_dispatch_complete_fatal_x(self): conductor.dispatch_complete(message, mock_task) mock_notify.assert_called_once_with() + @pytest.mark.filterwarnings("ignore:Aries RFC 0160.*:DeprecationWarning") async def test_print_invite_connection(self): builder: ContextBuilder = StubContextBuilder(self.test_settings) builder.update_settings( diff --git a/acapy_agent/protocols/connections/v1_0/tests/test_manager.py b/acapy_agent/protocols/connections/v1_0/tests/test_manager.py index 2d1896b652..a96363dc00 100644 --- a/acapy_agent/protocols/connections/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/connections/v1_0/tests/test_manager.py @@ -1,5 +1,7 @@ from unittest import IsolatedAsyncioTestCase +import pytest + from .....cache.base import BaseCache from .....cache.in_memory import InMemoryCache from .....connections.models.conn_record import ConnRecord @@ -29,6 +31,7 @@ from ..models.connection_detail import ConnectionDetail +@pytest.mark.filterwarnings("ignore:Aries RFC 0160.*:DeprecationWarning") class TestConnectionManager(IsolatedAsyncioTestCase): def make_did_doc(self, did, verkey): doc = DIDDoc(did=did) From 6f967c6719306d8105794eba9bf0dedf394ac40d Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 13:02:35 +0200 Subject: [PATCH 006/152] :art: Filter Pydantic UserWarning in test Signed-off-by: ff137 --- acapy_agent/connections/tests/test_base_manager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acapy_agent/connections/tests/test_base_manager.py b/acapy_agent/connections/tests/test_base_manager.py index 57cd426c2d..84089929ca 100644 --- a/acapy_agent/connections/tests/test_base_manager.py +++ b/acapy_agent/connections/tests/test_base_manager.py @@ -3,6 +3,7 @@ from unittest import IsolatedAsyncioTestCase from unittest.mock import call +import pytest from pydid import DID, DIDDocument, DIDDocumentBuilder from pydid.doc.builder import ServiceBuilder from pydid.verification_method import ( @@ -27,9 +28,7 @@ from ...protocols.connections.v1_0.messages.connection_invitation import ( ConnectionInvitation, ) -from ...protocols.coordinate_mediation.v1_0.models.mediation_record import ( - MediationRecord, -) +from ...protocols.coordinate_mediation.v1_0.models.mediation_record import MediationRecord from ...protocols.coordinate_mediation.v1_0.route_manager import ( CoordinateMediationV1RouteManager, RouteManager, @@ -1065,6 +1064,7 @@ async def test_resolve_connection_targets_x_bad_key_material(self): await self.manager.resolve_connection_targets(did) assert "not supported" in str(cm.exception) + @pytest.mark.filterwarnings("ignore::UserWarning") async def test_resolve_connection_targets_x_unsupported_key(self): did = "did:sov:" + self.test_did doc_builder = DIDDocumentBuilder(did) From c65f6ce7e02eaa9f3aaa20c634901003fb2ec1ca Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 13:04:38 +0200 Subject: [PATCH 007/152] :arrow_up: Upgrade aiohttp to latest release and update lock file Signed-off-by: ff137 --- poetry.lock | 762 +++++++++++++++++++++++-------------------------- pyproject.toml | 2 +- 2 files changed, 366 insertions(+), 398 deletions(-) diff --git a/poetry.lock b/poetry.lock index baafdb007a..cc45282759 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -13,102 +13,87 @@ files = [ [[package]] name = "aiohttp" -version = "3.10.10" +version = "3.11.0" description = "Async http client/server framework (asyncio)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f"}, - {file = "aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9"}, - {file = "aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026"}, - {file = "aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc"}, - {file = "aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68"}, - {file = "aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257"}, - {file = "aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a"}, - {file = "aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94"}, - {file = "aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205"}, - {file = "aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628"}, - {file = "aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d"}, - {file = "aiohttp-3.10.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e"}, - {file = "aiohttp-3.10.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67"}, - {file = "aiohttp-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b"}, - {file = "aiohttp-3.10.10-cp313-cp313-win32.whl", hash = "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8"}, - {file = "aiohttp-3.10.10-cp313-cp313-win_amd64.whl", hash = "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1b66ccafef7336a1e1f0e389901f60c1d920102315a56df85e49552308fc0486"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:acd48d5b80ee80f9432a165c0ac8cbf9253eaddb6113269a5e18699b33958dbb"}, - {file = "aiohttp-3.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3455522392fb15ff549d92fbf4b73b559d5e43dc522588f7eb3e54c3f38beee7"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c3b868724137f713a38376fef8120c166d1eadd50da1855c112fe97954aed8"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da1dee8948d2137bb51fbb8a53cce6b1bcc86003c6b42565f008438b806cccd8"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5ce2ce7c997e1971b7184ee37deb6ea9922ef5163c6ee5aa3c274b05f9e12fa"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28529e08fde6f12eba8677f5a8608500ed33c086f974de68cc65ab218713a59d"}, - {file = "aiohttp-3.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7db54c7914cc99d901d93a34704833568d86c20925b2762f9fa779f9cd2e70f"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03a42ac7895406220124c88911ebee31ba8b2d24c98507f4a8bf826b2937c7f2"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7e338c0523d024fad378b376a79faff37fafb3c001872a618cde1d322400a572"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:038f514fe39e235e9fef6717fbf944057bfa24f9b3db9ee551a7ecf584b5b480"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:64f6c17757251e2b8d885d728b6433d9d970573586a78b78ba8929b0f41d045a"}, - {file = "aiohttp-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:93429602396f3383a797a2a70e5f1de5df8e35535d7806c9f91df06f297e109b"}, - {file = "aiohttp-3.10.10-cp38-cp38-win32.whl", hash = "sha256:c823bc3971c44ab93e611ab1a46b1eafeae474c0c844aff4b7474287b75fe49c"}, - {file = "aiohttp-3.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:54ca74df1be3c7ca1cf7f4c971c79c2daf48d9aa65dea1a662ae18926f5bc8ce"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:01948b1d570f83ee7bbf5a60ea2375a89dfb09fd419170e7f5af029510033d24"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9fc1500fd2a952c5c8e3b29aaf7e3cc6e27e9cfc0a8819b3bce48cc1b849e4cc"}, - {file = "aiohttp-3.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f614ab0c76397661b90b6851a030004dac502e48260ea10f2441abd2207fbcc7"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00819de9e45d42584bed046314c40ea7e9aea95411b38971082cad449392b08c"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05646ebe6b94cc93407b3bf34b9eb26c20722384d068eb7339de802154d61bc5"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:998f3bd3cfc95e9424a6acd7840cbdd39e45bc09ef87533c006f94ac47296090"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9010c31cd6fa59438da4e58a7f19e4753f7f264300cd152e7f90d4602449762"}, - {file = "aiohttp-3.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ea7ffc6d6d6f8a11e6f40091a1040995cdff02cfc9ba4c2f30a516cb2633554"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ef9c33cc5cbca35808f6c74be11eb7f5f6b14d2311be84a15b594bd3e58b5527"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ce0cdc074d540265bfeb31336e678b4e37316849d13b308607efa527e981f5c2"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:597a079284b7ee65ee102bc3a6ea226a37d2b96d0418cc9047490f231dc09fe8"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7789050d9e5d0c309c706953e5e8876e38662d57d45f936902e176d19f1c58ab"}, - {file = "aiohttp-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e7f8b04d83483577fd9200461b057c9f14ced334dcb053090cea1da9c8321a91"}, - {file = "aiohttp-3.10.10-cp39-cp39-win32.whl", hash = "sha256:c02a30b904282777d872266b87b20ed8cc0d1501855e27f831320f471d54d983"}, - {file = "aiohttp-3.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:edfe3341033a6b53a5c522c802deb2079eee5cbfbb0af032a55064bd65c73a23"}, - {file = "aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a"}, + {file = "aiohttp-3.11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:024409c1b1d6076d0ed933dcebd7e4fc6f3320a227bfa0c1b6b93a8b5a146f04"}, + {file = "aiohttp-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:62502b8ffee8c6a4b5c6bf99d1de277d42bf51b2fb713975d9b63b560150b7ac"}, + {file = "aiohttp-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c54c635d1f52490cde7ef3a423645167a8284e452a35405d5c7dc1242a8e75c9"}, + {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:104ea21994b1403e4c1b398866f1187c1694fa291314ad7216ec1d8ec6b49f38"}, + {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b24497b3baf15035730de5f207ade88a67d4483a5f16ced7ece348933a5b47"}, + {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08474e71772a516ba2e2167b4707af8361d2c452b3d8a5364c984f4867869499"}, + {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f40380c96dd407dfa84eb2d264e68aa47717b53bdbe210a59cc3c35a4635f195"}, + {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1668ef2f3a7ec9881f4b6a917e5f97c87a343fa6b0d5fc826b7b0297ddd0887"}, + {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f3bf5c132eb48002bcc3825702d241d35b4e9585009e65e9dcf9c4635d0b7424"}, + {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0315978b2a4569e03fb59100f6a7e7d23f718a4521491f5c13d946d37549f3d"}, + {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d5cae4cd271e20b7ab757e966cc919186b9f02535418ab36c471a5377ef4deaa"}, + {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:31b91ff3a1fcb206a1fa76e0de1f08c9ffb1dc0deb7296fa2618adfe380fc676"}, + {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ebf610c37df4f09c71c9bbf8309b4b459107e6fe889ac0d7e16f6e4ebd975f86"}, + {file = "aiohttp-3.11.0-cp310-cp310-win32.whl", hash = "sha256:b40c304ab01e89ad0aeeecf91bbaa6ae3b00e27b796c9e8d50b71a4a7e885cc8"}, + {file = "aiohttp-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd0834e4260eab78671b81d34f110fbaac449563e48d419cec0030d9a8e58693"}, + {file = "aiohttp-3.11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:89a96a0696dc67d548f69cb518c581a7a33cc1f26ab42229dea1709217c9d926"}, + {file = "aiohttp-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6b925c7775ab857bdc1e52e1f5abcae7d18751c09b751aeb641a5276d9b990e"}, + {file = "aiohttp-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7867d0808614f04e78e0a8d5a2c1f8ac6bc626a0c0e2f62be48be6b749e2f8b2"}, + {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:229ae13959a5f499d90ffbb4b9eac2255d8599315027d6f7c22fa9803a94d5b1"}, + {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a2f5268b672087c45b33479ba1bb1d5a48c6d76c133cfce3a4f77410c200d1"}, + {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a896059b6937d1a22d8ee8377cdcd097bd26cd8c653b8f972051488b9baadee9"}, + {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:104deb7873681273c5daa13c41924693df394043a118dae90387d35bc5531788"}, + {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae36ae52b0c22fb69fb8b744eff82a20db512a29eafc6e3a4ab43b17215b219d"}, + {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7349205bb163318dcc102329d30be59a647a3d24c82c3d91ed35b7e7301ea7e"}, + {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9095580806d9ed07c0c29b23364a0b1fb78258ef9f4bddf7e55bac0e475d4edf"}, + {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4d218d3eca40196384ad3b481309c56fd60e664128885d1734da0a8aa530d433"}, + {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6533dd06df3d17d1756829b68b365b1583929b54082db8f65083a4184bf68322"}, + {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72cd984f7f14e8c01b3e38f18f39ea85dba84e52ea05e37116ba5e2a72eef396"}, + {file = "aiohttp-3.11.0-cp311-cp311-win32.whl", hash = "sha256:c1828e10c3a49e2b234b87600ecb68a92b8a8dcf8b99bca9447f16c4baaa1630"}, + {file = "aiohttp-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:900ff74d78eb580ae4aa5883242893b123a0c442a46570902500f08d6a7e6696"}, + {file = "aiohttp-3.11.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f8f0d79b923070f25674e4ea8f3d61c9d89d24d9598d50ff32c5b9b23c79a25b"}, + {file = "aiohttp-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:113bf06b029143e94a47c4f36e11a8b7e396e9d1f1fc8cea58e6b7e370cfed38"}, + {file = "aiohttp-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3e1ed8d152cccceffb1ee7a2ac227c16372e453fb11b3aeaa56783049b85d3f6"}, + {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2e82e515e268b965424ecabebd91834a41b36260b6ef5db015ee12ddb28ef3"}, + {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1c49bc393d854d4421ebc174a0a41f9261f50d3694d8ca277146cbbcfd24ee7"}, + {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57e17c6d71f2dc857a8a1d09be1be7802e35d90fb4ba4b06cf1aab6414a57894"}, + {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12071dd2cc95ba81e0f2737bebcb98b2a8656015e87772e84e8fb9e635b5da6e"}, + {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97056d3422594e0787733ac4c45bef58722d452f4dc6615fee42f59fe51707dd"}, + {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2ec5efbc872b00ddd85e3904059d274f284cff314e13f48776050ca2c58f451d"}, + {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dd505a1121ad5b666191840b7bd1d8cb917df2647deeca6f3474331b72452362"}, + {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:600b1d9f86a130131915e2f2127664311b33902c486b21a747d626f5144b4471"}, + {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8c47a0ba6c2b3d3e5715f8338d657badd21f778c6be16701922c65521c5ecfc9"}, + {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8b323b5d3aef7dd811424c269322eec58a977c0c8152e650159e47210d900504"}, + {file = "aiohttp-3.11.0-cp312-cp312-win32.whl", hash = "sha256:aabc4e92cb153636d6be54e84dad1b252ddb9aebe077942b6dcffe5e468d476a"}, + {file = "aiohttp-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:508cfcc99534b1282595357592d8367b44392b21f6eb5d4dc021f8d0d809e94d"}, + {file = "aiohttp-3.11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c98a596ac20e8980cc6f34c0c92a113e98eb08f3997c150064d26d2aeb043e5a"}, + {file = "aiohttp-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ad14cdc0fba4df31c0f6e06c21928c5b924725cbf60d0ccc5f6e7132636250e9"}, + {file = "aiohttp-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:170fb2324826bb9f08055a8291f42192ae5ee2f25b2966c8f0f4537c61d73a7b"}, + {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdad66685fcf2ad14ce522cf849d4a025f4fd206d6cfc3f403d9873e4c243b03"}, + {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8b95a63a8e8b5f0464bd8b1b0d59d2bec98a59b6aacc71e9be23df6989b3dfb"}, + {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7bcfcede95531589295f56e924702cef7f9685c9e4e5407592e04ded6a65bf3"}, + {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ecc2fb1a0a9d48cf773add34196cddf7e488e48e9596e090849751bf43098f4"}, + {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fef105113d56e817cb9bcc609667ee461321413a7b972b03f5b4939f40f307c"}, + {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d33b4490026968bdc7f0729b9d87a3a6b1e09043557d2fc1c605c6072deb2f11"}, + {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6362f50a6f0e5482c4330d2151cb682779230683da0e155c15ec9fc58cb50b6a"}, + {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4f698aa61879df64425191d41213dfd99efdc1627e6398e6d7aa5c312fac9702"}, + {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0e7a0762cc29cd3acd01a4d2b547b3af7956ad230ebb80b529a8e4f3e4740fe8"}, + {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b3e4fb7f5354d39490d8209aefdf5830b208d01c7293a2164e404312c3d8bc55"}, + {file = "aiohttp-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6c5a6958f4366496004cf503d847093d464814543f157ef3b738bbf604232415"}, + {file = "aiohttp-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:3ed360d6672a9423aad39902a4e9fe305464d20ed7931dbdba30a4625782d875"}, + {file = "aiohttp-3.11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d1ea006426edf7e1299c52a58b0443158012f7a56fed3515164b60bfcb1503a9"}, + {file = "aiohttp-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c5e6a1f8b0268ffa1c84d7c3558724956002ba8361176e76406233e704bbcffb"}, + {file = "aiohttp-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:40dc9446cff326672fcbf93efdb8ef7e949824de1097624efe4f61ac7f0d2c43"}, + {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b4545e8d96870da9652930c5198366605ff8f982757030e2148cf341e5746b"}, + {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37f8cf3c43f292d9bb3e6760476c2b55b9663a581fad682a586a410c43a7683e"}, + {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329f5059e0bf6983dceebac8e6ed20e75eaff6163b3414f4a4cb59e0d7037672"}, + {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ae6f182be72c3531915e90625cc65afce4df8a0fc4988bd52d8a5d5faaeb68"}, + {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d664e5f937c08adb7908ea9f391fbf2928a9b09cb412ac0aba602bde9e499e4"}, + {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:feca9fafa4385aea6759c171cd25ea82f7375312fca04178dae35331be45e538"}, + {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c415b9601ff50709d6050c8a9281733a9b042b9e589265ac40305b875cf9c463"}, + {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:91d3991fad8b65e5dbc13cd95669ea689fe0a96ff63e4e64ac24ed724e4f8103"}, + {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9231d610754724273a6ac05a1f177979490bfa6f84d49646df3928af2e88cfd5"}, + {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4e4e155968040e32c124a89852a1a5426d0e920a35f4331e1b3949037bfe93a3"}, + {file = "aiohttp-3.11.0-cp39-cp39-win32.whl", hash = "sha256:76d6ee8bb132f8ee0fcb0e205b4708ddb6fba524eb515ee168113063d825131b"}, + {file = "aiohttp-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:577c7429f8869fa30186fc2c9eee64d75a30b51b61f26aac9725866ae5985cfd"}, + {file = "aiohttp-3.11.0.tar.gz", hash = "sha256:f57a0de48dda792629e7952d34a0c7b81ea336bb9b721391c7c58145b237fe55"}, ] [package.dependencies] @@ -117,7 +102,8 @@ aiosignal = ">=1.1.2" attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" -yarl = ">=1.12.0,<2.0" +propcache = ">=0.2.0" +yarl = ">=1.17.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] @@ -573,73 +559,73 @@ yaml = ["PyYAML"] [[package]] name = "coverage" -version = "7.6.3" +version = "7.6.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6da42bbcec130b188169107ecb6ee7bd7b4c849d24c9370a0c884cf728d8e976"}, - {file = "coverage-7.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c222958f59b0ae091f4535851cbb24eb57fc0baea07ba675af718fb5302dddb2"}, - {file = "coverage-7.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab84a8b698ad5a6c365b08061920138e7a7dd9a04b6feb09ba1bfae68346ce6d"}, - {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70a6756ce66cd6fe8486c775b30889f0dc4cb20c157aa8c35b45fd7868255c5c"}, - {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c2e6fa98032fec8282f6b27e3f3986c6e05702828380618776ad794e938f53a"}, - {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:921fbe13492caf6a69528f09d5d7c7d518c8d0e7b9f6701b7719715f29a71e6e"}, - {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6d99198203f0b9cb0b5d1c0393859555bc26b548223a769baf7e321a627ed4fc"}, - {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:87cd2e29067ea397a47e352efb13f976eb1b03e18c999270bb50589323294c6e"}, - {file = "coverage-7.6.3-cp310-cp310-win32.whl", hash = "sha256:a3328c3e64ea4ab12b85999eb0779e6139295bbf5485f69d42cf794309e3d007"}, - {file = "coverage-7.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:bca4c8abc50d38f9773c1ec80d43f3768df2e8576807d1656016b9d3eeaa96fd"}, - {file = "coverage-7.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b"}, - {file = "coverage-7.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba"}, - {file = "coverage-7.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38"}, - {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549"}, - {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2"}, - {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175"}, - {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b"}, - {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f"}, - {file = "coverage-7.6.3-cp311-cp311-win32.whl", hash = "sha256:43517e1f6b19f610a93d8227e47790722c8bf7422e46b365e0469fc3d3563d97"}, - {file = "coverage-7.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:04f2189716e85ec9192df307f7c255f90e78b6e9863a03223c3b998d24a3c6c6"}, - {file = "coverage-7.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27bd5f18d8f2879e45724b0ce74f61811639a846ff0e5c0395b7818fae87aec6"}, - {file = "coverage-7.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d546cfa78844b8b9c1c0533de1851569a13f87449897bbc95d698d1d3cb2a30f"}, - {file = "coverage-7.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9975442f2e7a5cfcf87299c26b5a45266ab0696348420049b9b94b2ad3d40234"}, - {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:583049c63106c0555e3ae3931edab5669668bbef84c15861421b94e121878d3f"}, - {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2341a78ae3a5ed454d524206a3fcb3cec408c2a0c7c2752cd78b606a2ff15af4"}, - {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a4fb91d5f72b7e06a14ff4ae5be625a81cd7e5f869d7a54578fc271d08d58ae3"}, - {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e279f3db904e3b55f520f11f983cc8dc8a4ce9b65f11692d4718ed021ec58b83"}, - {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aa23ce39661a3e90eea5f99ec59b763b7d655c2cada10729ed920a38bfc2b167"}, - {file = "coverage-7.6.3-cp312-cp312-win32.whl", hash = "sha256:52ac29cc72ee7e25ace7807249638f94c9b6a862c56b1df015d2b2e388e51dbd"}, - {file = "coverage-7.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:40e8b1983080439d4802d80b951f4a93d991ef3261f69e81095a66f86cf3c3c6"}, - {file = "coverage-7.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9134032f5aa445ae591c2ba6991d10136a1f533b1d2fa8f8c21126468c5025c6"}, - {file = "coverage-7.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:99670790f21a96665a35849990b1df447993880bb6463a0a1d757897f30da929"}, - {file = "coverage-7.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc7d6b380ca76f5e817ac9eef0c3686e7834c8346bef30b041a4ad286449990"}, - {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7b26757b22faf88fcf232f5f0e62f6e0fd9e22a8a5d0d5016888cdfe1f6c1c4"}, - {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c59d6a4a4633fad297f943c03d0d2569867bd5372eb5684befdff8df8522e39"}, - {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f263b18692f8ed52c8de7f40a0751e79015983dbd77b16906e5b310a39d3ca21"}, - {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79644f68a6ff23b251cae1c82b01a0b51bc40c8468ca9585c6c4b1aeee570e0b"}, - {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:71967c35828c9ff94e8c7d405469a1fb68257f686bca7c1ed85ed34e7c2529c4"}, - {file = "coverage-7.6.3-cp313-cp313-win32.whl", hash = "sha256:e266af4da2c1a4cbc6135a570c64577fd3e6eb204607eaff99d8e9b710003c6f"}, - {file = "coverage-7.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:ea52bd218d4ba260399a8ae4bb6b577d82adfc4518b93566ce1fddd4a49d1dce"}, - {file = "coverage-7.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8d4c6ea0f498c7c79111033a290d060c517853a7bcb2f46516f591dab628ddd3"}, - {file = "coverage-7.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:331b200ad03dbaa44151d74daeb7da2cf382db424ab923574f6ecca7d3b30de3"}, - {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54356a76b67cf8a3085818026bb556545ebb8353951923b88292556dfa9f812d"}, - {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebec65f5068e7df2d49466aab9128510c4867e532e07cb6960075b27658dca38"}, - {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33a785ea8354c480515e781554d3be582a86297e41ccbea627a5c632647f2cd"}, - {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f7ddb920106bbbbcaf2a274d56f46956bf56ecbde210d88061824a95bdd94e92"}, - {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:70d24936ca6c15a3bbc91ee9c7fc661132c6f4c9d42a23b31b6686c05073bde5"}, - {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c30e42ea11badb147f0d2e387115b15e2bd8205a5ad70d6ad79cf37f6ac08c91"}, - {file = "coverage-7.6.3-cp313-cp313t-win32.whl", hash = "sha256:365defc257c687ce3e7d275f39738dcd230777424117a6c76043459db131dd43"}, - {file = "coverage-7.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:23bb63ae3f4c645d2d82fa22697364b0046fbafb6261b258a58587441c5f7bd0"}, - {file = "coverage-7.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:da29ceabe3025a1e5a5aeeb331c5b1af686daab4ff0fb4f83df18b1180ea83e2"}, - {file = "coverage-7.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df8c05a0f574d480947cba11b947dc41b1265d721c3777881da2fb8d3a1ddfba"}, - {file = "coverage-7.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1e3b40b82236d100d259854840555469fad4db64f669ab817279eb95cd535c"}, - {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4adeb878a374126f1e5cf03b87f66279f479e01af0e9a654cf6d1509af46c40"}, - {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43d6a66e33b1455b98fc7312b124296dad97a2e191c80320587234a77b1b736e"}, - {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1990b1f4e2c402beb317840030bb9f1b6a363f86e14e21b4212e618acdfce7f6"}, - {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:12f9515d875859faedb4144fd38694a761cd2a61ef9603bf887b13956d0bbfbb"}, - {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99ded130555c021d99729fabd4ddb91a6f4cc0707df4b1daf912c7850c373b13"}, - {file = "coverage-7.6.3-cp39-cp39-win32.whl", hash = "sha256:c3a79f56dee9136084cf84a6c7c4341427ef36e05ae6415bf7d787c96ff5eaa3"}, - {file = "coverage-7.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:aac7501ae73d4a02f4b7ac8fcb9dc55342ca98ffb9ed9f2dfb8a25d53eda0e4d"}, - {file = "coverage-7.6.3-pp39.pp310-none-any.whl", hash = "sha256:b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181"}, - {file = "coverage-7.6.3.tar.gz", hash = "sha256:bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054"}, + {file = "coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07"}, + {file = "coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0"}, + {file = "coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72"}, + {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51"}, + {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491"}, + {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b"}, + {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea"}, + {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a"}, + {file = "coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa"}, + {file = "coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172"}, + {file = "coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b"}, + {file = "coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25"}, + {file = "coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546"}, + {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b"}, + {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e"}, + {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718"}, + {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db"}, + {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522"}, + {file = "coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf"}, + {file = "coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19"}, + {file = "coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2"}, + {file = "coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117"}, + {file = "coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613"}, + {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27"}, + {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52"}, + {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2"}, + {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1"}, + {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5"}, + {file = "coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17"}, + {file = "coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08"}, + {file = "coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9"}, + {file = "coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba"}, + {file = "coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c"}, + {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06"}, + {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f"}, + {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b"}, + {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21"}, + {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a"}, + {file = "coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e"}, + {file = "coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963"}, + {file = "coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f"}, + {file = "coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806"}, + {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11"}, + {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3"}, + {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a"}, + {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc"}, + {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70"}, + {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef"}, + {file = "coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e"}, + {file = "coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1"}, + {file = "coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3"}, + {file = "coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c"}, + {file = "coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076"}, + {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376"}, + {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0"}, + {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"}, + {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111"}, + {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901"}, + {file = "coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09"}, + {file = "coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f"}, + {file = "coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e"}, + {file = "coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73"}, ] [package.extras] @@ -647,38 +633,38 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "43.0.1" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"}, - {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"}, - {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"}, - {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"}, - {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"}, - {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"}, - {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"}, - {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"}, - {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"}, - {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"}, - {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -691,7 +677,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -969,20 +955,19 @@ test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-utils" -version = "5.0.0" +version = "5.1.0" description = "eth-utils: Common utility functions for python code that interacts with Ethereum" optional = false python-versions = "<4,>=3.8" files = [ - {file = "eth_utils-5.0.0-py3-none-any.whl", hash = "sha256:99c44eca11db74dbb881a1d70b24cd80436fc62fe527d2f5c3e3cf7932aba7b2"}, - {file = "eth_utils-5.0.0.tar.gz", hash = "sha256:a5eb9555f43f4579eb83cb84f9dda9f3d6663bbd4a5a6b693f8d35045f305a1f"}, + {file = "eth_utils-5.1.0-py3-none-any.whl", hash = "sha256:a99f1f01b51206620904c5af47fac65abc143aebd0a76bdec860381c5a3230f8"}, + {file = "eth_utils-5.1.0.tar.gz", hash = "sha256:84c6314b9cf1fcd526107464bbf487e3f87097a2e753360d5ed319f7d42e3f20"}, ] [package.dependencies] cytoolz = {version = ">=0.10.1", markers = "implementation_name == \"cpython\""} eth-hash = ">=0.3.1" eth-typing = ">=5.0.0" -hexbytes = ">=1.0.0" toolz = {version = ">0.8.2", markers = "implementation_name == \"pypy\""} [package.extras] @@ -1070,115 +1055,114 @@ files = [ [[package]] name = "frozenlist" -version = "1.4.1" +version = "1.5.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" files = [ - {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, - {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, - {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, - {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, - {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, - {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, - {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, - {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, - {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, - {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, - {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, - {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, - {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, - {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, - {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, -] - -[[package]] -name = "hexbytes" -version = "1.2.1" -description = "hexbytes: Python `bytes` subclass that decodes hex, with a readable console output" -optional = false -python-versions = "<4,>=3.8" -files = [ - {file = "hexbytes-1.2.1-py3-none-any.whl", hash = "sha256:e64890b203a31f4a23ef11470ecfcca565beaee9198df623047df322b757471a"}, - {file = "hexbytes-1.2.1.tar.gz", hash = "sha256:515f00dddf31053db4d0d7636dd16061c1d896c3109b8e751005db4ca46bcca7"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5"}, + {file = "frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb"}, + {file = "frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, + {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, + {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f"}, + {file = "frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8"}, + {file = "frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03"}, + {file = "frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c"}, + {file = "frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e"}, + {file = "frozenlist-1.5.0-cp38-cp38-win32.whl", hash = "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723"}, + {file = "frozenlist-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c"}, + {file = "frozenlist-1.5.0-cp39-cp39-win32.whl", hash = "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3"}, + {file = "frozenlist-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0"}, + {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, + {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, ] -[package.extras] -dev = ["build (>=0.9.0)", "bump-my-version (>=0.19.0)", "eth-utils (>=2.0.0)", "hypothesis (>=3.44.24,<=6.31.6)", "ipython", "mypy (==1.10.0)", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] -test = ["eth-utils (>=2.0.0)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] - [[package]] name = "identify" -version = "2.6.1" +version = "2.6.2" description = "File identification library for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"}, - {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"}, + {file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"}, + {file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"}, ] [package.extras] @@ -2340,13 +2324,13 @@ testing = ["filelock"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -2889,13 +2873,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.26.6" +version = "20.27.1" description = "Virtual Python Environment builder" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"}, - {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"}, + {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, + {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, ] [package.dependencies] @@ -2942,109 +2926,93 @@ tests = ["Django (>=2.2.0)", "Flask (>=0.12.5)", "aiohttp (>=3.0.8)", "bottle (> [[package]] name = "yarl" -version = "1.15.2" +version = "1.17.1" description = "Yet another URL library" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "yarl-1.15.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e4ee8b8639070ff246ad3649294336b06db37a94bdea0d09ea491603e0be73b8"}, - {file = "yarl-1.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7cf963a357c5f00cb55b1955df8bbe68d2f2f65de065160a1c26b85a1e44172"}, - {file = "yarl-1.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:43ebdcc120e2ca679dba01a779333a8ea76b50547b55e812b8b92818d604662c"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3433da95b51a75692dcf6cc8117a31410447c75a9a8187888f02ad45c0a86c50"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38d0124fa992dbacd0c48b1b755d3ee0a9f924f427f95b0ef376556a24debf01"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ded1b1803151dd0f20a8945508786d57c2f97a50289b16f2629f85433e546d47"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace4cad790f3bf872c082366c9edd7f8f8f77afe3992b134cfc810332206884f"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c77494a2f2282d9bbbbcab7c227a4d1b4bb829875c96251f66fb5f3bae4fb053"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b7f227ca6db5a9fda0a2b935a2ea34a7267589ffc63c8045f0e4edb8d8dcf956"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:31561a5b4d8dbef1559b3600b045607cf804bae040f64b5f5bca77da38084a8a"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3e52474256a7db9dcf3c5f4ca0b300fdea6c21cca0148c8891d03a025649d935"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1af74a9529a1137c67c887ed9cde62cff53aa4d84a3adbec329f9ec47a3936"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:15c87339490100c63472a76d87fe7097a0835c705eb5ae79fd96e343473629ed"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:74abb8709ea54cc483c4fb57fb17bb66f8e0f04438cff6ded322074dbd17c7ec"}, - {file = "yarl-1.15.2-cp310-cp310-win32.whl", hash = "sha256:ffd591e22b22f9cb48e472529db6a47203c41c2c5911ff0a52e85723196c0d75"}, - {file = "yarl-1.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:1695497bb2a02a6de60064c9f077a4ae9c25c73624e0d43e3aa9d16d983073c2"}, - {file = "yarl-1.15.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9fcda20b2de7042cc35cf911702fa3d8311bd40055a14446c1e62403684afdc5"}, - {file = "yarl-1.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0545de8c688fbbf3088f9e8b801157923be4bf8e7b03e97c2ecd4dfa39e48e0e"}, - {file = "yarl-1.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fbda058a9a68bec347962595f50546a8a4a34fd7b0654a7b9697917dc2bf810d"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ac2bc069f4a458634c26b101c2341b18da85cb96afe0015990507efec2e417"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd126498171f752dd85737ab1544329a4520c53eed3997f9b08aefbafb1cc53b"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3db817b4e95eb05c362e3b45dafe7144b18603e1211f4a5b36eb9522ecc62bcf"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:076b1ed2ac819933895b1a000904f62d615fe4533a5cf3e052ff9a1da560575c"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f8cfd847e6b9ecf9f2f2531c8427035f291ec286c0a4944b0a9fce58c6446046"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32b66be100ac5739065496c74c4b7f3015cef792c3174982809274d7e51b3e04"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:34a2d76a1984cac04ff8b1bfc939ec9dc0914821264d4a9c8fd0ed6aa8d4cfd2"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0afad2cd484908f472c8fe2e8ef499facee54a0a6978be0e0cff67b1254fd747"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c68e820879ff39992c7f148113b46efcd6ec765a4865581f2902b3c43a5f4bbb"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:98f68df80ec6ca3015186b2677c208c096d646ef37bbf8b49764ab4a38183931"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56ec1eacd0a5d35b8a29f468659c47f4fe61b2cab948ca756c39b7617f0aa5"}, - {file = "yarl-1.15.2-cp311-cp311-win32.whl", hash = "sha256:eedc3f247ee7b3808ea07205f3e7d7879bc19ad3e6222195cd5fbf9988853e4d"}, - {file = "yarl-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:0ccaa1bc98751fbfcf53dc8dfdb90d96e98838010fc254180dd6707a6e8bb179"}, - {file = "yarl-1.15.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:82d5161e8cb8f36ec778fd7ac4d740415d84030f5b9ef8fe4da54784a1f46c94"}, - {file = "yarl-1.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa2bea05ff0a8fb4d8124498e00e02398f06d23cdadd0fe027d84a3f7afde31e"}, - {file = "yarl-1.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99e12d2bf587b44deb74e0d6170fec37adb489964dbca656ec41a7cd8f2ff178"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:243fbbbf003754fe41b5bdf10ce1e7f80bcc70732b5b54222c124d6b4c2ab31c"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:856b7f1a7b98a8c31823285786bd566cf06226ac4f38b3ef462f593c608a9bd6"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:553dad9af802a9ad1a6525e7528152a015b85fb8dbf764ebfc755c695f488367"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30c3ff305f6e06650a761c4393666f77384f1cc6c5c0251965d6bfa5fbc88f7f"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:353665775be69bbfc6d54c8d134bfc533e332149faeddd631b0bc79df0897f46"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f4fe99ce44128c71233d0d72152db31ca119711dfc5f2c82385ad611d8d7f897"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9c1e3ff4b89cdd2e1a24c214f141e848b9e0451f08d7d4963cb4108d4d798f1f"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:711bdfae4e699a6d4f371137cbe9e740dc958530cb920eb6f43ff9551e17cfbc"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4388c72174868884f76affcdd3656544c426407e0043c89b684d22fb265e04a5"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f0e1844ad47c7bd5d6fa784f1d4accc5f4168b48999303a868fe0f8597bde715"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5cafb02cf097a82d74403f7e0b6b9df3ffbfe8edf9415ea816314711764a27b"}, - {file = "yarl-1.15.2-cp312-cp312-win32.whl", hash = "sha256:156ececdf636143f508770bf8a3a0498de64da5abd890c7dbb42ca9e3b6c05b8"}, - {file = "yarl-1.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:435aca062444a7f0c884861d2e3ea79883bd1cd19d0a381928b69ae1b85bc51d"}, - {file = "yarl-1.15.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:416f2e3beaeae81e2f7a45dc711258be5bdc79c940a9a270b266c0bec038fb84"}, - {file = "yarl-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:173563f3696124372831007e3d4b9821746964a95968628f7075d9231ac6bb33"}, - {file = "yarl-1.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9ce2e0f6123a60bd1a7f5ae3b2c49b240c12c132847f17aa990b841a417598a2"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaea112aed589131f73d50d570a6864728bd7c0c66ef6c9154ed7b59f24da611"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4ca3b9f370f218cc2a0309542cab8d0acdfd66667e7c37d04d617012485f904"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23ec1d3c31882b2a8a69c801ef58ebf7bae2553211ebbddf04235be275a38548"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75119badf45f7183e10e348edff5a76a94dc19ba9287d94001ff05e81475967b"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e6fdc976ec966b99e4daa3812fac0274cc28cd2b24b0d92462e2e5ef90d368"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8657d3f37f781d987037f9cc20bbc8b40425fa14380c87da0cb8dfce7c92d0fb"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:93bed8a8084544c6efe8856c362af08a23e959340c87a95687fdbe9c9f280c8b"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:69d5856d526802cbda768d3e6246cd0d77450fa2a4bc2ea0ea14f0d972c2894b"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ccad2800dfdff34392448c4bf834be124f10a5bc102f254521d931c1c53c455a"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a880372e2e5dbb9258a4e8ff43f13888039abb9dd6d515f28611c54361bc5644"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c998d0558805860503bc3a595994895ca0f7835e00668dadc673bbf7f5fbfcbe"}, - {file = "yarl-1.15.2-cp313-cp313-win32.whl", hash = "sha256:533a28754e7f7439f217550a497bb026c54072dbe16402b183fdbca2431935a9"}, - {file = "yarl-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:5838f2b79dc8f96fdc44077c9e4e2e33d7089b10788464609df788eb97d03aad"}, - {file = "yarl-1.15.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fbbb63bed5fcd70cd3dd23a087cd78e4675fb5a2963b8af53f945cbbca79ae16"}, - {file = "yarl-1.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2e93b88ecc8f74074012e18d679fb2e9c746f2a56f79cd5e2b1afcf2a8a786b"}, - {file = "yarl-1.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af8ff8d7dc07ce873f643de6dfbcd45dc3db2c87462e5c387267197f59e6d776"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66f629632220a4e7858b58e4857927dd01a850a4cef2fb4044c8662787165cf7"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:833547179c31f9bec39b49601d282d6f0ea1633620701288934c5f66d88c3e50"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2aa738e0282be54eede1e3f36b81f1e46aee7ec7602aa563e81e0e8d7b67963f"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a13a07532e8e1c4a5a3afff0ca4553da23409fad65def1b71186fb867eeae8d"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c45817e3e6972109d1a2c65091504a537e257bc3c885b4e78a95baa96df6a3f8"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:670eb11325ed3a6209339974b276811867defe52f4188fe18dc49855774fa9cf"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:d417a4f6943112fae3924bae2af7112562285848d9bcee737fc4ff7cbd450e6c"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bc8936d06cd53fddd4892677d65e98af514c8d78c79864f418bbf78a4a2edde4"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:954dde77c404084c2544e572f342aef384240b3e434e06cecc71597e95fd1ce7"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5bc0df728e4def5e15a754521e8882ba5a5121bd6b5a3a0ff7efda5d6558ab3d"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b71862a652f50babab4a43a487f157d26b464b1dedbcc0afda02fd64f3809d04"}, - {file = "yarl-1.15.2-cp38-cp38-win32.whl", hash = "sha256:63eab904f8630aed5a68f2d0aeab565dcfc595dc1bf0b91b71d9ddd43dea3aea"}, - {file = "yarl-1.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:2cf441c4b6e538ba0d2591574f95d3fdd33f1efafa864faa077d9636ecc0c4e9"}, - {file = "yarl-1.15.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a32d58f4b521bb98b2c0aa9da407f8bd57ca81f34362bcb090e4a79e9924fefc"}, - {file = "yarl-1.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:766dcc00b943c089349d4060b935c76281f6be225e39994c2ccec3a2a36ad627"}, - {file = "yarl-1.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bed1b5dbf90bad3bfc19439258c97873eab453c71d8b6869c136346acfe497e7"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed20a4bdc635f36cb19e630bfc644181dd075839b6fc84cac51c0f381ac472e2"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d538df442c0d9665664ab6dd5fccd0110fa3b364914f9c85b3ef9b7b2e157980"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c6cf1d92edf936ceedc7afa61b07e9d78a27b15244aa46bbcd534c7458ee1b"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce44217ad99ffad8027d2fde0269ae368c86db66ea0571c62a000798d69401fb"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47a6000a7e833ebfe5886b56a31cb2ff12120b1efd4578a6fcc38df16cc77bd"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e52f77a0cd246086afde8815039f3e16f8d2be51786c0a39b57104c563c5cbb0"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:f9ca0e6ce7774dc7830dc0cc4bb6b3eec769db667f230e7c770a628c1aa5681b"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:136f9db0f53c0206db38b8cd0c985c78ded5fd596c9a86ce5c0b92afb91c3a19"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:173866d9f7409c0fb514cf6e78952e65816600cb888c68b37b41147349fe0057"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6e840553c9c494a35e449a987ca2c4f8372668ee954a03a9a9685075228e5036"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:458c0c65802d816a6b955cf3603186de79e8fdb46d4f19abaec4ef0a906f50a7"}, - {file = "yarl-1.15.2-cp39-cp39-win32.whl", hash = "sha256:5b48388ded01f6f2429a8c55012bdbd1c2a0c3735b3e73e221649e524c34a58d"}, - {file = "yarl-1.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:81dadafb3aa124f86dc267a2168f71bbd2bfb163663661ab0038f6e4b8edb810"}, - {file = "yarl-1.15.2-py3-none-any.whl", hash = "sha256:0d3105efab7c5c091609abacad33afff33bdff0035bece164c98bcf5a85ef90a"}, - {file = "yarl-1.15.2.tar.gz", hash = "sha256:a39c36f4218a5bb668b4f06874d676d35a035ee668e6e7e3538835c703634b84"}, + {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91"}, + {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da"}, + {file = "yarl-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3"}, + {file = "yarl-1.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f"}, + {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931"}, + {file = "yarl-1.17.1-cp310-cp310-win32.whl", hash = "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b"}, + {file = "yarl-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4"}, + {file = "yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7"}, + {file = "yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199"}, + {file = "yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96"}, + {file = "yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df"}, + {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488"}, + {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374"}, + {file = "yarl-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e"}, + {file = "yarl-1.17.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299"}, + {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258"}, + {file = "yarl-1.17.1-cp313-cp313-win32.whl", hash = "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2"}, + {file = "yarl-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda"}, + {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6"}, + {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159"}, + {file = "yarl-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934"}, + {file = "yarl-1.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5"}, + {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f"}, + {file = "yarl-1.17.1-cp39-cp39-win32.whl", hash = "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473"}, + {file = "yarl-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138"}, + {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, + {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, ] [package.dependencies] @@ -3060,4 +3028,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "20aeb9b87b2d4e7153898e75523ad9da8cc9ef611b17e96ac9ffbd2d463f974d" +content-hash = "d81899e5cdc890d282640cb4e12b4d6f1c5c294f1d59ba7045b96c0b35c0ef61" diff --git a/pyproject.toml b/pyproject.toml index 3d47940686..bcfe87c352 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ repository = "https://github.com/openwallet-foundation/acapy" [tool.poetry.dependencies] python = "^3.12" -aiohttp = "~3.10.5" +aiohttp = "~3.11.0" aiohttp-apispec-acapy = "~3.0.2" aiohttp-cors = "~0.7.0" apispec = "^6.6.0" From d84a384ec0f651b037e1ca466d244c00e462cf53 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 13:23:00 +0200 Subject: [PATCH 008/152] :art: Remove unnecessary asyncio pytest markers Resolves unclosed event loop warnings. Signed-off-by: ff137 --- acapy_agent/anoncreds/tests/test_revocation.py | 1 - acapy_agent/multitenant/admin/tests/test_routes.py | 3 --- .../v1_0/handlers/tests/test_response_handler.py | 7 ------- .../v2_0/formats/vc_di/tests/test_handler.py | 2 -- .../present_proof/dif/tests/test_pres_exch_handler.py | 9 --------- 5 files changed, 22 deletions(-) diff --git a/acapy_agent/anoncreds/tests/test_revocation.py b/acapy_agent/anoncreds/tests/test_revocation.py index 2f8ce80de4..5de4ef368e 100644 --- a/acapy_agent/anoncreds/tests/test_revocation.py +++ b/acapy_agent/anoncreds/tests/test_revocation.py @@ -1414,7 +1414,6 @@ async def test_create_credential_w3c(self, mock_supports_revocation): assert isinstance(result, tuple) assert mock_supports_revocation.call_count == 1 - @pytest.mark.asyncio @mock.patch.object(AskarAnoncredsProfileSession, "handle") async def test_create_credential_w3c_keyerror(self, mock_handle): mock_handle.fetch = mock.CoroutineMock(side_effect=[MockEntry(), MockEntry()]) diff --git a/acapy_agent/multitenant/admin/tests/test_routes.py b/acapy_agent/multitenant/admin/tests/test_routes.py index 2431e6f6d5..823d8704aa 100644 --- a/acapy_agent/multitenant/admin/tests/test_routes.py +++ b/acapy_agent/multitenant/admin/tests/test_routes.py @@ -1,6 +1,5 @@ from unittest import IsolatedAsyncioTestCase -import pytest from marshmallow.exceptions import ValidationError from ....admin.request_context import AdminRequestContext @@ -143,7 +142,6 @@ async def test_wallets_list_query(self): } ) - @pytest.mark.asyncio(loop_scope="function") async def test_wallet_create_tenant_settings(self): body = { "wallet_name": "test", @@ -796,7 +794,6 @@ async def test_wallet_create_token_x(self): ) await test_module.wallet_create_token(self.request) - @pytest.mark.asyncio(loop_scope="function") async def test_wallet_remove_managed(self): self.request.has_body = False self.request.match_info = {"wallet_id": "dummy"} diff --git a/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py b/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py index 87abd74791..d835ca2fc1 100644 --- a/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py +++ b/acapy_agent/protocols/didexchange/v1_0/handlers/tests/test_response_handler.py @@ -1,7 +1,5 @@ from unittest import IsolatedAsyncioTestCase -import pytest - from ......connections.models import connection_target from ......connections.models.diddoc import DIDDoc, PublicKey, PublicKeyType, Service from ......messaging.decorators.attach_decorator import AttachDecorator @@ -75,7 +73,6 @@ async def asyncSetUp(self): did_doc_attach=self.did_doc_attach, ) - @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") async def test_called(self, mock_didx_mgr): mock_didx_mgr.return_value.accept_response = mock.CoroutineMock() @@ -89,7 +86,6 @@ async def test_called(self, mock_didx_mgr): ) assert not responder.messages - @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") async def test_called_auto_ping(self, mock_didx_mgr): self.ctx.update_settings({"auto_ping_connection": True}) @@ -107,7 +103,6 @@ async def test_called_auto_ping(self, mock_didx_mgr): result, _ = messages[0] assert isinstance(result, Ping) - @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") @mock.patch.object(connection_target, "ConnectionTarget") async def test_problem_report(self, mock_conn_target, mock_didx_mgr): @@ -144,7 +139,6 @@ async def test_problem_report(self, mock_conn_target, mock_didx_mgr): ) assert target == {"target_list": [mock_conn_target]} - @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") @mock.patch.object(connection_target, "ConnectionTarget") async def test_problem_report_did_doc( @@ -191,7 +185,6 @@ async def test_problem_report_did_doc( ) assert target == {"target_list": [mock_conn_target]} - @pytest.mark.asyncio(loop_scope="function") @mock.patch.object(test_module, "DIDXManager") @mock.patch.object(connection_target, "ConnectionTarget") async def test_problem_report_did_doc_no_conn_target( diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py index 65d050e75e..ae8f23fa69 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py @@ -727,7 +727,6 @@ async def test_issue_credential_non_revocable(self): # assert data is encoded as base64 assert attachment.data.base64 - @pytest.mark.asyncio async def test_match_sent_cred_def_id_error(self): tag_query = {"tag": "test_tag"} @@ -737,7 +736,6 @@ async def test_match_sent_cred_def_id_error(self): context.exception ) - @pytest.mark.asyncio async def test_store_credential(self): attr_values = { "legalName": "value", diff --git a/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py b/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py index 35171b0d16..654c62f432 100644 --- a/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py +++ b/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py @@ -1549,7 +1549,6 @@ async def test_filter_string(self): ) assert len(tmp_vp.get("verifiableCredential")) == 1 - @pytest.mark.asyncio @pytest.mark.ursa_bbs_signatures async def test_filter_schema(self): cred_list, _ = await self.setup_tuple(self.profile) @@ -2384,7 +2383,6 @@ async def test_no_filter(self): ) assert len(tmp_vp.get("verifiableCredential")) == 6 - @pytest.mark.asyncio @pytest.mark.ursa_bbs_signatures async def test_filter_with_only_string_type(self): cred_list, _ = await self.setup_tuple(self.profile) @@ -2436,7 +2434,6 @@ async def test_filter_with_only_string_type(self): ) assert len(tmp_vp.get("verifiableCredential")) == 6 - @pytest.mark.asyncio @pytest.mark.ursa_bbs_signatures async def test_filter_with_only_num_type(self): await self.setup_tuple(self.profile) @@ -2850,7 +2847,6 @@ async def test_filter_by_field_path_match_on_proof(self): with pytest.raises(DIFPresExchError): await dif_pres_exch_handler.filter_by_field(field, cred) - @pytest.mark.asyncio async def test_filter_creds_record_id(self): dif_pres_exch_handler = DIFPresExchHandler(self.profile) cred_list = [ @@ -3214,7 +3210,6 @@ async def test_apply_constraint_received_cred_path_update(self): constraint=constraint, cred_dict=cred_dict ) - @pytest.mark.asyncio @pytest.mark.ursa_bbs_signatures async def test_apply_constraint_received_cred_invalid(self): dif_pres_exch_handler = DIFPresExchHandler( @@ -3270,7 +3265,6 @@ async def test_apply_constraint_received_cred_invalid(self): constraint=constraint, cred_dict=cred_dict ) - @pytest.mark.asyncio @pytest.mark.ursa_bbs_signatures async def test_apply_constraint_received_cred_valid(self): dif_pres_exch_handler = DIFPresExchHandler( @@ -3464,7 +3458,6 @@ async def test_apply_constraint_received_cred_no_sel_disc(self): constraint=constraint, cred_dict=cred_dict ) - @pytest.mark.asyncio async def test_get_updated_path(self): dif_pres_exch_handler = DIFPresExchHandler( self.profile, proof_type=BbsBlsSignature2020.signature_type @@ -3532,7 +3525,6 @@ def test_get_dict_keys_from_path(self): cred_dict, "credentialSubject.Patient.address" ) == ["@id"] - @pytest.mark.asyncio async def test_filter_by_field_keyerror(self): dif_pres_exch_handler = DIFPresExchHandler( self.profile, proof_type=BbsBlsSignature2020.signature_type @@ -3555,7 +3547,6 @@ async def test_filter_by_field_keyerror(self): ) assert not await dif_pres_exch_handler.filter_by_field(field, vc_record_cred) - @pytest.mark.asyncio async def test_filter_by_field_xsd_parser(self): dif_pres_exch_handler = DIFPresExchHandler( self.profile, proof_type=BbsBlsSignature2020.signature_type From 1d07edec1783ce44de58c0b7501287e272c5686d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:28:57 -0800 Subject: [PATCH 009/152] chore(deps-dev): Bump ruff from 0.7.3 to 0.7.4 (#3341) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.3 to 0.7.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.3...0.7.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 42 +++++++++++++++++++++--------------------- pyproject.toml | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/poetry.lock b/poetry.lock index cc45282759..0d804a62de 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -2501,29 +2501,29 @@ test = ["hypothesis (==5.19.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "ruff" -version = "0.7.3" +version = "0.7.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344"}, - {file = "ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0"}, - {file = "ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16"}, - {file = "ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc"}, - {file = "ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088"}, - {file = "ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c"}, - {file = "ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313"}, + {file = "ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478"}, + {file = "ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63"}, + {file = "ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a"}, + {file = "ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac"}, + {file = "ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6"}, + {file = "ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f"}, + {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"}, ] [[package]] @@ -3028,4 +3028,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "d81899e5cdc890d282640cb4e12b4d6f1c5c294f1d59ba7045b96c0b35c0ef61" +content-hash = "1ac7b5e9aa0c4f3168be836875f38790bbf1e6d784d77951d36ce1f018f369d5" diff --git a/pyproject.toml b/pyproject.toml index bcfe87c352..2d1c5b9dd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,7 @@ canonicaljson = "^2.0.0" [tool.poetry.group.dev.dependencies] pre-commit = "~3.8.0" # Sync with version in .pre-commit-config.yaml -ruff = "0.7.3" +ruff = "0.7.4" sphinx = "^5.3.0" sphinx-rtd-theme = ">=0.4.3" From 2522877d475524084c5c2bbdc69ef41670dd6313 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:38:07 -0800 Subject: [PATCH 010/152] chore(deps): Bump aiohttp from 3.11.0 to 3.11.2 (#3340) Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.11.0 to 3.11.2. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.11.0...v3.11.2) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 156 ++++++++++++++++++++++++------------------------- pyproject.toml | 2 +- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0d804a62de..021ea10faa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,87 +13,87 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.0" +version = "3.11.2" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:024409c1b1d6076d0ed933dcebd7e4fc6f3320a227bfa0c1b6b93a8b5a146f04"}, - {file = "aiohttp-3.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:62502b8ffee8c6a4b5c6bf99d1de277d42bf51b2fb713975d9b63b560150b7ac"}, - {file = "aiohttp-3.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c54c635d1f52490cde7ef3a423645167a8284e452a35405d5c7dc1242a8e75c9"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:104ea21994b1403e4c1b398866f1187c1694fa291314ad7216ec1d8ec6b49f38"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b24497b3baf15035730de5f207ade88a67d4483a5f16ced7ece348933a5b47"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08474e71772a516ba2e2167b4707af8361d2c452b3d8a5364c984f4867869499"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f40380c96dd407dfa84eb2d264e68aa47717b53bdbe210a59cc3c35a4635f195"}, - {file = "aiohttp-3.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1668ef2f3a7ec9881f4b6a917e5f97c87a343fa6b0d5fc826b7b0297ddd0887"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f3bf5c132eb48002bcc3825702d241d35b4e9585009e65e9dcf9c4635d0b7424"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0315978b2a4569e03fb59100f6a7e7d23f718a4521491f5c13d946d37549f3d"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d5cae4cd271e20b7ab757e966cc919186b9f02535418ab36c471a5377ef4deaa"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:31b91ff3a1fcb206a1fa76e0de1f08c9ffb1dc0deb7296fa2618adfe380fc676"}, - {file = "aiohttp-3.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ebf610c37df4f09c71c9bbf8309b4b459107e6fe889ac0d7e16f6e4ebd975f86"}, - {file = "aiohttp-3.11.0-cp310-cp310-win32.whl", hash = "sha256:b40c304ab01e89ad0aeeecf91bbaa6ae3b00e27b796c9e8d50b71a4a7e885cc8"}, - {file = "aiohttp-3.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd0834e4260eab78671b81d34f110fbaac449563e48d419cec0030d9a8e58693"}, - {file = "aiohttp-3.11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:89a96a0696dc67d548f69cb518c581a7a33cc1f26ab42229dea1709217c9d926"}, - {file = "aiohttp-3.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6b925c7775ab857bdc1e52e1f5abcae7d18751c09b751aeb641a5276d9b990e"}, - {file = "aiohttp-3.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7867d0808614f04e78e0a8d5a2c1f8ac6bc626a0c0e2f62be48be6b749e2f8b2"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:229ae13959a5f499d90ffbb4b9eac2255d8599315027d6f7c22fa9803a94d5b1"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a2f5268b672087c45b33479ba1bb1d5a48c6d76c133cfce3a4f77410c200d1"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a896059b6937d1a22d8ee8377cdcd097bd26cd8c653b8f972051488b9baadee9"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:104deb7873681273c5daa13c41924693df394043a118dae90387d35bc5531788"}, - {file = "aiohttp-3.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae36ae52b0c22fb69fb8b744eff82a20db512a29eafc6e3a4ab43b17215b219d"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b7349205bb163318dcc102329d30be59a647a3d24c82c3d91ed35b7e7301ea7e"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9095580806d9ed07c0c29b23364a0b1fb78258ef9f4bddf7e55bac0e475d4edf"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4d218d3eca40196384ad3b481309c56fd60e664128885d1734da0a8aa530d433"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6533dd06df3d17d1756829b68b365b1583929b54082db8f65083a4184bf68322"}, - {file = "aiohttp-3.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:72cd984f7f14e8c01b3e38f18f39ea85dba84e52ea05e37116ba5e2a72eef396"}, - {file = "aiohttp-3.11.0-cp311-cp311-win32.whl", hash = "sha256:c1828e10c3a49e2b234b87600ecb68a92b8a8dcf8b99bca9447f16c4baaa1630"}, - {file = "aiohttp-3.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:900ff74d78eb580ae4aa5883242893b123a0c442a46570902500f08d6a7e6696"}, - {file = "aiohttp-3.11.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f8f0d79b923070f25674e4ea8f3d61c9d89d24d9598d50ff32c5b9b23c79a25b"}, - {file = "aiohttp-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:113bf06b029143e94a47c4f36e11a8b7e396e9d1f1fc8cea58e6b7e370cfed38"}, - {file = "aiohttp-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3e1ed8d152cccceffb1ee7a2ac227c16372e453fb11b3aeaa56783049b85d3f6"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2e82e515e268b965424ecabebd91834a41b36260b6ef5db015ee12ddb28ef3"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1c49bc393d854d4421ebc174a0a41f9261f50d3694d8ca277146cbbcfd24ee7"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57e17c6d71f2dc857a8a1d09be1be7802e35d90fb4ba4b06cf1aab6414a57894"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12071dd2cc95ba81e0f2737bebcb98b2a8656015e87772e84e8fb9e635b5da6e"}, - {file = "aiohttp-3.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97056d3422594e0787733ac4c45bef58722d452f4dc6615fee42f59fe51707dd"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2ec5efbc872b00ddd85e3904059d274f284cff314e13f48776050ca2c58f451d"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dd505a1121ad5b666191840b7bd1d8cb917df2647deeca6f3474331b72452362"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:600b1d9f86a130131915e2f2127664311b33902c486b21a747d626f5144b4471"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8c47a0ba6c2b3d3e5715f8338d657badd21f778c6be16701922c65521c5ecfc9"}, - {file = "aiohttp-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8b323b5d3aef7dd811424c269322eec58a977c0c8152e650159e47210d900504"}, - {file = "aiohttp-3.11.0-cp312-cp312-win32.whl", hash = "sha256:aabc4e92cb153636d6be54e84dad1b252ddb9aebe077942b6dcffe5e468d476a"}, - {file = "aiohttp-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:508cfcc99534b1282595357592d8367b44392b21f6eb5d4dc021f8d0d809e94d"}, - {file = "aiohttp-3.11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c98a596ac20e8980cc6f34c0c92a113e98eb08f3997c150064d26d2aeb043e5a"}, - {file = "aiohttp-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ad14cdc0fba4df31c0f6e06c21928c5b924725cbf60d0ccc5f6e7132636250e9"}, - {file = "aiohttp-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:170fb2324826bb9f08055a8291f42192ae5ee2f25b2966c8f0f4537c61d73a7b"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdad66685fcf2ad14ce522cf849d4a025f4fd206d6cfc3f403d9873e4c243b03"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8b95a63a8e8b5f0464bd8b1b0d59d2bec98a59b6aacc71e9be23df6989b3dfb"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7bcfcede95531589295f56e924702cef7f9685c9e4e5407592e04ded6a65bf3"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ecc2fb1a0a9d48cf773add34196cddf7e488e48e9596e090849751bf43098f4"}, - {file = "aiohttp-3.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fef105113d56e817cb9bcc609667ee461321413a7b972b03f5b4939f40f307c"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d33b4490026968bdc7f0729b9d87a3a6b1e09043557d2fc1c605c6072deb2f11"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6362f50a6f0e5482c4330d2151cb682779230683da0e155c15ec9fc58cb50b6a"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4f698aa61879df64425191d41213dfd99efdc1627e6398e6d7aa5c312fac9702"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0e7a0762cc29cd3acd01a4d2b547b3af7956ad230ebb80b529a8e4f3e4740fe8"}, - {file = "aiohttp-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b3e4fb7f5354d39490d8209aefdf5830b208d01c7293a2164e404312c3d8bc55"}, - {file = "aiohttp-3.11.0-cp313-cp313-win32.whl", hash = "sha256:6c5a6958f4366496004cf503d847093d464814543f157ef3b738bbf604232415"}, - {file = "aiohttp-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:3ed360d6672a9423aad39902a4e9fe305464d20ed7931dbdba30a4625782d875"}, - {file = "aiohttp-3.11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d1ea006426edf7e1299c52a58b0443158012f7a56fed3515164b60bfcb1503a9"}, - {file = "aiohttp-3.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c5e6a1f8b0268ffa1c84d7c3558724956002ba8361176e76406233e704bbcffb"}, - {file = "aiohttp-3.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:40dc9446cff326672fcbf93efdb8ef7e949824de1097624efe4f61ac7f0d2c43"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b4545e8d96870da9652930c5198366605ff8f982757030e2148cf341e5746b"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37f8cf3c43f292d9bb3e6760476c2b55b9663a581fad682a586a410c43a7683e"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329f5059e0bf6983dceebac8e6ed20e75eaff6163b3414f4a4cb59e0d7037672"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ae6f182be72c3531915e90625cc65afce4df8a0fc4988bd52d8a5d5faaeb68"}, - {file = "aiohttp-3.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d664e5f937c08adb7908ea9f391fbf2928a9b09cb412ac0aba602bde9e499e4"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:feca9fafa4385aea6759c171cd25ea82f7375312fca04178dae35331be45e538"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c415b9601ff50709d6050c8a9281733a9b042b9e589265ac40305b875cf9c463"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:91d3991fad8b65e5dbc13cd95669ea689fe0a96ff63e4e64ac24ed724e4f8103"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9231d610754724273a6ac05a1f177979490bfa6f84d49646df3928af2e88cfd5"}, - {file = "aiohttp-3.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4e4e155968040e32c124a89852a1a5426d0e920a35f4331e1b3949037bfe93a3"}, - {file = "aiohttp-3.11.0-cp39-cp39-win32.whl", hash = "sha256:76d6ee8bb132f8ee0fcb0e205b4708ddb6fba524eb515ee168113063d825131b"}, - {file = "aiohttp-3.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:577c7429f8869fa30186fc2c9eee64d75a30b51b61f26aac9725866ae5985cfd"}, - {file = "aiohttp-3.11.0.tar.gz", hash = "sha256:f57a0de48dda792629e7952d34a0c7b81ea336bb9b721391c7c58145b237fe55"}, + {file = "aiohttp-3.11.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:783741f534c14957fbe657d62a34b947ec06db23d45a2fd4a8aeb73d9c84d7e6"}, + {file = "aiohttp-3.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:435f7a08d8aa42371a94e7c141205a9cb092ba551084b5e0c57492e6673601a3"}, + {file = "aiohttp-3.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c681f34e2814bc6e1eef49752b338061b94a42c92734d0be9513447d3f83718c"}, + {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73a664478ae1ea011b5a710fb100b115ca8b2146864fa0ce4143ff944df714b8"}, + {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1d06c8fd8b453c3e553c956bd3b8395100401060430572174bb7876dd95ad49"}, + {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b1f4844909321ef2c1cee50ddeccbd6018cd8c8d1ddddda3f553e94a5859497"}, + {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdc6f8dce09281ae534eaf08a54f0d38612398375f28dad733a8885f3bf9b978"}, + {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2d942421cf3a1d1eceae8fa192f1fbfb74eb9d3e207d35ad2696bd2ce2c987c"}, + {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:08ebe7a1d6c1e5ca766d68407280d69658f5f98821c2ba6c41c63cabfed159af"}, + {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2793d3297f3e49015140e6d3ea26142c967e07998e2fb00b6ee8d041138fbc4e"}, + {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4a23475d8d5c56e447b7752a1e2ac267c1f723f765e406c81feddcd16cdc97bc"}, + {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:556564d89e2f4a6e8fe000894c03e4e84cf0b6cfa5674e425db122633ee244d1"}, + {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:57993f406ce3f114b2a6756d7809be3ffd0cc40f33e8f8b9a4aa1b027fd4e3eb"}, + {file = "aiohttp-3.11.2-cp310-cp310-win32.whl", hash = "sha256:177b000efaf8d2f7012c649e8aee5b0bf488677b1162be5e7511aa4f9d567607"}, + {file = "aiohttp-3.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:ff5d22eece44528023254b595c670dfcf9733ac6af74c4b6cb4f6a784dc3870c"}, + {file = "aiohttp-3.11.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:50e0aee4adc9abcd2109c618a8d1b2c93b85ac277b24a003ab147d91e068b06d"}, + {file = "aiohttp-3.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9aa4e68f1e4f303971ec42976fb170204fb5092de199034b57199a1747e78a2d"}, + {file = "aiohttp-3.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d84930b4145991214602372edd7305fc76b700220db79ac0dd57d3afd0f0a1ca"}, + {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ec8afd362356b8798c8caa806e91deb3f0602d8ffae8e91d2d3ced2a90c35e"}, + {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb0544a0e8294a5a5e20d3cacdaaa9a911d7c0a9150f5264aef36e7d8fdfa07e"}, + {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7b0a1618060e3f5aa73d3526ca2108a16a1b6bf86612cd0bb2ddcbef9879d06"}, + {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d878a0186023ac391861958035174d0486f3259cabf8fd94e591985468da3ea"}, + {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e33a7eddcd07545ccf5c3ab230f60314a17dc33e285475e8405e26e21f02660"}, + {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4d7fad8c456d180a6d2f44c41cfab4b80e2e81451815825097db48b8293f59d5"}, + {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d954ba0eae7f33884d27dc00629ca4389d249eb8d26ca07c30911257cae8c96"}, + {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:afa55e863224e664a782effa62245df73fdfc55aee539bed6efacf35f6d4e4b7"}, + {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:10a5f91c319d9d4afba812f72984816b5fcd20742232ff7ecc1610ffbf3fc64d"}, + {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6e8e19a80ba194db5c06915a9df23c0c06e0e9ca9a4db9386a6056cca555a027"}, + {file = "aiohttp-3.11.2-cp311-cp311-win32.whl", hash = "sha256:9c8d1db4f65bbc9d75b7b271d68fb996f1c8c81a525263862477d93611856c2d"}, + {file = "aiohttp-3.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:2adb967454e10e69478ba4a8d8afbba48a7c7a8619216b7c807f8481cc66ddfb"}, + {file = "aiohttp-3.11.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f833a80d9de9307d736b6af58c235b17ef7f90ebea7b9c49cd274dec7a66a2f1"}, + {file = "aiohttp-3.11.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:382f853516664d2ebfc75dc01da4a10fdef5edcb335fe7b45cf471ce758ecb18"}, + {file = "aiohttp-3.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d3a2bcf6c81639a165da93469e1e0aff67c956721f3fa9c0560f07dd1e505116"}, + {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de3b4d5fb5d69749104b880a157f38baeea7765c93d9cd3837cedd5b84729e10"}, + {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a90a0dc4b054b5af299a900bf950fe8f9e3e54322bc405005f30aa5cacc5c98"}, + {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32334f35824811dd20a12cc90825d000e6b50faaeaa71408d42269151a66140d"}, + {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cba0b8d25aa2d450762f3dd6df85498f5e7c3ad0ddeb516ef2b03510f0eea32"}, + {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bbb2dbc2701ab7e9307ca3a8fa4999c5b28246968e0a0202a5afabf48a42e22"}, + {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97fba98fc5d9ccd3d33909e898d00f2494d6a9eec7cbda3d030632e2c8bb4d00"}, + {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0ebdf5087e2ce903d8220cc45dcece90c2199ae4395fd83ca616fcc81010db2c"}, + {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:122768e3ae9ce74f981b46edefea9c6e5a40aea38aba3ac50168e6370459bf20"}, + {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5587da333b7d280a312715b843d43e734652aa382cba824a84a67c81f75b338b"}, + {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:85de9904bc360fd29a98885d2bfcbd4e02ab33c53353cb70607f2bea2cb92468"}, + {file = "aiohttp-3.11.2-cp312-cp312-win32.whl", hash = "sha256:b470de64d17156c37e91effc109d3b032b39867000e2c126732fe01d034441f9"}, + {file = "aiohttp-3.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:3f617a48b70f4843d54f52440ea1e58da6bdab07b391a3a6aed8d3b311a4cc04"}, + {file = "aiohttp-3.11.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d90b5a3b0f32a5fecf5dd83d828713986c019585f5cddf40d288ff77f366615"}, + {file = "aiohttp-3.11.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d23854e5867650d40cba54d49956aad8081452aa80b2cf0d8c310633f4f48510"}, + {file = "aiohttp-3.11.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:486273d3b5af75a80c31c311988931bdd2a4b96a74d5c7f422bad948f99988ef"}, + {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9075313f8e41b481e4cb10af405054564b0247dc335db5398ed05f8ec38787e2"}, + {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44b69c69c194ffacbc50165911cf023a4b1b06422d1e1199d3aea82eac17004e"}, + {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b339d91ac9060bd6ecdc595a82dc151045e5d74f566e0864ef3f2ba0887fec42"}, + {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64e8f5178958a9954043bc8cd10a5ae97352c3f2fc99aa01f2aebb0026010910"}, + {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3129151378f858cdc4a0a4df355c9a0d060ab49e2eea7e62e9f085bac100551b"}, + {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:14eb6c628432720e41b4fab1ada879d56cfe7034159849e083eb536b4c2afa99"}, + {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e57a10aacedcf24666f4c90d03e599f71d172d1c5e00dcf48205c445806745b0"}, + {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:66e58a2e8c7609a3545c4b38fb8b01a6b8346c4862e529534f7674c5265a97b8"}, + {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9b6d15adc9768ff167614ca853f7eeb6ee5f1d55d5660e3af85ce6744fed2b82"}, + {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2914061f5ca573f990ec14191e6998752fa8fe50d518e3405410353c3f44aa5d"}, + {file = "aiohttp-3.11.2-cp313-cp313-win32.whl", hash = "sha256:1c2496182e577042e0e07a328d91c949da9e77a2047c7291071e734cd7a6e780"}, + {file = "aiohttp-3.11.2-cp313-cp313-win_amd64.whl", hash = "sha256:cccb2937bece1310c5c0163d0406aba170a2e5fb1f0444d7b0e7fdc9bd6bb713"}, + {file = "aiohttp-3.11.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:994cb893936dd2e1803655ae8667a45066bfd53360b148e22b4e3325cc5ea7a3"}, + {file = "aiohttp-3.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3666c750b73ce463a413692e3a57c60f7089e2d9116a2aa5a0f0eaf2ae325148"}, + {file = "aiohttp-3.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6ad9a7d2a3a0f235184426425f80bd3b26c66b24fd5fddecde66be30c01ebe6e"}, + {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c979fc92aba66730b66099cd5becb42d869a26c0011119bc1c2478408a8bf7a"}, + {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:766d0ebf8703d28f854f945982aa09224d5a27a29594c70d921c43c3930fe7ac"}, + {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79efd1ee3827b2f16797e14b1e45021206c3271249b4d0025014466d416d7413"}, + {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d6e069b882c1fdcbe5577dc4be372eda705180197140577a4cddb648c29d22e"}, + {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e9a766c346b2ed7e88937919d84ed64b4ef489dad1d8939f806ee52901dc142"}, + {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2b02a68b9445c70d7f5c8b578c5f5e5866b1d67ca23eb9e8bc8658ae9e3e2c74"}, + {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:374baefcb1b6275f350da605951f5f02487a9bc84a574a7d5b696439fabd49a3"}, + {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d2f991c18132f3e505c108147925372ffe4549173b7c258cf227df1c5977a635"}, + {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:34f37c59b12bc3afc52bab6fcd9cd3be82ff01c4598a84cbea934ccb3a9c54a0"}, + {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:33af11eca7bb0f5c6ffaf5e7d9d2336c2448f9c6279b93abdd6f3c35f9ee321f"}, + {file = "aiohttp-3.11.2-cp39-cp39-win32.whl", hash = "sha256:83a70e22e0f6222effe7f29fdeba6c6023f9595e59a0479edacfbd7de4b77bb7"}, + {file = "aiohttp-3.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:c28c1677ea33ccb8b14330560094cc44d3ff4fad617a544fd18beb90403fe0f1"}, + {file = "aiohttp-3.11.2.tar.gz", hash = "sha256:68d1f46f9387db3785508f5225d3acbc5825ca13d9c29f2b5cce203d5863eb79"}, ] [package.dependencies] @@ -3028,4 +3028,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "1ac7b5e9aa0c4f3168be836875f38790bbf1e6d784d77951d36ce1f018f369d5" +content-hash = "0b4f353fe6535b24f7eef4f13d6c415c9247da3fa47efd51ecc87413e248f3b8" diff --git a/pyproject.toml b/pyproject.toml index 2d1c5b9dd0..febe67b4d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ repository = "https://github.com/openwallet-foundation/acapy" [tool.poetry.dependencies] python = "^3.12" -aiohttp = "~3.11.0" +aiohttp = "~3.11.2" aiohttp-apispec-acapy = "~3.0.2" aiohttp-cors = "~0.7.0" apispec = "^6.6.0" From c18f6d19bcd9274dfb9cf7048c49291f4e1fc43b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:05:59 -0800 Subject: [PATCH 011/152] chore(deps): Bump pyjwt from 2.9.0 to 2.10.0 (#3339) Bumps [pyjwt](https://github.com/jpadilla/pyjwt) from 2.9.0 to 2.10.0. - [Release notes](https://github.com/jpadilla/pyjwt/releases) - [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst) - [Commits](https://github.com/jpadilla/pyjwt/compare/2.9.0...2.10.0) --- updated-dependencies: - dependency-name: pyjwt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 021ea10faa..60bfdb4510 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2168,13 +2168,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.0" description = "JSON Web Token implementation in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, + {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, ] [package.extras] @@ -3028,4 +3028,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "0b4f353fe6535b24f7eef4f13d6c415c9247da3fa47efd51ecc87413e248f3b8" +content-hash = "d5ab2d9c2721f87d92ca77cc8bf7a044cfc2c41b58b111af84a454ac2cc96910" diff --git a/pyproject.toml b/pyproject.toml index febe67b4d6..0064c4701d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ packaging = "~23.2" portalocker = "~2.10.1" prompt_toolkit = ">=2.0.9,<2.1.0" pydid = "^0.5.1" -pyjwt = "~2.9.0" +pyjwt = "~2.10.0" pyld = "^2.0.4" pynacl = "~1.5.0" python-dateutil = "^2.9.0" From f5c49b0710dd180ea31c45f73bc82ef06f9523b4 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Mon, 18 Nov 2024 14:40:31 -0800 Subject: [PATCH 012/152] did:tdw resolver (#3237) * did:tdw resolver Signed-off-by: jamshale * Update unit tests Signed-off-by: jamshale * Update poetry.lock Signed-off-by: jamshale --------- Signed-off-by: jamshale --- acapy_agent/messaging/tests/test_valid.py | 19 +++ acapy_agent/messaging/valid.py | 17 +++ acapy_agent/resolver/__init__.py | 6 + acapy_agent/resolver/default/tdw.py | 40 ++++++ .../resolver/default/tests/test_tdw.py | 36 ++++++ acapy_agent/wallet/did_method.py | 8 ++ poetry.lock | 119 +++++++++++++++++- pyproject.toml | 6 +- 8 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 acapy_agent/resolver/default/tdw.py create mode 100644 acapy_agent/resolver/default/tests/test_tdw.py diff --git a/acapy_agent/messaging/tests/test_valid.py b/acapy_agent/messaging/tests/test_valid.py index 8983d27964..0f3b3d3363 100644 --- a/acapy_agent/messaging/tests/test_valid.py +++ b/acapy_agent/messaging/tests/test_valid.py @@ -12,6 +12,7 @@ CREDENTIAL_TYPE_VALIDATE, DID_KEY_VALIDATE, DID_POSTURE_VALIDATE, + DID_TDW_VALIDATE, ENDPOINT_TYPE_VALIDATE, ENDPOINT_VALIDATE, INDY_CRED_DEF_ID_VALIDATE, @@ -114,6 +115,24 @@ def test_indy_did(self): INDY_DID_VALIDATE("Q4zqM7aXqm7gDQkUVLng9h") INDY_DID_VALIDATE("did:sov:Q4zqM7aXqm7gDQkUVLng9h") + def test_tdw_did(self): + valid_tdw_dids = [ + "did:tdw:QmUchSB5f5DJQks9CeyLJjhAy4iKJcYzRyiuYq3sjV13px:example.com", + "did:tdw:QmZiKXwQVfyZVuvCsuHpQh4arSUpEmeVVRvSfv3uiEycSr:example.com%3A5000", + ] + for valid_tdw_did in valid_tdw_dids: + DID_TDW_VALIDATE(valid_tdw_did) + + non_valid_tdw_dids = [ + "did:web:QmUchSB5f5DJQks9CeyLJjhAy4iKJcYzRyiuYq3sjV13px", + # Did urls are not allowed + "did:tdw:QmP9VWaTCHcyztDpRj9XSHvZbmYe3m9HZ61KoDtZgWaXVU:example.com%3A5000#z6MkkzY9skorPaoEbCJFKUo7thD8Yb8MBs28aJRopf1TUo9V", + "did:tdw:QmZiKXwQVfyZVuvCsuHpQh4arSUpEmeVVRvSfv3uiEycSr:example.com%3A5000/whois", + ] + for non_valid_tdw_did in non_valid_tdw_dids: + with self.assertRaises(ValidationError): + DID_TDW_VALIDATE(non_valid_tdw_did) + def test_indy_raw_public_key(self): non_indy_raw_public_keys = [ "Q4zqM7aXqm7gDQkUVLng9JQ4zqM7aXqm7gDQkUVLng9I", # 'I' not a base58 char diff --git a/acapy_agent/messaging/valid.py b/acapy_agent/messaging/valid.py index 894c1a819b..fc1749d600 100644 --- a/acapy_agent/messaging/valid.py +++ b/acapy_agent/messaging/valid.py @@ -319,6 +319,20 @@ def __init__(self): ) +class DIDTdw(Regexp): + """Validate value against did:tdw specification.""" + + EXAMPLE = "did:tdw:QmP9VWaTCHcyztDpRj9XSHvZbmYe3m9HZ61KoDtZgWaXVU:example.com%3A5000" + PATTERN = re.compile(r"^(did:tdw:)([a-zA-Z0-9%._-]*:)*[a-zA-Z0-9%._-]+$") + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + DIDTdw.PATTERN, error="Value {input} is not in W3C did:tdw format" + ) + + class DIDPosture(OneOf): """Validate value against defined DID postures.""" @@ -934,6 +948,9 @@ def __init__( DID_WEB_VALIDATE = DIDWeb() DID_WEB_EXAMPLE = DIDWeb.EXAMPLE +DID_TDW_VALIDATE = DIDTdw() +DID_TDW_EXAMPLE = DIDTdw.EXAMPLE + ROUTING_KEY_VALIDATE = RoutingKey() ROUTING_KEY_EXAMPLE = RoutingKey.EXAMPLE diff --git a/acapy_agent/resolver/__init__.py b/acapy_agent/resolver/__init__.py index 005cce6df9..3998b3da1c 100644 --- a/acapy_agent/resolver/__init__.py +++ b/acapy_agent/resolver/__init__.py @@ -49,6 +49,12 @@ async def setup(context: InjectionContext): await web_resolver.setup(context) registry.register_resolver(web_resolver) + tdw_resolver = ClassProvider( + "acapy_agent.resolver.default.tdw.TdwDIDResolver" + ).provide(context.settings, context.injector) + await tdw_resolver.setup(context) + registry.register_resolver(tdw_resolver) + if context.settings.get("resolver.universal"): universal_resolver = ClassProvider( "acapy_agent.resolver.default.universal.UniversalResolver" diff --git a/acapy_agent/resolver/default/tdw.py b/acapy_agent/resolver/default/tdw.py new file mode 100644 index 0000000000..4aabd198e8 --- /dev/null +++ b/acapy_agent/resolver/default/tdw.py @@ -0,0 +1,40 @@ +"""TDW DID Resolver. + +Resolution is performed by the did_tdw library. +""" + +from re import Pattern +from typing import Optional, Sequence, Text + +from did_tdw.resolver import ResolutionResult, resolve_did + +from ...config.injection_context import InjectionContext +from ...core.profile import Profile +from ...messaging.valid import DIDTdw +from ..base import BaseDIDResolver, ResolverType + + +class TdwDIDResolver(BaseDIDResolver): + """TDW DID Resolver.""" + + def __init__(self): + """Initialize the TDW DID Resolver.""" + super().__init__(ResolverType.NATIVE) + + async def setup(self, context: InjectionContext): + """Perform required setup for TDW DID resolution.""" + + @property + def supported_did_regex(self) -> Pattern: + """Return supported DID regex of TDW DID Resolver.""" + return DIDTdw.PATTERN + + async def _resolve( + self, profile: Profile, did: str, service_accept: Optional[Sequence[Text]] = None + ) -> dict: + """Resolve DID using TDW.""" + response: ResolutionResult = await resolve_did(did) + if response.resolution_metadata and response.resolution_metadata.get("error"): + return response.resolution_metadata + + return response.document diff --git a/acapy_agent/resolver/default/tests/test_tdw.py b/acapy_agent/resolver/default/tests/test_tdw.py new file mode 100644 index 0000000000..8829b9f031 --- /dev/null +++ b/acapy_agent/resolver/default/tests/test_tdw.py @@ -0,0 +1,36 @@ +import pytest + +from ....core.profile import Profile +from ....messaging.valid import DIDTdw +from ....utils.testing import create_test_profile +from ..tdw import TdwDIDResolver + +TEST_DID = "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example" + + +@pytest.fixture +def resolver(): + """Resolver fixture.""" + yield TdwDIDResolver() + + +@pytest.fixture +async def profile(): + """Profile fixture.""" + yield await create_test_profile() + + +@pytest.mark.asyncio +async def test_supported_did_regex(profile, resolver: TdwDIDResolver): + """Test the supported_did_regex.""" + assert resolver.supported_did_regex == DIDTdw.PATTERN + assert await resolver.supports( + profile, + TEST_DID, + ) + + +@pytest.mark.asyncio +async def test_resolve(resolver: TdwDIDResolver, profile: Profile): + """Test resolve method.""" + assert await resolver.resolve(profile, TEST_DID) diff --git a/acapy_agent/wallet/did_method.py b/acapy_agent/wallet/did_method.py index bf6ff57304..2acf670837 100644 --- a/acapy_agent/wallet/did_method.py +++ b/acapy_agent/wallet/did_method.py @@ -90,6 +90,13 @@ def holder_defined_did(self) -> HolderDefinedDid: holder_defined_did=HolderDefinedDid.NO, ) +TDW = DIDMethod( + name="tdw", + key_types=[ED25519, X25519], + rotation=False, + holder_defined_did=HolderDefinedDid.NO, +) + class DIDMethods: """DID Method class specifying DID methods with supported key types.""" @@ -102,6 +109,7 @@ def __init__(self) -> None: WEB.method_name: WEB, PEER2.method_name: PEER2, PEER4.method_name: PEER4, + TDW.method_name: TDW, } def registered(self, method: str) -> bool: diff --git a/poetry.lock b/poetry.lock index 60bfdb4510..465055db55 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,15 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. + +[[package]] +name = "aiofiles" +version = "24.1.0" +description = "File support for asyncio." +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"}, + {file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"}, +] [[package]] name = "aiohappyeyeballs" @@ -213,7 +224,7 @@ yaml = ["PyYAML (>=3.10)"] name = "aries-askar" version = "0.3.2" description = "" -optional = true +optional = false python-versions = ">=3.6.3" files = [ {file = "aries_askar-0.3.2-py3-none-macosx_10_9_universal2.whl", hash = "sha256:02ddbe1773ce72c57edafff5777a1337d4a678da7484596712949170fb3ca1dc"}, @@ -283,11 +294,29 @@ files = [ [package.extras] tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", "pytest-cov", "pytest-flake8"] +[[package]] +name = "bases" +version = "0.3.0" +description = "Python library for general Base-N encodings." +optional = false +python-versions = ">=3.7" +files = [ + {file = "bases-0.3.0-py3-none-any.whl", hash = "sha256:a2fef3366f3e522ff473d2e95c21523fe8e44251038d5c6150c01481585ebf5b"}, + {file = "bases-0.3.0.tar.gz", hash = "sha256:70f04a4a45d63245787f9e89095ca11042685b6b64b542ad916575ba3ccd1570"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0" +typing-validation = ">=1.1.0" + +[package.extras] +dev = ["base58", "mypy", "pylint", "pytest", "pytest-cov"] + [[package]] name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." -optional = true +optional = false python-versions = "*" files = [ {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, @@ -855,6 +884,25 @@ files = [ [package.dependencies] base58 = ">=2.1.1" +[[package]] +name = "did-tdw" +version = "0.2.1" +description = "This repository includes Python libraries for working with `did:tdw` (Trust DID Web) DID documents and the underlying log format." +optional = false +python-versions = "<4.0,>=3.10" +files = [ + {file = "did_tdw-0.2.1-py3-none-any.whl", hash = "sha256:80c727d0bef37e2211d3caddb97ba3c4aa508c67d4ef502da5f326d9bf4c3ffb"}, + {file = "did_tdw-0.2.1.tar.gz", hash = "sha256:a61ed9f49369ea4c365e5e380431feae8cb3988375de37f73be2abe15d0bfde6"}, +] + +[package.dependencies] +aiofiles = ">=24.1.0,<25.0.0" +aiohttp = ">=3.10.5,<4.0.0" +aries-askar = ">=0.3.2,<0.4.0" +base58 = ">=2.1.0,<2.2.0" +jsoncanon = ">=0.2.3,<0.3.0" +multiformats = ">=0.3.1,<0.4.0" + [[package]] name = "didcomm-messaging" version = "0.1.1" @@ -1258,6 +1306,17 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jsoncanon" +version = "0.2.3" +description = "Typed Python implementation of JSON Canonicalization Scheme as described in RFC 8785. Currently lacks full floating point support" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "jsoncanon-0.2.3-py3-none-any.whl", hash = "sha256:adb35dac2d0c5dd56f1cb374f1ea6f1fff2ebbb4e844b06d9c96b9ccadf12bf0"}, + {file = "jsoncanon-0.2.3.tar.gz", hash = "sha256:483c1ef14e6c8151ba69c0bf646551f249698dd523e9c6da1339a688c5f96d6d"}, +] + [[package]] name = "jsonpath-ng" version = "1.7.0" @@ -1644,6 +1703,44 @@ files = [ {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, ] +[[package]] +name = "multiformats" +version = "0.3.1.post4" +description = "Python implementation of multiformats protocols." +optional = false +python-versions = ">=3.7" +files = [ + {file = "multiformats-0.3.1.post4-py3-none-any.whl", hash = "sha256:5b1d61bd8275c9e817bdbee38dbd501b26629011962ee3c86c46e7ccd0b14129"}, + {file = "multiformats-0.3.1.post4.tar.gz", hash = "sha256:d00074fdbc7d603c2084b4c38fa17bbc28173cf2750f51f46fbbc5c4d5605fbb"}, +] + +[package.dependencies] +bases = ">=0.3.0" +multiformats-config = ">=0.3.0" +typing-extensions = ">=4.6.0" +typing-validation = ">=1.1.0" + +[package.extras] +dev = ["blake3", "mmh3", "mypy", "pycryptodomex", "pylint", "pyskein", "pytest", "pytest-cov", "rich"] +full = ["blake3", "mmh3", "pycryptodomex", "pyskein", "rich"] + +[[package]] +name = "multiformats-config" +version = "0.3.1" +description = "Pre-loading configuration module for the 'multiformats' package." +optional = false +python-versions = ">=3.7" +files = [ + {file = "multiformats-config-0.3.1.tar.gz", hash = "sha256:7eaa80ef5d9c5ee9b86612d21f93a087c4a655cbcb68960457e61adbc62b47a7"}, + {file = "multiformats_config-0.3.1-py3-none-any.whl", hash = "sha256:dec4c9d42ed0d9305889b67440f72e8e8d74b82b80abd7219667764b5b0a8e1d"}, +] + +[package.dependencies] +multiformats = "*" + +[package.extras] +dev = ["mypy", "pylint", "pytest", "pytest-cov"] + [[package]] name = "nest-asyncio" version = "1.6.0" @@ -2746,6 +2843,20 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "typing-validation" +version = "1.2.11.post4" +description = "A simple library for runtime type-checking." +optional = false +python-versions = ">=3.7" +files = [ + {file = "typing_validation-1.2.11.post4-py3-none-any.whl", hash = "sha256:73dd504ddebf5210e80d5f65ba9b30efbd0fa42f266728fda7c4f0ba335c699c"}, + {file = "typing_validation-1.2.11.post4.tar.gz", hash = "sha256:7aed04ecfbda07e63b7266f90e5d096f96344f7facfe04bb081b21e4a9781670"}, +] + +[package.extras] +dev = ["mypy", "pylint", "pytest", "pytest-cov", "rich"] + [[package]] name = "unflatten" version = "0.2.0" @@ -3028,4 +3139,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "d5ab2d9c2721f87d92ca77cc8bf7a044cfc2c41b58b111af84a454ac2cc96910" +content-hash = "543d20028efad5a9d798071ba86e9d1ab39b202fe1afaa27f8f4c7f656f1d7cc" diff --git a/pyproject.toml b/pyproject.toml index 0064c4701d..7de97f37b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,9 +45,13 @@ requests = "~2.32.3" rlp = "4.0.1" unflatten = "~0.2" sd-jwt = "^0.10.3" +uuid_utils = "^0.9.0" + +# did libraries did-peer-2 = "^0.1.2" did-peer-4 = "^0.1.4" -uuid_utils = "^0.9.0" +did-tdw = "^0.2.1" + # askar aries-askar = { version = "~0.3.2", optional = true } From 3c7dee88572facbb77304fca138320591ab76d1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:42:10 +0000 Subject: [PATCH 013/152] chore(deps): Bump aiohttp (#3342) Bumps the pip group with 1 update in the /scenarios directory: [aiohttp](https://github.com/aio-libs/aiohttp). Updates `aiohttp` from 3.10.5 to 3.10.11 - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.10.5...v3.10.11) --- updated-dependencies: - dependency-name: aiohttp dependency-type: indirect dependency-group: pip ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com> --- scenarios/poetry.lock | 474 +++++++++++++++++++++++++----------------- 1 file changed, 287 insertions(+), 187 deletions(-) diff --git a/scenarios/poetry.lock b/scenarios/poetry.lock index 512f6c51a0..87805a2cb5 100644 --- a/scenarios/poetry.lock +++ b/scenarios/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "acapy-controller" @@ -36,112 +36,112 @@ files = [ [[package]] name = "aiohttp" -version = "3.10.5" +version = "3.10.11" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6"}, - {file = "aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb"}, - {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3"}, - {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683"}, - {file = "aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef"}, - {file = "aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf"}, - {file = "aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7"}, - {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277"}, - {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058"}, - {file = "aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072"}, - {file = "aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a"}, - {file = "aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f"}, - {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91"}, - {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6"}, - {file = "aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12"}, - {file = "aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77"}, - {file = "aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa"}, - {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5"}, - {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987"}, - {file = "aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04"}, - {file = "aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a"}, - {file = "aiohttp-3.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5"}, - {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f"}, - {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511"}, - {file = "aiohttp-3.10.5-cp38-cp38-win32.whl", hash = "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a"}, - {file = "aiohttp-3.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172"}, - {file = "aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f"}, - {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857"}, - {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11"}, - {file = "aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1"}, - {file = "aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862"}, - {file = "aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d"}, + {file = "aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120"}, + {file = "aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8"}, + {file = "aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9"}, + {file = "aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4"}, + {file = "aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb"}, + {file = "aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00"}, + {file = "aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71"}, + {file = "aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7"}, + {file = "aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4"}, + {file = "aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f"}, + {file = "aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9"}, + {file = "aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb"}, + {file = "aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7"}, ] [package.dependencies] aiohappyeyeballs = ">=2.3.0" aiosignal = ">=1.1.2" -async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} +async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" -yarl = ">=1.0,<2.0" +yarl = ">=1.12.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] @@ -485,6 +485,113 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "propcache" +version = "0.2.0" +description = "Accelerated property cache" +optional = false +python-versions = ">=3.8" +files = [ + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, + {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, + {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, + {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, + {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, + {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, + {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, + {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, + {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, + {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, + {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, + {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, + {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, + {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, + {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, +] + [[package]] name = "pydantic" version = "2.8.2" @@ -683,106 +790,99 @@ files = [ [[package]] name = "yarl" -version = "1.9.4" +version = "1.17.2" description = "Yet another URL library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, - {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, - {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, - {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, - {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, - {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, - {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, - {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, - {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, - {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, - {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, - {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, - {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, - {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, - {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, - {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, - {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, - {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, - {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, - {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, - {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, - {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, - {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, - {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, - {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, - {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, - {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, - {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, - {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, - {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, - {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, - {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, - {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:93771146ef048b34201bfa382c2bf74c524980870bb278e6df515efaf93699ff"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8281db240a1616af2f9c5f71d355057e73a1409c4648c8949901396dc0a3c151"}, + {file = "yarl-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:170ed4971bf9058582b01a8338605f4d8c849bd88834061e60e83b52d0c76870"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc61b005f6521fcc00ca0d1243559a5850b9dd1e1fe07b891410ee8fe192d0c0"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871e1b47eec7b6df76b23c642a81db5dd6536cbef26b7e80e7c56c2fd371382e"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a58a2f2ca7aaf22b265388d40232f453f67a6def7355a840b98c2d547bd037f"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:736bb076f7299c5c55dfef3eb9e96071a795cb08052822c2bb349b06f4cb2e0a"}, + {file = "yarl-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fd51299e21da709eabcd5b2dd60e39090804431292daacbee8d3dabe39a6bc0"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:358dc7ddf25e79e1cc8ee16d970c23faee84d532b873519c5036dbb858965795"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:50d866f7b1a3f16f98603e095f24c0eeba25eb508c85a2c5939c8b3870ba2df8"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b9c4643e7d843a0dca9cd9d610a0876e90a1b2cbc4c5ba7930a0d90baf6903f"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d63123bfd0dce5f91101e77c8a5427c3872501acece8c90df457b486bc1acd47"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4e76381be3d8ff96a4e6c77815653063e87555981329cf8f85e5be5abf449021"}, + {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:734144cd2bd633a1516948e477ff6c835041c0536cef1d5b9a823ae29899665b"}, + {file = "yarl-1.17.2-cp310-cp310-win32.whl", hash = "sha256:26bfb6226e0c157af5da16d2d62258f1ac578d2899130a50433ffee4a5dfa673"}, + {file = "yarl-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:76499469dcc24759399accd85ec27f237d52dec300daaca46a5352fcbebb1071"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:792155279dc093839e43f85ff7b9b6493a8eaa0af1f94f1f9c6e8f4de8c63500"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38bc4ed5cae853409cb193c87c86cd0bc8d3a70fd2268a9807217b9176093ac6"}, + {file = "yarl-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4a8c83f6fcdc327783bdc737e8e45b2e909b7bd108c4da1892d3bc59c04a6d84"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6d5fed96f0646bfdf698b0a1cebf32b8aae6892d1bec0c5d2d6e2df44e1e2d"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:782ca9c58f5c491c7afa55518542b2b005caedaf4685ec814fadfcee51f02493"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff6af03cac0d1a4c3c19e5dcc4c05252411bf44ccaa2485e20d0a7c77892ab6e"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a3f47930fbbed0f6377639503848134c4aa25426b08778d641491131351c2c8"}, + {file = "yarl-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1fa68a3c921365c5745b4bd3af6221ae1f0ea1bf04b69e94eda60e57958907f"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:187df91395c11e9f9dc69b38d12406df85aa5865f1766a47907b1cc9855b6303"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:93d1c8cc5bf5df401015c5e2a3ce75a5254a9839e5039c881365d2a9dcfc6dc2"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:11d86c6145ac5c706c53d484784cf504d7d10fa407cb73b9d20f09ff986059ef"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c42774d1d1508ec48c3ed29e7b110e33f5e74a20957ea16197dbcce8be6b52ba"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8e589379ef0407b10bed16cc26e7392ef8f86961a706ade0a22309a45414d7"}, + {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1056cadd5e850a1c026f28e0704ab0a94daaa8f887ece8dfed30f88befb87bb0"}, + {file = "yarl-1.17.2-cp311-cp311-win32.whl", hash = "sha256:be4c7b1c49d9917c6e95258d3d07f43cfba2c69a6929816e77daf322aaba6628"}, + {file = "yarl-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:ac8eda86cc75859093e9ce390d423aba968f50cf0e481e6c7d7d63f90bae5c9c"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dd90238d3a77a0e07d4d6ffdebc0c21a9787c5953a508a2231b5f191455f31e9"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c74f0b0472ac40b04e6d28532f55cac8090e34c3e81f118d12843e6df14d0909"}, + {file = "yarl-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d486ddcaca8c68455aa01cf53d28d413fb41a35afc9f6594a730c9779545876"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25b7e93f5414b9a983e1a6c1820142c13e1782cc9ed354c25e933aebe97fcf2"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a0baff7827a632204060f48dca9e63fbd6a5a0b8790c1a2adfb25dc2c9c0d50"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:460024cacfc3246cc4d9f47a7fc860e4fcea7d1dc651e1256510d8c3c9c7cde0"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5870d620b23b956f72bafed6a0ba9a62edb5f2ef78a8849b7615bd9433384171"}, + {file = "yarl-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2941756754a10e799e5b87e2319bbec481ed0957421fba0e7b9fb1c11e40509f"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9611b83810a74a46be88847e0ea616794c406dbcb4e25405e52bff8f4bee2d0a"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cd7e35818d2328b679a13268d9ea505c85cd773572ebb7a0da7ccbca77b6a52e"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6b981316fcd940f085f646b822c2ff2b8b813cbd61281acad229ea3cbaabeb6b"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:688058e89f512fb7541cb85c2f149c292d3fa22f981d5a5453b40c5da49eb9e8"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56afb44a12b0864d17b597210d63a5b88915d680f6484d8d202ed68ade38673d"}, + {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:17931dfbb84ae18b287279c1f92b76a3abcd9a49cd69b92e946035cff06bcd20"}, + {file = "yarl-1.17.2-cp312-cp312-win32.whl", hash = "sha256:ff8d95e06546c3a8c188f68040e9d0360feb67ba8498baf018918f669f7bc39b"}, + {file = "yarl-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:4c840cc11163d3c01a9d8aad227683c48cd3e5be5a785921bcc2a8b4b758c4f3"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3294f787a437cb5d81846de3a6697f0c35ecff37a932d73b1fe62490bef69211"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1e7fedb09c059efee2533119666ca7e1a2610072076926fa028c2ba5dfeb78c"}, + {file = "yarl-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da9d3061e61e5ae3f753654813bc1cd1c70e02fb72cf871bd6daf78443e9e2b1"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91c012dceadc695ccf69301bfdccd1fc4472ad714fe2dd3c5ab4d2046afddf29"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f11fd61d72d93ac23718d393d2a64469af40be2116b24da0a4ca6922df26807e"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46c465ad06971abcf46dd532f77560181387b4eea59084434bdff97524444032"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef6eee1a61638d29cd7c85f7fd3ac7b22b4c0fabc8fd00a712b727a3e73b0685"}, + {file = "yarl-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4434b739a8a101a837caeaa0137e0e38cb4ea561f39cb8960f3b1e7f4967a3fc"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:752485cbbb50c1e20908450ff4f94217acba9358ebdce0d8106510859d6eb19a"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:17791acaa0c0f89323c57da7b9a79f2174e26d5debbc8c02d84ebd80c2b7bff8"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5c6ea72fe619fee5e6b5d4040a451d45d8175f560b11b3d3e044cd24b2720526"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db5ac3871ed76340210fe028f535392f097fb31b875354bcb69162bba2632ef4"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7a1606ba68e311576bcb1672b2a1543417e7e0aa4c85e9e718ba6466952476c0"}, + {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9bc27dd5cfdbe3dc7f381b05e6260ca6da41931a6e582267d5ca540270afeeb2"}, + {file = "yarl-1.17.2-cp313-cp313-win32.whl", hash = "sha256:52492b87d5877ec405542f43cd3da80bdcb2d0c2fbc73236526e5f2c28e6db28"}, + {file = "yarl-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:8e1bf59e035534ba4077f5361d8d5d9194149f9ed4f823d1ee29ef3e8964ace3"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c556fbc6820b6e2cda1ca675c5fa5589cf188f8da6b33e9fc05b002e603e44fa"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f44a4247461965fed18b2573f3a9eb5e2c3cad225201ee858726cde610daca"}, + {file = "yarl-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a3ede8c248f36b60227eb777eac1dbc2f1022dc4d741b177c4379ca8e75571a"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2654caaf5584449d49c94a6b382b3cb4a246c090e72453493ea168b931206a4d"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d41c684f286ce41fa05ab6af70f32d6da1b6f0457459a56cf9e393c1c0b2217"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2270d590997445a0dc29afa92e5534bfea76ba3aea026289e811bf9ed4b65a7f"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18662443c6c3707e2fc7fad184b4dc32dd428710bbe72e1bce7fe1988d4aa654"}, + {file = "yarl-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75ac158560dec3ed72f6d604c81090ec44529cfb8169b05ae6fcb3e986b325d9"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1fee66b32e79264f428dc8da18396ad59cc48eef3c9c13844adec890cd339db5"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:585ce7cd97be8f538345de47b279b879e091c8b86d9dbc6d98a96a7ad78876a3"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c019abc2eca67dfa4d8fb72ba924871d764ec3c92b86d5b53b405ad3d6aa56b0"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c6e659b9a24d145e271c2faf3fa6dd1fcb3e5d3f4e17273d9e0350b6ab0fe6e2"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d17832ba39374134c10e82d137e372b5f7478c4cceeb19d02ae3e3d1daed8721"}, + {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bc3003710e335e3f842ae3fd78efa55f11a863a89a72e9a07da214db3bf7e1f8"}, + {file = "yarl-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f5ffc6b7ace5b22d9e73b2a4c7305740a339fbd55301d52735f73e21d9eb3130"}, + {file = "yarl-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:48e424347a45568413deec6f6ee2d720de2cc0385019bedf44cd93e8638aa0ed"}, + {file = "yarl-1.17.2-py3-none-any.whl", hash = "sha256:dd7abf4f717e33b7487121faf23560b3a50924f80e4bef62b22dab441ded8f3b"}, + {file = "yarl-1.17.2.tar.gz", hash = "sha256:753eaaa0c7195244c84b5cc159dc8204b7fd99f716f11198f999f2332a86b178"}, ] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" +propcache = ">=0.2.0" [metadata] lock-version = "2.0" From 815a0f3288e807a084fd18b6004a2ca4d8cc0f58 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 6 Nov 2024 20:27:33 +0200 Subject: [PATCH 014/152] :art: Refactor `register_plugin` steps for maintainability Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 144 ++++++++++++++++------------ 1 file changed, 84 insertions(+), 60 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index b3fa709386..43aacdb810 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -117,70 +117,94 @@ def validate_version(self, version_list, module_name): return True - def register_plugin(self, module_name: str) -> ModuleType: + def register_plugin(self, module_name: str) -> Optional[ModuleType]: """Register a plugin module.""" - if module_name in self._plugins: - mod = self._plugins[module_name] - elif module_name in self._blocklist: - LOGGER.debug(f"Blocked {module_name} from loading due to blocklist") + if self._is_already_registered(module_name): + return self._plugins.get(module_name) + + if self._is_blocked(module_name): return None - else: - try: - mod = ClassLoader.load_module(module_name) - LOGGER.debug(f"Loaded module: {module_name}") - except ModuleLoadError as e: - LOGGER.error(f"Error loading plugin module: {e}") - return None - # Module must exist - if not mod: - LOGGER.error(f"Module doesn't exist: {module_name}") - return None - - # Any plugin with a setup method is considered valid. - if hasattr(mod, "setup"): - self._plugins[module_name] = mod - return mod - - # Make an exception for non-protocol modules - # that contain admin routes and for old-style protocol - # modules without version support - routes = ClassLoader.load_module("routes", module_name) - message_types = ClassLoader.load_module("message_types", module_name) - if routes or message_types: - self._plugins[module_name] = mod - return mod - - definition = ClassLoader.load_module("definition", module_name) - - # definition.py must exist in protocol - if not definition: - LOGGER.error(f"Protocol does not include definition.py: {module_name}") - return None - - # definition.py must include versions attribute - if not hasattr(definition, "versions"): - LOGGER.error( - "Protocol definition does not include " - f"versions attribute: {module_name}" - ) - return None + mod = self._load_module(module_name) + if not mod: + return None - # Definition list must not be malformed - try: - self.validate_version(definition.versions, module_name) - except ProtocolDefinitionValidationError as e: - LOGGER.error(f"Protocol versions definition is malformed. {e}") - return None - - self._plugins[module_name] = mod - return mod - - # # Load each version as a separate plugin - # for version in definition.versions: - # mod = ClassLoader.load_module(f"{module_name}.{version['path']}") - # self._plugins[module_name] = mod - # return mod + if self._is_valid_plugin(mod, module_name): + self._plugins[module_name] = mod + LOGGER.debug("Registered plugin: %s", module_name) + return mod + + LOGGER.debug("Failed to register plugin: %s", module_name) + return None + + def _is_already_registered(self, module_name: str) -> bool: + """Check if the plugin is already registered.""" + if module_name in self._plugins: + LOGGER.debug("Plugin %s is already registered.", module_name) + return True + return False + + def _is_blocked(self, module_name: str) -> bool: + """Check if the plugin is in the blocklist.""" + if module_name in self._blocklist: + LOGGER.debug("Blocked %s from loading due to blocklist.", module_name) + return True + return False + + def _load_module(self, module_name: str) -> Optional[ModuleType]: + """Load the plugin module using ClassLoader.""" + try: + mod = ClassLoader.load_module(module_name) + LOGGER.debug("Successfully loaded module: %s", module_name) + return mod + except ModuleLoadError as e: + LOGGER.error("Error loading plugin module '%s': %s", module_name, e) + return None + + def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: + """Validate the plugin based on various criteria.""" + # Check if the plugin has a 'setup' method + if hasattr(mod, "setup"): + LOGGER.debug("Plugin %s has a 'setup' method.", module_name) + return True + + # Check for 'routes' or 'message_types' modules + # This makes an exception for non-protocol modules that contain admin routes + # and for old-style protocol modules without version support + routes = ClassLoader.load_module("routes", module_name) + message_types = ClassLoader.load_module("message_types", module_name) + if routes or message_types: + LOGGER.debug("Plugin %s has 'routes' or 'message_types'.", module_name) + return True + + # Check for 'definition' module with 'versions' attribute + definition = ClassLoader.load_module("definition", module_name) + if not definition: + LOGGER.error( + "Protocol does not include 'definition.py' for module: %s", + module_name, + ) + return False + + if not hasattr(definition, "versions"): + LOGGER.error( + "Protocol definition does not include versions attribute for module: %s", + module_name, + ) + return False + + # Validate the 'versions' attribute + try: + self.validate_version(definition.versions, module_name) + LOGGER.debug("Plugin %s has valid versions.", module_name) + return True + except ProtocolDefinitionValidationError as e: + LOGGER.error( + "Protocol versions definition is malformed for module '%s': %s", + module_name, + e, + ) + return False def register_package(self, package_name: str) -> Sequence[ModuleType]: """Register all modules (sub-packages) under a given package name.""" From ce9f8b766a0ae88162786c259290e6dd688c2354 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 6 Nov 2024 20:36:43 +0200 Subject: [PATCH 015/152] :art: improve logging in register_package Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 43aacdb810..3a97d50ee4 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -208,21 +208,27 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: def register_package(self, package_name: str) -> Sequence[ModuleType]: """Register all modules (sub-packages) under a given package name.""" + LOGGER.debug("Registering package: %s", package_name) try: module_names = ClassLoader.scan_subpackages(package_name) except ModuleLoadError: LOGGER.error("Plugin module package not found: %s", package_name) module_names = [] - return list( - filter( - None, - ( - self.register_plugin(module_name) - for module_name in module_names - if module_name.split(".")[-1] != "tests" - ), - ) - ) + + registered_plugins = [] + for module_name in module_names: + # Skip any module whose last segment is 'tests' + if module_name.split(".")[-1] == "tests": + LOGGER.debug("Skipping test module: %s", module_name) + continue + + plugin = self.register_plugin(module_name) + if plugin: + registered_plugins.append(plugin) + else: + LOGGER.debug("Failed to register %s under %s", module_name, package_name) + + return registered_plugins async def init_context(self, context: InjectionContext): """Call plugin setup methods on the current context.""" From 3e5088e911a748fcffb80db767e46dbe0fb60e67 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 6 Nov 2024 21:07:22 +0200 Subject: [PATCH 016/152] :art: Rename method and remove redundant main call Signed-off-by: ff137 --- acapy_agent/commands/provision.py | 11 +++-------- acapy_agent/commands/tests/test_provision.py | 13 ++++++++----- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/acapy_agent/commands/provision.py b/acapy_agent/commands/provision.py index 962b38dc8e..a463dd6e48 100644 --- a/acapy_agent/commands/provision.py +++ b/acapy_agent/commands/provision.py @@ -67,7 +67,7 @@ async def provision(settings: dict): raise ProvisionError("Error during provisioning") from e -def execute(argv: Sequence[str] = None): +def execute_provision(argv: Sequence[str] = None): """Entrypoint.""" parser = arg.create_argument_parser(prog=PROG) parser.prog += " provision" @@ -84,10 +84,5 @@ def execute(argv: Sequence[str] = None): loop.run_until_complete(provision(settings)) -def main(): - """Execute the main line.""" - if __name__ == "__main__": - execute() - - -main() +if __name__ == "__main__": + execute_provision() diff --git a/acapy_agent/commands/tests/test_provision.py b/acapy_agent/commands/tests/test_provision.py index 65d0d488bd..3fbeb00208 100644 --- a/acapy_agent/commands/tests/test_provision.py +++ b/acapy_agent/commands/tests/test_provision.py @@ -14,10 +14,10 @@ class TestProvision(IsolatedAsyncioTestCase): def test_bad_calls(self): with self.assertRaises(ArgsParseError): - test_module.execute([]) + test_module.execute_provision([]) with self.assertRaises(SystemExit): - test_module.execute(["bad"]) + test_module.execute_provision(["bad"]) async def test_provision_ledger_configured(self): profile = mock.MagicMock(close=mock.CoroutineMock()) @@ -43,11 +43,14 @@ async def test_provision_config_x(self): with self.assertRaises(test_module.ProvisionError): await test_module.provision({}) - def test_main(self): + def test_main_entry_point(self): + """Test that the execute_provision function is called when the module is run as main.""" with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "execute", mock.MagicMock() + test_module, "execute_provision", mock.MagicMock() ) as mock_execute: - test_module.main() + import importlib + + importlib.reload(test_module) # Reload the module to trigger the main guard mock_execute.assert_called_once async def test_provision_should_store_provided_mediation_invite(self): From 59e49518ecf144318d2db8fd9f9f1502a6e70ef2 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 6 Nov 2024 21:08:48 +0200 Subject: [PATCH 017/152] :art: Signed-off-by: ff137 --- acapy_agent/config/argparse.py | 2 +- acapy_agent/config/default_context.py | 12 +++++------ acapy_agent/core/plugin_registry.py | 30 +++++++++++++-------------- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/acapy_agent/config/argparse.py b/acapy_agent/config/argparse.py index ec0d3d95e1..222c7c2461 100644 --- a/acapy_agent/config/argparse.py +++ b/acapy_agent/config/argparse.py @@ -63,7 +63,7 @@ def get_registered(cls, category: Optional[str] = None): def create_argument_parser(*, prog: Optional[str] = None): - """Create am instance of an arg parser, force yaml format for external config.""" + """Create an instance of an arg parser, force yaml format for external config.""" return ArgumentParser(config_file_parser_class=YAMLConfigFileParser, prog=prog) diff --git a/acapy_agent/config/default_context.py b/acapy_agent/config/default_context.py index 136c79791d..d3c345136d 100644 --- a/acapy_agent/config/default_context.py +++ b/acapy_agent/config/default_context.py @@ -132,9 +132,7 @@ async def load_plugins(self, context: InjectionContext): # Currently providing admin routes only plugin_registry.register_plugin("acapy_agent.holder") - plugin_registry.register_plugin("acapy_agent.ledger") - plugin_registry.register_plugin("acapy_agent.messaging.jsonld") plugin_registry.register_plugin("acapy_agent.resolver") plugin_registry.register_plugin("acapy_agent.settings") @@ -165,15 +163,15 @@ def register_anoncreds_plugins(): for plugin in anoncreds_plugins: plugin_registry.register_plugin(plugin) - if wallet_type == "askar-anoncreds": - register_anoncreds_plugins() - else: - register_askar_plugins() - if context.settings.get("multitenant.admin_enabled"): plugin_registry.register_plugin("acapy_agent.multitenant.admin") register_askar_plugins() register_anoncreds_plugins() + else: + if wallet_type == "askar-anoncreds": + register_anoncreds_plugins() + else: + register_askar_plugins() # Register external plugins for plugin_path in self.settings.get("external_plugins", []): diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 3a97d50ee4..61ea440f74 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -3,7 +3,7 @@ import logging from collections import OrderedDict from types import ModuleType -from typing import Iterable, Optional, Sequence +from typing import Optional, Sequence, Set from ..config.injection_context import InjectionContext from ..core.event_bus import EventBus @@ -18,10 +18,10 @@ class PluginRegistry: """Plugin registry for indexing application plugins.""" - def __init__(self, blocklist: Iterable[str] = []): + def __init__(self, blocklist: Optional[Set[str]] = None): """Initialize a `PluginRegistry` instance.""" - self._plugins = OrderedDict() - self._blocklist = set(blocklist) + self._plugins: OrderedDict[str, ModuleType] = OrderedDict() + self._blocklist: Set[str] = set(blocklist) if blocklist else set() @property def plugin_names(self) -> Sequence[str]: @@ -57,7 +57,6 @@ def validate_version(self, version_list, module_name): for version_dict in version_list: # Dicts must have correct format - try: if not ( isinstance(version_dict["major_version"], int) @@ -89,8 +88,8 @@ def validate_version(self, version_list, module_name): > version_dict["current_minor_version"] ): raise ProtocolDefinitionValidationError( - "Minimum supported minor version cannot" - + " be greater than current minor version" + "Minimum supported minor version cannot " + "be greater than current minor version" ) # There can only be one definition per major version @@ -102,7 +101,7 @@ def validate_version(self, version_list, module_name): if count > 1: raise ProtocolDefinitionValidationError( "There can only be one definition per major version. " - + f"Found {count} for major version {major_version}." + f"Found {count} for major version {major_version}." ) # Specified module must be loadable @@ -111,8 +110,7 @@ def validate_version(self, version_list, module_name): if not mod: raise ProtocolDefinitionValidationError( - "Version module path is not " - + f"loadable: {module_name}, {version_path}" + f"Version module path is not loadable: {module_name}, {version_path}" ) return True @@ -230,7 +228,7 @@ def register_package(self, package_name: str) -> Sequence[ModuleType]: return registered_plugins - async def init_context(self, context: InjectionContext): + async def init_context(self, context: InjectionContext) -> None: """Call plugin setup methods on the current context.""" for plugin in self._plugins.values(): if hasattr(plugin, "setup"): @@ -246,7 +244,7 @@ async def load_protocol_version( context: InjectionContext, mod: ModuleType, version_definition: Optional[dict] = None, - ): + ) -> None: """Load a particular protocol version.""" protocol_registry = context.inject(ProtocolRegistry) goal_code_registry = context.inject(GoalCodeRegistry) @@ -258,7 +256,7 @@ async def load_protocol_version( protocol_registry.register_controllers(mod.CONTROLLERS) goal_code_registry.register_controllers(mod.CONTROLLERS) - async def load_protocols(self, context: InjectionContext, plugin: ModuleType): + async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> None: """For modules that don't implement setup, register protocols manually.""" # If this module contains message_types, then assume that @@ -293,7 +291,7 @@ async def load_protocols(self, context: InjectionContext, plugin: ModuleType): LOGGER.error("Error loading plugin module message types: %s", e) return - async def register_admin_routes(self, app): + async def register_admin_routes(self, app) -> None: """Call route registration methods on the current context.""" for plugin in self._plugins.values(): definition = ClassLoader.load_module("definition", plugin.__name__) @@ -319,7 +317,7 @@ async def register_admin_routes(self, app): if mod and hasattr(mod, "register"): await mod.register(app) - def register_protocol_events(self, context: InjectionContext): + def register_protocol_events(self, context: InjectionContext) -> None: """Call route register_events methods on the current context.""" event_bus = context.inject_or(EventBus) if not event_bus: @@ -349,7 +347,7 @@ def register_protocol_events(self, context: InjectionContext): if mod and hasattr(mod, "register_events"): mod.register_events(event_bus) - def post_process_routes(self, app): + def post_process_routes(self, app) -> None: """Call route binary file response OpenAPI fixups if applicable.""" for plugin in self._plugins.values(): definition = ClassLoader.load_module("definition", plugin.__name__) From 02011a83486c06a0706ab8215640885efcc10f22 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 11:42:14 +0200 Subject: [PATCH 018/152] :loud_sound: Add debug logging to Context Builder Signed-off-by: ff137 --- acapy_agent/config/default_context.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/acapy_agent/config/default_context.py b/acapy_agent/config/default_context.py index d3c345136d..1f049f8ece 100644 --- a/acapy_agent/config/default_context.py +++ b/acapy_agent/config/default_context.py @@ -1,5 +1,7 @@ """Classes for configuring the default injection context.""" +import logging + from ..anoncreds.registry import AnonCredsRegistry from ..cache.base import BaseCache from ..cache.in_memory import InMemoryCache @@ -26,17 +28,22 @@ from .injection_context import InjectionContext from .provider import CachedProvider, ClassProvider +LOGGER = logging.getLogger(__name__) + class DefaultContextBuilder(ContextBuilder): """Default context builder.""" async def build_context(self) -> InjectionContext: """Build the base injection context; set DIDComm prefix to emit.""" + LOGGER.debug("Building new injection context with settings: %s", self.settings) + context = InjectionContext(settings=self.settings) context.settings.set_default("default_label", "Aries Cloud Agent") if context.settings.get("timing.enabled"): timing_log = context.settings.get("timing.log_file") + LOGGER.debug("Enabling timing collector with log file: %s", timing_log) collector = Collector(log_path=timing_log) context.injector.bind_instance(Collector, collector) @@ -63,11 +70,8 @@ async def build_context(self) -> InjectionContext: # DIDComm Messaging if context.settings.get("experiment.didcomm_v2"): - from didcomm_messaging import ( - CryptoService, - PackagingService, - RoutingService, - ) + LOGGER.info("DIDComm v2 experimental mode enabled") + from didcomm_messaging import CryptoService, PackagingService, RoutingService from didcomm_messaging.crypto.backend.askar import AskarCryptoService context.injector.bind_instance(CryptoService, AskarCryptoService()) @@ -81,11 +85,13 @@ async def build_context(self) -> InjectionContext: async def bind_providers(self, context: InjectionContext): """Bind various class providers.""" + LOGGER.debug("Begin binding providers to context") context.injector.bind_provider(ProfileManager, ProfileManagerProvider()) wallet_type = self.settings.get("wallet.type") if wallet_type == "askar-anoncreds": + LOGGER.debug("Using AnonCreds tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -93,6 +99,7 @@ async def bind_providers(self, context: InjectionContext): ), ) else: + LOGGER.debug("Using Indy tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -120,6 +127,7 @@ async def bind_providers(self, context: InjectionContext): async def load_plugins(self, context: InjectionContext): """Set up plugin registry and load plugins.""" + LOGGER.debug("Initializing plugin registry") plugin_registry = PluginRegistry( blocklist=self.settings.get("blocked_plugins", []) ) @@ -164,6 +172,7 @@ def register_anoncreds_plugins(): plugin_registry.register_plugin(plugin) if context.settings.get("multitenant.admin_enabled"): + LOGGER.debug("Multitenant admin enabled - registering additional plugins") plugin_registry.register_plugin("acapy_agent.multitenant.admin") register_askar_plugins() register_anoncreds_plugins() @@ -175,6 +184,7 @@ def register_anoncreds_plugins(): # Register external plugins for plugin_path in self.settings.get("external_plugins", []): + LOGGER.debug("Registering external plugin: %s", plugin_path) plugin_registry.register_plugin(plugin_path) # Register message protocols From 12631918269608b77d00229f73de4d2e60df4cb6 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 11:42:34 +0200 Subject: [PATCH 019/152] :art: Deduplicate registering list of plugins Signed-off-by: ff137 --- acapy_agent/config/default_context.py | 36 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/acapy_agent/config/default_context.py b/acapy_agent/config/default_context.py index 1f049f8ece..8f2978b4fc 100644 --- a/acapy_agent/config/default_context.py +++ b/acapy_agent/config/default_context.py @@ -138,16 +138,18 @@ async def load_plugins(self, context: InjectionContext): if not self.settings.get("transport.disabled"): plugin_registry.register_package("acapy_agent.protocols") - # Currently providing admin routes only - plugin_registry.register_plugin("acapy_agent.holder") - plugin_registry.register_plugin("acapy_agent.ledger") - plugin_registry.register_plugin("acapy_agent.messaging.jsonld") - plugin_registry.register_plugin("acapy_agent.resolver") - plugin_registry.register_plugin("acapy_agent.settings") - plugin_registry.register_plugin("acapy_agent.vc") - plugin_registry.register_plugin("acapy_agent.vc.data_integrity") - plugin_registry.register_plugin("acapy_agent.wallet") - plugin_registry.register_plugin("acapy_agent.wallet.keys") + # Define plugin groups + default_plugins = [ + "acapy_agent.holder", + "acapy_agent.ledger", + "acapy_agent.messaging.jsonld", + "acapy_agent.resolver", + "acapy_agent.settings", + "acapy_agent.vc", + "acapy_agent.vc.data_integrity", + "acapy_agent.wallet", + "acapy_agent.wallet.keys", + ] anoncreds_plugins = [ "acapy_agent.anoncreds", @@ -163,13 +165,19 @@ async def load_plugins(self, context: InjectionContext): "acapy_agent.revocation", ] - def register_askar_plugins(): - for plugin in askar_plugins: + def register_plugins(plugins: list[str], plugin_type: str): + """Register a group of plugins with logging.""" + LOGGER.debug("Registering %s plugins", plugin_type) + for plugin in plugins: plugin_registry.register_plugin(plugin) + def register_askar_plugins(): + register_plugins(askar_plugins, "askar") + def register_anoncreds_plugins(): - for plugin in anoncreds_plugins: - plugin_registry.register_plugin(plugin) + register_plugins(anoncreds_plugins, "anoncreds") + + register_plugins(default_plugins, "default") if context.settings.get("multitenant.admin_enabled"): LOGGER.debug("Multitenant admin enabled - registering additional plugins") From 24c14269b6a2d98a934e6afb1cd00367ce122df9 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 11:45:36 +0200 Subject: [PATCH 020/152] :art: Signed-off-by: ff137 --- acapy_agent/config/default_context.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/acapy_agent/config/default_context.py b/acapy_agent/config/default_context.py index 8f2978b4fc..ed49ff175d 100644 --- a/acapy_agent/config/default_context.py +++ b/acapy_agent/config/default_context.py @@ -111,12 +111,7 @@ async def bind_providers(self, context: InjectionContext): context.injector.bind_provider( BaseWireFormat, CachedProvider( - # StatsProvider( ClassProvider("acapy_agent.transport.pack_format.PackWireFormat"), - # ( - # "encode_message", "parse_message" - # ), - # ) ), ) From 826468878e7a65f915b7ec542134dac0a9cbe55f Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:23:58 +0200 Subject: [PATCH 021/152] :loud_sound: Add debug logging to init_context Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 61ea440f74..be58ba0661 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -230,10 +230,17 @@ def register_package(self, package_name: str) -> Sequence[ModuleType]: async def init_context(self, context: InjectionContext) -> None: """Call plugin setup methods on the current context.""" + LOGGER.debug("Initializing plugin context for %d plugins", len(self._plugins)) + for plugin in self._plugins.values(): + plugin_name = plugin.__name__ if hasattr(plugin, "setup"): + LOGGER.debug("Running setup for plugin: %s", plugin_name) await plugin.setup(context) else: + LOGGER.debug( + "Loading protocols for plugin without setup: %s", plugin_name + ) await self.load_protocols(context, plugin) # register event handlers for each protocol, if provided From b539ab0a130147399edb3a8e0c67ce16cd1d16fc Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:24:10 +0200 Subject: [PATCH 022/152] :loud_sound: Add debug logging to load_protocol_version Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index be58ba0661..1ad320e2d4 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -255,11 +255,18 @@ async def load_protocol_version( """Load a particular protocol version.""" protocol_registry = context.inject(ProtocolRegistry) goal_code_registry = context.inject(GoalCodeRegistry) + + module_name = mod.__name__ + LOGGER.debug("Loading protocol version for module: %s", module_name) + if hasattr(mod, "MESSAGE_TYPES"): + LOGGER.debug("Registering message types for: %s", module_name) protocol_registry.register_message_types( mod.MESSAGE_TYPES, version_definition=version_definition ) + if hasattr(mod, "CONTROLLERS"): + LOGGER.debug("Registering controllers for: %s", module_name) protocol_registry.register_controllers(mod.CONTROLLERS) goal_code_registry.register_controllers(mod.CONTROLLERS) From 595d391cc3da3349bcae21b5a19f2890f134858b Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:25:30 +0200 Subject: [PATCH 023/152] :loud_sound: Add debug logging to load_protocols Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 31 +++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 1ad320e2d4..d21eebeb66 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -272,37 +272,48 @@ async def load_protocol_version( async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> None: """For modules that don't implement setup, register protocols manually.""" + plugin_name = plugin.__name__ + LOGGER.debug("Loading protocols for plugin: %s", plugin_name) # If this module contains message_types, then assume that # this is a valid module of the old style (not versioned) try: - mod = ClassLoader.load_module(plugin.__name__ + ".message_types") + message_types_path = f"{plugin_name}.message_types" + LOGGER.debug("Attempting to load message types from: %s", message_types_path) + mod = ClassLoader.load_module(message_types_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin module message types: %s", e) return if mod: + LOGGER.debug("Found non-versioned message types for: %s", plugin_name) await self.load_protocol_version(context, mod) else: - # Otherwise, try check for definition.py for versioned - # protocol packages + # Otherwise, try check for definition.py for versioned protocol packages try: - definition = ClassLoader.load_module(plugin.__name__ + ".definition") + definition_path = f"{plugin_name}.definition" + LOGGER.debug("Attempting to load definition from: %s", definition_path) + definition = ClassLoader.load_module(definition_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin definition module: %s", e) return if definition: + LOGGER.debug("Loading versioned protocols for: %s", plugin_name) for protocol_version in definition.versions: + version_path = ( + f"{plugin_name}.{protocol_version['path']}.message_types" + ) try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{protocol_version['path']}" - + ".message_types" - ) + LOGGER.debug("Loading message types from: %s", version_path) + mod = ClassLoader.load_module(version_path) await self.load_protocol_version(context, mod, protocol_version) - except ModuleLoadError as e: - LOGGER.error("Error loading plugin module message types: %s", e) + LOGGER.error( + "Error loading plugin module message types from %s: %s", + version_path, + e, + ) return async def register_admin_routes(self, app) -> None: From b1a73a03df21aebbcb67be225e9a88e49900109f Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:25:52 +0200 Subject: [PATCH 024/152] :loud_sound: Add debug logging to register_admin_routes Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 32 +++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index d21eebeb66..909bac2436 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -318,29 +318,39 @@ async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> async def register_admin_routes(self, app) -> None: """Call route registration methods on the current context.""" + LOGGER.debug("Registering admin routes for %d plugins", len(self._plugins)) + for plugin in self._plugins.values(): - definition = ClassLoader.load_module("definition", plugin.__name__) + plugin_name = plugin.__name__ + LOGGER.debug("Processing routes for plugin: %s", plugin_name) + mod = None + definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. + LOGGER.debug("Loading versioned routes for: %s", plugin_name) for plugin_version in definition.versions: + version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{plugin_version['path']}.routes" - ) + LOGGER.debug("Loading routes from: %s", version_path) + mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error( + "Error loading admin routes from %s: %s", version_path, e + ) continue - if mod and hasattr(mod, "register"): - await mod.register(app) else: # Load plugin routes that aren't in a versioned package. + routes_path = f"{plugin_name}.routes" try: - mod = ClassLoader.load_module(f"{plugin.__name__}.routes") + LOGGER.debug("Loading non-versioned routes from: %s", routes_path) + mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading admin routes from %s: %s", routes_path, e) continue - if mod and hasattr(mod, "register"): - await mod.register(app) + + if mod and hasattr(mod, "register"): + LOGGER.debug("Registering routes from: %s", version_path) + await mod.register(app) def register_protocol_events(self, context: InjectionContext) -> None: """Call route register_events methods on the current context.""" From 5e199d19df420c2592785983aeaee7cf23078f63 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:26:17 +0200 Subject: [PATCH 025/152] :loud_sound: Add debug logging to register_protocol_events Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 31 +++++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 909bac2436..302a409062 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -354,33 +354,42 @@ async def register_admin_routes(self, app) -> None: def register_protocol_events(self, context: InjectionContext) -> None: """Call route register_events methods on the current context.""" + LOGGER.debug("Registering protocol events for %d plugins", len(self._plugins)) + event_bus = context.inject_or(EventBus) if not event_bus: LOGGER.error("No event bus in context") return + for plugin in self._plugins.values(): - definition = ClassLoader.load_module("definition", plugin.__name__) + plugin_name = plugin.__name__ + LOGGER.debug("Processing events for plugin: %s", plugin_name) + mod = None + definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. + LOGGER.debug("Loading versioned events for: %s", plugin_name) for plugin_version in definition.versions: + version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{plugin_version['path']}.routes" - ) + LOGGER.debug("Loading events from: %s", version_path) + mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading events from %s: %s", version_path, e) continue - if mod and hasattr(mod, "register_events"): - mod.register_events(event_bus) else: # Load plugin routes that aren't in a versioned package. + routes_path = f"{plugin_name}.routes" try: - mod = ClassLoader.load_module(f"{plugin.__name__}.routes") + LOGGER.debug("Loading non-versioned events from: %s", routes_path) + mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading events from %s: %s", routes_path, e) continue - if mod and hasattr(mod, "register_events"): - mod.register_events(event_bus) + + if mod and hasattr(mod, "register_events"): + LOGGER.debug("Registering events from: %s", version_path) + mod.register_events(event_bus) def post_process_routes(self, app) -> None: """Call route binary file response OpenAPI fixups if applicable.""" From 9cf03f6bb4a088c9de66b8ede70d42804626e70f Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:26:40 +0200 Subject: [PATCH 026/152] :loud_sound: Add debug logging to post_process_routes Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 302a409062..b4094e4e19 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -393,29 +393,37 @@ def register_protocol_events(self, context: InjectionContext) -> None: def post_process_routes(self, app) -> None: """Call route binary file response OpenAPI fixups if applicable.""" + LOGGER.debug("Post-processing routes for %d plugins", len(self._plugins)) + for plugin in self._plugins.values(): - definition = ClassLoader.load_module("definition", plugin.__name__) + plugin_name = plugin.__name__ + LOGGER.debug("Post-processing routes for plugin: %s", plugin_name) + mod = None + definition = ClassLoader.load_module("definition", plugin_name) if definition: # Set binary file responses for routes that are in a versioned package. + LOGGER.debug("Processing versioned routes for: %s", plugin_name) for plugin_version in definition.versions: + version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - mod = ClassLoader.load_module( - f"{plugin.__name__}.{plugin_version['path']}.routes" - ) + LOGGER.debug("Loading routes from: %s", version_path) + mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading routes from %s: %s", version_path, e) continue - if mod and hasattr(mod, "post_process_routes"): - mod.post_process_routes(app) else: # Set binary file responses for routes not in a versioned package. + routes_path = f"{plugin_name}.routes" try: - mod = ClassLoader.load_module(f"{plugin.__name__}.routes") + LOGGER.debug("Loading non-versioned routes from: %s", routes_path) + mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: - LOGGER.error("Error loading admin routes: %s", e) + LOGGER.error("Error loading routes from %s: %s", routes_path, e) continue - if mod and hasattr(mod, "post_process_routes"): - mod.post_process_routes(app) + + if mod and hasattr(mod, "post_process_routes"): + LOGGER.debug("Post-processing routes from: %s", version_path) + mod.post_process_routes(app) def __repr__(self) -> str: """Return a string representation for this class.""" From 6330701c912ac0c8e510dce329a6afe0d709b82e Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:38:00 +0200 Subject: [PATCH 027/152] :art: Replace print statements with info logs Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index d9db66ad7a..36bb6017ba 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -401,18 +401,19 @@ async def start(self) -> None: their_endpoint=their_endpoint, alias="test-suite", ) - print("Created static connection for test suite") - print(" - My DID:", test_conn.my_did) - print(" - Their DID:", test_conn.their_did) - print(" - Their endpoint:", their_endpoint) - print() + LOGGER.info( + "Created static connection for test suite\n" + f" - My DID: {test_conn.my_did}\n" + f" - Their DID: {test_conn.their_did}\n" + f" - Their endpoint: {their_endpoint}\n" + ) del mgr # Clear default mediator if context.settings.get("mediation.clear"): mediation_mgr = MediationManager(self.root_profile) await mediation_mgr.clear_default_mediator() - print("Default mediator cleared.") + LOGGER.info("Default mediator cleared.") # Clear default mediator # Set default mediator by id @@ -421,7 +422,7 @@ async def start(self) -> None: mediation_mgr = MediationManager(self.root_profile) try: await mediation_mgr.set_default_mediator_by_id(default_mediator_id) - print(f"Default mediator set to {default_mediator_id}") + LOGGER.info(f"Default mediator set to {default_mediator_id}") except Exception: LOGGER.exception("Error updating default mediator") @@ -440,8 +441,7 @@ async def start(self) -> None: ) base_url = context.settings.get("invite_base_url") invite_url = invi_rec.invitation.to_url(base_url) - print("Invitation URL:") - print(invite_url, flush=True) + LOGGER.info(f"Invitation URL:\n{invite_url}") qr = QRCode(border=1) qr.add_data(invite_url) qr.print_ascii(invert=True) @@ -463,8 +463,7 @@ async def start(self) -> None: ) base_url = context.settings.get("invite_base_url") invite_url = invite.to_url(base_url) - print("Invitation URL (Connections protocol):") - print(invite_url, flush=True) + LOGGER.info(f"Invitation URL (Connections protocol):\n{invite_url}") qr = QRCode(border=1) qr.add_data(invite_url) qr.print_ascii(invert=True) @@ -525,7 +524,7 @@ async def start(self) -> None: session, MediationManager.SET_TO_DEFAULT_ON_GRANTED, True ) - print("Attempting to connect to mediator...") + LOGGER.info("Attempting to connect to mediator...") del mgr except Exception: LOGGER.exception("Error accepting mediation invitation") From 6a8febdf6f731a008bbf6dfd2077ad1fd5df443e Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 12:58:06 +0200 Subject: [PATCH 028/152] :art: Replace almost all print statements with info logs Signed-off-by: ff137 --- acapy_agent/__main__.py | 13 +++++++---- .../anoncreds/default/did_indy/registry.py | 2 +- .../anoncreds/default/did_web/registry.py | 5 ++++- .../anoncreds/default/legacy_indy/registry.py | 2 +- acapy_agent/commands/provision.py | 7 ++++-- acapy_agent/commands/start.py | 4 ++-- acapy_agent/config/wallet.py | 22 +++++++++---------- acapy_agent/transport/v2_pack_format.py | 3 +-- acapy_agent/vc/vc_di/prove.py | 5 ++++- acapy_agent/wallet/crypto.py | 5 ++++- 10 files changed, 42 insertions(+), 26 deletions(-) diff --git a/acapy_agent/__main__.py b/acapy_agent/__main__.py index bd0c964705..9669588b83 100644 --- a/acapy_agent/__main__.py +++ b/acapy_agent/__main__.py @@ -1,8 +1,11 @@ """acapy_agent package entry point.""" +import logging import os import sys +LOGGER = logging.getLogger(__name__) + def init_debug(args): """Initialize debugging environment.""" @@ -26,16 +29,18 @@ def init_debug(args): import debugpy debugpy.listen((DAP_HOST, DAP_PORT)) - print(f"=== Waiting for debugger to attach to {DAP_HOST}:{DAP_PORT} ===") + LOGGER.info( + f"=== Waiting for debugger to attach to {DAP_HOST}:{DAP_PORT} ===" + ) debugpy.wait_for_client() except ImportError: - print("debugpy library was not found") + LOGGER.error("debugpy library was not found") if ENABLE_PYDEVD_PYCHARM or "--debug-pycharm" in args: try: import pydevd_pycharm - print( + LOGGER.info( "aca-py remote debugging to " f"{PYDEVD_PYCHARM_HOST}:{PYDEVD_PYCHARM_AGENT_PORT}" ) @@ -47,7 +52,7 @@ def init_debug(args): suspend=False, ) except ImportError: - print("pydevd_pycharm library was not found") + LOGGER.error("pydevd_pycharm library was not found") def run(args): diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index 567d90ccce..5bef819f82 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -41,7 +41,7 @@ def supported_identifiers_regex(self) -> Pattern: async def setup(self, context: InjectionContext): """Setup.""" - print("Successfully registered DIDIndyRegistry") + LOGGER.info("Successfully registered DIDIndyRegistry") async def get_schema(self, profile: Profile, schema_id: str) -> GetSchemaResult: """Get a schema from the registry.""" diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index 63382f3606..0585e2b924 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -1,5 +1,6 @@ """DID Web Registry.""" +import logging import re from typing import Optional, Pattern, Sequence @@ -17,6 +18,8 @@ ) from ...models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +LOGGER = logging.getLogger(__name__) + class DIDWebRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar): """DIDWebRegistry.""" @@ -40,7 +43,7 @@ def supported_identifiers_regex(self) -> Pattern: async def setup(self, context: InjectionContext): """Setup.""" - print("Successfully registered DIDWebRegistry") + LOGGER.info("Successfully registered DIDWebRegistry") async def get_schema(self, profile, schema_id: str) -> GetSchemaResult: """Get a schema from the registry.""" diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index e173bbde32..892a9d17fe 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -144,7 +144,7 @@ def supported_identifiers_regex(self) -> Pattern: async def setup(self, context: InjectionContext): """Setup.""" - print("Successfully registered LegacyIndyRegistry") + LOGGER.info("Successfully registered LegacyIndyRegistry") @staticmethod def make_schema_id(schema: AnonCredsSchema) -> str: diff --git a/acapy_agent/commands/provision.py b/acapy_agent/commands/provision.py index a463dd6e48..6d86d412b6 100644 --- a/acapy_agent/commands/provision.py +++ b/acapy_agent/commands/provision.py @@ -1,6 +1,7 @@ """Provision command for setting up agent settings before starting.""" import asyncio +import logging from typing import Sequence from configargparse import ArgumentParser @@ -22,6 +23,8 @@ from ..storage.base import BaseStorage from . import PROG +LOGGER = logging.getLogger(__name__) + class ProvisionError(BaseError): """Base exception for provisioning errors.""" @@ -58,9 +61,9 @@ async def provision(settings: dict): ) if await ledger_config(root_profile, public_did and public_did.did, True): - print("Ledger configured") + LOGGER.info("Ledger configured") else: - print("Ledger not configured") + LOGGER.warning("Ledger not configured") await root_profile.close() except BaseError as e: diff --git a/acapy_agent/commands/start.py b/acapy_agent/commands/start.py index f30fc5c582..ee256f1e4c 100644 --- a/acapy_agent/commands/start.py +++ b/acapy_agent/commands/start.py @@ -31,7 +31,7 @@ async def start_app(conductor: Conductor): async def shutdown_app(conductor: Conductor): """Shut down.""" - print("\nShutting down") + LOGGER.warning("Shutting down") await conductor.stop() @@ -59,7 +59,7 @@ def execute(argv: Sequence[str] = None): # Run the application if uvloop: uvloop.install() - print("uvloop installed") + LOGGER.info("uvloop installed") run_loop(start_app(conductor), shutdown_app(conductor)) diff --git a/acapy_agent/config/wallet.py b/acapy_agent/config/wallet.py index f857b07847..89bfdad681 100644 --- a/acapy_agent/config/wallet.py +++ b/acapy_agent/config/wallet.py @@ -61,11 +61,11 @@ async def wallet_config( if provision: if profile.created: - print("Created new profile") + LOGGER.info("Created new profile") else: - print("Opened existing profile") - print("Profile backend:", profile.backend) - print("Profile name:", profile.name) + LOGGER.info("Opened existing profile") + LOGGER.info("Profile backend:", profile.backend) + LOGGER.info("Profile name:", profile.name) wallet_seed = context.settings.get("wallet.seed") wallet_local_did = context.settings.get("wallet.local_did") @@ -84,8 +84,8 @@ async def wallet_config( ) public_did = replace_did_info.did await wallet.set_public_did(public_did) - print(f"Created new public DID: {public_did}") - print(f"Verkey: {replace_did_info.verkey}") + LOGGER.info(f"Created new public DID: {public_did}") + LOGGER.info(f"Verkey: {replace_did_info.verkey}") else: # If we already have a registered public did and it doesn't match # the one derived from `wallet_seed` then we error out. @@ -107,20 +107,20 @@ async def wallet_config( ) local_did = local_did_info.did if provision: - print(f"Created new local DID: {local_did}") - print(f"Verkey: {local_did_info.verkey}") + LOGGER.info(f"Created new local DID: {local_did}") + LOGGER.info(f"Verkey: {local_did_info.verkey}") else: public_did_info = await wallet.create_public_did( method=SOV, key_type=ED25519, seed=wallet_seed ) public_did = public_did_info.did if provision: - print(f"Created new public DID: {public_did}") - print(f"Verkey: {public_did_info.verkey}") + LOGGER.info(f"Created new public DID: {public_did}") + LOGGER.info(f"Verkey: {public_did_info.verkey}") # wait until ledger config to set public DID endpoint - wallet goes first if provision and not wallet_local_did and not public_did: - print("No public DID") + LOGGER.info("No public DID") # Debug settings test_seed = context.settings.get("debug.seed") diff --git a/acapy_agent/transport/v2_pack_format.py b/acapy_agent/transport/v2_pack_format.py index 266c0b8b08..92e26da698 100644 --- a/acapy_agent/transport/v2_pack_format.py +++ b/acapy_agent/transport/v2_pack_format.py @@ -63,8 +63,7 @@ async def parse_message( try: message_unpack = await messaging.unpack(message_json) except CryptoServiceError: - LOGGER.debug("Message unpack failed, falling back to JSON") - print("HIT CRTYPTO SER ERR EXCEPT BLOC") + LOGGER.info("Message unpack failed, falling back to JSON") else: # Set message_dict to be the dictionary that we unpacked message_dict = message_unpack.message diff --git a/acapy_agent/vc/vc_di/prove.py b/acapy_agent/vc/vc_di/prove.py index 33c94fa544..acba4359fe 100644 --- a/acapy_agent/vc/vc_di/prove.py +++ b/acapy_agent/vc/vc_di/prove.py @@ -1,6 +1,7 @@ """Verifiable Credential and Presentation proving methods.""" import asyncio +import logging import re from hashlib import sha256 from typing import Any, Optional, Tuple @@ -20,6 +21,8 @@ from ...core.profile import Profile from ..ld_proofs import LinkedDataProofException, ProofPurpose +LOGGER = logging.getLogger(__name__) + async def create_signed_anoncreds_presentation( *, @@ -311,7 +314,7 @@ async def prepare_data_for_presentation( # issuer_id = field["filter"]["const"] pass else: - print("... skipping:", path) + LOGGER.info("... skipping: %s", path) return anoncreds_proofrequest, w3c_creds_metadata diff --git a/acapy_agent/wallet/crypto.py b/acapy_agent/wallet/crypto.py index 0ceef63a91..37ddeb7a13 100644 --- a/acapy_agent/wallet/crypto.py +++ b/acapy_agent/wallet/crypto.py @@ -1,5 +1,6 @@ """Cryptography functions used by BasicWallet.""" +import logging import re from collections import OrderedDict from typing import Callable, List, Optional, Sequence, Tuple, Union @@ -20,6 +21,8 @@ from .key_type import BLS12381G2, ED25519, KeyType from .util import b58_to_bytes, b64_to_bytes, bytes_to_b58, random_seed +LOGGER = logging.getLogger(__name__) + def create_keypair( key_type: KeyType, seed: Optional[bytes] = None @@ -423,7 +426,7 @@ def decode_pack_message_outer(enc_message: bytes) -> Tuple[dict, dict, bool]: try: wrapper = JweEnvelope.from_json(enc_message) except ValidationError as err: - print(err) + LOGGER.error(err) raise ValueError("Invalid packed message") alg = wrapper.protected.get("alg") From 8f46fdb4f00a33c3bcaee3dc6a62c4b561616dbe Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 13:05:40 +0200 Subject: [PATCH 029/152] :loud_sound: Expand logging for Conductor setup Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 49 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 36bb6017ba..1384ff9e87 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -124,41 +124,62 @@ def context(self) -> InjectionContext: async def setup(self): """Initialize the global request context.""" + LOGGER.debug("Starting setup of the Conductor") context = await self.context_builder.build_context() + LOGGER.debug("Context built successfully") if self.force_agent_anoncreds: + LOGGER.debug( + "Force agent anoncreds is enabled. " + "Setting wallet type to 'askar-anoncreds'." + ) context.settings.set_value("wallet.type", "askar-anoncreds") # Fetch genesis transactions if necessary if context.settings.get("ledger.ledger_config_list"): + LOGGER.debug( + "Ledger config list found. Loading multiple genesis transactions" + ) await load_multiple_genesis_transactions_from_config(context.settings) if ( context.settings.get("ledger.genesis_transactions") or context.settings.get("ledger.genesis_file") or context.settings.get("ledger.genesis_url") ): + LOGGER.debug( + "Genesis transactions/configurations found. Fetching genesis transactions" + ) await get_genesis_transactions(context.settings) # Configure the root profile + LOGGER.debug("Configuring the root profile and setting up public DID") self.root_profile, self.setup_public_did = await wallet_config(context) context = self.root_profile.context + LOGGER.debug("Root profile configured successfully") # Multiledger Setup if ( context.settings.get("ledger.ledger_config_list") and len(context.settings.get("ledger.ledger_config_list")) > 0 ): + LOGGER.debug("Setting up multiledger manager") context.injector.bind_provider( BaseMultipleLedgerManager, MultiIndyLedgerManagerProvider(self.root_profile), ) if not (context.settings.get("ledger.genesis_transactions")): ledger = context.injector.inject(BaseLedger) + LOGGER.debug( + "Ledger backend: %s, Profile backend: %s", + ledger.BACKEND_NAME, + self.root_profile.BACKEND_NAME, + ) if ( self.root_profile.BACKEND_NAME == "askar" and ledger.BACKEND_NAME == "indy-vdr" ): + LOGGER.debug("Binding IndyCredxVerifier for 'askar' backend.") context.injector.bind_provider( IndyVerifier, ClassProvider( @@ -170,6 +191,9 @@ async def setup(self): self.root_profile.BACKEND_NAME == "askar-anoncreds" and ledger.BACKEND_NAME == "indy-vdr" ): + LOGGER.debug( + "Binding IndyCredxVerifier for 'askar-anoncreds' backend." + ) context.injector.bind_provider( IndyVerifier, ClassProvider( @@ -178,6 +202,7 @@ async def setup(self): ), ) else: + LOGGER.error("Unsupported ledger backend for multiledger setup.") raise MultipleLedgerManagerError( "Multiledger is supported only for Indy SDK or Askar " "[Indy VDR] profile" @@ -190,10 +215,13 @@ async def setup(self): if not await ledger_config( self.root_profile, self.setup_public_did and self.setup_public_did.did ): - LOGGER.warning("No ledger configured") + LOGGER.warning("No ledger configured.") + else: + LOGGER.debug("Ledger configured successfully.") if not context.settings.get("transport.disabled"): # Register all inbound transports if enabled + LOGGER.debug("Transport not disabled. Setting up inbound transports.") self.inbound_transport_manager = InboundTransportManager( self.root_profile, self.inbound_message_router, self.handle_not_returned ) @@ -201,45 +229,55 @@ async def setup(self): context.injector.bind_instance( InboundTransportManager, self.inbound_transport_manager ) + LOGGER.debug("Inbound transports registered successfully.") if not context.settings.get("transport.disabled"): # Register all outbound transports + LOGGER.debug("Transport not disabled. Setting up outbound transports.") self.outbound_transport_manager = OutboundTransportManager( self.root_profile, self.handle_not_delivered ) await self.outbound_transport_manager.setup() + LOGGER.debug("Outbound transports registered successfully.") # Initialize dispatcher + LOGGER.debug("Initializing dispatcher.") self.dispatcher = Dispatcher(self.root_profile) await self.dispatcher.setup() + LOGGER.debug("Dispatcher initialized successfully.") wire_format = context.inject_or(BaseWireFormat) if wire_format and hasattr(wire_format, "task_queue"): wire_format.task_queue = self.dispatcher.task_queue + LOGGER.debug("Wire format task queue bound to dispatcher.") # Bind manager for multitenancy related tasks if context.settings.get("multitenant.enabled"): + LOGGER.debug("Multitenant is enabled. Binding MultitenantManagerProvider.") context.injector.bind_provider( BaseMultitenantManager, MultitenantManagerProvider(self.root_profile) ) # Bind route manager provider + LOGGER.debug("Binding RouteManagerProvider.") context.injector.bind_provider( RouteManager, RouteManagerProvider(self.root_profile) ) - # Bind oob message processor to be able to receive and process un-encrypted - # messages + # Bind oob message processor to be able to receive and process un-encrypted messages + LOGGER.debug("Binding OobMessageProcessor.") context.injector.bind_instance( OobMessageProcessor, OobMessageProcessor(inbound_message_router=self.inbound_message_router), ) # Bind default PyLD document loader + LOGGER.debug("Binding default DocumentLoader.") context.injector.bind_instance(DocumentLoader, DocumentLoader(self.root_profile)) # Admin API if context.settings.get("admin.enabled"): + LOGGER.debug("Admin API is enabled. Attempting to register admin server.") try: admin_host = context.settings.get("admin.host", "0.0.0.0") admin_port = context.settings.get("admin.port", "80") @@ -255,13 +293,15 @@ async def setup(self): self.get_stats, ) context.injector.bind_instance(BaseAdminServer, self.admin_server) + LOGGER.debug("Admin server registered on %s:%s.", admin_host, admin_port) except Exception: - LOGGER.exception("Unable to register admin server") + LOGGER.exception("Unable to register admin server.") raise # Fetch stats collector, if any collector = context.inject_or(Collector) if collector: + LOGGER.debug("Stats collector found. Wrapping methods for collection.") # add stats to our own methods collector.wrap( self, @@ -280,6 +320,7 @@ async def setup(self): "find_inbound_connection", ), ) + LOGGER.debug("Methods wrapped with stats collector.") async def start(self) -> None: """Start the agent.""" From edde403a119959a26c385d878e790d38faac22c1 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 13:30:26 +0200 Subject: [PATCH 030/152] :art: Correct to uphold previous "Module doesn't exist" log behaviour Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index b4094e4e19..e1743afb0c 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -125,6 +125,7 @@ def register_plugin(self, module_name: str) -> Optional[ModuleType]: mod = self._load_module(module_name) if not mod: + LOGGER.error("Module doesn't exist: %s", module_name) return None if self._is_valid_plugin(mod, module_name): @@ -153,7 +154,6 @@ def _load_module(self, module_name: str) -> Optional[ModuleType]: """Load the plugin module using ClassLoader.""" try: mod = ClassLoader.load_module(module_name) - LOGGER.debug("Successfully loaded module: %s", module_name) return mod except ModuleLoadError as e: LOGGER.error("Error loading plugin module '%s': %s", module_name, e) From cc5ceab5c40f293a1d78725398e27ea5d9ae8ba3 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 13:37:00 +0200 Subject: [PATCH 031/152] :white_check_mark: Fix test by using assertLogs instead of capturing stdout Signed-off-by: ff137 --- acapy_agent/core/tests/test_conductor.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acapy_agent/core/tests/test_conductor.py b/acapy_agent/core/tests/test_conductor.py index 875623deee..9d4525e4e9 100644 --- a/acapy_agent/core/tests/test_conductor.py +++ b/acapy_agent/core/tests/test_conductor.py @@ -1210,7 +1210,7 @@ async def test_print_invite_connection(self): test_profile, DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), ), - ), mock.patch("sys.stdout", new=StringIO()) as captured, mock.patch.object( + ), self.assertLogs(level="INFO") as captured, mock.patch.object( test_module, "OutboundTransportManager", autospec=True ) as mock_outbound_mgr: mock_outbound_mgr.return_value.registered_transports = { @@ -1220,9 +1220,9 @@ async def test_print_invite_connection(self): await conductor.start() await conductor.stop() - value = captured.getvalue() - assert "http://localhost?oob=" in value - assert "http://localhost?c_i=" in value + value = captured.output + assert any("http://localhost?oob=" in msg for msg in value) + assert any("http://localhost?c_i=" in msg for msg in value) async def test_clear_default_mediator(self): builder: ContextBuilder = StubContextBuilder(self.test_settings) From 44e980772de6f9da2044460f2c4d446db14c1f22 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 13:51:54 +0200 Subject: [PATCH 032/152] Revert ":art: Rename method and remove redundant main call" This reverts commit 2f6526d108b3a8df527d2694c9ce3c46e438f963. Signed-off-by: ff137 --- acapy_agent/commands/provision.py | 11 ++++++++--- acapy_agent/commands/tests/test_provision.py | 13 +++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/acapy_agent/commands/provision.py b/acapy_agent/commands/provision.py index 6d86d412b6..f0fb7cf561 100644 --- a/acapy_agent/commands/provision.py +++ b/acapy_agent/commands/provision.py @@ -70,7 +70,7 @@ async def provision(settings: dict): raise ProvisionError("Error during provisioning") from e -def execute_provision(argv: Sequence[str] = None): +def execute(argv: Sequence[str] = None): """Entrypoint.""" parser = arg.create_argument_parser(prog=PROG) parser.prog += " provision" @@ -87,5 +87,10 @@ def execute_provision(argv: Sequence[str] = None): loop.run_until_complete(provision(settings)) -if __name__ == "__main__": - execute_provision() +def main(): + """Execute the main line.""" + if __name__ == "__main__": + execute() + + +main() diff --git a/acapy_agent/commands/tests/test_provision.py b/acapy_agent/commands/tests/test_provision.py index 3fbeb00208..65d0d488bd 100644 --- a/acapy_agent/commands/tests/test_provision.py +++ b/acapy_agent/commands/tests/test_provision.py @@ -14,10 +14,10 @@ class TestProvision(IsolatedAsyncioTestCase): def test_bad_calls(self): with self.assertRaises(ArgsParseError): - test_module.execute_provision([]) + test_module.execute([]) with self.assertRaises(SystemExit): - test_module.execute_provision(["bad"]) + test_module.execute(["bad"]) async def test_provision_ledger_configured(self): profile = mock.MagicMock(close=mock.CoroutineMock()) @@ -43,14 +43,11 @@ async def test_provision_config_x(self): with self.assertRaises(test_module.ProvisionError): await test_module.provision({}) - def test_main_entry_point(self): - """Test that the execute_provision function is called when the module is run as main.""" + def test_main(self): with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "execute_provision", mock.MagicMock() + test_module, "execute", mock.MagicMock() ) as mock_execute: - import importlib - - importlib.reload(test_module) # Reload the module to trigger the main guard + test_module.main() mock_execute.assert_called_once async def test_provision_should_store_provided_mediation_invite(self): From cfec6a67d97a4e6cee413575c156c97a0a22e775 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 13:55:19 +0200 Subject: [PATCH 033/152] :art: Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 7 ++----- acapy_agent/core/plugin_registry.py | 2 +- acapy_agent/core/tests/test_conductor.py | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 1384ff9e87..641a989cfe 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -42,10 +42,7 @@ from ..messaging.responder import BaseResponder from ..multitenant.base import BaseMultitenantManager from ..multitenant.manager_provider import MultitenantManagerProvider -from ..protocols.connections.v1_0.manager import ( - ConnectionManager, - ConnectionManagerError, -) +from ..protocols.connections.v1_0.manager import ConnectionManager, ConnectionManagerError from ..protocols.connections.v1_0.messages.connection_invitation import ( ConnectionInvitation, ) @@ -264,7 +261,7 @@ async def setup(self): RouteManager, RouteManagerProvider(self.root_profile) ) - # Bind oob message processor to be able to receive and process un-encrypted messages + # Bind OobMessageProcessor to be able to receive and process unencrypted messages LOGGER.debug("Binding OobMessageProcessor.") context.injector.bind_instance( OobMessageProcessor, diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index e1743afb0c..08f4edb2bd 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -422,7 +422,7 @@ def post_process_routes(self, app) -> None: continue if mod and hasattr(mod, "post_process_routes"): - LOGGER.debug("Post-processing routes from: %s", version_path) + LOGGER.debug("Post-processing routes for %s", plugin_name) mod.post_process_routes(app) def __repr__(self) -> str: diff --git a/acapy_agent/core/tests/test_conductor.py b/acapy_agent/core/tests/test_conductor.py index 9d4525e4e9..9f8e783491 100644 --- a/acapy_agent/core/tests/test_conductor.py +++ b/acapy_agent/core/tests/test_conductor.py @@ -1,4 +1,3 @@ -from io import StringIO from unittest import IsolatedAsyncioTestCase import pytest From 500e4b29b9c07c645a884e14105315e12f8986cd Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 14:15:39 +0200 Subject: [PATCH 034/152] :white_check_mark: Fix test by adding __name__ to mock object Signed-off-by: ff137 --- acapy_agent/core/tests/test_plugin_registry.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acapy_agent/core/tests/test_plugin_registry.py b/acapy_agent/core/tests/test_plugin_registry.py index b5727a4546..4e870fbdfb 100644 --- a/acapy_agent/core/tests/test_plugin_registry.py +++ b/acapy_agent/core/tests/test_plugin_registry.py @@ -537,6 +537,7 @@ async def test_load_protocols_load_mod(self): mock_mod = mock.MagicMock() mock_mod.MESSAGE_TYPES = mock.MagicMock() mock_mod.CONTROLLERS = mock.MagicMock() + mock_mod.__name__ = "test_mod" with mock.patch.object( ClassLoader, "load_module", mock.MagicMock() @@ -595,6 +596,7 @@ async def test_load_protocols_no_mod_def_message_types(self): mock_mod = mock.MagicMock() mock_mod.MESSAGE_TYPES = mock.MagicMock() mock_mod.CONTROLLERS = mock.MagicMock() + mock_mod.__name__ = "test_mod" with mock.patch.object( ClassLoader, "load_module", mock.MagicMock() From 5134d163c451ec839ec8d4b0e8057762c6a2a550 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 14:17:10 +0200 Subject: [PATCH 035/152] :art: Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 13 ++++++------- acapy_agent/core/plugin_registry.py | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 641a989cfe..f0ad8ff887 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -156,16 +156,14 @@ async def setup(self): LOGGER.debug("Root profile configured successfully") # Multiledger Setup - if ( - context.settings.get("ledger.ledger_config_list") - and len(context.settings.get("ledger.ledger_config_list")) > 0 - ): + ledger_config_list = context.settings.get("ledger.ledger_config_list") + if ledger_config_list and len(ledger_config_list) > 0: LOGGER.debug("Setting up multiledger manager") context.injector.bind_provider( BaseMultipleLedgerManager, MultiIndyLedgerManagerProvider(self.root_profile), ) - if not (context.settings.get("ledger.genesis_transactions")): + if not context.settings.get("ledger.genesis_transactions"): ledger = context.injector.inject(BaseLedger) LOGGER.debug( "Ledger backend: %s, Profile backend: %s", @@ -209,9 +207,10 @@ async def setup(self): ) # Configure the ledger - if not await ledger_config( + ledger_configured = await ledger_config( self.root_profile, self.setup_public_did and self.setup_public_did.did - ): + ) + if not ledger_configured: LOGGER.warning("No ledger configured.") else: LOGGER.debug("Ledger configured successfully.") diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 08f4edb2bd..cd4942ffa3 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -349,7 +349,7 @@ async def register_admin_routes(self, app) -> None: continue if mod and hasattr(mod, "register"): - LOGGER.debug("Registering routes from: %s", version_path) + LOGGER.debug("Registering routes for: %s", plugin_name) await mod.register(app) def register_protocol_events(self, context: InjectionContext) -> None: From aa0765a3d7a0681c85bb5bab27114cf67463ca4a Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 14:59:43 +0200 Subject: [PATCH 036/152] :sparkles: Add custom trace log level Signed-off-by: ff137 --- acapy_agent/config/logging/configurator.py | 5 ++ acapy_agent/config/logging/utils.py | 98 ++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 acapy_agent/config/logging/utils.py diff --git a/acapy_agent/config/logging/configurator.py b/acapy_agent/config/logging/configurator.py index 11763dca08..8843ed78e2 100644 --- a/acapy_agent/config/logging/configurator.py +++ b/acapy_agent/config/logging/configurator.py @@ -31,6 +31,11 @@ from .timed_rotating_file_multi_process_handler import ( TimedRotatingFileMultiProcessHandler, ) +from .utils import add_trace_level + + +# Add TRACE level to logging before any configuration +add_trace_level() def load_resource(path: str, encoding: Optional[str] = None): diff --git a/acapy_agent/config/logging/utils.py b/acapy_agent/config/logging/utils.py new file mode 100644 index 0000000000..20f76e00b7 --- /dev/null +++ b/acapy_agent/config/logging/utils.py @@ -0,0 +1,98 @@ +"""Logging utilities.""" + +import logging +from functools import partial, partialmethod +from typing import Optional + + +def add_logging_level( + level_name: str, level_num: int, method_name: Optional[str] = None +) -> None: + """Add a custom logging level to the `logging` module. + + Comprehensively adds a new logging level to the `logging` module and the + currently configured logging class. + + `level_name` becomes an attribute of the `logging` module with the value + `level_num`. + `methodName` becomes a convenience method for both `logging` itself + and the class returned by `logging.getLoggerClass()` (usually just + `logging.Logger`). + If `methodName` is not specified, `levelName.lower()` is used. + + To avoid accidental clobberings of existing attributes, this method will + raise an `AttributeError` if the level name is already an attribute of the + `logging` module or if the method name is already present + + Example: + ------- + >>> add_logging_level('TRACE', logging.DEBUG - 5) + >>> logging.getLogger(__name__).setLevel('TRACE') + >>> logging.getLogger(__name__).trace('that worked') + >>> logging.trace('so did this') + >>> logging.TRACE + 5 + + References: + - https://stackoverflow.com/a/35804945 + """ + if not method_name: + method_name = level_name.lower() + + if hasattr(logging, level_name): + raise AttributeError(f"{level_name} already defined in logging module") + if hasattr(logging, method_name): + raise AttributeError(f"{method_name} already defined in logging module") + if hasattr(logging.getLoggerClass(), method_name): + raise AttributeError(f"{method_name} already defined in logger class") + + # Add the new logging level + logging.addLevelName(level_num, level_name) + setattr(logging, level_name, level_num) + setattr( + logging.getLoggerClass(), + method_name, + partialmethod(logging.getLoggerClass().log, level_num), + ) + setattr(logging, method_name, partial(logging.log, level_num)) + + +def add_trace_level() -> None: + """Add the TRACE level to the logging module safely. + + This function adds a TRACE level to the logging module if it hasn't been added yet. + It handles the case where TRACE is already defined, avoiding duplicate additions. + + Returns: + None + """ + TRACE_LEVEL_NUM = logging.DEBUG - 5 + TRACE_LEVEL_NAME = "TRACE" + TRACE_METHOD_NAME = "trace" + + # Check if TRACE level is already defined + level_exists = ( + hasattr(logging, TRACE_LEVEL_NAME) + and getattr(logging, TRACE_LEVEL_NAME) == TRACE_LEVEL_NUM + ) + + method_exists = hasattr(logging, TRACE_METHOD_NAME) and callable( + getattr(logging, TRACE_METHOD_NAME) + ) + + if not level_exists or not method_exists: + try: + add_logging_level(TRACE_LEVEL_NAME, TRACE_LEVEL_NUM, TRACE_METHOD_NAME) + logging.getLogger(__name__).debug( + f"{TRACE_LEVEL_NAME} level added to logging module." + ) + except AttributeError as e: + # Log a warning if TRACE level already exists + logging.getLogger(__name__).warning( + f"{TRACE_LEVEL_NAME} level already exists: {e}" + ) + else: + # Optionally, you can log that TRACE level is already present + logging.getLogger(__name__).debug( + f"{TRACE_LEVEL_NAME} level is already present in the logging module." + ) From 190cc281626552eefa435d8fe1733062d65ce71f Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 15:00:11 +0200 Subject: [PATCH 037/152] :art: Ensure trace level can only be added once Signed-off-by: ff137 --- acapy_agent/config/logging/utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/acapy_agent/config/logging/utils.py b/acapy_agent/config/logging/utils.py index 20f76e00b7..e6527aa852 100644 --- a/acapy_agent/config/logging/utils.py +++ b/acapy_agent/config/logging/utils.py @@ -3,6 +3,7 @@ import logging from functools import partial, partialmethod from typing import Optional +_TRACE_LEVEL_ADDED = False def add_logging_level( @@ -66,6 +67,11 @@ def add_trace_level() -> None: Returns: None """ + global _TRACE_LEVEL_ADDED + + if _TRACE_LEVEL_ADDED: + return + TRACE_LEVEL_NUM = logging.DEBUG - 5 TRACE_LEVEL_NAME = "TRACE" TRACE_METHOD_NAME = "trace" @@ -96,3 +102,5 @@ def add_trace_level() -> None: logging.getLogger(__name__).debug( f"{TRACE_LEVEL_NAME} level is already present in the logging module." ) + + _TRACE_LEVEL_ADDED = True From 63ca170e35ca7261db16c9b6bade6a96cacddd3c Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 15:00:22 +0200 Subject: [PATCH 038/152] :art: Add Logger Signed-off-by: ff137 --- acapy_agent/config/logging/utils.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/acapy_agent/config/logging/utils.py b/acapy_agent/config/logging/utils.py index e6527aa852..5ee6108607 100644 --- a/acapy_agent/config/logging/utils.py +++ b/acapy_agent/config/logging/utils.py @@ -3,6 +3,8 @@ import logging from functools import partial, partialmethod from typing import Optional + +LOGGER = logging.getLogger(__name__) _TRACE_LEVEL_ADDED = False @@ -89,18 +91,14 @@ def add_trace_level() -> None: if not level_exists or not method_exists: try: add_logging_level(TRACE_LEVEL_NAME, TRACE_LEVEL_NUM, TRACE_METHOD_NAME) - logging.getLogger(__name__).debug( - f"{TRACE_LEVEL_NAME} level added to logging module." - ) + LOGGER.debug("%s level added to logging module.", TRACE_LEVEL_NAME) except AttributeError as e: # Log a warning if TRACE level already exists - logging.getLogger(__name__).warning( - f"{TRACE_LEVEL_NAME} level already exists: {e}" - ) + LOGGER.warning("%s level already exists: %s", TRACE_LEVEL_NAME, e) else: # Optionally, you can log that TRACE level is already present - logging.getLogger(__name__).debug( - f"{TRACE_LEVEL_NAME} level is already present in the logging module." + LOGGER.debug( + "%s level is already present in the logging module.", TRACE_LEVEL_NAME ) _TRACE_LEVEL_ADDED = True From 3641e2fd26e8cc4d65032361114b4c3a3d895fc4 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 15:08:53 +0200 Subject: [PATCH 039/152] :art: Update newly added logs to be trace level instead of debug Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 78 +++++++++++++++-------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index cd4942ffa3..f86495291e 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -6,6 +6,7 @@ from typing import Optional, Sequence, Set from ..config.injection_context import InjectionContext +from ..config.logging.utils import add_trace_level from ..core.event_bus import EventBus from ..utils.classloader import ClassLoader, ModuleLoadError from .error import ProtocolDefinitionValidationError @@ -13,6 +14,7 @@ from .protocol_registry import ProtocolRegistry LOGGER = logging.getLogger(__name__) +add_trace_level() # Allow trace logs from this module class PluginRegistry: @@ -130,7 +132,7 @@ def register_plugin(self, module_name: str) -> Optional[ModuleType]: if self._is_valid_plugin(mod, module_name): self._plugins[module_name] = mod - LOGGER.debug("Registered plugin: %s", module_name) + LOGGER.trace("Registered plugin: %s", module_name) return mod LOGGER.debug("Failed to register plugin: %s", module_name) @@ -139,7 +141,7 @@ def register_plugin(self, module_name: str) -> Optional[ModuleType]: def _is_already_registered(self, module_name: str) -> bool: """Check if the plugin is already registered.""" if module_name in self._plugins: - LOGGER.debug("Plugin %s is already registered.", module_name) + LOGGER.trace("Plugin %s is already registered.", module_name) return True return False @@ -163,7 +165,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: """Validate the plugin based on various criteria.""" # Check if the plugin has a 'setup' method if hasattr(mod, "setup"): - LOGGER.debug("Plugin %s has a 'setup' method.", module_name) + LOGGER.trace("Plugin %s has a 'setup' method.", module_name) return True # Check for 'routes' or 'message_types' modules @@ -172,7 +174,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: routes = ClassLoader.load_module("routes", module_name) message_types = ClassLoader.load_module("message_types", module_name) if routes or message_types: - LOGGER.debug("Plugin %s has 'routes' or 'message_types'.", module_name) + LOGGER.trace("Plugin %s has 'routes' or 'message_types'.", module_name) return True # Check for 'definition' module with 'versions' attribute @@ -194,7 +196,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: # Validate the 'versions' attribute try: self.validate_version(definition.versions, module_name) - LOGGER.debug("Plugin %s has valid versions.", module_name) + LOGGER.trace("Plugin %s has valid versions.", module_name) return True except ProtocolDefinitionValidationError as e: LOGGER.error( @@ -206,7 +208,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: def register_package(self, package_name: str) -> Sequence[ModuleType]: """Register all modules (sub-packages) under a given package name.""" - LOGGER.debug("Registering package: %s", package_name) + LOGGER.trace("Registering package: %s", package_name) try: module_names = ClassLoader.scan_subpackages(package_name) except ModuleLoadError: @@ -217,28 +219,28 @@ def register_package(self, package_name: str) -> Sequence[ModuleType]: for module_name in module_names: # Skip any module whose last segment is 'tests' if module_name.split(".")[-1] == "tests": - LOGGER.debug("Skipping test module: %s", module_name) + LOGGER.trace("Skipping test module: %s", module_name) continue plugin = self.register_plugin(module_name) if plugin: registered_plugins.append(plugin) else: - LOGGER.debug("Failed to register %s under %s", module_name, package_name) + LOGGER.trace("Failed to register %s under %s", module_name, package_name) return registered_plugins async def init_context(self, context: InjectionContext) -> None: """Call plugin setup methods on the current context.""" - LOGGER.debug("Initializing plugin context for %d plugins", len(self._plugins)) + LOGGER.trace("Initializing plugin context for %d plugins", len(self._plugins)) for plugin in self._plugins.values(): plugin_name = plugin.__name__ if hasattr(plugin, "setup"): - LOGGER.debug("Running setup for plugin: %s", plugin_name) + LOGGER.trace("Running setup for plugin: %s", plugin_name) await plugin.setup(context) else: - LOGGER.debug( + LOGGER.trace( "Loading protocols for plugin without setup: %s", plugin_name ) await self.load_protocols(context, plugin) @@ -257,55 +259,55 @@ async def load_protocol_version( goal_code_registry = context.inject(GoalCodeRegistry) module_name = mod.__name__ - LOGGER.debug("Loading protocol version for module: %s", module_name) + LOGGER.trace("Loading protocol version for module: %s", module_name) if hasattr(mod, "MESSAGE_TYPES"): - LOGGER.debug("Registering message types for: %s", module_name) + LOGGER.trace("Registering message types for: %s", module_name) protocol_registry.register_message_types( mod.MESSAGE_TYPES, version_definition=version_definition ) if hasattr(mod, "CONTROLLERS"): - LOGGER.debug("Registering controllers for: %s", module_name) + LOGGER.trace("Registering controllers for: %s", module_name) protocol_registry.register_controllers(mod.CONTROLLERS) goal_code_registry.register_controllers(mod.CONTROLLERS) async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> None: """For modules that don't implement setup, register protocols manually.""" plugin_name = plugin.__name__ - LOGGER.debug("Loading protocols for plugin: %s", plugin_name) + LOGGER.trace("Loading protocols for plugin: %s", plugin_name) # If this module contains message_types, then assume that # this is a valid module of the old style (not versioned) try: message_types_path = f"{plugin_name}.message_types" - LOGGER.debug("Attempting to load message types from: %s", message_types_path) + LOGGER.trace("Attempting to load message types from: %s", message_types_path) mod = ClassLoader.load_module(message_types_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin module message types: %s", e) return if mod: - LOGGER.debug("Found non-versioned message types for: %s", plugin_name) + LOGGER.trace("Found non-versioned message types for: %s", plugin_name) await self.load_protocol_version(context, mod) else: # Otherwise, try check for definition.py for versioned protocol packages try: definition_path = f"{plugin_name}.definition" - LOGGER.debug("Attempting to load definition from: %s", definition_path) + LOGGER.trace("Attempting to load definition from: %s", definition_path) definition = ClassLoader.load_module(definition_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin definition module: %s", e) return if definition: - LOGGER.debug("Loading versioned protocols for: %s", plugin_name) + LOGGER.trace("Loading versioned protocols for: %s", plugin_name) for protocol_version in definition.versions: version_path = ( f"{plugin_name}.{protocol_version['path']}.message_types" ) try: - LOGGER.debug("Loading message types from: %s", version_path) + LOGGER.trace("Loading message types from: %s", version_path) mod = ClassLoader.load_module(version_path) await self.load_protocol_version(context, mod, protocol_version) except ModuleLoadError as e: @@ -318,20 +320,20 @@ async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> async def register_admin_routes(self, app) -> None: """Call route registration methods on the current context.""" - LOGGER.debug("Registering admin routes for %d plugins", len(self._plugins)) + LOGGER.trace("Registering admin routes for %d plugins", len(self._plugins)) for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.debug("Processing routes for plugin: %s", plugin_name) + LOGGER.trace("Processing routes for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. - LOGGER.debug("Loading versioned routes for: %s", plugin_name) + LOGGER.trace("Loading versioned routes for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.debug("Loading routes from: %s", version_path) + LOGGER.trace("Loading routes from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error( @@ -342,19 +344,19 @@ async def register_admin_routes(self, app) -> None: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.debug("Loading non-versioned routes from: %s", routes_path) + LOGGER.trace("Loading non-versioned routes from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading admin routes from %s: %s", routes_path, e) continue if mod and hasattr(mod, "register"): - LOGGER.debug("Registering routes for: %s", plugin_name) + LOGGER.trace("Registering routes for: %s", plugin_name) await mod.register(app) def register_protocol_events(self, context: InjectionContext) -> None: """Call route register_events methods on the current context.""" - LOGGER.debug("Registering protocol events for %d plugins", len(self._plugins)) + LOGGER.trace("Registering protocol events for %d plugins", len(self._plugins)) event_bus = context.inject_or(EventBus) if not event_bus: @@ -363,16 +365,16 @@ def register_protocol_events(self, context: InjectionContext) -> None: for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.debug("Processing events for plugin: %s", plugin_name) + LOGGER.trace("Processing events for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. - LOGGER.debug("Loading versioned events for: %s", plugin_name) + LOGGER.trace("Loading versioned events for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.debug("Loading events from: %s", version_path) + LOGGER.trace("Loading events from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error("Error loading events from %s: %s", version_path, e) @@ -381,32 +383,32 @@ def register_protocol_events(self, context: InjectionContext) -> None: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.debug("Loading non-versioned events from: %s", routes_path) + LOGGER.trace("Loading non-versioned events from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading events from %s: %s", routes_path, e) continue if mod and hasattr(mod, "register_events"): - LOGGER.debug("Registering events from: %s", version_path) + LOGGER.trace("Registering events from: %s", version_path) mod.register_events(event_bus) def post_process_routes(self, app) -> None: """Call route binary file response OpenAPI fixups if applicable.""" - LOGGER.debug("Post-processing routes for %d plugins", len(self._plugins)) + LOGGER.trace("Post-processing routes for %d plugins", len(self._plugins)) for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.debug("Post-processing routes for plugin: %s", plugin_name) + LOGGER.trace("Post-processing routes for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Set binary file responses for routes that are in a versioned package. - LOGGER.debug("Processing versioned routes for: %s", plugin_name) + LOGGER.trace("Processing versioned routes for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.debug("Loading routes from: %s", version_path) + LOGGER.trace("Loading routes from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error("Error loading routes from %s: %s", version_path, e) @@ -415,14 +417,14 @@ def post_process_routes(self, app) -> None: # Set binary file responses for routes not in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.debug("Loading non-versioned routes from: %s", routes_path) + LOGGER.trace("Loading non-versioned routes from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading routes from %s: %s", routes_path, e) continue if mod and hasattr(mod, "post_process_routes"): - LOGGER.debug("Post-processing routes for %s", plugin_name) + LOGGER.trace("Post-processing routes for %s", plugin_name) mod.post_process_routes(app) def __repr__(self) -> str: From bf1295f076f4119786a52d78b0a8cb1379508202 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 15:14:10 +0200 Subject: [PATCH 040/152] :art: Update newly added logs to be trace level instead of debug Signed-off-by: ff137 --- acapy_agent/config/default_context.py | 20 +++++++------ acapy_agent/core/conductor.py | 41 +++++++++++++-------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/acapy_agent/config/default_context.py b/acapy_agent/config/default_context.py index ed49ff175d..35ee02a184 100644 --- a/acapy_agent/config/default_context.py +++ b/acapy_agent/config/default_context.py @@ -5,6 +5,7 @@ from ..anoncreds.registry import AnonCredsRegistry from ..cache.base import BaseCache from ..cache.in_memory import InMemoryCache +from ..config.logging.utils import add_trace_level from ..core.event_bus import EventBus from ..core.goal_code_registry import GoalCodeRegistry from ..core.plugin_registry import PluginRegistry @@ -29,6 +30,7 @@ from .provider import CachedProvider, ClassProvider LOGGER = logging.getLogger(__name__) +add_trace_level() # Allow trace logs from this module class DefaultContextBuilder(ContextBuilder): @@ -36,14 +38,14 @@ class DefaultContextBuilder(ContextBuilder): async def build_context(self) -> InjectionContext: """Build the base injection context; set DIDComm prefix to emit.""" - LOGGER.debug("Building new injection context with settings: %s", self.settings) + LOGGER.trace("Building new injection context with settings: %s", self.settings) context = InjectionContext(settings=self.settings) context.settings.set_default("default_label", "Aries Cloud Agent") if context.settings.get("timing.enabled"): timing_log = context.settings.get("timing.log_file") - LOGGER.debug("Enabling timing collector with log file: %s", timing_log) + LOGGER.trace("Enabling timing collector with log file: %s", timing_log) collector = Collector(log_path=timing_log) context.injector.bind_instance(Collector, collector) @@ -85,13 +87,13 @@ async def build_context(self) -> InjectionContext: async def bind_providers(self, context: InjectionContext): """Bind various class providers.""" - LOGGER.debug("Begin binding providers to context") + LOGGER.trace("Begin binding providers to context") context.injector.bind_provider(ProfileManager, ProfileManagerProvider()) wallet_type = self.settings.get("wallet.type") if wallet_type == "askar-anoncreds": - LOGGER.debug("Using AnonCreds tails server") + LOGGER.trace("Using AnonCreds tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -99,7 +101,7 @@ async def bind_providers(self, context: InjectionContext): ), ) else: - LOGGER.debug("Using Indy tails server") + LOGGER.trace("Using Indy tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -122,7 +124,7 @@ async def bind_providers(self, context: InjectionContext): async def load_plugins(self, context: InjectionContext): """Set up plugin registry and load plugins.""" - LOGGER.debug("Initializing plugin registry") + LOGGER.trace("Initializing plugin registry") plugin_registry = PluginRegistry( blocklist=self.settings.get("blocked_plugins", []) ) @@ -162,7 +164,7 @@ async def load_plugins(self, context: InjectionContext): def register_plugins(plugins: list[str], plugin_type: str): """Register a group of plugins with logging.""" - LOGGER.debug("Registering %s plugins", plugin_type) + LOGGER.trace("Registering %s plugins", plugin_type) for plugin in plugins: plugin_registry.register_plugin(plugin) @@ -175,7 +177,7 @@ def register_anoncreds_plugins(): register_plugins(default_plugins, "default") if context.settings.get("multitenant.admin_enabled"): - LOGGER.debug("Multitenant admin enabled - registering additional plugins") + LOGGER.trace("Multitenant admin enabled - registering additional plugins") plugin_registry.register_plugin("acapy_agent.multitenant.admin") register_askar_plugins() register_anoncreds_plugins() @@ -187,7 +189,7 @@ def register_anoncreds_plugins(): # Register external plugins for plugin_path in self.settings.get("external_plugins", []): - LOGGER.debug("Registering external plugin: %s", plugin_path) + LOGGER.trace("Registering external plugin: %s", plugin_path) plugin_registry.register_plugin(plugin_path) # Register message protocols diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index f0ad8ff887..5d547bb935 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -124,7 +124,7 @@ async def setup(self): LOGGER.debug("Starting setup of the Conductor") context = await self.context_builder.build_context() - LOGGER.debug("Context built successfully") + LOGGER.trace("Context built successfully") if self.force_agent_anoncreds: LOGGER.debug( @@ -150,15 +150,15 @@ async def setup(self): await get_genesis_transactions(context.settings) # Configure the root profile - LOGGER.debug("Configuring the root profile and setting up public DID") + LOGGER.trace("Configuring the root profile and setting up public DID") self.root_profile, self.setup_public_did = await wallet_config(context) context = self.root_profile.context - LOGGER.debug("Root profile configured successfully") + LOGGER.trace("Root profile configured successfully") # Multiledger Setup ledger_config_list = context.settings.get("ledger.ledger_config_list") if ledger_config_list and len(ledger_config_list) > 0: - LOGGER.debug("Setting up multiledger manager") + LOGGER.trace("Setting up multiledger manager") context.injector.bind_provider( BaseMultipleLedgerManager, MultiIndyLedgerManagerProvider(self.root_profile), @@ -174,7 +174,7 @@ async def setup(self): self.root_profile.BACKEND_NAME == "askar" and ledger.BACKEND_NAME == "indy-vdr" ): - LOGGER.debug("Binding IndyCredxVerifier for 'askar' backend.") + LOGGER.trace("Binding IndyCredxVerifier for 'askar' backend.") context.injector.bind_provider( IndyVerifier, ClassProvider( @@ -186,7 +186,7 @@ async def setup(self): self.root_profile.BACKEND_NAME == "askar-anoncreds" and ledger.BACKEND_NAME == "indy-vdr" ): - LOGGER.debug( + LOGGER.trace( "Binding IndyCredxVerifier for 'askar-anoncreds' backend." ) context.injector.bind_provider( @@ -225,55 +225,54 @@ async def setup(self): context.injector.bind_instance( InboundTransportManager, self.inbound_transport_manager ) - LOGGER.debug("Inbound transports registered successfully.") + LOGGER.trace("Inbound transports registered successfully.") - if not context.settings.get("transport.disabled"): # Register all outbound transports - LOGGER.debug("Transport not disabled. Setting up outbound transports.") + LOGGER.debug("Setting up outbound transports.") self.outbound_transport_manager = OutboundTransportManager( self.root_profile, self.handle_not_delivered ) await self.outbound_transport_manager.setup() - LOGGER.debug("Outbound transports registered successfully.") + LOGGER.trace("Outbound transports registered successfully.") # Initialize dispatcher - LOGGER.debug("Initializing dispatcher.") + LOGGER.trace("Initializing dispatcher.") self.dispatcher = Dispatcher(self.root_profile) await self.dispatcher.setup() - LOGGER.debug("Dispatcher initialized successfully.") + LOGGER.trace("Dispatcher initialized successfully.") wire_format = context.inject_or(BaseWireFormat) if wire_format and hasattr(wire_format, "task_queue"): wire_format.task_queue = self.dispatcher.task_queue - LOGGER.debug("Wire format task queue bound to dispatcher.") + LOGGER.trace("Wire format task queue bound to dispatcher.") # Bind manager for multitenancy related tasks if context.settings.get("multitenant.enabled"): - LOGGER.debug("Multitenant is enabled. Binding MultitenantManagerProvider.") + LOGGER.trace("Multitenant is enabled. Binding MultitenantManagerProvider.") context.injector.bind_provider( BaseMultitenantManager, MultitenantManagerProvider(self.root_profile) ) # Bind route manager provider - LOGGER.debug("Binding RouteManagerProvider.") + LOGGER.trace("Binding RouteManagerProvider.") context.injector.bind_provider( RouteManager, RouteManagerProvider(self.root_profile) ) # Bind OobMessageProcessor to be able to receive and process unencrypted messages - LOGGER.debug("Binding OobMessageProcessor.") + LOGGER.trace("Binding OobMessageProcessor.") context.injector.bind_instance( OobMessageProcessor, OobMessageProcessor(inbound_message_router=self.inbound_message_router), ) # Bind default PyLD document loader - LOGGER.debug("Binding default DocumentLoader.") + LOGGER.trace("Binding default DocumentLoader.") context.injector.bind_instance(DocumentLoader, DocumentLoader(self.root_profile)) # Admin API if context.settings.get("admin.enabled"): - LOGGER.debug("Admin API is enabled. Attempting to register admin server.") + LOGGER.trace("Admin API is enabled. Attempting to register admin server.") try: admin_host = context.settings.get("admin.host", "0.0.0.0") admin_port = context.settings.get("admin.port", "80") @@ -289,7 +288,7 @@ async def setup(self): self.get_stats, ) context.injector.bind_instance(BaseAdminServer, self.admin_server) - LOGGER.debug("Admin server registered on %s:%s.", admin_host, admin_port) + LOGGER.debug("Admin server registered on %s:%s", admin_host, admin_port) except Exception: LOGGER.exception("Unable to register admin server.") raise @@ -297,7 +296,7 @@ async def setup(self): # Fetch stats collector, if any collector = context.inject_or(Collector) if collector: - LOGGER.debug("Stats collector found. Wrapping methods for collection.") + LOGGER.trace("Stats collector found. Wrapping methods for collection.") # add stats to our own methods collector.wrap( self, @@ -316,7 +315,7 @@ async def setup(self): "find_inbound_connection", ), ) - LOGGER.debug("Methods wrapped with stats collector.") + LOGGER.trace("Methods wrapped with stats collector.") async def start(self) -> None: """Start the agent.""" From 926eab19c923c68f0755159ace100b7368cf0bf1 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 15:22:01 +0200 Subject: [PATCH 041/152] :loud_sound: Expand logging for Conductor start and stop Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 103 +++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 5d547bb935..5cf6bf1811 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -319,29 +319,36 @@ async def setup(self): async def start(self) -> None: """Start the agent.""" - + LOGGER.debug("Starting the Conductor agent.") context = self.root_profile.context await self.check_for_valid_wallet_type(self.root_profile) + LOGGER.trace("Wallet type validated.") if not context.settings.get("transport.disabled"): # Start up transports if enabled try: + LOGGER.trace("Transport not disabled. Starting inbound transports.") await self.inbound_transport_manager.start() + LOGGER.trace("Inbound transports started successfully.") except Exception: - LOGGER.exception("Unable to start inbound transports") + LOGGER.exception("Unable to start inbound transports.") raise try: + LOGGER.trace("Starting outbound transports.") await self.outbound_transport_manager.start() + LOGGER.trace("Outbound transports started successfully.") except Exception: - LOGGER.exception("Unable to start outbound transports") + LOGGER.exception("Unable to start outbound transports.") raise # Start up Admin server if self.admin_server: + LOGGER.trace("Admin server present. Starting admin server.") try: await self.admin_server.start() + LOGGER.debug("Admin server started successfully.") except Exception: - LOGGER.exception("Unable to start administration API") + LOGGER.exception("Unable to start administration API.") # Make admin responder available during message parsing # This allows webhooks to be called when a connection is marked active, # for example @@ -350,9 +357,11 @@ async def start(self) -> None: self.admin_server.outbound_message_router, ) context.injector.bind_instance(BaseResponder, responder) + LOGGER.trace("Admin responder bound to injector.") # Get agent label default_label = context.settings.get("default_label") + LOGGER.debug("Agent label: %s", default_label) if context.settings.get("transport.disabled"): LoggingConfigurator.print_banner( @@ -377,6 +386,7 @@ async def start(self) -> None: from_version_storage = None from_version = None agent_version = f"v{__version__}" + LOGGER.trace("Recording ACA-Py version in wallet if needed.") async with self.root_profile.session() as session: storage: BaseStorage = session.context.inject(BaseStorage) try: @@ -391,10 +401,16 @@ async def start(self) -> None: ) except StorageNotFoundError: LOGGER.warning("Wallet version storage record not found.") + from_version_config = self.root_profile.settings.get("upgrade.from_version") force_upgrade_flag = ( self.root_profile.settings.get("upgrade.force_upgrade") or False ) + LOGGER.trace( + "Force upgrade flag: %s, From version config: %s", + force_upgrade_flag, + from_version_config, + ) if force_upgrade_flag and from_version_config: if from_version_storage: @@ -406,8 +422,13 @@ async def start(self) -> None: from_version = from_version_storage else: from_version = from_version_config + LOGGER.trace( + "Determined from_version based on force_upgrade: %s", from_version + ) else: from_version = from_version_storage or from_version_config + LOGGER.trace("Determined from_version: %s", from_version) + if not from_version: LOGGER.warning( ( @@ -418,17 +439,27 @@ async def start(self) -> None: ) from_version = DEFAULT_ACAPY_VERSION self.root_profile.settings.set_value("upgrade.from_version", from_version) + LOGGER.trace("Set upgrade.from_version to default: %s", from_version) + config_available_list = get_upgrade_version_list( config_path=self.root_profile.settings.get("upgrade.config_path"), from_version=from_version, ) + LOGGER.trace("Available upgrade versions: %s", config_available_list) + if len(config_available_list) >= 1: + LOGGER.info("Upgrade configurations available. Initiating upgrade.") await upgrade(profile=self.root_profile) elif not (from_version_storage and from_version_storage == agent_version): + LOGGER.debug("No upgrades needed. Adding version record.") await add_version_record(profile=self.root_profile, version=agent_version) # Create a static connection for use by the test-suite if context.settings.get("debug.test_suite_endpoint"): + LOGGER.debug( + "Test suite endpoint configured. " + "Creating static connection for test suite." + ) mgr = ConnectionManager(self.root_profile) their_endpoint = context.settings["debug.test_suite_endpoint"] test_conn = await mgr.create_static_connection( @@ -444,26 +475,31 @@ async def start(self) -> None: f" - Their endpoint: {their_endpoint}\n" ) del mgr + LOGGER.debug("Static connection for test suite created and manager deleted.") # Clear default mediator if context.settings.get("mediation.clear"): + LOGGER.debug("Mediation clear flag set. Clearing default mediator.") mediation_mgr = MediationManager(self.root_profile) await mediation_mgr.clear_default_mediator() LOGGER.info("Default mediator cleared.") - # Clear default mediator # Set default mediator by id default_mediator_id = context.settings.get("mediation.default_id") if default_mediator_id: + LOGGER.debug("Setting default mediator to ID: %s", default_mediator_id) mediation_mgr = MediationManager(self.root_profile) try: await mediation_mgr.set_default_mediator_by_id(default_mediator_id) LOGGER.info(f"Default mediator set to {default_mediator_id}") except Exception: - LOGGER.exception("Error updating default mediator") + LOGGER.exception("Error updating default mediator.") # Print an invitation to the terminal if context.settings.get("debug.print_invitation"): + LOGGER.debug( + "Debug flag for printing invitation is set. Creating invitation." + ) try: mgr = OutOfBandManager(self.root_profile) invi_rec = await mgr.create_invitation( @@ -482,11 +518,16 @@ async def start(self) -> None: qr.add_data(invite_url) qr.print_ascii(invert=True) del mgr + LOGGER.trace("Invitation created and QR code printed.") except Exception: - LOGGER.exception("Error creating invitation") + LOGGER.exception("Error creating invitation.") # Print connections protocol invitation to the terminal if context.settings.get("debug.print_connections_invitation"): + LOGGER.debug( + "Debug flag for printing connections invitation is set. " + "Creating connections invitation." + ) try: mgr = ConnectionManager(self.root_profile) _record, invite = await mgr.create_invitation( @@ -504,11 +545,15 @@ async def start(self) -> None: qr.add_data(invite_url) qr.print_ascii(invert=True) del mgr + LOGGER.trace( + "Connections protocol invitation created and QR code printed." + ) except Exception: - LOGGER.exception("Error creating invitation") + LOGGER.exception("Error creating connections protocol invitation.") # mediation connection establishment provided_invite: str = context.settings.get("mediation.invite") + LOGGER.debug("Mediation invite provided: %s", provided_invite) try: async with self.root_profile.session() as session: @@ -516,16 +561,24 @@ async def start(self) -> None: mediation_invite_record = await invite_store.get_mediation_invite_record( provided_invite ) + LOGGER.debug("Mediation invite record retrieved successfully.") except Exception: - LOGGER.exception("Error retrieving mediator invitation") + LOGGER.exception("Error retrieving mediator invitation.") mediation_invite_record = None # Accept mediation invitation if one was specified or stored if mediation_invite_record is not None: + LOGGER.debug( + "Mediation invite record found. " + "Attempting to accept mediation invitation." + ) try: mediation_connections_invite = context.settings.get( "mediation.connections_invite", False ) + LOGGER.trace( + "Mediation connections invite flag: %s", mediation_connections_invite + ) invitation_handler = ( ConnectionInvitation if mediation_connections_invite @@ -533,8 +586,11 @@ async def start(self) -> None: ) if not mediation_invite_record.used: - # clear previous mediator configuration before establishing a - # new one + # clear previous mediator configuration before establishing a new one + LOGGER.trace( + "Mediation invite not used. " + "Clearing default mediator before accepting new invite." + ) await MediationManager(self.root_profile).clear_default_mediator() mgr = ( @@ -542,6 +598,7 @@ async def start(self) -> None: if mediation_connections_invite else OutOfBandManager(self.root_profile) ) + LOGGER.debug("Receiving mediation invitation.") record = await mgr.receive_invitation( invitation=invitation_handler.from_url( mediation_invite_record.invite @@ -552,6 +609,7 @@ async def start(self) -> None: await MediationInviteStore( session.context.inject(BaseStorage) ).mark_default_invite_as_used() + LOGGER.trace("Marked mediation invite as used.") await record.metadata_set( session, MediationManager.SEND_REQ_AFTER_CONNECTION, True @@ -559,48 +617,65 @@ async def start(self) -> None: await record.metadata_set( session, MediationManager.SET_TO_DEFAULT_ON_GRANTED, True ) + LOGGER.trace("Set mediation metadata after connection.") LOGGER.info("Attempting to connect to mediator...") del mgr + LOGGER.trace("Mediation manager deleted after setting up mediator.") except Exception: - LOGGER.exception("Error accepting mediation invitation") + LOGGER.exception("Error accepting mediation invitation.") try: + LOGGER.debug("Checking for wallet upgrades in progress.") await self.check_for_wallet_upgrades_in_progress() + LOGGER.debug("Wallet upgrades check completed.") except Exception: LOGGER.exception( - "An exception was caught while checking for wallet upgrades in progress" + "An exception was caught while checking for wallet upgrades in progress." ) # notify protocols of startup status + LOGGER.trace("Notifying protocols of startup status.") await self.root_profile.notify(STARTUP_EVENT_TOPIC, {}) + LOGGER.debug("Startup notification sent.") async def stop(self, timeout=1.0): """Stop the agent.""" + LOGGER.info("Stopping the Conductor agent.") # notify protocols that we are shutting down if self.root_profile: + LOGGER.debug("Notifying protocols of shutdown.") await self.root_profile.notify(SHUTDOWN_EVENT_TOPIC, {}) + LOGGER.debug("Shutdown notification sent.") shutdown = TaskQueue() if self.dispatcher: + LOGGER.trace("Initiating shutdown of dispatcher.") shutdown.run(self.dispatcher.complete()) if self.admin_server: + LOGGER.trace("Initiating shutdown of admin server.") shutdown.run(self.admin_server.stop()) if self.inbound_transport_manager: + LOGGER.trace("Initiating shutdown of inbound transport manager.") shutdown.run(self.inbound_transport_manager.stop()) if self.outbound_transport_manager: + LOGGER.trace("Initiating shutdown of outbound transport manager.") shutdown.run(self.outbound_transport_manager.stop()) if self.root_profile: # close multitenant profiles multitenant_mgr = self.context.inject_or(BaseMultitenantManager) if multitenant_mgr: + LOGGER.debug("Closing multitenant profiles.") for profile in multitenant_mgr.open_profiles: + LOGGER.trace("Closing profile: %s", profile.name) shutdown.run(profile.close()) - + LOGGER.debug("Closing root profile.") shutdown.run(self.root_profile.close()) + LOGGER.trace("Waiting for shutdown tasks to complete with timeout=%f.", timeout) await shutdown.complete(timeout) + LOGGER.info("Conductor agent stopped successfully.") def inbound_message_router( self, From 32bb6b4c8bdfbc92689f073e4df9faba18d5d339 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 16:03:20 +0200 Subject: [PATCH 042/152] :white_check_mark: Add unit tests for adding trace level functionality Signed-off-by: ff137 --- acapy_agent/config/tests/test_logging.py | 115 +++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/acapy_agent/config/tests/test_logging.py b/acapy_agent/config/tests/test_logging.py index cf23074568..5eb2294faa 100644 --- a/acapy_agent/config/tests/test_logging.py +++ b/acapy_agent/config/tests/test_logging.py @@ -1,9 +1,11 @@ import contextlib +import logging from io import BufferedReader, StringIO, TextIOWrapper from tempfile import NamedTemporaryFile from unittest import IsolatedAsyncioTestCase, mock from ..logging import configurator as test_module +from ..logging import utils class TestLoggingConfigurator(IsolatedAsyncioTestCase): @@ -162,3 +164,116 @@ def test_load_resource(self): mock_files.return_value.joinpath.assert_called_once_with("def") mock_resource_path.open.assert_called_once_with("rb") assert result == mock_resource_handle # Verify the returned binary stream + + +class TestLoggingUtils(IsolatedAsyncioTestCase): + def setUp(self): + # Backup existing logging attributes to restore after tests + self.original_levels = { + attr: getattr(logging, attr) for attr in dir(logging) if attr.isupper() + } + self.original_logger_methods = { + attr: getattr(logging.getLoggerClass(), attr, None) + for attr in dir(logging.getLoggerClass()) + if not attr.startswith("_") + } + # Reset TRACE level if it exists + if hasattr(logging, "TRACE"): + delattr(logging, "TRACE") + if hasattr(logging.getLoggerClass(), "trace"): + delattr(logging.getLoggerClass(), "trace") + # Ensure _TRACE_LEVEL_ADDED is False before each test + self._trace_level_added_patcher = mock.patch( + "acapy_agent.config.logging.utils._TRACE_LEVEL_ADDED", False + ) + self.mock_trace_level_added = self._trace_level_added_patcher.start() + + def tearDown(self): + # Restore original logging levels + for attr, value in self.original_levels.items(): + setattr(logging, attr, value) + # Restore original logger methods + for attr, method in self.original_logger_methods.items(): + if method is not None: + setattr(logging.getLoggerClass(), attr, method) + elif hasattr(logging.getLoggerClass(), attr): + delattr(logging.getLoggerClass(), attr) + # Remove TRACE if it was added during tests + if hasattr(logging, "TRACE"): + delattr(logging, "TRACE") + if hasattr(logging.getLoggerClass(), "trace"): + delattr(logging.getLoggerClass(), "trace") + # Stop patching _TRACE_LEVEL_ADDED + self._trace_level_added_patcher.stop() + + @mock.patch("acapy_agent.config.logging.utils.LOGGER") + @mock.patch("acapy_agent.config.logging.utils.logging.addLevelName") + def test_add_logging_level_success(self, mock_addLevelName, mock_logger): + utils.add_logging_level("CUSTOM", 2) + + mock_addLevelName.assert_called_once_with(2, "CUSTOM") + self.assertTrue(hasattr(logging, "CUSTOM")) + self.assertEqual(logging.CUSTOM, 2) + + logger = logging.getLogger(__name__) + self.assertTrue(hasattr(logger, "custom")) + self.assertTrue(callable(logger.custom)) + + self.assertTrue(hasattr(logging, "custom")) + self.assertTrue(callable(logging.custom)) + + def test_add_logging_level_existing_level_name(self): + # Add a level named 'DEBUG' which already exists + with self.assertRaises(AttributeError) as context: + utils.add_logging_level("DEBUG", 15) + self.assertIn("DEBUG already defined in logging module", str(context.exception)) + + def test_add_logging_level_existing_method_name(self): + # Add a logging method that already exists ('debug') + with self.assertRaises(AttributeError) as context: + utils.add_logging_level("CUSTOM", 25, method_name="debug") + self.assertIn("debug already defined in logging module", str(context.exception)) + + @mock.patch("acapy_agent.config.logging.utils.add_logging_level") + @mock.patch("acapy_agent.config.logging.utils.LOGGER") + def test_add_trace_level_new(self, mock_logger, mock_add_logging_level): + # Ensure _TRACE_LEVEL_ADDED is False + utils.add_trace_level() + + mock_add_logging_level.assert_called_once_with( + "TRACE", logging.DEBUG - 5, "trace" + ) + + # Verify logger.debug was called + mock_logger.debug.assert_called_with("%s level added to logging module.", "TRACE") + + # Check that _TRACE_LEVEL_ADDED is now True + self.assertTrue(utils._TRACE_LEVEL_ADDED) + + @mock.patch("acapy_agent.config.logging.utils.LOGGER") + @mock.patch( + "acapy_agent.config.logging.utils.add_logging_level", + side_effect=AttributeError("TRACE already exists"), + ) + def test_add_trace_level_already_exists_exception( + self, mock_add_logging_level, mock_logger + ): + utils.add_trace_level() + + # Verify logger.warning was called + mock_logger.warning.assert_called_with( + "%s level already exists: %s", "TRACE", mock_add_logging_level.side_effect + ) + + @mock.patch("acapy_agent.config.logging.utils.LOGGER") + @mock.patch("acapy_agent.config.logging.utils.add_logging_level") + def test_add_trace_level_already_present(self, mock_add_logging_level, mock_logger): + # Manually set _TRACE_LEVEL_ADDED to True to simulate already added TRACE level + with mock.patch("acapy_agent.config.logging.utils._TRACE_LEVEL_ADDED", True): + utils.add_trace_level() + + # add_logging_level should not be called since TRACE level is already added + mock_add_logging_level.assert_not_called() + + # Verify logger.debug was not called + mock_logger.debug.assert_not_called() From 9d0275adaf80cebc849693aa7015b4926445eb99 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 17:06:32 +0200 Subject: [PATCH 043/152] :white_check_mark: Reset the logging states before and after TestLoggingUtils is run Signed-off-by: ff137 --- acapy_agent/config/tests/test_logging.py | 53 +++++++++++++++--------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/acapy_agent/config/tests/test_logging.py b/acapy_agent/config/tests/test_logging.py index 5eb2294faa..9effb41c16 100644 --- a/acapy_agent/config/tests/test_logging.py +++ b/acapy_agent/config/tests/test_logging.py @@ -168,43 +168,58 @@ def test_load_resource(self): class TestLoggingUtils(IsolatedAsyncioTestCase): def setUp(self): - # Backup existing logging attributes to restore after tests + """Set up test environment by backing up logging states and resetting TRACE level.""" + # Backup existing logging attributes (e.g., DEBUG, INFO) self.original_levels = { attr: getattr(logging, attr) for attr in dir(logging) if attr.isupper() } + + # Backup existing logger class methods (e.g., debug, info) self.original_logger_methods = { attr: getattr(logging.getLoggerClass(), attr, None) for attr in dir(logging.getLoggerClass()) if not attr.startswith("_") } - # Reset TRACE level if it exists + + # Remove TRACE level and 'trace' method if they exist if hasattr(logging, "TRACE"): delattr(logging, "TRACE") if hasattr(logging.getLoggerClass(), "trace"): delattr(logging.getLoggerClass(), "trace") - # Ensure _TRACE_LEVEL_ADDED is False before each test - self._trace_level_added_patcher = mock.patch( + + # Patch the TRACE_LEVEL_ADDED flag to False before each test + self.trace_level_added_patcher = mock.patch( "acapy_agent.config.logging.utils._TRACE_LEVEL_ADDED", False ) - self.mock_trace_level_added = self._trace_level_added_patcher.start() + self.mock_trace_level_added = self.trace_level_added_patcher.start() def tearDown(self): - # Restore original logging levels + """Restore original logging states after each test.""" + # Stop patching TRACE_LEVEL_ADDED + self.trace_level_added_patcher.stop() + + # Restore original logging level attributes for attr, value in self.original_levels.items(): setattr(logging, attr, value) - # Restore original logger methods - for attr, method in self.original_logger_methods.items(): - if method is not None: - setattr(logging.getLoggerClass(), attr, method) - elif hasattr(logging.getLoggerClass(), attr): - delattr(logging.getLoggerClass(), attr) - # Remove TRACE if it was added during tests - if hasattr(logging, "TRACE"): - delattr(logging, "TRACE") - if hasattr(logging.getLoggerClass(), "trace"): - delattr(logging.getLoggerClass(), "trace") - # Stop patching _TRACE_LEVEL_ADDED - self._trace_level_added_patcher.stop() + + # Identify and remove any new uppercase attributes added during tests (e.g., TRACE) + current_levels = {attr for attr in dir(logging) if attr.isupper()} + for attr in current_levels - set(self.original_levels.keys()): + delattr(logging, attr) + + # Restore original logger class methods + LoggerClass = logging.getLoggerClass() + for attr, value in self.original_logger_methods.items(): + if value is not None: + setattr(LoggerClass, attr, value) + else: + if hasattr(LoggerClass, attr): + delattr(LoggerClass, attr) + + # Identify and remove any new logger methods added during tests (e.g., trace) + current_methods = {attr for attr in dir(LoggerClass) if not attr.startswith("_")} + for attr in current_methods - set(self.original_logger_methods.keys()): + delattr(LoggerClass, attr) @mock.patch("acapy_agent.config.logging.utils.LOGGER") @mock.patch("acapy_agent.config.logging.utils.logging.addLevelName") From a53b9492039c055e2936602d186f469b0f787719 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 17:17:42 +0200 Subject: [PATCH 044/152] :art: Signed-off-by: ff137 --- acapy_agent/commands/start.py | 2 +- acapy_agent/config/logging/utils.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/acapy_agent/commands/start.py b/acapy_agent/commands/start.py index ee256f1e4c..fb8652314c 100644 --- a/acapy_agent/commands/start.py +++ b/acapy_agent/commands/start.py @@ -31,7 +31,7 @@ async def start_app(conductor: Conductor): async def shutdown_app(conductor: Conductor): """Shut down.""" - LOGGER.warning("Shutting down") + LOGGER.info("Shutting down") await conductor.stop() diff --git a/acapy_agent/config/logging/utils.py b/acapy_agent/config/logging/utils.py index 5ee6108607..10092d261a 100644 --- a/acapy_agent/config/logging/utils.py +++ b/acapy_agent/config/logging/utils.py @@ -93,10 +93,8 @@ def add_trace_level() -> None: add_logging_level(TRACE_LEVEL_NAME, TRACE_LEVEL_NUM, TRACE_METHOD_NAME) LOGGER.debug("%s level added to logging module.", TRACE_LEVEL_NAME) except AttributeError as e: - # Log a warning if TRACE level already exists LOGGER.warning("%s level already exists: %s", TRACE_LEVEL_NAME, e) else: - # Optionally, you can log that TRACE level is already present LOGGER.debug( "%s level is already present in the logging module.", TRACE_LEVEL_NAME ) From e77cf3f764c0a935985b83e8cb206d06c7e57e7e Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 17:31:20 +0200 Subject: [PATCH 045/152] :test_tube: Debug log assertion test failing sporadically Filter the logs being read by module name, and add short sleep to allow log handlers to flush Signed-off-by: ff137 --- acapy_agent/core/tests/test_conductor.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/acapy_agent/core/tests/test_conductor.py b/acapy_agent/core/tests/test_conductor.py index 9f8e783491..199e946060 100644 --- a/acapy_agent/core/tests/test_conductor.py +++ b/acapy_agent/core/tests/test_conductor.py @@ -1,3 +1,4 @@ +import asyncio from unittest import IsolatedAsyncioTestCase import pytest @@ -1209,7 +1210,9 @@ async def test_print_invite_connection(self): test_profile, DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), ), - ), self.assertLogs(level="INFO") as captured, mock.patch.object( + ), self.assertLogs( + "acapy_agent.core.conductor", level="INFO" + ) as captured, mock.patch.object( test_module, "OutboundTransportManager", autospec=True ) as mock_outbound_mgr: mock_outbound_mgr.return_value.registered_transports = { @@ -1219,6 +1222,7 @@ async def test_print_invite_connection(self): await conductor.start() await conductor.stop() + await asyncio.sleep(0.1) # Allow log handlers to flush value = captured.output assert any("http://localhost?oob=" in msg for msg in value) assert any("http://localhost?c_i=" in msg for msg in value) From 4f632404c486f1e1ee08738801b015b6d9785785 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 18:37:06 +0200 Subject: [PATCH 046/152] :white_check_mark: Modify log assertion to be more robust Signed-off-by: ff137 --- acapy_agent/core/tests/test_conductor.py | 45 +++++++++++++++++++----- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/acapy_agent/core/tests/test_conductor.py b/acapy_agent/core/tests/test_conductor.py index 199e946060..e6e95a0cf8 100644 --- a/acapy_agent/core/tests/test_conductor.py +++ b/acapy_agent/core/tests/test_conductor.py @@ -1,5 +1,5 @@ -import asyncio from unittest import IsolatedAsyncioTestCase +from unittest.mock import call import pytest @@ -1203,6 +1203,18 @@ async def test_print_invite_connection(self): test_profile = await create_test_profile(None, await builder.build_context()) + # Define expected invitation URLs + expected_oob_url = "http://localhost?oob=test_oob_invite" + expected_ci_url = "http://localhost?c_i=test_ci_invite" + + # Mock the InvitationRecord returned by create_invitation for OOB + mock_oob_invitation = mock.MagicMock() + mock_oob_invitation.invitation.to_url.return_value = expected_oob_url + + # Mock the InvitationRecord returned by create_invitation for Connections Protocol + mock_ci_invitation = mock.MagicMock() + mock_ci_invitation.to_url.return_value = expected_ci_url + with mock.patch.object( test_module, "wallet_config", @@ -1210,22 +1222,37 @@ async def test_print_invite_connection(self): test_profile, DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), ), - ), self.assertLogs( - "acapy_agent.core.conductor", level="INFO" - ) as captured, mock.patch.object( + ), mock.patch.object( test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + ) as mock_outbound_mgr, mock.patch.object( + test_module, "OutOfBandManager" + ) as oob_mgr, mock.patch.object( + test_module, "ConnectionManager" + ) as conn_mgr, mock.patch.object(test_module.LOGGER, "info") as mock_logger_info: mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } + + # Configure create_invitation to return the mocked invitations + oob_mgr.return_value.create_invitation = mock.CoroutineMock( + return_value=mock_oob_invitation + ) + conn_mgr.return_value.create_invitation = mock.CoroutineMock( + return_value=(None, mock_ci_invitation) + ) + + # Execute the conductor lifecycle await conductor.setup() await conductor.start() await conductor.stop() - await asyncio.sleep(0.1) # Allow log handlers to flush - value = captured.output - assert any("http://localhost?oob=" in msg for msg in value) - assert any("http://localhost?c_i=" in msg for msg in value) + + # Assert that LOGGER.info was called twice with the expected URLs + expected_calls = [ + call(f"Invitation URL:\n{expected_oob_url}"), + call(f"Invitation URL (Connections protocol):\n{expected_ci_url}"), + ] + mock_logger_info.assert_has_calls(expected_calls, any_order=True) async def test_clear_default_mediator(self): builder: ContextBuilder = StubContextBuilder(self.test_settings) From 0ff9da49bd231fd788587a126e55b6205d39ec74 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 20:15:18 +0200 Subject: [PATCH 047/152] :art: Signed-off-by: ff137 --- acapy_agent/config/tests/test_logging.py | 4 ++-- acapy_agent/config/wallet.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/acapy_agent/config/tests/test_logging.py b/acapy_agent/config/tests/test_logging.py index 9effb41c16..446395003d 100644 --- a/acapy_agent/config/tests/test_logging.py +++ b/acapy_agent/config/tests/test_logging.py @@ -223,10 +223,10 @@ def tearDown(self): @mock.patch("acapy_agent.config.logging.utils.LOGGER") @mock.patch("acapy_agent.config.logging.utils.logging.addLevelName") - def test_add_logging_level_success(self, mock_addLevelName, mock_logger): + def test_add_logging_level_success(self, mock_add_level_name, mock_logger): utils.add_logging_level("CUSTOM", 2) - mock_addLevelName.assert_called_once_with(2, "CUSTOM") + mock_add_level_name.assert_called_once_with(2, "CUSTOM") self.assertTrue(hasattr(logging, "CUSTOM")) self.assertEqual(logging.CUSTOM, 2) diff --git a/acapy_agent/config/wallet.py b/acapy_agent/config/wallet.py index 89bfdad681..b19e202aa2 100644 --- a/acapy_agent/config/wallet.py +++ b/acapy_agent/config/wallet.py @@ -64,8 +64,8 @@ async def wallet_config( LOGGER.info("Created new profile") else: LOGGER.info("Opened existing profile") - LOGGER.info("Profile backend:", profile.backend) - LOGGER.info("Profile name:", profile.name) + LOGGER.info("Profile backend: %s", profile.backend) + LOGGER.info("Profile name: %s", profile.name) wallet_seed = context.settings.get("wallet.seed") wallet_local_did = context.settings.get("wallet.local_did") From 9058784f95b9ff905670f984fa351ef623b710ac Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 20:58:12 +0200 Subject: [PATCH 048/152] :bug: Handle case that load_module return type is Optional Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 6 +++++- acapy_agent/utils/classloader.py | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index f86495291e..47617a047d 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -309,7 +309,6 @@ async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> try: LOGGER.trace("Loading message types from: %s", version_path) mod = ClassLoader.load_module(version_path) - await self.load_protocol_version(context, mod, protocol_version) except ModuleLoadError as e: LOGGER.error( "Error loading plugin module message types from %s: %s", @@ -318,6 +317,11 @@ async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> ) return + if mod: + await self.load_protocol_version(context, mod, protocol_version) + else: + LOGGER.debug("Failed to load %s", version_path) + async def register_admin_routes(self, app) -> None: """Call route registration methods on the current context.""" LOGGER.trace("Registering admin routes for %d plugins", len(self._plugins)) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 29fd81bc4d..1eda57efbb 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -22,7 +22,9 @@ class ClassLoader: """Class used to load classes from modules dynamically.""" @classmethod - def load_module(cls, mod_path: str, package: Optional[str] = None) -> ModuleType: + def load_module( + cls, mod_path: str, package: Optional[str] = None + ) -> Optional[ModuleType]: """Load a module by its absolute path. Args: From ebfbaafe71f5772eadd120f3fcf1619ea0a2fb01 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 7 Nov 2024 21:37:52 +0200 Subject: [PATCH 049/152] :loud_sound: Expand logging for ClassLoader Signed-off-by: ff137 --- acapy_agent/utils/classloader.py | 88 ++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 1eda57efbb..1a6684fdcb 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -1,6 +1,7 @@ """The classloader provides utilities to dynamically load classes and modules.""" import inspect +import logging import sys from importlib import import_module, resources from importlib.util import find_spec, resolve_name @@ -9,6 +10,8 @@ from ..core.error import BaseError +LOGGER = logging.getLogger(__name__) + class ModuleLoadError(BaseError): """Module load error.""" @@ -38,36 +41,52 @@ def load_module( ModuleLoadError: If there was an error loading the module """ + LOGGER.trace("Attempting to load module: %s with package: %s", mod_path, package) + if package: + LOGGER.trace("Preloading parent package: %s", package) # preload parent package if not cls.load_module(package): + LOGGER.trace("Failed to preload parent package: %s", package) return None # must treat as a relative import if not mod_path.startswith("."): mod_path = f".{mod_path}" + LOGGER.trace("Adjusted mod_path for relative import: %s", mod_path) full_path = resolve_name(mod_path, package) + LOGGER.trace("Resolved full module path: %s", full_path) + if full_path in sys.modules: + LOGGER.trace("Module %s is already loaded", full_path) return sys.modules[full_path] if "." in mod_path: parent_mod_path, mod_name = mod_path.rsplit(".", 1) + LOGGER.trace( + "Parent module path: %s, Module name: %s", parent_mod_path, mod_name + ) if parent_mod_path and parent_mod_path[-1] != ".": parent_mod = cls.load_module(parent_mod_path, package) if not parent_mod: + LOGGER.trace("Failed to load parent module: %s", parent_mod_path) return None package = parent_mod.__name__ mod_path = f".{mod_name}" + LOGGER.trace("Adjusted mod_path after loading parent: %s", mod_path) # Load the module spec first - # this means that a later ModuleNotFoundError indicates a code issue + LOGGER.trace("Finding spec for module: %s with package: %s", mod_path, package) spec = find_spec(mod_path, package) if not spec: + LOGGER.trace("Module spec not found for: %s", mod_path) return None try: + LOGGER.trace("Importing module: %s with package: %s", mod_path, package) return import_module(mod_path, package) except ModuleNotFoundError as e: + LOGGER.warning("Module %s not found during import", full_path) raise ModuleLoadError(f"Unable to import module {full_path}: {str(e)}") from e @classmethod @@ -93,29 +112,53 @@ def load_class( """ + LOGGER.trace( + "Attempting to load class: %s with default_module: %s and package: %s", + class_name, + default_module, + package, + ) + if "." in class_name: # import module and find class mod_path, class_name = class_name.rsplit(".", 1) + LOGGER.trace( + "Extracted module path: %s, class name: %s from full class path", + mod_path, + class_name, + ) elif default_module: mod_path = default_module + LOGGER.trace("No module in class name, using default_module: %s", mod_path) else: + LOGGER.warning( + "Cannot resolve class name %s with no default module", class_name + ) raise ClassNotFoundError( f"Cannot resolve class name with no default module: {class_name}" ) mod = cls.load_module(mod_path, package) if not mod: - raise ClassNotFoundError(f"Module '{mod_path}' not found") + LOGGER.warning( + "Module %s not found when loading class %s", mod_path, class_name + ) + raise ClassNotFoundError(f"Module {mod_path} not found") resolved = getattr(mod, class_name, None) if not resolved: + LOGGER.warning("Class %s not found in module %s", class_name, mod_path) raise ClassNotFoundError( f"Class '{class_name}' not defined in module: {mod_path}" ) if not isinstance(resolved, type): + LOGGER.warning( + "Resolved attribute %s in module %s is not a class", class_name, mod_path + ) raise ClassNotFoundError( f"Resolved value is not a class: {mod_path}.{class_name}" ) + LOGGER.trace("Successfully loaded class %s from module %s", class_name, mod_path) return resolved @classmethod @@ -138,18 +181,45 @@ def load_subclass_of( """ + LOGGER.trace( + "Attempting to load subclass of %s from module %s with package %s", + base_class.__name__, + mod_path, + package, + ) + mod = cls.load_module(mod_path, package) if not mod: + LOGGER.warning( + "Module %s not found when loading subclass of %s", + mod_path, + base_class.__name__, + ) raise ClassNotFoundError(f"Module '{mod_path}' not found") - # Find an the first declared class that inherits from + # Find the first declared class that inherits from the base_class try: + LOGGER.trace( + "Inspecting classes in module %s for subclasses of %s", + mod_path, + base_class.__name__, + ) imported_class = next( obj for name, obj in inspect.getmembers(mod, inspect.isclass) if issubclass(obj, base_class) and obj is not base_class ) + LOGGER.trace( + "Found subclass %s of base class %s", + imported_class.__name__, + base_class.__name__, + ) except StopIteration: + LOGGER.trace( + "No subclass of %s found in module %s", + base_class.__name__, + mod_path, + ) raise ClassNotFoundError( f"Could not resolve a class that inherits from {base_class}" ) from None @@ -158,25 +228,35 @@ def load_subclass_of( @classmethod def scan_subpackages(cls, package: str) -> Sequence[str]: """Return a list of sub-packages defined under a named package.""" + LOGGER.debug("Scanning subpackages under package %s", package) if "." in package: package, sub_pkg = package.split(".", 1) + LOGGER.trace("Extracted main package: %s, sub-package: %s", package, sub_pkg) else: sub_pkg = "." + LOGGER.trace("No sub-package provided, defaulting to %s", sub_pkg) try: package_path = resources.files(package) + LOGGER.trace("Found package path: %s", package_path) except FileNotFoundError: + LOGGER.warning("Package %s not found during subpackage scan", package) raise ModuleLoadError(f"Undefined package {package}") if not (package_path / sub_pkg).is_dir(): + LOGGER.warning("Sub-package %s is not a directory under %s", sub_pkg, package) raise ModuleLoadError(f"Undefined package {package}") found = [] joiner = "" if sub_pkg == "." else f"{sub_pkg}." sub_path = package_path / sub_pkg + LOGGER.trace("Iterating over items in sub-package path: %s", sub_path) for item in sub_path.iterdir(): if (item / "__init__.py").exists(): - found.append(f"{package}.{joiner}{item.name}") + subpackage = f"{package}.{joiner}{item.name}" + found.append(subpackage) + LOGGER.trace("Found sub-package: %s", subpackage) + LOGGER.debug("Total sub-packages found under %s: %s", package, found) return found From 431290535434b61fd6b86ade364ebdf9603605d6 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 11 Nov 2024 10:22:16 +0200 Subject: [PATCH 050/152] :loud_sound: Log a warning if resource not found, instead of passing Signed-off-by: ff137 --- acapy_agent/config/logging/configurator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acapy_agent/config/logging/configurator.py b/acapy_agent/config/logging/configurator.py index 8843ed78e2..5eec80999c 100644 --- a/acapy_agent/config/logging/configurator.py +++ b/acapy_agent/config/logging/configurator.py @@ -34,6 +34,8 @@ from .utils import add_trace_level +LOGGER = logging.getLogger(__name__) + # Add TRACE level to logging before any configuration add_trace_level() @@ -62,7 +64,8 @@ def load_resource(path: str, encoding: Optional[str] = None): return io.TextIOWrapper(bstream, encoding=encoding) return bstream except IOError: - pass + LOGGER.warning("Resource not found: %s", path) + return None def dictConfig(config, new_file_path=None): From 9d347bb6a314de259dbfeff7e1c0bc33c7234f43 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 11 Nov 2024 10:22:45 +0200 Subject: [PATCH 051/152] :art: Signed-off-by: ff137 --- acapy_agent/config/logging/configurator.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/acapy_agent/config/logging/configurator.py b/acapy_agent/config/logging/configurator.py index 5eec80999c..fb9e2cb347 100644 --- a/acapy_agent/config/logging/configurator.py +++ b/acapy_agent/config/logging/configurator.py @@ -103,18 +103,7 @@ def fileConfig( raise RuntimeError(f"{fname} is invalid: {e}") if new_file_path and cp.has_section("handler_timed_file_handler"): - cp.set( - "handler_timed_file_handler", - "args", - str( - ( - f"{new_file_path}", - "d", - 7, - 1, - ) - ), - ) + cp.set("handler_timed_file_handler", "args", str((new_file_path, "d", 7, 1))) formatters = _create_formatters(cp) with logging._lock: From 06ceea91b75c50e05854089d70449ccfbf4bf7c4 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 11 Nov 2024 10:53:30 +0200 Subject: [PATCH 052/152] :art: Enable trace logs for remaining modules Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 3 +++ acapy_agent/utils/classloader.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 5cf6bf1811..c949cca782 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -27,6 +27,7 @@ load_multiple_genesis_transactions_from_config, ) from ..config.logging import LoggingConfigurator +from ..config.logging.utils import add_trace_level from ..config.provider import ClassProvider from ..config.wallet import wallet_config from ..core.profile import Profile @@ -82,6 +83,8 @@ from .util import SHUTDOWN_EVENT_TOPIC, STARTUP_EVENT_TOPIC LOGGER = logging.getLogger(__name__) +add_trace_level() # Allow trace logs from this module + # Refer ACA-Py issue #2197 # When the from version is not found DEFAULT_ACAPY_VERSION = "v0.7.5" diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 1a6684fdcb..e257abdb3a 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -8,9 +8,11 @@ from types import ModuleType from typing import Optional, Sequence, Type +from ..config.logging.utils import add_trace_level from ..core.error import BaseError LOGGER = logging.getLogger(__name__) +add_trace_level() # Allow trace logs from this module class ModuleLoadError(BaseError): From 838adcdb9c7ee29940df6f43400bbb459c09ec53 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 11:04:16 +0200 Subject: [PATCH 053/152] :bug: Fix registering and loading of modules Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 30 ++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 47617a047d..542203c819 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -344,6 +344,10 @@ async def register_admin_routes(self, app) -> None: "Error loading admin routes from %s: %s", version_path, e ) continue + + if mod and hasattr(mod, "register"): + LOGGER.trace("Registering routes for: %s", plugin_name) + await mod.register(app) else: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" @@ -354,9 +358,9 @@ async def register_admin_routes(self, app) -> None: LOGGER.error("Error loading admin routes from %s: %s", routes_path, e) continue - if mod and hasattr(mod, "register"): - LOGGER.trace("Registering routes for: %s", plugin_name) - await mod.register(app) + if mod and hasattr(mod, "register"): + LOGGER.trace("Registering routes for: %s", plugin_name) + await mod.register(app) def register_protocol_events(self, context: InjectionContext) -> None: """Call route register_events methods on the current context.""" @@ -383,6 +387,10 @@ def register_protocol_events(self, context: InjectionContext) -> None: except ModuleLoadError as e: LOGGER.error("Error loading events from %s: %s", version_path, e) continue + + if mod and hasattr(mod, "register_events"): + LOGGER.trace("Registering events from: %s", version_path) + mod.register_events(event_bus) else: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" @@ -393,9 +401,9 @@ def register_protocol_events(self, context: InjectionContext) -> None: LOGGER.error("Error loading events from %s: %s", routes_path, e) continue - if mod and hasattr(mod, "register_events"): - LOGGER.trace("Registering events from: %s", version_path) - mod.register_events(event_bus) + if mod and hasattr(mod, "register_events"): + LOGGER.trace("Registering events from: %s", version_path) + mod.register_events(event_bus) def post_process_routes(self, app) -> None: """Call route binary file response OpenAPI fixups if applicable.""" @@ -417,6 +425,10 @@ def post_process_routes(self, app) -> None: except ModuleLoadError as e: LOGGER.error("Error loading routes from %s: %s", version_path, e) continue + + if mod and hasattr(mod, "post_process_routes"): + LOGGER.trace("Post-processing routes for %s", plugin_name) + mod.post_process_routes(app) else: # Set binary file responses for routes not in a versioned package. routes_path = f"{plugin_name}.routes" @@ -427,9 +439,9 @@ def post_process_routes(self, app) -> None: LOGGER.error("Error loading routes from %s: %s", routes_path, e) continue - if mod and hasattr(mod, "post_process_routes"): - LOGGER.trace("Post-processing routes for %s", plugin_name) - mod.post_process_routes(app) + if mod and hasattr(mod, "post_process_routes"): + LOGGER.trace("Post-processing routes for %s", plugin_name) + mod.post_process_routes(app) def __repr__(self) -> str: """Return a string representation for this class.""" From f34264676ad5e6bc09467b05f37f67166d0d58ae Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 13:01:19 +0200 Subject: [PATCH 054/152] :loud_sound: Expand logging for Ledger Configuration Signed-off-by: ff137 --- acapy_agent/config/ledger.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/acapy_agent/config/ledger.py b/acapy_agent/config/ledger.py index 7d7acb1e7e..ab335913b9 100644 --- a/acapy_agent/config/ledger.py +++ b/acapy_agent/config/ledger.py @@ -34,14 +34,18 @@ async def fetch_genesis_transactions(genesis_url: str) -> str: # https://github.com/openwallet-foundation/acapy/issues/1745 return await fetch(genesis_url, headers=headers, max_attempts=20) except FetchError as e: + LOGGER.error("Error retrieving genesis transactions from %s: %s", genesis_url, e) raise ConfigError("Error retrieving ledger genesis transactions") from e async def get_genesis_transactions(settings: Settings) -> str: """Fetch genesis transactions if necessary.""" + LOGGER.debug("Getting genesis transactions from settings") txns = settings.get("ledger.genesis_transactions") + LOGGER.debug("Genesis transactions from settings: %s", "found" if txns else "absent") if not txns: + LOGGER.debug("No genesis transactions found in settings") if settings.get("ledger.genesis_url"): txns = await fetch_genesis_transactions(settings["ledger.genesis_url"]) elif settings.get("ledger.genesis_file"): @@ -51,8 +55,10 @@ async def get_genesis_transactions(settings: Settings) -> str: with open(genesis_path, "r") as genesis_file: txns = genesis_file.read() except IOError as e: + LOGGER.error("Failed to read genesis file: %s", str(e)) raise ConfigError("Error reading ledger genesis transactions") from e if txns: + LOGGER.debug("Storing genesis transactions in settings") settings["ledger.genesis_transactions"] = txns return txns @@ -63,6 +69,8 @@ async def load_multiple_genesis_transactions_from_config(settings: Settings): ledger_config_list = settings.get("ledger.ledger_config_list") ledger_txns_list = [] write_ledger_set = False + LOGGER.debug("Processing %d ledger configs", len(ledger_config_list)) + for config in ledger_config_list: txns = None if "genesis_transactions" in config: @@ -74,11 +82,12 @@ async def load_multiple_genesis_transactions_from_config(settings: Settings): try: genesis_path = config.get("genesis_file") LOGGER.info( - "Reading ledger genesis transactions from: %s", genesis_path + "Reading ledger genesis transactions from file: %s", genesis_path ) with open(genesis_path, "r") as genesis_file: txns = genesis_file.read() except IOError as e: + LOGGER.error("Failed to read genesis file: %s", str(e)) raise ConfigError("Error reading ledger genesis transactions") from e is_write_ledger = ( False if config.get("is_write") is None else config.get("is_write") @@ -119,6 +128,7 @@ async def load_multiple_genesis_transactions_from_config(settings: Settings): " genesis_file and genesis_transactions provided." ) settings["ledger.ledger_config_list"] = ledger_txns_list + LOGGER.debug("Processed %d ledger configs successfully", len(ledger_txns_list)) async def ledger_config( @@ -126,6 +136,10 @@ async def ledger_config( ) -> bool: """Perform Indy ledger configuration.""" + LOGGER.debug( + "Configuring ledger for profile %s and public_did %s", profile.name, public_did + ) + session = await profile.session() ledger = session.inject_or(BaseLedger) @@ -136,32 +150,46 @@ async def ledger_config( async with ledger: # Check transaction author agreement acceptance if not ledger.read_only: + LOGGER.debug("Checking transaction author agreement") taa_info = await ledger.get_txn_author_agreement() if taa_info["taa_required"] and public_did: + LOGGER.debug("TAA acceptance required") taa_accepted = await ledger.get_latest_txn_author_acceptance() if ( not taa_accepted or taa_info["taa_record"]["digest"] != taa_accepted["digest"] ): + LOGGER.info("TAA acceptance needed - performing acceptance") if not await accept_taa(ledger, profile, taa_info, provision): + LOGGER.warning("TAA acceptance failed") return False + LOGGER.info("TAA acceptance completed") # Publish endpoints if necessary - skipped if TAA is required but not accepted endpoint = session.settings.get("default_endpoint") if public_did: wallet = session.inject(BaseWallet) try: + LOGGER.debug("Setting DID endpoint to: %s", endpoint) await wallet.set_did_endpoint(public_did, endpoint, ledger) except LedgerError as x_ledger: + LOGGER.error("Error setting DID endpoint: %s", x_ledger.message) raise ConfigError(x_ledger.message) from x_ledger # e.g., read-only # Publish profile endpoint if ledger is NOT read-only profile_endpoint = session.settings.get("profile_endpoint") if profile_endpoint and not ledger.read_only: + LOGGER.debug( + "Publishing profile endpoint: %s for DID: %s", + profile_endpoint, + public_did, + ) await ledger.update_endpoint_for_did( public_did, profile_endpoint, EndpointType.PROFILE ) + LOGGER.info("Profile endpoint published successfully") + LOGGER.info("Ledger configuration complete") return True From 5ec73ac6dd99215f29c9b77ac700657f1a5a932c Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 21 Nov 2024 19:18:54 +0000 Subject: [PATCH 055/152] Fix tails upload for anoncreds multitenancy Signed-off-by: jamshale --- acapy_agent/anoncreds/revocation.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/acapy_agent/anoncreds/revocation.py b/acapy_agent/anoncreds/revocation.py index 56b19d222d..96d2795246 100644 --- a/acapy_agent/anoncreds/revocation.py +++ b/acapy_agent/anoncreds/revocation.py @@ -32,6 +32,8 @@ from ..core.error import BaseError from ..core.event_bus import Event, EventBus from ..core.profile import Profile, ProfileSession +from ..multitenant.base import BaseMultitenantManager +from ..tails.anoncreds_tails_server import AnonCredsTailsServer from ..tails.base import BaseTailsServer from .error_messages import ANONCREDS_PROFILE_REQUIRED_MSG from .events import RevListFinishedEvent, RevRegDefFinishedEvent @@ -694,7 +696,12 @@ def get_local_tails_path(self, rev_reg_def: RevRegDef) -> str: async def upload_tails_file(self, rev_reg_def: RevRegDef): """Upload the local tails file to the tails server.""" - tails_server = self.profile.inject_or(BaseTailsServer) + multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + tails_server = AnonCredsTailsServer() + else: + tails_server = self.profile.inject_or(BaseTailsServer) + if not tails_server: raise AnonCredsRevocationError("Tails server not configured") if not Path(self.get_local_tails_path(rev_reg_def)).is_file(): From 8a3ad2e6e63827cae0dc83cfa0272135336f090b Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 21 Nov 2024 20:35:26 +0000 Subject: [PATCH 056/152] Update unit test Signed-off-by: jamshale --- .../anoncreds/tests/test_revocation.py | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/acapy_agent/anoncreds/tests/test_revocation.py b/acapy_agent/anoncreds/tests/test_revocation.py index 5de4ef368e..4faf33429f 100644 --- a/acapy_agent/anoncreds/tests/test_revocation.py +++ b/acapy_agent/anoncreds/tests/test_revocation.py @@ -836,21 +836,40 @@ def test_generate_public_tails_uri(self): async def test_upload_tails_file(self): self.profile.inject_or = mock.Mock( - return_value=mock.MagicMock( - upload_tails_file=mock.CoroutineMock( - side_effect=[ - (True, "http://tails-server.com"), - (None, "http://tails-server.com"), - (True, "not-http://tails-server.com"), - ] - ) - ) + side_effect=[ + None, + mock.MagicMock( + upload_tails_file=mock.CoroutineMock( + return_value=(True, "http://tails-server.com") + ) + ), + ] ) # valid await self.revocation.upload_tails_file(rev_reg_def) # upload fails + self.profile.inject_or = mock.Mock( + side_effect=[ + None, + mock.MagicMock( + upload_tails_file=mock.CoroutineMock( + return_value=(None, "http://tails-server.com"), + ) + ), + ] + ) with self.assertRaises(test_module.AnonCredsRevocationError): await self.revocation.upload_tails_file(rev_reg_def) + self.profile.inject_or = mock.Mock( + side_effect=[ + None, + mock.MagicMock( + upload_tails_file=mock.CoroutineMock( + return_value=(True, "not-http://tails-server.com"), + ) + ), + ] + ) # tails location does not match with self.assertRaises(test_module.AnonCredsRevocationError): await self.revocation.upload_tails_file(rev_reg_def) From 8e704bbe7de4d987ed69cb818ee4654a6d10c2b8 Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 21 Nov 2024 21:49:26 +0000 Subject: [PATCH 057/152] Make sonarcloud happy with https in test Signed-off-by: jamshale --- acapy_agent/anoncreds/tests/test_revocation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acapy_agent/anoncreds/tests/test_revocation.py b/acapy_agent/anoncreds/tests/test_revocation.py index 4faf33429f..ff9ed6d09f 100644 --- a/acapy_agent/anoncreds/tests/test_revocation.py +++ b/acapy_agent/anoncreds/tests/test_revocation.py @@ -48,7 +48,7 @@ "accum_key": {"z": "1 0BB...386"}, }, tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", - tails_location="http://tails-server.com", + tails_location="https://tails-server.com", ), issuer_id="CsQY9MGeD3CQP4EyuVFo5m", type="CL_ACCUM", @@ -840,7 +840,7 @@ async def test_upload_tails_file(self): None, mock.MagicMock( upload_tails_file=mock.CoroutineMock( - return_value=(True, "http://tails-server.com") + return_value=(True, "https://tails-server.com") ) ), ] @@ -853,7 +853,7 @@ async def test_upload_tails_file(self): None, mock.MagicMock( upload_tails_file=mock.CoroutineMock( - return_value=(None, "http://tails-server.com"), + return_value=(None, "https://tails-server.com"), ) ), ] From a00b5f5c98a13dfa756500141f164a14d0d17217 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:11:42 -0800 Subject: [PATCH 058/152] Add anoncreds issuance and presentation format (#3331) * Add anoncreds issuance and presentation formats Signed-off-by: jamshale * Fix unit tests Signed-off-by: jamshale * Fix error in _formats_attach Signed-off-by: jamshale * Fix AnoncredsDID validation pattern Signed-off-by: jamshale * Fix name Signed-off-by: jamshale * Fix scenario test Signed-off-by: jamshale * Update demo with anoncreds format Signed-off-by: jamshale * Fix the scenario test and add better description Signed-off-by: jamshale * Add service_healthy check for indy agent Signed-off-by: jamshale * Fix/update BDD tests Signed-off-by: jamshale * Add issuer askar to holder anoncreds support Signed-off-by: jamshale * Update BDD tests Signed-off-by: jamshale * Remove commented code Signed-off-by: jamshale * Expand scenario test Signed-off-by: jamshale * Add better comments for format compatibilty imports Signed-off-by: jamshale * Add anocnreds compatibilty bdd test to PR workflow Signed-off-by: jamshale --------- Signed-off-by: jamshale --- acapy_agent/anoncreds/base.py | 6 +- .../anoncreds/default/did_indy/registry.py | 6 +- .../anoncreds/default/did_web/registry.py | 6 +- .../anoncreds/default/legacy_indy/recover.py | 2 +- .../anoncreds/default/legacy_indy/registry.py | 6 +- .../default/legacy_indy/tests/test_recover.py | 5 +- .../legacy_indy/tests/test_registry.py | 34 +- acapy_agent/anoncreds/events.py | 2 +- acapy_agent/anoncreds/holder.py | 4 +- acapy_agent/anoncreds/issuer.py | 4 +- acapy_agent/anoncreds/models/credential.py | 167 ++++ ...s_cred_def.py => credential_definition.py} | 14 +- .../anoncreds/models/credential_offer.py | 149 ++++ .../anoncreds/models/credential_proposal.py | 58 ++ .../anoncreds/models/credential_request.py | 81 ++ .../anoncreds/models/non_rev_interval.py | 78 ++ acapy_agent/anoncreds/models/predicate.py | 82 ++ .../anoncreds/models/presentation_request.py | 306 +++++++ acapy_agent/anoncreds/models/proof.py | 749 ++++++++++++++++++ .../anoncreds/models/requested_credentials.py | 47 ++ ...{anoncreds_revocation.py => revocation.py} | 29 +- .../models/{anoncreds_schema.py => schema.py} | 14 +- acapy_agent/anoncreds/models/utils.py | 99 +++ acapy_agent/anoncreds/registry.py | 6 +- acapy_agent/anoncreds/revocation.py | 5 +- acapy_agent/anoncreds/routes.py | 47 +- acapy_agent/anoncreds/tests/test_holder.py | 4 +- acapy_agent/anoncreds/tests/test_issuer.py | 4 +- .../anoncreds/tests/test_revocation.py | 6 +- .../anoncreds/tests/test_revocation_setup.py | 2 +- acapy_agent/anoncreds/tests/test_routes.py | 2 +- acapy_agent/anoncreds/tests/test_verifier.py | 6 +- acapy_agent/anoncreds/verifier.py | 16 +- acapy_agent/connections/models/conn_record.py | 8 +- .../connections/models/connection_target.py | 16 +- acapy_agent/indy/models/cred_def.py | 8 +- acapy_agent/indy/models/pres_preview.py | 8 +- acapy_agent/indy/models/proof_request.py | 16 +- acapy_agent/indy/models/revocation.py | 12 +- acapy_agent/indy/models/schema.py | 15 +- acapy_agent/ledger/routes.py | 12 +- .../messaging/credential_definitions/util.py | 11 +- .../messaging/decorators/attach_decorator.py | 8 +- .../messaging/decorators/service_decorator.py | 13 +- .../decorators/signature_decorator.py | 12 +- .../messaging/decorators/timing_decorator.py | 22 +- acapy_agent/messaging/models/base_record.py | 10 +- acapy_agent/messaging/schemas/routes.py | 11 +- acapy_agent/messaging/schemas/util.py | 11 +- acapy_agent/messaging/tests/test_valid.py | 56 +- acapy_agent/messaging/valid.py | 116 ++- .../v1_0/messages/basicmessage.py | 8 +- .../v1_0/messages/connection_invitation.py | 12 +- .../protocols/connections/v1_0/routes.py | 24 +- .../v1_0/messages/credential_proposal.py | 8 +- .../protocols/issue_credential/v1_0/routes.py | 18 +- .../v2_0/formats/anoncreds/handler.py | 171 ++-- .../formats/anoncreds/tests/test_handler.py | 161 ++-- .../v2_0/formats/indy/handler.py | 98 +-- .../ld_proof/models/cred_detail_options.py | 8 +- .../v2_0/formats/vc_di/tests/test_handler.py | 4 +- .../issue_credential/v2_0/manager.py | 10 +- .../issue_credential/v2_0/message_types.py | 4 + .../v2_0/messages/cred_format.py | 30 +- .../v2_0/models/detail/anoncreds.py | 131 +++ .../protocols/issue_credential/v2_0/routes.py | 71 +- .../v2_0/tests/test_routes.py | 24 +- .../anoncreds/pres_exch_handler.py | 40 +- .../present_proof/indy/pres_exch_handler.py | 7 + .../present_proof/v1_0/tests/test_routes.py | 6 +- .../v2_0/formats/anoncreds/handler.py | 98 ++- .../present_proof/v2_0/formats/handler.py | 2 +- .../v2_0/formats/indy/handler.py | 23 +- .../present_proof/v2_0/message_types.py | 3 + .../v2_0/messages/pres_format.py | 20 +- .../protocols/present_proof/v2_0/routes.py | 64 +- .../v2_0/tests/test_manager_anoncreds.py | 446 ++++++----- .../present_proof/v2_0/tests/test_routes.py | 6 +- .../v2_0/tests/test_routes_anoncreds.py | 6 +- acapy_agent/revocation_anoncreds/routes.py | 2 +- .../revocation_anoncreds/tests/test_routes.py | 2 +- .../vc/vc_ld/models/linked_data_proof.py | 8 +- acapy_agent/vc/vc_ld/models/options.py | 8 +- acapy_agent/wallet/anoncreds_upgrade.py | 6 +- acapy_agent/wallet/routes.py | 15 +- demo/bdd_support/agent_backchannel_client.py | 4 + demo/features/0453-issue-credential.feature | 2 +- demo/features/steps/0453-issue-credential.py | 5 +- demo/features/steps/0454-present-proof.py | 11 +- demo/features/steps/0586-sign-transaction.py | 34 +- demo/features/upgrade.feature | 3 - demo/runners/agent_container.py | 132 ++- demo/runners/faber.py | 109 ++- demo/runners/support/agent.py | 3 +- .../docker-compose.yml | 61 +- .../example.py | 647 +++++++++++++-- 96 files changed, 3917 insertions(+), 1049 deletions(-) create mode 100644 acapy_agent/anoncreds/models/credential.py rename acapy_agent/anoncreds/models/{anoncreds_cred_def.py => credential_definition.py} (97%) create mode 100644 acapy_agent/anoncreds/models/credential_offer.py create mode 100644 acapy_agent/anoncreds/models/credential_proposal.py create mode 100644 acapy_agent/anoncreds/models/credential_request.py create mode 100644 acapy_agent/anoncreds/models/non_rev_interval.py create mode 100644 acapy_agent/anoncreds/models/predicate.py create mode 100644 acapy_agent/anoncreds/models/presentation_request.py create mode 100644 acapy_agent/anoncreds/models/proof.py create mode 100644 acapy_agent/anoncreds/models/requested_credentials.py rename acapy_agent/anoncreds/models/{anoncreds_revocation.py => revocation.py} (96%) rename acapy_agent/anoncreds/models/{anoncreds_schema.py => schema.py} (95%) create mode 100644 acapy_agent/anoncreds/models/utils.py create mode 100644 acapy_agent/protocols/issue_credential/v2_0/models/detail/anoncreds.py diff --git a/acapy_agent/anoncreds/base.py b/acapy_agent/anoncreds/base.py index 6cb5940bb2..32c0a1c1f1 100644 --- a/acapy_agent/anoncreds/base.py +++ b/acapy_agent/anoncreds/base.py @@ -6,8 +6,8 @@ from ..config.injection_context import InjectionContext from ..core.error import BaseError from ..core.profile import Profile -from .models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from .models.anoncreds_revocation import ( +from .models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from .models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -15,7 +15,7 @@ RevRegDef, RevRegDefResult, ) -from .models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from .models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult T = TypeVar("T") diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index 567d90ccce..dcaafe4c06 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -7,8 +7,8 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver -from ...models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from ...models.anoncreds_revocation import ( +from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from ...models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -16,7 +16,7 @@ RevRegDef, RevRegDefResult, ) -from ...models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from ...models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index 63382f3606..f97ba88fb8 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -6,8 +6,8 @@ from ....config.injection_context import InjectionContext from ....core.profile import Profile from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver -from ...models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from ...models.anoncreds_revocation import ( +from ...models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from ...models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -15,7 +15,7 @@ RevRegDef, RevRegDefResult, ) -from ...models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from ...models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult class DIDWebRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar): diff --git a/acapy_agent/anoncreds/default/legacy_indy/recover.py b/acapy_agent/anoncreds/default/legacy_indy/recover.py index cd183adf15..4c3eaf0517 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/recover.py +++ b/acapy_agent/anoncreds/default/legacy_indy/recover.py @@ -9,7 +9,7 @@ import indy_vdr from anoncreds import RevocationRegistry, RevocationRegistryDefinition -from ...models.anoncreds_revocation import RevList +from ...models.revocation import RevList LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index e173bbde32..aff1040616 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -56,14 +56,14 @@ ) from ...events import RevListFinishedEvent from ...issuer import CATEGORY_CRED_DEF, AnonCredsIssuer, AnonCredsIssuerError -from ...models.anoncreds_cred_def import ( +from ...models.credential_definition import ( CredDef, CredDefResult, CredDefState, CredDefValue, GetCredDefResult, ) -from ...models.anoncreds_revocation import ( +from ...models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -74,7 +74,7 @@ RevRegDefState, RevRegDefValue, ) -from ...models.anoncreds_schema import ( +from ...models.schema import ( AnonCredsSchema, GetSchemaResult, SchemaResult, diff --git a/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py b/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py index 61c0a90f40..b504690c5e 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py +++ b/acapy_agent/anoncreds/default/legacy_indy/tests/test_recover.py @@ -9,9 +9,8 @@ import pytest from anoncreds import RevocationRegistryDefinition -from acapy_agent.tests import mock - -from ....models.anoncreds_revocation import RevList, RevRegDef, RevRegDefValue +from .....tests import mock +from ....models.revocation import RevList, RevRegDef, RevRegDefValue from ..recover import ( RevocRecoveryException, _check_tails_hash_for_inconsistency, diff --git a/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py b/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py index 2b6b6c0b76..c41eb80797 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/tests/test_registry.py @@ -16,25 +16,6 @@ from .....anoncreds.base import AnonCredsSchemaAlreadyExists from .....anoncreds.default.legacy_indy import registry as test_module from .....anoncreds.issuer import AnonCredsIssuer -from .....anoncreds.models.anoncreds_cred_def import ( - CredDef, - CredDefResult, - CredDefValue, - CredDefValuePrimary, -) -from .....anoncreds.models.anoncreds_revocation import ( - RevList, - RevListResult, - RevRegDef, - RevRegDefResult, - RevRegDefState, - RevRegDefValue, -) -from .....anoncreds.models.anoncreds_schema import ( - AnonCredsSchema, - GetSchemaResult, - SchemaResult, -) from .....askar.profile_anon import ( AskarAnoncredsProfileSession, ) @@ -55,6 +36,21 @@ ) from .....tests import mock from .....utils.testing import create_test_profile +from ....models.credential_definition import ( + CredDef, + CredDefResult, + CredDefValue, + CredDefValuePrimary, +) +from ....models.revocation import ( + RevList, + RevListResult, + RevRegDef, + RevRegDefResult, + RevRegDefState, + RevRegDefValue, +) +from ....models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult B58 = alphabet if isinstance(alphabet, str) else alphabet.decode("ascii") INDY_DID = rf"^(did:sov:)?[{B58}]{{21,22}}$" diff --git a/acapy_agent/anoncreds/events.py b/acapy_agent/anoncreds/events.py index 4511b546f7..98477bf4e1 100644 --- a/acapy_agent/anoncreds/events.py +++ b/acapy_agent/anoncreds/events.py @@ -4,7 +4,7 @@ from typing import NamedTuple, Optional from ..core.event_bus import Event -from .models.anoncreds_revocation import RevRegDef +from .models.revocation import RevRegDef CRED_DEF_FINISHED_EVENT = "anoncreds::credential-definition::finished" REV_REG_DEF_FINISHED_EVENT = "anoncreds::revocation-registry-definition::finished" diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index 04a1a16fac..f8dd4445f7 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -23,7 +23,6 @@ from pyld.jsonld import JsonLdProcessor from uuid_utils import uuid4 -from ..anoncreds.models.anoncreds_schema import AnonCredsSchema from ..askar.profile_anon import AskarAnoncredsProfile from ..core.error import BaseError from ..core.profile import Profile @@ -33,7 +32,8 @@ from ..vc.vc_ld import VerifiableCredential from ..wallet.error import WalletNotFoundError from .error_messages import ANONCREDS_PROFILE_REQUIRED_MSG -from .models.anoncreds_cred_def import CredDef +from .models.credential_definition import CredDef +from .models.schema import AnonCredsSchema from .registry import AnonCredsRegistry LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/issuer.py b/acapy_agent/anoncreds/issuer.py index ad79173e16..6dc3fababa 100644 --- a/acapy_agent/anoncreds/issuer.py +++ b/acapy_agent/anoncreds/issuer.py @@ -24,8 +24,8 @@ from .base import AnonCredsSchemaAlreadyExists, BaseAnonCredsError from .error_messages import ANONCREDS_PROFILE_REQUIRED_MSG from .events import CredDefFinishedEvent -from .models.anoncreds_cred_def import CredDef, CredDefResult -from .models.anoncreds_schema import AnonCredsSchema, SchemaResult, SchemaState +from .models.credential_definition import CredDef, CredDefResult +from .models.schema import AnonCredsSchema, SchemaResult, SchemaState from .registry import AnonCredsRegistry LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/models/credential.py b/acapy_agent/anoncreds/models/credential.py new file mode 100644 index 0000000000..c008fc16c7 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential.py @@ -0,0 +1,167 @@ +"""Credential artifacts.""" + +from typing import Mapping, Optional + +from marshmallow import EXCLUDE, ValidationError, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ANONCREDS_REV_REG_ID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, + NUM_STR_ANY_EXAMPLE, + NUM_STR_ANY_VALIDATE, +) + + +class AnoncredsAttrValue(BaseModel): + """Anoncreds attribute value.""" + + class Meta: + """Anoncreds attribute value.""" + + schema_class = "AnoncredsAttrValueSchema" + + def __init__( + self, raw: Optional[str] = None, encoded: Optional[str] = None, **kwargs + ): + """Initialize anoncreds (credential) attribute value.""" + super().__init__(**kwargs) + self.raw = raw + self.encoded = encoded + + +class AnoncredsAttrValueSchema(BaseModelSchema): + """Anoncreds attribute value schema.""" + + class Meta: + """Anoncreds attribute value schema metadata.""" + + model_class = AnoncredsAttrValue + unknown = EXCLUDE + + raw = fields.Str(required=True, metadata={"description": "Attribute raw value"}) + encoded = fields.Str( + required=True, + validate=NUM_STR_ANY_VALIDATE, + metadata={ + "description": "Attribute encoded value", + "example": NUM_STR_ANY_EXAMPLE, + }, + ) + + +class DictWithAnoncredsAttrValueSchema(fields.Dict): + """Dict with anoncreds attribute value schema.""" + + def __init__(self, **kwargs): + """Initialize the custom schema for a dictionary with AnoncredsAttrValue.""" + super().__init__( + keys=fields.Str(metadata={"description": "Attribute name"}), + values=fields.Nested(AnoncredsAttrValueSchema()), + **kwargs, + ) + + def _deserialize(self, value, attr, data, **kwargs): + """Deserialize dict with anoncreds attribute value.""" + if not isinstance(value, dict): + raise ValidationError("Value must be a dict.") + + errors = {} + anoncreds_attr_value_schema = AnoncredsAttrValueSchema() + + for k, v in value.items(): + if isinstance(v, dict): + validation_errors = anoncreds_attr_value_schema.validate(v) + if validation_errors: + errors[k] = validation_errors + + if errors: + raise ValidationError(errors) + + return value + + +class AnoncredsCredential(BaseModel): + """Anoncreds credential.""" + + class Meta: + """Anoncreds credential metadata.""" + + schema_class = "AnoncredsCredentialSchema" + + def __init__( + self, + schema_id: Optional[str] = None, + cred_def_id: Optional[str] = None, + rev_reg_id: Optional[str] = None, + values: Mapping[str, AnoncredsAttrValue] = None, + signature: Optional[Mapping] = None, + signature_correctness_proof: Optional[Mapping] = None, + rev_reg: Optional[Mapping] = None, + witness: Optional[Mapping] = None, + ): + """Initialize anoncreds credential.""" + self.schema_id = schema_id + self.cred_def_id = cred_def_id + self.rev_reg_id = rev_reg_id + self.values = values + self.signature = signature + self.signature_correctness_proof = signature_correctness_proof + self.rev_reg = rev_reg + self.witness = witness + + +class AnoncredsCredentialSchema(BaseModelSchema): + """Anoncreds credential schema.""" + + class Meta: + """Anoncreds credential schemametadata.""" + + model_class = AnoncredsCredential + unknown = EXCLUDE + + schema_id = fields.Str( + required=True, + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + cred_def_id = fields.Str( + required=True, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + rev_reg_id = fields.Str( + allow_none=True, + validate=ANONCREDS_REV_REG_ID_VALIDATE, + metadata={ + "description": "Revocation registry identifier", + "example": ANONCREDS_REV_REG_ID_EXAMPLE, + }, + ) + values = DictWithAnoncredsAttrValueSchema( + required=True, + metadata={"description": "Credential attributes"}, + ) + signature = fields.Dict( + required=True, metadata={"description": "Credential signature"} + ) + signature_correctness_proof = fields.Dict( + required=True, + metadata={"description": "Credential signature correctness proof"}, + ) + rev_reg = fields.Dict( + allow_none=True, metadata={"description": "Revocation registry state"} + ) + witness = fields.Dict( + allow_none=True, metadata={"description": "Witness for revocation proof"} + ) diff --git a/acapy_agent/anoncreds/models/anoncreds_cred_def.py b/acapy_agent/anoncreds/models/credential_definition.py similarity index 97% rename from acapy_agent/anoncreds/models/anoncreds_cred_def.py rename to acapy_agent/anoncreds/models/credential_definition.py index 17d41098e7..4e543eaf57 100644 --- a/acapy_agent/anoncreds/models/anoncreds_cred_def.py +++ b/acapy_agent/anoncreds/models/credential_definition.py @@ -9,9 +9,9 @@ from ...messaging.models.base import BaseModel, BaseModelSchema from ...messaging.valid import ( - INDY_CRED_DEF_ID_EXAMPLE, - INDY_OR_KEY_DID_EXAMPLE, - INDY_SCHEMA_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, NUM_STR_WHOLE_EXAMPLE, NUM_STR_WHOLE_VALIDATE, ) @@ -256,7 +256,7 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) @@ -264,7 +264,7 @@ class Meta: data_key="schemaId", metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, }, ) type = fields.Str(validate=OneOf(["CL"])) @@ -333,7 +333,7 @@ class Meta: credential_definition_id = fields.Str( metadata={ "description": "credential definition id", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, allow_none=True, ) @@ -434,7 +434,7 @@ class Meta: credential_definition_id = fields.Str( metadata={ "description": "credential definition id", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, ) credential_definition = fields.Nested( diff --git a/acapy_agent/anoncreds/models/credential_offer.py b/acapy_agent/anoncreds/models/credential_offer.py new file mode 100644 index 0000000000..c77419eba3 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential_offer.py @@ -0,0 +1,149 @@ +"""Anoncreds Credential Offer format for v2.0 of the issue-credential protocol.""" + +from typing import Optional, Sequence + +from marshmallow import EXCLUDE, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, +) + + +class AnoncredsKeyCorrectnessProof(BaseModel): + """Anoncreds key correctness proof.""" + + class Meta: + """AnoncredsKeyCorrectnessProof metadata.""" + + schema_class = "AnoncredsKeyCorrectnessProofSchema" + + def __init__( + self, + c: Optional[str] = None, + xz_cap: Optional[str] = None, + xr_cap: Sequence[Sequence[str]] = None, + **kwargs, + ): + """Initialize XR cap for anoncreds key correctness proof.""" + super().__init__(**kwargs) + + self.c = c + self.xz_cap = xz_cap + self.xr_cap = xr_cap + + +class AnoncredsCorrectnessProofSchema(BaseModelSchema): + """Anoncreds key correctness proof schema.""" + + class Meta: + """Anoncreds key correctness proof schema metadata.""" + + model_class = AnoncredsKeyCorrectnessProof + unknown = EXCLUDE + + c = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "c in key correctness proof", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) + xz_cap = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "xz_cap in key correctness proof", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) + xr_cap = fields.List( + fields.List( + fields.Str( + required=True, + metadata={ + "description": "xr_cap component values in key correctness proof" + }, + ), + required=True, + metadata={ + "description": "xr_cap components in key correctness proof", + "many": True, + }, + ), + required=True, + metadata={"description": "xr_cap in key correctness proof", "many": True}, + ) + + +class AnoncredsCredentialOffer(BaseModel): + """Anoncreds Credential Offer.""" + + class Meta: + """AnoncredsCredentialOffer metadata.""" + + schema_class = "AnoncredsCredentialOfferSchema" + + def __init__( + self, + schema_id: Optional[str] = None, + cred_def_id: Optional[str] = None, + nonce: Optional[str] = None, + key_correctness_proof: Optional[str] = None, + **kwargs, + ): + """Initialize values .""" + super().__init__(**kwargs) + self.schema_id = schema_id + self.cred_def_id = cred_def_id + self.nonce = nonce + self.key_correctness_proof = key_correctness_proof + + +class AnoncredsCredentialOfferSchema(BaseModelSchema): + """Anoncreds Credential Offer Schema.""" + + class Meta: + """AnoncredsCredentialOffer schema metadata.""" + + model_class = AnoncredsCredentialOffer + unknown = EXCLUDE + + schema_id = fields.Str( + required=True, + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + + cred_def_id = fields.Str( + required=True, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + + nonce = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "Nonce in credential abstract", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) + + key_correctness_proof = fields.Nested( + AnoncredsCorrectnessProofSchema(), + required=True, + metadata={"description": "Key correctness proof"}, + ) diff --git a/acapy_agent/anoncreds/models/credential_proposal.py b/acapy_agent/anoncreds/models/credential_proposal.py new file mode 100644 index 0000000000..3d41d08747 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential_proposal.py @@ -0,0 +1,58 @@ +"""Anoncreds credential definition proposal.""" + +import re + +from marshmallow import fields + +from ...core.profile import Profile +from ...messaging.models.openapi import OpenAPISchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_DID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, +) + + +class AnoncredsCredentialDefinitionProposal(OpenAPISchema): + """Query string parameters for credential definition searches.""" + + schema_id = fields.Str( + required=False, + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + issuer_id = fields.Str( + required=False, + validate=ANONCREDS_DID_VALIDATE, + metadata={"description": "Issuer DID", "example": ANONCREDS_DID_EXAMPLE}, + ) + cred_def_id = fields.Str( + required=False, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition id", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + + +CRED_DEF_TAGS = list( + vars(AnoncredsCredentialDefinitionProposal).get("_declared_fields", []) +) + +CRED_DEF_EVENT_PREFIX = "acapy::CRED_DEF::" +EVENT_LISTENER_PATTERN = re.compile(f"^{CRED_DEF_EVENT_PREFIX}(.*)?$") + + +async def notify_cred_def_event(profile: Profile, cred_def_id: str, meta_data: dict): + """Send notification for a cred def post-process event.""" + await profile.notify( + CRED_DEF_EVENT_PREFIX + cred_def_id, + meta_data, + ) diff --git a/acapy_agent/anoncreds/models/credential_request.py b/acapy_agent/anoncreds/models/credential_request.py new file mode 100644 index 0000000000..49fd58e996 --- /dev/null +++ b/acapy_agent/anoncreds/models/credential_request.py @@ -0,0 +1,81 @@ +"""Cred request artifacts to attach to RFC 453 messages.""" + +from typing import Mapping, Optional + +from marshmallow import EXCLUDE, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, + UUID4_EXAMPLE, +) + + +class AnoncredsCredRequest(BaseModel): + """Anoncreds credential request.""" + + class Meta: + """Anoncreds credential request metadata.""" + + schema_class = "AnoncredsCredRequestSchema" + + def __init__( + self, + prover_did: Optional[str] = None, + cred_def_id: Optional[str] = None, + blinded_ms: Optional[Mapping] = None, + blinded_ms_correctness_proof: Optional[Mapping] = None, + nonce: Optional[str] = None, + **kwargs, + ): + """Initialize anoncreds credential request.""" + super().__init__(**kwargs) + self.prover_did = prover_did + self.cred_def_id = cred_def_id + self.blinded_ms = blinded_ms + self.blinded_ms_correctness_proof = blinded_ms_correctness_proof + self.nonce = nonce + + +class AnoncredsCredRequestSchema(BaseModelSchema): + """Anoncreds credential request schema.""" + + class Meta: + """Anoncreds credential request schema metadata.""" + + model_class = AnoncredsCredRequest + unknown = EXCLUDE + + prover_did = fields.Str( + required=True, + metadata={ + "description": "Prover DID/Random String/UUID", + "example": UUID4_EXAMPLE, + }, + ) + cred_def_id = fields.Str( + required=True, + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + blinded_ms = fields.Dict( + required=True, metadata={"description": "Blinded master secret"} + ) + blinded_ms_correctness_proof = fields.Dict( + required=True, + metadata={"description": "Blinded master secret correctness proof"}, + ) + nonce = fields.Str( + required=True, + validate=NUM_STR_WHOLE_VALIDATE, + metadata={ + "description": "Nonce in credential request", + "example": NUM_STR_WHOLE_EXAMPLE, + }, + ) diff --git a/acapy_agent/anoncreds/models/non_rev_interval.py b/acapy_agent/anoncreds/models/non_rev_interval.py new file mode 100644 index 0000000000..a224891189 --- /dev/null +++ b/acapy_agent/anoncreds/models/non_rev_interval.py @@ -0,0 +1,78 @@ +"""Anoncreds non-revocation interval.""" + +from time import time +from typing import Optional + +from marshmallow import EXCLUDE, fields + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE + + +class AnoncredsNonRevocationInterval(BaseModel): + """Anoncreds non-revocation interval.""" + + class Meta: + """NonRevocationInterval metadata.""" + + schema_class = "AnoncredsNonRevocationIntervalSchema" + + def __init__(self, fro: Optional[int] = None, to: Optional[int] = None, **kwargs): + """Initialize non-revocation interval. + + Args: + fro: earliest time of interest + to: latest time of interest + kwargs: additional attributes + + """ + super().__init__(**kwargs) + self.fro = fro + self.to = to + + def covers(self, timestamp: Optional[int] = None) -> bool: + """Whether input timestamp (default now) lies within non-revocation interval. + + Args: + timestamp: time of interest + + Returns: + whether input time satisfies non-revocation interval + + """ + timestamp = timestamp or int(time()) + return (self.fro or 0) <= timestamp <= (self.to or timestamp) + + def timestamp(self) -> bool: + """Return a timestamp that the non-revocation interval covers.""" + return self.to or self.fro or int(time()) + + +class AnoncredsNonRevocationIntervalSchema(BaseModelSchema): + """Schema to allow serialization/deserialization of non-revocation intervals.""" + + class Meta: + """AnoncredsNonRevocationIntervalSchema metadata.""" + + model_class = AnoncredsNonRevocationInterval + unknown = EXCLUDE + + fro = fields.Int( + required=False, + data_key="from", + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": "Earliest time of interest in non-revocation interval", + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ) + to = fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": "Latest time of interest in non-revocation interval", + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ) diff --git a/acapy_agent/anoncreds/models/predicate.py b/acapy_agent/anoncreds/models/predicate.py new file mode 100644 index 0000000000..9810a7bb78 --- /dev/null +++ b/acapy_agent/anoncreds/models/predicate.py @@ -0,0 +1,82 @@ +"""Utilities for dealing with predicates.""" + +from collections import namedtuple +from enum import Enum +from typing import Any + +Relation = namedtuple("Relation", "fortran wql math yes no") + + +class Predicate(Enum): + """Enum for predicate types that anoncreds-sdk supports.""" + + LT = Relation( + "LT", + "$lt", + "<", + lambda x, y: Predicate.to_int(x) < Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) >= Predicate.to_int(y), + ) + LE = Relation( + "LE", + "$lte", + "<=", + lambda x, y: Predicate.to_int(x) <= Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) > Predicate.to_int(y), + ) + GE = Relation( + "GE", + "$gte", + ">=", + lambda x, y: Predicate.to_int(x) >= Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) < Predicate.to_int(y), + ) + GT = Relation( + "GT", + "$gt", + ">", + lambda x, y: Predicate.to_int(x) > Predicate.to_int(y), + lambda x, y: Predicate.to_int(x) <= Predicate.to_int(y), + ) + + @property + def fortran(self) -> str: + """Fortran nomenclature.""" + return self.value.fortran + + @property + def wql(self) -> str: + """WQL nomenclature.""" + return self.value.wql + + @property + def math(self) -> str: + """Mathematical nomenclature.""" + return self.value.math + + @staticmethod + def get(relation: str) -> "Predicate": + """Return enum instance corresponding to input relation string.""" + + for pred in Predicate: + if relation.upper() in ( + pred.value.fortran, + pred.value.wql.upper(), + pred.value.math, + ): + return pred + return None + + @staticmethod + def to_int(value: Any) -> int: + """Cast a value as its equivalent int for anoncreds predicate argument. + + Raise ValueError for any input but int, stringified int, or boolean. + + Args: + value: value to coerce + """ + + if isinstance(value, (bool, int)): + return int(value) + return int(str(value)) # kick out floats diff --git a/acapy_agent/anoncreds/models/presentation_request.py b/acapy_agent/anoncreds/models/presentation_request.py new file mode 100644 index 0000000000..05881dfdc8 --- /dev/null +++ b/acapy_agent/anoncreds/models/presentation_request.py @@ -0,0 +1,306 @@ +"""Classes to represent anoncreds presentation request.""" + +from typing import Mapping, Optional + +from marshmallow import ( + EXCLUDE, + Schema, + ValidationError, + fields, + validate, + validates_schema, +) + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.models.openapi import OpenAPISchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + INT_EPOCH_EXAMPLE, + INT_EPOCH_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, + NUM_STR_NATURAL_EXAMPLE, + NUM_STR_NATURAL_VALIDATE, + PREDICATE_EXAMPLE, + PREDICATE_VALIDATE, +) + + +class AnoncredsPresentationReqPredSpecSchema(OpenAPISchema): + """Schema for predicate specification in anoncreds proof request.""" + + name = fields.Str( + required=True, metadata={"example": "index", "description": "Attribute name"} + ) + p_type = fields.Str( + required=True, + validate=PREDICATE_VALIDATE, + metadata={ + "description": "Predicate type ('<', '<=', '>=', or '>')", + "example": PREDICATE_EXAMPLE, + }, + ) + p_value = fields.Int( + required=True, metadata={"description": "Threshold value", "strict": True} + ) + restrictions = fields.List( + fields.Dict( + keys=fields.Str( + validate=validate.Regexp( + "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" + "cred_def_id|attr::.+::value$" + ), + metadata={"example": "cred_def_id"}, + ), + values=fields.Str(metadata={"example": ANONCREDS_CRED_DEF_ID_EXAMPLE}), + ), + required=False, + metadata={ + "description": ( + "If present, credential must satisfy one of given restrictions: specify" + " schema_id, schema_issuer_did, schema_name, schema_version," + " issuer_did, cred_def_id, and/or attr::::value where" + " represents a credential attribute name" + ) + }, + ) + non_revoked = fields.Nested( + Schema.from_dict( + { + "from": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Earliest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + "to": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Latest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + }, + name="AnoncredsPresentationReqPredSpecNonRevokedSchema", + ), + allow_none=True, + required=False, + ) + + +class AnoncredsPresentationReqAttrSpecSchema(OpenAPISchema): + """Schema for attribute specification in anoncreds proof request.""" + + name = fields.Str( + required=False, + metadata={"example": "favouriteDrink", "description": "Attribute name"}, + ) + names = fields.List( + fields.Str(metadata={"example": "age"}), + required=False, + metadata={"description": "Attribute name group"}, + ) + restrictions = fields.List( + fields.Dict( + keys=fields.Str( + validate=validate.Regexp( + "^schema_id|schema_issuer_did|schema_name|schema_version|issuer_did|" + "cred_def_id|attr::.+::value$" + ), + metadata={"example": "cred_def_id"}, + ), + values=fields.Str(metadata={"example": ANONCREDS_CRED_DEF_ID_EXAMPLE}), + ), + required=False, + metadata={ + "description": ( + "If present, credential must satisfy one of given restrictions: specify" + " schema_id, schema_issuer_did, schema_name, schema_version," + " issuer_did, cred_def_id, and/or attr::::value where" + " represents a credential attribute name" + ) + }, + ) + non_revoked = fields.Nested( + Schema.from_dict( + { + "from": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Earliest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + "to": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Latest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + }, + name="AnoncredsPresentationReqAttrSpecNonRevokedSchema", + ), + allow_none=True, + required=False, + ) + + @validates_schema + def validate_fields(self, data, **kwargs): + """Validate schema fields. + + Data must have exactly one of name or names; if names then restrictions are + mandatory. + + Args: + data: The data to validate + kwargs: Additional keyword arguments + + Raises: + ValidationError: if data has both or neither of name and names + + """ + if ("name" in data) == ("names" in data): + raise ValidationError( + "Attribute specification must have either name or names but not both" + ) + restrictions = data.get("restrictions") + if ("names" in data) and (not restrictions or all(not r for r in restrictions)): + raise ValidationError( + "Attribute specification on 'names' must have non-empty restrictions" + ) + + +class AnoncredsPresentationRequest(BaseModel): + """anoncreds proof request.""" + + class Meta: + """Anoncreds proof request metadata.""" + + schema_class = "AnoncredsPresentationRequestSchema" + + def __init__( + self, + nonce: Optional[str] = None, + name: Optional[str] = None, + version: Optional[str] = None, + requested_attributes: Optional[Mapping] = None, + requested_predicates: Optional[Mapping] = None, + non_revoked: Optional[Mapping] = None, + **kwargs, + ): + """Initialize anoncreds cred abstract object. + + Args: + nonce (str): The nonce value. + name (str): The name of the proof request. + version (str): The version of the proof request. + requested_attributes (Mapping): A mapping of attribute names to attribute + constraints. + requested_predicates (Mapping): A mapping of predicate names to predicate + constraints. + non_revoked (Mapping): A mapping of non-revocation timestamps. + kwargs: Keyword arguments for BaseModel + + """ + super().__init__(**kwargs) + self.nonce = nonce + self.name = name + self.version = version + self.requested_attributes = requested_attributes + self.requested_predicates = requested_predicates + self.non_revoked = non_revoked + + +class AnoncredsPresentationRequestSchema(BaseModelSchema): + """Schema for anoncreds proof request.""" + + class Meta: + """Anoncreds proof request schema metadata.""" + + model_class = AnoncredsPresentationRequest + unknown = EXCLUDE + + nonce = fields.Str( + required=False, + validate=NUM_STR_NATURAL_VALIDATE, + metadata={"description": "Nonce", "example": NUM_STR_NATURAL_EXAMPLE}, + ) + name = fields.Str( + required=False, + dump_default="Proof request", + metadata={"description": "Proof request name", "example": "Proof request"}, + ) + version = fields.Str( + required=False, + dump_default="1.0", + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Proof request version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, + ) + requested_attributes = fields.Dict( + required=True, + keys=fields.Str( + metadata={"decription": "Attribute referent", "example": "0_legalname_uuid"} + ), + values=fields.Nested(AnoncredsPresentationReqAttrSpecSchema()), + metadata={"description": "Requested attribute specifications of proof request"}, + ) + requested_predicates = fields.Dict( + required=True, + keys=fields.Str( + metadata={"description": "Predicate referent", "example": "0_age_GE_uuid"} + ), + values=fields.Nested(AnoncredsPresentationReqPredSpecSchema()), + metadata={"description": "Requested predicate specifications of proof request"}, + ) + non_revoked = fields.Nested( + Schema.from_dict( + { + "from": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Earliest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + "to": fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": ( + "Latest time of interest in non-revocation interval" + ), + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ), + }, + name="AnoncredPresentationRequestNonRevokedSchema", + ), + allow_none=True, + required=False, + ) diff --git a/acapy_agent/anoncreds/models/proof.py b/acapy_agent/anoncreds/models/proof.py new file mode 100644 index 0000000000..817b947cc5 --- /dev/null +++ b/acapy_agent/anoncreds/models/proof.py @@ -0,0 +1,749 @@ +"""Marshmallow bindings for anoncreds proofs.""" + +from typing import Mapping, Optional, Sequence + +from marshmallow import EXCLUDE, fields, validate + +from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_VALIDATE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ANONCREDS_REV_REG_ID_VALIDATE, + ANONCREDS_SCHEMA_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_VALIDATE, + INT_EPOCH_EXAMPLE, + INT_EPOCH_VALIDATE, + NUM_STR_ANY_EXAMPLE, + NUM_STR_ANY_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, +) +from ...utils.tracing import AdminAPIMessageTracingSchema +from .predicate import Predicate +from .requested_credentials import ( + AnoncredsRequestedCredsRequestedAttrSchema, + AnoncredsRequestedCredsRequestedPredSchema, +) + + +class AnoncredsEQProof(BaseModel): + """Equality proof for anoncreds primary proof.""" + + class Meta: + """Equality proof metadata.""" + + schema_class = "AnoncredsEQProofMeta" + + def __init__( + self, + revealed_attrs: Mapping[str, str] = None, + a_prime: Optional[str] = None, + e: Optional[str] = None, + v: Optional[str] = None, + m: Mapping[str, str] = None, + m2: Optional[str] = None, + **kwargs, + ): + """Initialize equality proof object.""" + super().__init__(**kwargs) + self.revealed_attrs = revealed_attrs + self.a_prime = a_prime + self.e = e + self.v = v + self.m = m + self.m2 = m2 + + +class AnoncredsEQProofSchema(BaseModelSchema): + """Anoncreds equality proof schema.""" + + class Meta: + """Anoncreds equality proof metadata.""" + + model_class = AnoncredsEQProof + unknown = EXCLUDE + + revealed_attrs = fields.Dict( + keys=fields.Str(metadata={"example": "preference"}), + values=fields.Str( + validate=NUM_STR_ANY_VALIDATE, metadata={"example": NUM_STR_ANY_EXAMPLE} + ), + ) + a_prime = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + e = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + v = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + m = fields.Dict( + keys=fields.Str(metadata={"example": "master_secret"}), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + m2 = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + + +class AnoncredsGEProofPred(BaseModel): + """Anoncreds GE proof predicate.""" + + class Meta: + """Anoncreds GE proof predicate metadata.""" + + schema_class = "AnoncredsGEProofPredSchema" + + def __init__( + self, + attr_name: Optional[str] = None, + p_type: Optional[str] = None, + value: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds GE proof predicate.""" + super().__init__(**kwargs) + self.attr_name = attr_name + self.p_type = p_type + self.value = value + + +class AnoncredsGEProofPredSchema(BaseModelSchema): + """Anoncreds GE proof predicate schema.""" + + class Meta: + """Anoncreds GE proof predicate metadata.""" + + model_class = AnoncredsGEProofPred + unknown = EXCLUDE + + attr_name = fields.Str( + metadata={"description": "Attribute name, anoncreds-canonicalized"} + ) + p_type = fields.Str( + validate=validate.OneOf([p.fortran for p in Predicate]), + metadata={"description": "Predicate type"}, + ) + value = fields.Integer( + metadata={"strict": True, "description": "Predicate threshold value"} + ) + + +class AnoncredsGEProof(BaseModel): + """Greater-than-or-equal-to proof for anoncreds primary proof.""" + + class Meta: + """GE proof metadata.""" + + schema_class = "AnoncredsGEProofMeta" + + def __init__( + self, + u: Mapping[str, str] = None, + r: Mapping[str, str] = None, + mj: Optional[str] = None, + alpha: Optional[str] = None, + t: Mapping[str, str] = None, + predicate: Optional[AnoncredsGEProofPred] = None, + **kwargs, + ): + """Initialize GE proof object.""" + super().__init__(**kwargs) + self.u = u + self.r = r + self.mj = mj + self.alpha = alpha + self.t = t + self.predicate = predicate + + +class AnoncredsGEProofSchema(BaseModelSchema): + """Anoncreds GE proof schema.""" + + class Meta: + """Anoncreds GE proof schema metadata.""" + + model_class = AnoncredsGEProof + unknown = EXCLUDE + + u = fields.Dict( + keys=fields.Str(), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + r = fields.Dict( + keys=fields.Str(), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + mj = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + alpha = fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ) + t = fields.Dict( + keys=fields.Str(), + values=fields.Str( + validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE} + ), + ) + predicate = fields.Nested(AnoncredsGEProofPredSchema) + + +class AnoncredsPrimaryProof(BaseModel): + """Anoncreds primary proof.""" + + class Meta: + """Anoncreds primary proof metadata.""" + + schema_class = "AnoncredsPrimaryProofSchema" + + def __init__( + self, + eq_proof: Optional[AnoncredsEQProof] = None, + ge_proofs: Sequence[AnoncredsGEProof] = None, + **kwargs, + ): + """Initialize anoncreds primary proof.""" + super().__init__(**kwargs) + self.eq_proof = eq_proof + self.ge_proofs = ge_proofs + + +class AnoncredsPrimaryProofSchema(BaseModelSchema): + """Anoncreds primary proof schema.""" + + class Meta: + """Anoncreds primary proof schema metadata.""" + + model_class = AnoncredsPrimaryProof + unknown = EXCLUDE + + eq_proof = fields.Nested( + AnoncredsEQProofSchema, + allow_none=True, + metadata={"description": "Anoncreds equality proof"}, + ) + ge_proofs = fields.Nested( + AnoncredsGEProofSchema, + many=True, + allow_none=True, + metadata={"description": "Anoncreds GE proofs"}, + ) + + +class AnoncredsNonRevocProof(BaseModel): + """Anoncreds non-revocation proof.""" + + class Meta: + """Anoncreds non-revocation proof metadata.""" + + schema_class = "AnoncredsNonRevocProofSchema" + + def __init__( + self, + x_list: Optional[Mapping] = None, + c_list: Optional[Mapping] = None, + **kwargs, + ): + """Initialize anoncreds non-revocation proof.""" + super().__init__(**kwargs) + self.x_list = x_list + self.c_list = c_list + + +class AnoncredsNonRevocProofSchema(BaseModelSchema): + """Anoncreds non-revocation proof schema.""" + + class Meta: + """Anoncreds non-revocation proof schema metadata.""" + + model_class = AnoncredsNonRevocProof + unknown = EXCLUDE + + x_list = fields.Dict(keys=fields.Str(), values=fields.Str()) + c_list = fields.Dict(keys=fields.Str(), values=fields.Str()) + + +class AnoncredsProofProofProofsProof(BaseModel): + """Anoncreds proof.proof.proofs constituent proof.""" + + class Meta: + """Anoncreds proof.proof.proofs constituent proof schema.""" + + schema_class = "AnoncredsProofProofProofsProofSchema" + + def __init__( + self, + primary_proof: Optional[AnoncredsPrimaryProof] = None, + non_revoc_proof: Optional[AnoncredsNonRevocProof] = None, + **kwargs, + ): + """Initialize proof.proof.proofs constituent proof.""" + super().__init__(**kwargs) + self.primary_proof = primary_proof + self.non_revoc_proof = non_revoc_proof + + +class AnoncredsProofProofProofsProofSchema(BaseModelSchema): + """Anoncreds proof.proof.proofs constituent proof schema.""" + + class Meta: + """Anoncreds proof.proof.proofs constituent proof schema metadata.""" + + model_class = AnoncredsProofProofProofsProof + unknown = EXCLUDE + + primary_proof = fields.Nested( + AnoncredsPrimaryProofSchema, metadata={"description": "Anoncreds primary proof"} + ) + non_revoc_proof = fields.Nested( + AnoncredsNonRevocProofSchema, + allow_none=True, + metadata={"description": "Anoncreds non-revocation proof"}, + ) + + +class AnoncredsProofProofAggregatedProof(BaseModel): + """Anoncreds proof.proof aggregated proof.""" + + class Meta: + """Anoncreds proof.proof aggregated proof metadata.""" + + schema_class = "AnoncredsProofProofAggregatedProofSchema" + + def __init__( + self, + c_hash: Optional[str] = None, + c_list: Sequence[Sequence[int]] = None, + **kwargs, + ): + """Initialize anoncreds proof.proof agreggated proof.""" + super().__init__(**kwargs) + self.c_hash = c_hash + self.c_list = c_list + + +class AnoncredsProofProofAggregatedProofSchema(BaseModelSchema): + """Anoncreds proof.proof aggregated proof schema.""" + + class Meta: + """Anoncreds proof.proof aggregated proof schema metadata.""" + + model_class = AnoncredsProofProofAggregatedProof + unknown = EXCLUDE + + c_hash = fields.Str(metadata={"description": "c_hash value"}) + c_list = fields.List( + fields.List(fields.Int(metadata={"strict": True})), + metadata={"description": "c_list value"}, + ) + + +class AnoncredsProofProof(BaseModel): + """Anoncreds proof.proof content.""" + + class Meta: + """Anoncreds proof.proof content metadata.""" + + schema_class = "AnoncredsProofProofSchema" + + def __init__( + self, + proofs: Sequence[AnoncredsProofProofProofsProof] = None, + aggregated_proof: Optional[AnoncredsProofProofAggregatedProof] = None, + **kwargs, + ): + """Initialize anoncreds proof.proof content.""" + super().__init__(**kwargs) + self.proofs = proofs + self.aggregated_proof = aggregated_proof + + +class AnoncredsProofProofSchema(BaseModelSchema): + """Anoncreds proof.proof content schema.""" + + class Meta: + """Anoncreds proof.proof content schema metadata.""" + + model_class = AnoncredsProofProof + unknown = EXCLUDE + + proofs = fields.Nested( + AnoncredsProofProofProofsProofSchema, + many=True, + metadata={"description": "Anoncreds proof proofs"}, + ) + aggregated_proof = fields.Nested( + AnoncredsProofProofAggregatedProofSchema, + metadata={"description": "Anoncreds proof aggregated proof"}, + ) + + +class RawEncoded(BaseModel): + """Raw and encoded attribute values.""" + + class Meta: + """Raw and encoded attribute values metadata.""" + + schema_class = "RawEncodedSchema" + + def __init__( + self, + raw: Optional[str] = None, + encoded: Optional[str] = None, + **kwargs, + ): + """Initialize raw and encoded attribute values.""" + super().__init__(**kwargs) + self.raw = raw + self.encoded = encoded + + +class RawEncodedSchema(BaseModelSchema): + """Raw and encoded attribute values schema.""" + + class Meta: + """Raw and encoded attribute values schema metadata.""" + + model_class = RawEncoded + unknown = EXCLUDE + + raw = fields.Str(metadata={"description": "Raw value"}) + encoded = fields.Str( + validate=NUM_STR_ANY_VALIDATE, + metadata={"description": "Encoded value", "example": NUM_STR_ANY_EXAMPLE}, + ) + + +class AnoncredsProofRequestedProofRevealedAttr(RawEncoded): + """Anoncreds proof requested proof revealed attr.""" + + class Meta: + """Anoncreds proof requested proof revealed attr metadata.""" + + schema_class = "AnoncredsProofRequestedProofRevealedAttrSchema" + + def __init__( + self, + sub_proof_index: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof revealed attr.""" + super().__init__(**kwargs) + self.sub_proof_index = sub_proof_index + + +class AnoncredsProofRequestedProofRevealedAttrSchema(RawEncodedSchema): + """Anoncreds proof requested proof revealed attr schema.""" + + class Meta: + """Anoncreds proof requested proof revealed attr schema metadata.""" + + model_class = AnoncredsProofRequestedProofRevealedAttr + unknown = EXCLUDE + + sub_proof_index = fields.Int( + metadata={"strict": True, "description": "Sub-proof index"} + ) + + +class AnoncredsProofRequestedProofRevealedAttrGroup(BaseModel): + """Anoncreds proof requested proof revealed attr group.""" + + class Meta: + """Anoncreds proof requested proof revealed attr group metadata.""" + + schema_class = "AnoncredsProofRequestedProofRevealedAttrGroupSchema" + + def __init__( + self, + sub_proof_index: Optional[int] = None, + values: Mapping[str, RawEncoded] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof revealed attr.""" + super().__init__(**kwargs) + self.sub_proof_index = sub_proof_index + self.values = values + + +class AnoncredsProofRequestedProofRevealedAttrGroupSchema(BaseModelSchema): + """Anoncreds proof requested proof revealed attr group schema.""" + + class Meta: + """Anoncreds proof requested proof revealed attr group schema metadata.""" + + model_class = AnoncredsProofRequestedProofRevealedAttrGroup + unknown = EXCLUDE + + sub_proof_index = fields.Int( + metadata={"strict": True, "description": "Sub-proof index"} + ) + values = fields.Dict( + keys=fields.Str(), + values=fields.Nested(RawEncodedSchema), + metadata={ + "description": "Anoncreds proof requested proof revealed attr groups group value" # noqa: E501 + }, + ) + + +class AnoncredsProofRequestedProofPredicate(BaseModel): + """Anoncreds proof requested proof predicate.""" + + class Meta: + """Anoncreds proof requested proof requested proof predicate metadata.""" + + schema_class = "AnoncredsProofRequestedProofPredicateSchema" + + def __init__( + self, + sub_proof_index: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof predicate.""" + super().__init__(**kwargs) + self.sub_proof_index = sub_proof_index + + +class AnoncredsProofRequestedProofPredicateSchema(BaseModelSchema): + """Anoncreds proof requested prrof predicate schema.""" + + class Meta: + """Anoncreds proof requested proof requested proof predicate schema metadata.""" + + model_class = AnoncredsProofRequestedProofPredicate + unknown = EXCLUDE + + sub_proof_index = fields.Int( + metadata={"strict": True, "description": "Sub-proof index"} + ) + + +class AnoncredsProofRequestedProof(BaseModel): + """Anoncreds proof.requested_proof content.""" + + class Meta: + """Anoncreds proof.requested_proof content metadata.""" + + schema_class = "AnoncredsProofRequestedProofSchema" + + def __init__( + self, + revealed_attrs: Mapping[str, AnoncredsProofRequestedProofRevealedAttr] = None, + revealed_attr_groups: Mapping[ + str, + AnoncredsProofRequestedProofRevealedAttrGroup, + ] = None, + self_attested_attrs: Optional[Mapping] = None, + unrevealed_attrs: Optional[Mapping] = None, + predicates: Mapping[str, AnoncredsProofRequestedProofPredicate] = None, + **kwargs, + ): + """Initialize anoncreds proof requested proof.""" + super().__init__(**kwargs) + self.revealed_attrs = revealed_attrs + self.revealed_attr_groups = revealed_attr_groups + self.self_attested_attrs = self_attested_attrs + self.unrevealed_attrs = unrevealed_attrs + self.predicates = predicates + + +class AnoncredsProofRequestedProofSchema(BaseModelSchema): + """Anoncreds proof requested proof schema.""" + + class Meta: + """Anoncreds proof requested proof schema metadata.""" + + model_class = AnoncredsProofRequestedProof + unknown = EXCLUDE + + revealed_attrs = fields.Dict( + keys=fields.Str(), + values=fields.Nested(AnoncredsProofRequestedProofRevealedAttrSchema), + allow_none=True, + metadata={"description": "Proof requested proof revealed attributes"}, + ) + revealed_attr_groups = fields.Dict( + keys=fields.Str(), + values=fields.Nested(AnoncredsProofRequestedProofRevealedAttrGroupSchema), + allow_none=True, + metadata={"description": "Proof requested proof revealed attribute groups"}, + ) + self_attested_attrs = fields.Dict( + metadata={"description": "Proof requested proof self-attested attributes"} + ) + unrevealed_attrs = fields.Dict(metadata={"description": "Unrevealed attributes"}) + predicates = fields.Dict( + keys=fields.Str(), + values=fields.Nested(AnoncredsProofRequestedProofPredicateSchema), + metadata={"description": "Proof requested proof predicates."}, + ) + + +class AnoncredsProofIdentifier(BaseModel): + """Anoncreds proof identifier.""" + + class Meta: + """Anoncreds proof identifier metadata.""" + + schema_class = "AnoncredsProofIdentifierSchema" + + def __init__( + self, + schema_id: Optional[str] = None, + cred_def_id: Optional[str] = None, + rev_reg_id: Optional[str] = None, + timestamp: Optional[int] = None, + **kwargs, + ): + """Initialize anoncreds proof identifier.""" + super().__init__(**kwargs) + self.schema_id = schema_id + self.cred_def_id = cred_def_id + self.rev_reg_id = rev_reg_id + self.timestamp = timestamp + + +class AnoncredsProofIdentifierSchema(BaseModelSchema): + """Anoncreds proof identifier schema.""" + + class Meta: + """Anoncreds proof identifier schema metadata.""" + + model_class = AnoncredsProofIdentifier + unknown = EXCLUDE + + schema_id = fields.Str( + validate=ANONCREDS_SCHEMA_ID_VALIDATE, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + cred_def_id = fields.Str( + validate=ANONCREDS_CRED_DEF_ID_VALIDATE, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) + rev_reg_id = fields.Str( + allow_none=True, + validate=ANONCREDS_REV_REG_ID_VALIDATE, + metadata={ + "description": "Revocation registry identifier", + "example": ANONCREDS_REV_REG_ID_EXAMPLE, + }, + ) + timestamp = fields.Int( + allow_none=True, + validate=INT_EPOCH_VALIDATE, + metadata={ + "strict": True, + "description": "Timestamp epoch", + "example": INT_EPOCH_EXAMPLE, + }, + ) + + +class AnoncredsProof(BaseModel): + """Anoncreds proof.""" + + class Meta: + """Anoncreds proof metadata.""" + + schema_class = "AnoncredsProofSchema" + + def __init__( + self, + proof: Optional[AnoncredsProofProof] = None, + requested_proof: Optional[AnoncredsProofRequestedProof] = None, + identifiers: Sequence[AnoncredsProofIdentifier] = None, + **kwargs, + ): + """Initialize anoncreds proof.""" + super().__init__(**kwargs) + self.proof = proof + self.requested_proof = requested_proof + self.identifiers = identifiers + + +class AnoncredsProofSchema(BaseModelSchema): + """Anoncreds proof schema.""" + + class Meta: + """Anoncreds proof schema metadata.""" + + model_class = AnoncredsProof + unknown = EXCLUDE + + proof = fields.Nested( + AnoncredsProofProofSchema, + metadata={"description": "Anoncreds proof.proof content"}, + ) + requested_proof = fields.Nested( + AnoncredsProofRequestedProofSchema, + metadata={"description": "Anoncreds proof.requested_proof content"}, + ) + identifiers = fields.Nested( + AnoncredsProofIdentifierSchema, + many=True, + metadata={"description": "Anoncreds proof.identifiers content"}, + ) + + +class AnoncredsPresSpecSchema(AdminAPIMessageTracingSchema): + """Request schema for anoncreds proof specification to send as presentation.""" + + self_attested_attributes = fields.Dict( + required=True, + keys=fields.Str(metadata={"example": "attr_name"}), + values=fields.Str( + metadata={ + "example": "self_attested_value", + "description": ( + "Self-attested attribute values to use in requested-credentials" + " structure for proof construction" + ), + } + ), + metadata={"description": "Self-attested attributes to build into proof"}, + ) + requested_attributes = fields.Dict( + required=True, + keys=fields.Str(metadata={"example": "attr_referent"}), + values=fields.Nested(AnoncredsRequestedCredsRequestedAttrSchema), + metadata={ + "description": ( + "Nested object mapping proof request attribute referents to" + " requested-attribute specifiers" + ) + }, + ) + requested_predicates = fields.Dict( + required=True, + keys=fields.Str(metadata={"example": "pred_referent"}), + values=fields.Nested(AnoncredsRequestedCredsRequestedPredSchema), + metadata={ + "description": ( + "Nested object mapping proof request predicate referents to" + " requested-predicate specifiers" + ) + }, + ) + trace = fields.Bool( + required=False, + metadata={ + "description": "Whether to trace event (default false)", + "example": False, + }, + ) diff --git a/acapy_agent/anoncreds/models/requested_credentials.py b/acapy_agent/anoncreds/models/requested_credentials.py new file mode 100644 index 0000000000..ac0fcf3d33 --- /dev/null +++ b/acapy_agent/anoncreds/models/requested_credentials.py @@ -0,0 +1,47 @@ +"""Admin routes for presentations.""" + +from marshmallow import fields + +from ...messaging.models.openapi import OpenAPISchema +from ...messaging.valid import INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE + + +class AnoncredsRequestedCredsRequestedAttrSchema(OpenAPISchema): + """Schema for requested attributes within anoncreds requested creds structure.""" + + cred_id = fields.Str( + required=True, + metadata={ + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description": ( + "Wallet credential identifier (typically but not necessarily a UUID)" + ), + }, + ) + revealed = fields.Bool( + dump_default=True, + metadata={"description": "Whether to reveal attribute in proof (default true)"}, + ) + + +class AnoncredsRequestedCredsRequestedPredSchema(OpenAPISchema): + """Schema for requested predicates within anoncreds requested creds structure.""" + + cred_id = fields.Str( + required=True, + metadata={ + "description": ( + "Wallet credential identifier (typically but not necessarily a UUID)" + ), + "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + }, + ) + timestamp = fields.Int( + required=False, + validate=INT_EPOCH_VALIDATE, + metadata={ + "description": "Epoch timestamp of interest for non-revocation proof", + "strict": True, + "example": INT_EPOCH_EXAMPLE, + }, + ) diff --git a/acapy_agent/anoncreds/models/anoncreds_revocation.py b/acapy_agent/anoncreds/models/revocation.py similarity index 96% rename from acapy_agent/anoncreds/models/anoncreds_revocation.py rename to acapy_agent/anoncreds/models/revocation.py index cc90469eac..94c75a525a 100644 --- a/acapy_agent/anoncreds/models/anoncreds_revocation.py +++ b/acapy_agent/anoncreds/models/revocation.py @@ -7,15 +7,14 @@ from marshmallow.validate import OneOf from typing_extensions import Literal -from acapy_agent.messaging.valid import ( - INDY_CRED_DEF_ID_EXAMPLE, - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_OR_KEY_DID_EXAMPLE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_REV_REG_ID_EXAMPLE, -) - from ...messaging.models.base import BaseModel, BaseModelSchema +from ...messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ISO8601_DATETIME_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, +) class RevRegDefValue(BaseModel): @@ -60,7 +59,7 @@ class Meta: unknown = EXCLUDE public_keys = fields.Dict( - data_key="publicKeys", metadata={"example": INDY_RAW_PUBLIC_KEY_EXAMPLE} + data_key="publicKeys", metadata={"example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE} ) max_cred_num = fields.Int(data_key="maxCredNum", metadata={"example": 777}) tails_location = fields.Str( @@ -131,7 +130,7 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) @@ -139,7 +138,7 @@ class Meta: cred_def_id = fields.Str( metadata={ "description": "Credential definition identifier", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, data_key="credDefId", ) @@ -209,7 +208,7 @@ class Meta: revocation_registry_definition_id = fields.Str( metadata={ "description": "revocation registry definition id", - "example": INDY_REV_REG_ID_EXAMPLE, + "example": ANONCREDS_REV_REG_ID_EXAMPLE, } ) revocation_registry_definition = fields.Nested( @@ -380,14 +379,14 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) rev_reg_def_id = fields.Str( metadata={ "description": "The ID of the revocation registry definition", - "example": INDY_REV_REG_ID_EXAMPLE, + "example": ANONCREDS_REV_REG_ID_EXAMPLE, }, data_key="revRegDefId", ) @@ -409,7 +408,7 @@ class Meta: timestamp = fields.Int( metadata={ "description": "Timestamp at which revocation list is applicable", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, required=False, ) diff --git a/acapy_agent/anoncreds/models/anoncreds_schema.py b/acapy_agent/anoncreds/models/schema.py similarity index 95% rename from acapy_agent/anoncreds/models/anoncreds_schema.py rename to acapy_agent/anoncreds/models/schema.py index b2383ff60f..6a3f56bc03 100644 --- a/acapy_agent/anoncreds/models/anoncreds_schema.py +++ b/acapy_agent/anoncreds/models/schema.py @@ -7,7 +7,10 @@ from marshmallow.validate import OneOf from ...messaging.models.base import BaseModel, BaseModelSchema -from ...messaging.valid import INDY_OR_KEY_DID_EXAMPLE, INDY_SCHEMA_ID_EXAMPLE +from ...messaging.valid import ( + ANONCREDS_DID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, +) class AnonCredsSchema(BaseModel): @@ -58,7 +61,7 @@ class Meta: issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) @@ -129,7 +132,10 @@ class Meta: schema_value = fields.Nested(AnonCredsSchemaSchema(), data_key="schema") schema_id = fields.Str( - metadata={"description": "Schema identifier", "example": INDY_SCHEMA_ID_EXAMPLE} + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + } ) resolution_metadata = fields.Dict() schema_metadata = fields.Dict() @@ -185,7 +191,7 @@ class Meta: schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) schema_value = fields.Nested(AnonCredsSchemaSchema(), data_key="schema") diff --git a/acapy_agent/anoncreds/models/utils.py b/acapy_agent/anoncreds/models/utils.py new file mode 100644 index 0000000000..51f140844f --- /dev/null +++ b/acapy_agent/anoncreds/models/utils.py @@ -0,0 +1,99 @@ +"""Utilities to deal with anoncreds objects.""" + +from ..holder import AnonCredsHolder + + +def _get_value_error_msg(proof_request: dict, referent: str) -> str: + return ( + "Could not automatically construct presentation for " + + f"presentation request {proof_request['name']}" + + f":{proof_request['version']} because referent " + + f"{referent} did not produce any credentials." + ) + + +async def get_requested_creds_from_proof_request_preview( + proof_request: dict, + *, + holder: AnonCredsHolder, +): + """Build anoncreds requested-credentials structure. + + Given input proof request and presentation preview, use credentials in + holder's wallet to build anoncreds requested credentials structure for input + to proof creation. + + Args: + proof_request: anoncreds proof request + preview: preview from presentation proposal, if applicable + holder: holder injected into current context + + """ + req_creds = { + "self_attested_attributes": {}, + "requested_attributes": {}, + "requested_predicates": {}, + } + + for referent, _ in proof_request["requested_attributes"].items(): + credentials = await holder.get_credentials_for_presentation_request_by_referent( + presentation_request=proof_request, + referents=(referent,), + start=0, + count=100, + ) + if not credentials: + raise ValueError(_get_value_error_msg(proof_request, referent)) + + cred_match = credentials[0] # holder sorts + + if "restrictions" in proof_request["requested_attributes"][referent]: + req_creds["requested_attributes"][referent] = { + "cred_id": cred_match["cred_info"]["referent"], + "revealed": True, + } + else: + req_creds["self_attested_attributes"][referent] = cred_match["cred_info"][ + "attrs" + ][proof_request["requested_attributes"][referent]["name"]] + + for referent in proof_request["requested_predicates"]: + credentials = await holder.get_credentials_for_presentation_request_by_referent( + presentation_request=proof_request, + referents=(referent,), + start=0, + count=100, + ) + if not credentials: + raise ValueError(_get_value_error_msg(proof_request, referent)) + + cred_match = credentials[0] # holder sorts + if "restrictions" in proof_request["requested_predicates"][referent]: + req_creds["requested_predicates"][referent] = { + "cred_id": cred_match["cred_info"]["referent"], + "revealed": True, + } + else: + req_creds["self_attested_attributes"][referent] = cred_match["cred_info"][ + "attrs" + ][proof_request["requested_predicates"][referent]["name"]] + + return req_creds + + +def extract_non_revocation_intervals_from_proof_request(proof_req: dict): + """Return non-revocation intervals by requested item referent in proof request.""" + non_revoc_intervals = {} + for req_item_type in ("requested_attributes", "requested_predicates"): + for reft, req_item in proof_req[req_item_type].items(): + interval = req_item.get( + "non_revoked", + proof_req.get("non_revoked"), + ) + if interval: + timestamp_from = interval.get("from") + timestamp_to = interval.get("to") + if (timestamp_to is not None) and timestamp_from == timestamp_to: + interval["from"] = 0 # accommodate verify=False if from=to + non_revoc_intervals[reft] = interval + return non_revoc_intervals diff --git a/acapy_agent/anoncreds/registry.py b/acapy_agent/anoncreds/registry.py index 79aba036cc..c355b447cd 100644 --- a/acapy_agent/anoncreds/registry.py +++ b/acapy_agent/anoncreds/registry.py @@ -11,8 +11,8 @@ BaseAnonCredsRegistrar, BaseAnonCredsResolver, ) -from .models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult -from .models.anoncreds_revocation import ( +from .models.credential_definition import CredDef, CredDefResult, GetCredDefResult +from .models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, @@ -20,7 +20,7 @@ RevRegDef, RevRegDefResult, ) -from .models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult +from .models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult LOGGER = logging.getLogger(__name__) diff --git a/acapy_agent/anoncreds/revocation.py b/acapy_agent/anoncreds/revocation.py index 96d2795246..e9cc88293f 100644 --- a/acapy_agent/anoncreds/revocation.py +++ b/acapy_agent/anoncreds/revocation.py @@ -26,8 +26,6 @@ from requests import RequestException, Session from uuid_utils import uuid4 -from acapy_agent.anoncreds.models.anoncreds_cred_def import CredDef - from ..askar.profile_anon import AskarAnoncredsProfile, AskarAnoncredsProfileSession from ..core.error import BaseError from ..core.event_bus import Event, EventBus @@ -43,7 +41,8 @@ STATE_FINISHED, AnonCredsIssuer, ) -from .models.anoncreds_revocation import ( +from .models.credential_definition import CredDef +from .models.revocation import ( RevList, RevListResult, RevListState, diff --git a/acapy_agent/anoncreds/routes.py b/acapy_agent/anoncreds/routes.py index 9cf1d6ad98..9a8fe04669 100644 --- a/acapy_agent/anoncreds/routes.py +++ b/acapy_agent/anoncreds/routes.py @@ -16,13 +16,12 @@ from ..admin.decorators.auth import tenant_authentication from ..admin.request_context import AdminRequestContext from ..core.event_bus import EventBus -from ..ledger.error import LedgerError from ..messaging.models.openapi import OpenAPISchema from ..messaging.valid import ( - INDY_CRED_DEF_ID_EXAMPLE, - INDY_OR_KEY_DID_EXAMPLE, - INDY_REV_REG_ID_EXAMPLE, - INDY_SCHEMA_ID_EXAMPLE, + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_DID_EXAMPLE, + ANONCREDS_REV_REG_ID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, UUIDFour, ) from ..revocation.error import RevocationNotSupportedError @@ -35,9 +34,9 @@ AnonCredsResolutionError, ) from .issuer import AnonCredsIssuer, AnonCredsIssuerError -from .models.anoncreds_cred_def import CredDefResultSchema, GetCredDefResultSchema -from .models.anoncreds_revocation import RevListResultSchema, RevRegDefResultSchema -from .models.anoncreds_schema import ( +from .models.credential_definition import CredDefResultSchema, GetCredDefResultSchema +from .models.revocation import RevListResultSchema, RevRegDefResultSchema +from .models.schema import ( AnonCredsSchemaSchema, GetSchemaResultSchema, SchemaResultSchema, @@ -69,7 +68,7 @@ class SchemaIdMatchInfo(OpenAPISchema): schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) @@ -112,7 +111,7 @@ class SchemasQueryStringSchema(OpenAPISchema): schema_issuer_id = fields.Str( metadata={ "description": "Schema issuer identifier", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, } ) @@ -124,7 +123,7 @@ class GetSchemasResponseSchema(OpenAPISchema): fields.Str( metadata={ "description": "Schema identifiers", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) ) @@ -137,7 +136,7 @@ class SchemaPostRequestSchema(OpenAPISchema): options = fields.Nested(SchemaPostOptionSchema()) -@docs(tags=["anoncreds - schemas"], summary="Create a schema on the connected ledger") +@docs(tags=["anoncreds - schemas"], summary="Create a schema on the connected datastore") @request_schema(SchemaPostRequestSchema()) @response_schema(SchemaResultSchema(), 200, description="") @tenant_authentication @@ -278,7 +277,7 @@ class CredIdMatchInfo(OpenAPISchema): cred_def_id = fields.Str( metadata={ "description": "Credential definition identifier", - "example": INDY_CRED_DEF_ID_EXAMPLE, + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, }, required=True, ) @@ -297,7 +296,7 @@ class InnerCredDefSchema(OpenAPISchema): schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, }, required=True, data_key="schemaId", @@ -305,7 +304,7 @@ class InnerCredDefSchema(OpenAPISchema): issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, required=True, data_key="issuerId", @@ -357,13 +356,13 @@ class CredDefsQueryStringSchema(OpenAPISchema): issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, } ) schema_id = fields.Str( metadata={ "description": "Schema identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, } ) schema_name = fields.Str( @@ -382,7 +381,7 @@ class CredDefsQueryStringSchema(OpenAPISchema): @docs( tags=["anoncreds - credential definitions"], - summary="Create a credential definition on the connected ledger", + summary="Create a credential definition on the connected datastore", ) @request_schema(CredDefPostRequestSchema()) @response_schema(CredDefResultSchema(), 200, description="") @@ -522,14 +521,14 @@ class InnerRevRegDefSchema(OpenAPISchema): issuer_id = fields.Str( metadata={ "description": "Issuer Identifier of the credential definition or schema", - "example": INDY_OR_KEY_DID_EXAMPLE, + "example": ANONCREDS_DID_EXAMPLE, }, data_key="issuerId", ) cred_def_id = fields.Str( metadata={ "description": "Credential definition identifier", - "example": INDY_SCHEMA_ID_EXAMPLE, + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, }, data_key="credDefId", ) @@ -573,7 +572,7 @@ class RevRegCreateRequestSchemaAnoncreds(OpenAPISchema): @docs( tags=["anoncreds - revocation"], - summary="Create and publish a registration revocation on the connected ledger", + summary="Create and publish a registration revocation on the connected datastore", ) @request_schema(RevRegCreateRequestSchemaAnoncreds()) @response_schema(RevRegDefResultSchema(), 200, description="") @@ -649,7 +648,7 @@ class RevListCreateRequestSchema(OpenAPISchema): rev_reg_def_id = fields.Str( metadata={ "description": "Revocation registry definition identifier", - "example": INDY_REV_REG_ID_EXAMPLE, + "example": ANONCREDS_REV_REG_ID_EXAMPLE, } ) options = fields.Nested(RevListOptionsSchema) @@ -657,7 +656,7 @@ class RevListCreateRequestSchema(OpenAPISchema): @docs( tags=["anoncreds - revocation"], - summary="Create and publish a revocation status list on the connected ledger", + summary="Create and publish a revocation status list on the connected datastore", ) @request_schema(RevListCreateRequestSchema()) @response_schema(RevListResultSchema(), 200, description="") @@ -687,7 +686,7 @@ async def rev_list_post(request: web.BaseRequest): handle_value_error(e) except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - except (AnonCredsRevocationError, LedgerError) as err: + except AnonCredsRevocationError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err diff --git a/acapy_agent/anoncreds/tests/test_holder.py b/acapy_agent/anoncreds/tests/test_holder.py index ba69a7ebd7..34d23ef75f 100644 --- a/acapy_agent/anoncreds/tests/test_holder.py +++ b/acapy_agent/anoncreds/tests/test_holder.py @@ -45,8 +45,8 @@ from ...wallet.error import WalletNotFoundError from .. import holder as test_module from ..holder import CATEGORY_CREDENTIAL, AnonCredsHolder, AnonCredsHolderError -from ..models.anoncreds_cred_def import CredDef, CredDefValue, CredDefValuePrimary -from ..models.anoncreds_revocation import GetRevListResult, RevList +from ..models.credential_definition import CredDef, CredDefValue, CredDefValuePrimary +from ..models.revocation import GetRevListResult, RevList from ..registry import AnonCredsRegistry diff --git a/acapy_agent/anoncreds/tests/test_issuer.py b/acapy_agent/anoncreds/tests/test_issuer.py index f165f178d6..7442ffd2ae 100644 --- a/acapy_agent/anoncreds/tests/test_issuer.py +++ b/acapy_agent/anoncreds/tests/test_issuer.py @@ -10,7 +10,7 @@ AnonCredsObjectAlreadyExists, AnonCredsSchemaAlreadyExists, ) -from ...anoncreds.models.anoncreds_cred_def import ( +from ...anoncreds.models.credential_definition import ( CredDef, CredDefResult, CredDefState, @@ -19,7 +19,7 @@ CredDefValueRevocation, GetCredDefResult, ) -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, GetSchemaResult, SchemaResult, diff --git a/acapy_agent/anoncreds/tests/test_revocation.py b/acapy_agent/anoncreds/tests/test_revocation.py index ff9ed6d09f..2d9bc62e15 100644 --- a/acapy_agent/anoncreds/tests/test_revocation.py +++ b/acapy_agent/anoncreds/tests/test_revocation.py @@ -16,8 +16,8 @@ from requests import RequestException, Session from ...anoncreds.issuer import AnonCredsIssuer -from ...anoncreds.models.anoncreds_cred_def import CredDef -from ...anoncreds.models.anoncreds_revocation import ( +from ...anoncreds.models.credential_definition import CredDef +from ...anoncreds.models.revocation import ( RevList, RevListResult, RevListState, @@ -26,7 +26,7 @@ RevRegDefState, RevRegDefValue, ) -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, GetSchemaResult, ) diff --git a/acapy_agent/anoncreds/tests/test_revocation_setup.py b/acapy_agent/anoncreds/tests/test_revocation_setup.py index e56291efeb..357899f4c9 100644 --- a/acapy_agent/anoncreds/tests/test_revocation_setup.py +++ b/acapy_agent/anoncreds/tests/test_revocation_setup.py @@ -11,7 +11,7 @@ RevRegDefFinishedEvent, RevRegDefFinishedPayload, ) -from ..models.anoncreds_revocation import RevRegDef, RevRegDefValue +from ..models.revocation import RevRegDef, RevRegDefValue from ..revocation import AnonCredsRevocation diff --git a/acapy_agent/anoncreds/tests/test_routes.py b/acapy_agent/anoncreds/tests/test_routes.py index 17c4d15bee..607b81f4ae 100644 --- a/acapy_agent/anoncreds/tests/test_routes.py +++ b/acapy_agent/anoncreds/tests/test_routes.py @@ -7,7 +7,7 @@ from ...admin.request_context import AdminRequestContext from ...anoncreds.base import AnonCredsObjectNotFound from ...anoncreds.issuer import AnonCredsIssuer -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, SchemaResult, SchemaState, diff --git a/acapy_agent/anoncreds/tests/test_verifier.py b/acapy_agent/anoncreds/tests/test_verifier.py index 8f912a3f0f..0ff11fcb95 100644 --- a/acapy_agent/anoncreds/tests/test_verifier.py +++ b/acapy_agent/anoncreds/tests/test_verifier.py @@ -3,21 +3,21 @@ import pytest -from ...anoncreds.models.anoncreds_cred_def import ( +from ...anoncreds.models.credential_definition import ( CredDef, CredDefValue, CredDefValuePrimary, CredDefValueRevocation, GetCredDefResult, ) -from ...anoncreds.models.anoncreds_revocation import ( +from ...anoncreds.models.revocation import ( GetRevListResult, GetRevRegDefResult, RevList, RevRegDef, RevRegDefValue, ) -from ...anoncreds.models.anoncreds_schema import ( +from ...anoncreds.models.schema import ( AnonCredsSchema, GetSchemaResult, ) diff --git a/acapy_agent/anoncreds/verifier.py b/acapy_agent/anoncreds/verifier.py index 4f7972371d..849c44ab5b 100644 --- a/acapy_agent/anoncreds/verifier.py +++ b/acapy_agent/anoncreds/verifier.py @@ -1,4 +1,4 @@ -"""Indy-Credx verifier implementation.""" +"""Anoncreds verifier implementation.""" import asyncio import logging @@ -9,10 +9,10 @@ from anoncreds import AnoncredsError, Presentation, W3cPresentation from ..core.profile import Profile -from ..indy.models.xform import indy_proof_req2non_revoc_intervals from ..messaging.util import canon, encode from ..vc.vc_ld.validation_result import PresentationVerificationResult -from .models.anoncreds_cred_def import GetCredDefResult +from .models.credential_definition import GetCredDefResult +from .models.utils import extract_non_revocation_intervals_from_proof_request from .registry import AnonCredsRegistry LOGGER = logging.getLogger(__name__) @@ -45,7 +45,7 @@ def non_revoc_intervals(self, pres_req: dict, pres: dict, cred_defs: dict) -> li """Remove superfluous non-revocation intervals in presentation request. Irrevocable credentials constitute proof of non-revocation, but - indy rejects proof requests with non-revocation intervals lining up + anoncreds rejects proof requests with non-revocation intervals lining up with non-revocable credentials in proof: seek and remove. Args: @@ -116,13 +116,15 @@ async def check_timestamps( Args: profile: relevant profile - pres_req: indy proof request - pres: indy proof request + pres_req: anoncreds proof request + pres: anoncreds proof request rev_reg_defs: rev reg defs by rev reg id, augmented with transaction times """ msgs = [] now = int(time()) - non_revoc_intervals = indy_proof_req2non_revoc_intervals(pres_req) + non_revoc_intervals = extract_non_revocation_intervals_from_proof_request( + pres_req + ) LOGGER.debug(f">>> got non-revoc intervals: {non_revoc_intervals}") # timestamp for irrevocable credential diff --git a/acapy_agent/connections/models/conn_record.py b/acapy_agent/connections/models/conn_record.py index 874d8c3d7f..e27be92c4f 100644 --- a/acapy_agent/connections/models/conn_record.py +++ b/acapy_agent/connections/models/conn_record.py @@ -11,8 +11,8 @@ from ...messaging.valid import ( GENERIC_DID_EXAMPLE, GENERIC_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, UUID4_EXAMPLE, ) from ...protocols.connections.v1_0.message_types import ARIES_PROTOCOL as CONN_PROTO @@ -725,10 +725,10 @@ class Meta: ) invitation_key = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Public key for connection", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) invitation_msg_id = fields.Str( diff --git a/acapy_agent/connections/models/connection_target.py b/acapy_agent/connections/models/connection_target.py index ad7219db0a..bc81adc42e 100644 --- a/acapy_agent/connections/models/connection_target.py +++ b/acapy_agent/connections/models/connection_target.py @@ -8,8 +8,8 @@ from ...messaging.valid import ( GENERIC_DID_EXAMPLE, GENERIC_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, ) @@ -75,10 +75,10 @@ class Meta: ) recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), required=False, @@ -86,10 +86,10 @@ class Meta: ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="routingKeys", @@ -98,9 +98,9 @@ class Meta: ) sender_key = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Sender public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) diff --git a/acapy_agent/indy/models/cred_def.py b/acapy_agent/indy/models/cred_def.py index dbdaea2b2d..4c5547f96e 100644 --- a/acapy_agent/indy/models/cred_def.py +++ b/acapy_agent/indy/models/cred_def.py @@ -6,8 +6,8 @@ from ...messaging.valid import ( INDY_CRED_DEF_ID_EXAMPLE, INDY_CRED_DEF_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NUM_STR_WHOLE_EXAMPLE, NUM_STR_WHOLE_VALIDATE, ) @@ -92,10 +92,10 @@ class CredentialDefinitionSchema(OpenAPISchema): """Marshmallow schema for indy cred def.""" ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Node protocol version", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) ident = fields.Str( diff --git a/acapy_agent/indy/models/pres_preview.py b/acapy_agent/indy/models/pres_preview.py index 496c1e93cd..d9e740193e 100644 --- a/acapy_agent/indy/models/pres_preview.py +++ b/acapy_agent/indy/models/pres_preview.py @@ -16,8 +16,8 @@ from ...messaging.valid import ( INDY_CRED_DEF_ID_EXAMPLE, INDY_CRED_DEF_ID_VALIDATE, - INDY_PREDICATE_EXAMPLE, - INDY_PREDICATE_VALIDATE, + PREDICATE_EXAMPLE, + PREDICATE_VALIDATE, ) from ...multitenant.base import BaseMultitenantManager from ...protocols.didcomm_prefix import DIDCommPrefix @@ -100,10 +100,10 @@ class Meta: ) predicate = fields.Str( required=True, - validate=INDY_PREDICATE_VALIDATE, + validate=PREDICATE_VALIDATE, metadata={ "description": "Predicate type ('<', '<=', '>=', or '>')", - "example": INDY_PREDICATE_EXAMPLE, + "example": PREDICATE_EXAMPLE, }, ) threshold = fields.Int( diff --git a/acapy_agent/indy/models/proof_request.py b/acapy_agent/indy/models/proof_request.py index 1c87ecf454..f27ac5a8f6 100644 --- a/acapy_agent/indy/models/proof_request.py +++ b/acapy_agent/indy/models/proof_request.py @@ -15,14 +15,14 @@ from ...messaging.models.openapi import OpenAPISchema from ...messaging.valid import ( INDY_CRED_DEF_ID_EXAMPLE, - INDY_PREDICATE_EXAMPLE, - INDY_PREDICATE_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NUM_STR_NATURAL_EXAMPLE, NUM_STR_NATURAL_VALIDATE, + PREDICATE_EXAMPLE, + PREDICATE_VALIDATE, ) @@ -125,10 +125,10 @@ class IndyProofReqPredSpecSchema(OpenAPISchema): ) p_type = fields.Str( required=True, - validate=INDY_PREDICATE_VALIDATE, + validate=PREDICATE_VALIDATE, metadata={ "description": "Predicate type ('<', '<=', '>=', or '>')", - "example": INDY_PREDICATE_EXAMPLE, + "example": PREDICATE_EXAMPLE, }, ) p_value = fields.Int( @@ -251,10 +251,10 @@ class Meta: version = fields.Str( required=False, dump_default="1.0", - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Proof request version", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) requested_attributes = fields.Dict( diff --git a/acapy_agent/indy/models/revocation.py b/acapy_agent/indy/models/revocation.py index a7a2795fbd..14c5617709 100644 --- a/acapy_agent/indy/models/revocation.py +++ b/acapy_agent/indy/models/revocation.py @@ -12,8 +12,8 @@ INDY_CRED_DEF_ID_VALIDATE, INDY_REV_REG_ID_EXAMPLE, INDY_REV_REG_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NATURAL_NUM_EXAMPLE, NATURAL_NUM_VALIDATE, ) @@ -180,10 +180,10 @@ class Meta: unknown = EXCLUDE ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Version of revocation registry definition", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) id_ = fields.Str( @@ -294,10 +294,10 @@ class Meta: unknown = EXCLUDE ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Version of revocation registry entry", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) value = fields.Nested( diff --git a/acapy_agent/indy/models/schema.py b/acapy_agent/indy/models/schema.py index 5dff944356..df91802bc7 100644 --- a/acapy_agent/indy/models/schema.py +++ b/acapy_agent/indy/models/schema.py @@ -6,8 +6,8 @@ from ...messaging.valid import ( INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, NATURAL_NUM_EXAMPLE, NATURAL_NUM_VALIDATE, ) @@ -17,10 +17,10 @@ class SchemaSchema(OpenAPISchema): """Marshmallow schema for indy schema.""" ver = fields.Str( - validate=INDY_VERSION_VALIDATE, + validate=MAJOR_MINOR_VERSION_VALIDATE, metadata={ "description": "Node protocol version", - "example": INDY_VERSION_EXAMPLE, + "example": MAJOR_MINOR_VERSION_EXAMPLE, }, ) ident = fields.Str( @@ -38,8 +38,11 @@ class SchemaSchema(OpenAPISchema): } ) version = fields.Str( - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) attr_names = fields.List( fields.Str(metadata={"description": "Attribute name", "example": "score"}), diff --git a/acapy_agent/ledger/routes.py b/acapy_agent/ledger/routes.py index 4d63eb5af3..fee5e15261 100644 --- a/acapy_agent/ledger/routes.py +++ b/acapy_agent/ledger/routes.py @@ -25,10 +25,10 @@ ENDPOINT_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, INT_EPOCH_EXAMPLE, INT_EPOCH_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, UUID4_EXAMPLE, ) from ..multitenant.base import BaseMultitenantManager @@ -133,10 +133,10 @@ class RegisterLedgerNymQueryStringSchema(OpenAPISchema): ) verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) alias = fields.Str( @@ -230,10 +230,10 @@ class GetDIDVerkeyResponseSchema(OpenAPISchema): verkey = fields.Str( allow_none=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Full verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) diff --git a/acapy_agent/messaging/credential_definitions/util.py b/acapy_agent/messaging/credential_definitions/util.py index fb732ecd44..1cca544747 100644 --- a/acapy_agent/messaging/credential_definitions/util.py +++ b/acapy_agent/messaging/credential_definitions/util.py @@ -13,8 +13,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, ) CRED_DEF_SENT_RECORD_TYPE = "cred_def_sent" @@ -41,8 +41,11 @@ class CredDefQueryStringSchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, diff --git a/acapy_agent/messaging/decorators/attach_decorator.py b/acapy_agent/messaging/decorators/attach_decorator.py index 98fc177996..7b17c6f670 100644 --- a/acapy_agent/messaging/decorators/attach_decorator.py +++ b/acapy_agent/messaging/decorators/attach_decorator.py @@ -29,8 +29,8 @@ BASE64_VALIDATE, BASE64URL_NO_PAD_EXAMPLE, BASE64URL_NO_PAD_VALIDATE, - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, JWS_HEADER_KID_EXAMPLE, JWS_HEADER_KID_VALIDATE, SHA256_EXAMPLE, @@ -778,12 +778,12 @@ class Meta: ) lastmod_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "Hint regarding last modification datetime, in ISO-8601 format" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) description = fields.Str( diff --git a/acapy_agent/messaging/decorators/service_decorator.py b/acapy_agent/messaging/decorators/service_decorator.py index 0a4695a01c..e4f94b90e3 100644 --- a/acapy_agent/messaging/decorators/service_decorator.py +++ b/acapy_agent/messaging/decorators/service_decorator.py @@ -9,7 +9,10 @@ from marshmallow import EXCLUDE, fields from ..models.base import BaseModel, BaseModelSchema -from ..valid import INDY_RAW_PUBLIC_KEY_EXAMPLE, INDY_RAW_PUBLIC_KEY_VALIDATE +from ..valid import ( + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, +) class ServiceDecorator(BaseModel): @@ -82,10 +85,10 @@ class Meta: recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="recipientKeys", @@ -102,10 +105,10 @@ class Meta: ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="routingKeys", diff --git a/acapy_agent/messaging/decorators/signature_decorator.py b/acapy_agent/messaging/decorators/signature_decorator.py index 22ec1b38c1..ed7a217611 100644 --- a/acapy_agent/messaging/decorators/signature_decorator.py +++ b/acapy_agent/messaging/decorators/signature_decorator.py @@ -3,7 +3,7 @@ import json import struct import time -from typing import Optional +from typing import Optional, Tuple from marshmallow import EXCLUDE, fields @@ -15,8 +15,8 @@ from ..valid import ( BASE64URL_EXAMPLE, BASE64URL_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, ) @@ -86,7 +86,7 @@ async def create( signer=signer, ) - def decode(self) -> (object, int): + def decode(self) -> Tuple[object, int]: """Decode the signature to its timestamp and value. Returns: @@ -164,9 +164,9 @@ class Meta: ) signer = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Signer verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) diff --git a/acapy_agent/messaging/decorators/timing_decorator.py b/acapy_agent/messaging/decorators/timing_decorator.py index 7ad8fc8c86..cd8dd829d7 100644 --- a/acapy_agent/messaging/decorators/timing_decorator.py +++ b/acapy_agent/messaging/decorators/timing_decorator.py @@ -11,7 +11,7 @@ from ..models.base import BaseModel, BaseModelSchema from ..util import datetime_to_str -from ..valid import INDY_ISO8601_DATETIME_EXAMPLE, INDY_ISO8601_DATETIME_VALIDATE +from ..valid import ISO8601_DATETIME_EXAMPLE, ISO8601_DATETIME_VALIDATE class TimingDecorator(BaseModel): @@ -62,34 +62,34 @@ class Meta: in_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of message receipt", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) out_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of message dispatch", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) stale_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time when message should be considered stale", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) expires_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time when message should be considered expired", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) delay_milli = fields.Int( @@ -102,9 +102,9 @@ class Meta: ) wait_until_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Earliest time at which to perform processing", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/messaging/models/base_record.py b/acapy_agent/messaging/models/base_record.py index a89894dfc6..e613c6e6d9 100644 --- a/acapy_agent/messaging/models/base_record.py +++ b/acapy_agent/messaging/models/base_record.py @@ -20,7 +20,7 @@ ) from ...storage.record import StorageRecord from ..util import datetime_to_str, time_now -from ..valid import INDY_ISO8601_DATETIME_EXAMPLE, INDY_ISO8601_DATETIME_VALIDATE +from ..valid import ISO8601_DATETIME_EXAMPLE, ISO8601_DATETIME_VALIDATE from .base import BaseModel, BaseModelError, BaseModelSchema LOGGER = logging.getLogger(__name__) @@ -583,18 +583,18 @@ class Meta: ) created_at = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of record creation", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) updated_at = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": "Time of last record update", - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/messaging/schemas/routes.py b/acapy_agent/messaging/schemas/routes.py index d8128a5398..c31983d264 100644 --- a/acapy_agent/messaging/schemas/routes.py +++ b/acapy_agent/messaging/schemas/routes.py @@ -49,8 +49,8 @@ B58, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, UUID4_EXAMPLE, ) from .util import ( @@ -70,8 +70,11 @@ class SchemaSendRequestSchema(OpenAPISchema): ) schema_version = fields.Str( required=True, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) attributes = fields.List( fields.Str(metadata={"description": "attribute name", "example": "score"}), diff --git a/acapy_agent/messaging/schemas/util.py b/acapy_agent/messaging/schemas/util.py index 35f8ce5bae..9a3e0cf989 100644 --- a/acapy_agent/messaging/schemas/util.py +++ b/acapy_agent/messaging/schemas/util.py @@ -11,8 +11,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, ) @@ -37,8 +37,11 @@ class SchemaQueryStringSchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) diff --git a/acapy_agent/messaging/tests/test_valid.py b/acapy_agent/messaging/tests/test_valid.py index 0f3b3d3363..b99737c4a8 100644 --- a/acapy_agent/messaging/tests/test_valid.py +++ b/acapy_agent/messaging/tests/test_valid.py @@ -19,20 +19,20 @@ INDY_CRED_REV_ID_VALIDATE, INDY_DID_VALIDATE, INDY_EXTRA_WQL_VALIDATE, - INDY_ISO8601_DATETIME_VALIDATE, - INDY_PREDICATE_VALIDATE, - INDY_RAW_PUBLIC_KEY_VALIDATE, INDY_REV_REG_ID_VALIDATE, INDY_REV_REG_SIZE_VALIDATE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_VALIDATE, INDY_WQL_VALIDATE, INT_EPOCH_VALIDATE, + ISO8601_DATETIME_VALIDATE, JWS_HEADER_KID_VALIDATE, JWT_VALIDATE, + MAJOR_MINOR_VERSION_VALIDATE, NATURAL_NUM_VALIDATE, NUM_STR_NATURAL_VALIDATE, NUM_STR_WHOLE_VALIDATE, + PREDICATE_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, SHA256_VALIDATE, UUID4_VALIDATE, WHOLE_NUM_VALIDATE, @@ -141,9 +141,11 @@ def test_indy_raw_public_key(self): ] for non_indy_raw_public_key in non_indy_raw_public_keys: with self.assertRaises(ValidationError): - INDY_RAW_PUBLIC_KEY_VALIDATE(non_indy_raw_public_key) + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE(non_indy_raw_public_key) - INDY_RAW_PUBLIC_KEY_VALIDATE("Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h") + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE( + "Q4zqM7aXqm7gDQkUVLng9hQ4zqM7aXqm7gDQkUVLng9h" + ) def test_jws_header_kid(self): non_kids = [ @@ -283,12 +285,12 @@ def test_version(self): non_versions = ["-1", "", "3_5", "3.5a"] for non_version in non_versions: with self.assertRaises(ValidationError): - INDY_VERSION_VALIDATE(non_version) + MAJOR_MINOR_VERSION_VALIDATE(non_version) - INDY_VERSION_VALIDATE("1.0") - INDY_VERSION_VALIDATE(".05") - INDY_VERSION_VALIDATE("1.2.3") - INDY_VERSION_VALIDATE("..") # perverse but technically OK + MAJOR_MINOR_VERSION_VALIDATE("1.0") + MAJOR_MINOR_VERSION_VALIDATE(".05") + MAJOR_MINOR_VERSION_VALIDATE("1.2.3") + MAJOR_MINOR_VERSION_VALIDATE("..") # perverse but technically OK def test_schema_id(self): non_schema_ids = [ @@ -311,12 +313,12 @@ def test_predicate(self): non_predicates = [">>", "", " >= ", "<<<=", "==", "=", "!="] for non_predicate in non_predicates: with self.assertRaises(ValidationError): - INDY_PREDICATE_VALIDATE(non_predicate) + PREDICATE_VALIDATE(non_predicate) - INDY_PREDICATE_VALIDATE("<") - INDY_PREDICATE_VALIDATE("<=") - INDY_PREDICATE_VALIDATE(">=") - INDY_PREDICATE_VALIDATE(">") + PREDICATE_VALIDATE("<") + PREDICATE_VALIDATE("<=") + PREDICATE_VALIDATE(">=") + PREDICATE_VALIDATE(">") def test_indy_date(self): non_datetimes = [ @@ -329,17 +331,17 @@ def test_indy_date(self): ] for non_datetime in non_datetimes: with self.assertRaises(ValidationError): - INDY_ISO8601_DATETIME_VALIDATE(non_datetime) - - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00Z") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00Z") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00+00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00-00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00-00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.1-00:00") - INDY_ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.123456-00:00") + ISO8601_DATETIME_VALIDATE(non_datetime) + + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00Z") + ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00Z") + ISO8601_DATETIME_VALIDATE("2020-01-01T00:00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00+00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00-00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00-00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.1-00:00") + ISO8601_DATETIME_VALIDATE("2020-01-01 00:00:00.123456-00:00") def test_indy_wql(self): non_wqls = [ diff --git a/acapy_agent/messaging/valid.py b/acapy_agent/messaging/valid.py index fc1749d600..c5026ca382 100644 --- a/acapy_agent/messaging/valid.py +++ b/acapy_agent/messaging/valid.py @@ -362,6 +362,21 @@ def __init__(self): ) +class AnoncredsDID(Regexp): + """Validate value against indy DID.""" + + EXAMPLE = "did:(method):WgWxqztrNooG92RXvxSTWv" + PATTERN = re.compile("^(did:[a-z]:.+$)?$") + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + IndyDID.PATTERN, + error="Value {input} is not an decentralized identifier (DID)", + ) + + class DIDValidation(Regexp): """Validate value against any valid DID spec.""" @@ -400,8 +415,8 @@ def __init__(self): ) -class IndyRawPublicKey(Regexp): - """Validate value against indy (Ed25519VerificationKey2018) raw public key.""" +class RawPublicEd25519VerificationKey2018(Regexp): + """Validate value against (Ed25519VerificationKey2018) raw public key.""" EXAMPLE = "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV" PATTERN = rf"^[{B58}]{{43,44}}$" @@ -410,7 +425,7 @@ def __init__(self): """Initialize the instance.""" super().__init__( - IndyRawPublicKey.PATTERN, + RawPublicEd25519VerificationKey2018.PATTERN, error="Value {input} is not a raw Ed25519VerificationKey2018 key", ) @@ -423,7 +438,9 @@ class RoutingKey(Regexp): """ EXAMPLE = DIDKey.EXAMPLE - PATTERN = re.compile(DIDKey.PATTERN.pattern + "|" + IndyRawPublicKey.PATTERN) + PATTERN = re.compile( + DIDKey.PATTERN.pattern + "|" + RawPublicEd25519VerificationKey2018.PATTERN + ) def __init__(self): """Initialize the instance.""" @@ -458,8 +475,23 @@ def __init__(self): ) -class IndyVersion(Regexp): - """Validate value against indy version specification.""" +class AnoncredsCredDefId(Regexp): + """Validate value against anoncreds credential definition identifier specification.""" + + EXAMPLE = "did:(method):3:CL:20:tag" + PATTERN = r"^(.+$)" + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + IndyCredDefId.PATTERN, + error="Value {input} is not an anoncreds credential definition identifier", + ) + + +class MajorMinorVersion(Regexp): + """Validate value against major minor version specification.""" EXAMPLE = "1.0" PATTERN = r"^[0-9.]+$" @@ -468,8 +500,8 @@ def __init__(self): """Initialize the instance.""" super().__init__( - IndyVersion.PATTERN, - error="Value {input} is not an indy version (use only digits and '.')", + MajorMinorVersion.PATTERN, + error="Value {input} is not a valid version major minor version (use only digits and '.')", # noqa: E501 ) @@ -488,6 +520,21 @@ def __init__(self): ) +class AnoncredsSchemaId(Regexp): + """Validate value against indy schema identifier specification.""" + + EXAMPLE = "did:(method):2:schema_name:1.0" + PATTERN = r"^(.+$)" + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + IndySchemaId.PATTERN, + error="Value {input} is not an anoncreds schema identifier", + ) + + class IndyRevRegId(Regexp): """Validate value against indy revocation registry identifier specification.""" @@ -508,6 +555,21 @@ def __init__(self): ) +class AnoncredsRevRegId(Regexp): + """Validate value against anoncreds revocation registry identifier specification.""" + + EXAMPLE = "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0" + PATTERN = r"^(.+$)" + + def __init__(self): + """Initialize the instance.""" + + super().__init__( + AnoncredsRevRegId.PATTERN, + error="Value {input} is not an anoncreds revocation registry identifier", + ) + + class IndyCredRevId(Regexp): """Validate value against indy credential revocation identifier specification.""" @@ -523,8 +585,8 @@ def __init__(self): ) -class IndyPredicate(OneOf): - """Validate value against indy predicate.""" +class Predicate(OneOf): + """Validate value against predicate.""" EXAMPLE = ">=" @@ -537,8 +599,8 @@ def __init__(self): ) -class IndyISO8601DateTime(Regexp): - """Validate value against ISO 8601 datetime format, indy profile.""" +class ISO8601DateTime(Regexp): + """Validate value against ISO 8601 datetime format.""" EXAMPLE = epoch_to_str(EXAMPLE_TIMESTAMP) PATTERN = ( @@ -550,7 +612,7 @@ def __init__(self): """Initialize the instance.""" super().__init__( - IndyISO8601DateTime.PATTERN, + ISO8601DateTime.PATTERN, error="Value {input} is not a date in valid format", ) @@ -960,29 +1022,38 @@ def __init__( GENERIC_DID_VALIDATE = MaybeIndyDID() GENERIC_DID_EXAMPLE = MaybeIndyDID.EXAMPLE -INDY_RAW_PUBLIC_KEY_VALIDATE = IndyRawPublicKey() -INDY_RAW_PUBLIC_KEY_EXAMPLE = IndyRawPublicKey.EXAMPLE +RAW_ED25519_2018_PUBLIC_KEY_VALIDATE = RawPublicEd25519VerificationKey2018() +RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE = RawPublicEd25519VerificationKey2018.EXAMPLE INDY_SCHEMA_ID_VALIDATE = IndySchemaId() INDY_SCHEMA_ID_EXAMPLE = IndySchemaId.EXAMPLE +ANONCREDS_SCHEMA_ID_VALIDATE = AnoncredsSchemaId() +ANONCREDS_SCHEMA_ID_EXAMPLE = AnoncredsSchemaId.EXAMPLE + INDY_CRED_DEF_ID_VALIDATE = IndyCredDefId() INDY_CRED_DEF_ID_EXAMPLE = IndyCredDefId.EXAMPLE +ANONCREDS_CRED_DEF_ID_VALIDATE = AnoncredsCredDefId() +ANONCREDS_CRED_DEF_ID_EXAMPLE = AnoncredsCredDefId.EXAMPLE + INDY_REV_REG_ID_VALIDATE = IndyRevRegId() INDY_REV_REG_ID_EXAMPLE = IndyRevRegId.EXAMPLE +ANONCREDS_REV_REG_ID_VALIDATE = AnoncredsRevRegId() +ANONCREDS_REV_REG_ID_EXAMPLE = AnoncredsRevRegId.EXAMPLE + INDY_CRED_REV_ID_VALIDATE = IndyCredRevId() INDY_CRED_REV_ID_EXAMPLE = IndyCredRevId.EXAMPLE -INDY_VERSION_VALIDATE = IndyVersion() -INDY_VERSION_EXAMPLE = IndyVersion.EXAMPLE +MAJOR_MINOR_VERSION_VALIDATE = MajorMinorVersion() +MAJOR_MINOR_VERSION_EXAMPLE = MajorMinorVersion.EXAMPLE -INDY_PREDICATE_VALIDATE = IndyPredicate() -INDY_PREDICATE_EXAMPLE = IndyPredicate.EXAMPLE +PREDICATE_VALIDATE = Predicate() +PREDICATE_EXAMPLE = Predicate.EXAMPLE -INDY_ISO8601_DATETIME_VALIDATE = IndyISO8601DateTime() -INDY_ISO8601_DATETIME_EXAMPLE = IndyISO8601DateTime.EXAMPLE +ISO8601_DATETIME_VALIDATE = ISO8601DateTime() +ISO8601_DATETIME_EXAMPLE = ISO8601DateTime.EXAMPLE RFC3339_DATETIME_VALIDATE = RFC3339DateTime() RFC3339_DATETIME_EXAMPLE = RFC3339DateTime.EXAMPLE @@ -1037,3 +1108,6 @@ def __init__( INDY_OR_KEY_DID_VALIDATE = IndyOrKeyDID() INDY_OR_KEY_DID_EXAMPLE = IndyOrKeyDID.EXAMPLE + +ANONCREDS_DID_VALIDATE = AnoncredsDID() +ANONCREDS_DID_EXAMPLE = AnoncredsDID.EXAMPLE diff --git a/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py b/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py index 840be506b9..1a8940a904 100644 --- a/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py +++ b/acapy_agent/protocols/basicmessage/v1_0/messages/basicmessage.py @@ -8,8 +8,8 @@ from .....messaging.agent_message import AgentMessage, AgentMessageSchema from .....messaging.util import datetime_now, datetime_to_str from .....messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, ) from ..message_types import BASIC_MESSAGE, PROTOCOL_PACKAGE @@ -63,12 +63,12 @@ class Meta: sent_time = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "Time message was sent, ISO8601 with space date/time separator" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) content = fields.Str( diff --git a/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py b/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py index d983eb0ede..51e9f5f3c2 100644 --- a/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py +++ b/acapy_agent/protocols/connections/v1_0/messages/connection_invitation.py @@ -10,8 +10,8 @@ from .....messaging.valid import ( GENERIC_DID_EXAMPLE, GENERIC_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, ) from .....wallet.util import b64_to_bytes, bytes_to_b64 from ..message_types import CONNECTION_INVITATION, PROTOCOL_PACKAGE @@ -131,10 +131,10 @@ class Meta: ) recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="recipientKeys", @@ -151,10 +151,10 @@ class Meta: ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), data_key="routingKeys", diff --git a/acapy_agent/protocols/connections/v1_0/routes.py b/acapy_agent/protocols/connections/v1_0/routes.py index c6cbe47ecd..63344e5749 100644 --- a/acapy_agent/protocols/connections/v1_0/routes.py +++ b/acapy_agent/protocols/connections/v1_0/routes.py @@ -26,8 +26,8 @@ GENERIC_DID_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, ) @@ -91,10 +91,10 @@ class CreateInvitationRequestSchema(OpenAPISchema): recipient_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Recipient public key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), required=False, @@ -109,10 +109,10 @@ class CreateInvitationRequestSchema(OpenAPISchema): ) routing_keys = fields.List( fields.Str( - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Routing key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ), required=False, @@ -210,10 +210,10 @@ class ConnectionStaticResultSchema(OpenAPISchema): ) my_verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "My verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) my_endpoint = fields.Str( @@ -228,10 +228,10 @@ class ConnectionStaticResultSchema(OpenAPISchema): ) their_verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Remote verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) record = fields.Nested(ConnRecordSchema(), required=True) @@ -245,10 +245,10 @@ class ConnectionsListQueryStringSchema(PaginatedQuerySchema): ) invitation_key = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "invitation key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) my_did = fields.Str( diff --git a/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py b/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py index 05416c54b1..d53ce0e549 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py +++ b/acapy_agent/protocols/issue_credential/v1_0/messages/credential_proposal.py @@ -12,8 +12,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, ) from ..message_types import CREDENTIAL_PROPOSAL, PROTOCOL_PACKAGE from .inner.credential_preview import CredentialPreview, CredentialPreviewSchema @@ -104,8 +104,8 @@ class Meta: schema_version = fields.Str( required=False, allow_none=False, - validate=INDY_VERSION_VALIDATE, - metadata={"example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={"example": MAJOR_MINOR_VERSION_EXAMPLE}, ) cred_def_id = fields.Str( required=False, diff --git a/acapy_agent/protocols/issue_credential/v1_0/routes.py b/acapy_agent/protocols/issue_credential/v1_0/routes.py index 725ad02992..1b5581a51b 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v1_0/routes.py @@ -31,8 +31,8 @@ INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, ) @@ -139,8 +139,11 @@ class V10CredentialCreateSchema(AdminAPIMessageTracingSchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, @@ -198,8 +201,11 @@ class V10CredentialProposalRequestSchemaBase(AdminAPIMessageTracingSchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py index e72614437a..a25e4bb62c 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/handler.py @@ -1,30 +1,28 @@ -"""V2.0 issue-credential indy credential format handler.""" +"""V2.0 issue-credential anoncreds credential format handler.""" import json import logging from typing import Mapping, Optional, Tuple +from anoncreds import CredentialDefinition, Schema from marshmallow import RAISE +from ......anoncreds.base import AnonCredsResolutionError from ......anoncreds.holder import AnonCredsHolder, AnonCredsHolderError -from ......anoncreds.issuer import AnonCredsIssuer +from ......anoncreds.issuer import CATEGORY_CRED_DEF, CATEGORY_SCHEMA, AnonCredsIssuer +from ......anoncreds.models.credential import AnoncredsCredentialSchema +from ......anoncreds.models.credential_offer import AnoncredsCredentialOfferSchema +from ......anoncreds.models.credential_proposal import ( + AnoncredsCredentialDefinitionProposal, +) +from ......anoncreds.models.credential_request import AnoncredsCredRequestSchema from ......anoncreds.registry import AnonCredsRegistry from ......anoncreds.revocation import AnonCredsRevocation from ......cache.base import BaseCache -from ......indy.models.cred import IndyCredentialSchema -from ......indy.models.cred_abstract import IndyCredAbstractSchema -from ......indy.models.cred_request import IndyCredRequestSchema -from ......ledger.base import BaseLedger -from ......ledger.multiple_ledger.ledger_requests_executor import ( - GET_CRED_DEF, - IndyLedgerRequestsExecutor, -) from ......messaging.credential_definitions.util import ( CRED_DEF_SENT_RECORD_TYPE, - CredDefQueryStringSchema, ) from ......messaging.decorators.attach_decorator import AttachDecorator -from ......multitenant.base import BaseMultitenantManager from ......revocation_anoncreds.models.issuer_cred_rev_record import IssuerCredRevRecord from ......storage.base import BaseStorage from ...message_types import ( @@ -40,16 +38,16 @@ from ...messages.cred_proposal import V20CredProposal from ...messages.cred_request import V20CredRequest from ...models.cred_ex_record import V20CredExRecord -from ...models.detail.indy import V20CredExRecordIndy +from ...models.detail.anoncreds import V20CredExRecordAnoncreds from ..handler import CredFormatAttachment, V20CredFormatError, V20CredFormatHandler LOGGER = logging.getLogger(__name__) class AnonCredsCredFormatHandler(V20CredFormatHandler): - """Indy credential format handler.""" + """Anoncreds credential format handler.""" - format = V20CredFormat.Format.INDY + format = V20CredFormat.Format.ANONCREDS @classmethod def validate_fields(cls, message_type: str, attachment_data: Mapping): @@ -71,10 +69,10 @@ def validate_fields(cls, message_type: str, attachment_data: Mapping): """ mapping = { - CRED_20_PROPOSAL: CredDefQueryStringSchema, - CRED_20_OFFER: IndyCredAbstractSchema, - CRED_20_REQUEST: IndyCredRequestSchema, - CRED_20_ISSUE: IndyCredentialSchema, + CRED_20_PROPOSAL: AnoncredsCredentialDefinitionProposal, + CRED_20_OFFER: AnoncredsCredentialOfferSchema, + CRED_20_REQUEST: AnoncredsCredRequestSchema, + CRED_20_ISSUE: AnoncredsCredentialSchema, } # Get schema class @@ -83,7 +81,7 @@ def validate_fields(cls, message_type: str, attachment_data: Mapping): # Validate, throw if not valid Schema(unknown=RAISE).load(attachment_data) - async def get_detail_record(self, cred_ex_id: str) -> V20CredExRecordIndy: + async def get_detail_record(self, cred_ex_id: str) -> V20CredExRecordAnoncreds: """Retrieve credential exchange detail record by cred_ex_id.""" async with self.profile.session() as session: @@ -167,7 +165,7 @@ async def _match_sent_cred_def_id(self, tag_query: Mapping[str, str]) -> str: async def create_proposal( self, cred_ex_record: V20CredExRecord, proposal_data: Mapping[str, str] ) -> Tuple[V20CredFormat, AttachDecorator]: - """Create indy credential proposal.""" + """Create anoncreds credential proposal.""" if proposal_data is None: proposal_data = {} @@ -176,7 +174,7 @@ async def create_proposal( async def receive_proposal( self, cred_ex_record: V20CredExRecord, cred_proposal_message: V20CredProposal ) -> None: - """Receive indy credential proposal. + """Receive anoncreds credential proposal. No custom handling is required for this step. """ @@ -184,35 +182,37 @@ async def receive_proposal( async def create_offer( self, cred_proposal_message: V20CredProposal ) -> CredFormatAttachment: - """Create indy credential offer.""" + """Create anoncreds credential offer.""" issuer = AnonCredsIssuer(self.profile) - ledger = self.profile.inject(BaseLedger) cache = self.profile.inject_or(BaseCache) + anoncreds_attachment = cred_proposal_message.attachment( + AnonCredsCredFormatHandler.format + ) + + if not anoncreds_attachment: + anoncreds_attachment = cred_proposal_message.attachment( + V20CredFormat.Format.INDY.api + ) + cred_def_id = await issuer.match_created_credential_definitions( - **cred_proposal_message.attachment(AnonCredsCredFormatHandler.format) + **anoncreds_attachment ) async def _create(): offer_json = await issuer.create_credential_offer(cred_def_id) return json.loads(offer_json) - multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) - if multitenant_mgr: - ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) - else: - ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) - ledger = ( - await ledger_exec_inst.get_ledger_for_identifier( - cred_def_id, - txn_record_type=GET_CRED_DEF, + async with self.profile.session() as session: + cred_def_entry = await session.handle.fetch(CATEGORY_CRED_DEF, cred_def_id) + cred_def_dict = CredentialDefinition.load(cred_def_entry.value).to_dict() + schema_entry = await session.handle.fetch( + CATEGORY_SCHEMA, cred_def_dict["schemaId"] ) - )[1] - async with ledger: - schema_id = await ledger.credential_definition_id2schema_id(cred_def_id) - schema = await ledger.get_schema(schema_id) - schema_attrs = set(schema["attrNames"]) + schema_dict = Schema.load(schema_entry.value).to_dict() + + schema_attrs = set(schema_dict["attrNames"]) preview_attrs = set(cred_proposal_message.credential_preview.attr_dict()) if preview_attrs != schema_attrs: raise V20CredFormatError( @@ -238,23 +238,26 @@ async def _create(): async def receive_offer( self, cred_ex_record: V20CredExRecord, cred_offer_message: V20CredOffer ) -> None: - """Receive indy credential offer.""" + """Receive anoncreds credential offer.""" async def create_request( self, cred_ex_record: V20CredExRecord, request_data: Optional[Mapping] = None ) -> CredFormatAttachment: - """Create indy credential request.""" + """Create anoncreds credential request.""" if cred_ex_record.state != V20CredExRecord.STATE_OFFER_RECEIVED: raise V20CredFormatError( - "Indy issue credential format cannot start from credential request" + "Anoncreds issue credential format cannot start from credential request" ) await self._check_uniqueness(cred_ex_record.cred_ex_id) - holder_did = request_data.get("holder_did") if request_data else None + + # For backwards compatibility, remove indy backup when indy format is retired + from ..indy.handler import IndyCredFormatHandler + cred_offer = cred_ex_record.cred_offer.attachment( AnonCredsCredFormatHandler.format - ) + ) or cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format) if "nonce" not in cred_offer: raise V20CredFormatError("Missing nonce in credential offer") @@ -265,19 +268,24 @@ async def create_request( async def _create(): anoncreds_registry = self.profile.inject(AnonCredsRegistry) - cred_def_result = await anoncreds_registry.get_credential_definition( - self.profile, cred_def_id - ) - - holder = AnonCredsHolder(self.profile) - request_json, metadata_json = await holder.create_credential_request( - cred_offer, cred_def_result.credential_definition, holder_did - ) + try: + cred_def_result = await anoncreds_registry.get_credential_definition( + self.profile, cred_def_id + ) + holder = AnonCredsHolder(self.profile) + request_json, metadata_json = await holder.create_credential_request( + cred_offer, cred_def_result.credential_definition, holder_did + ) - return { - "request": json.loads(request_json), - "metadata": json.loads(metadata_json), - } + return { + "request": json.loads(request_json), + "metadata": json.loads(metadata_json), + } + # This is for compatability with a holder that isn't anoncreds capable + except AnonCredsResolutionError: + return await IndyCredFormatHandler.create_cred_request_result( + self, cred_offer, holder_did, cred_def_id + ) cache_key = f"credential_request::{cred_def_id}::{holder_did}::{nonce}" cred_req_result = None @@ -292,7 +300,7 @@ async def _create(): if not cred_req_result: cred_req_result = await _create() - detail_record = V20CredExRecordIndy( + detail_record = V20CredExRecordAnoncreds( cred_ex_id=cred_ex_record.cred_ex_id, cred_request_metadata=cred_req_result["metadata"], ) @@ -305,18 +313,25 @@ async def _create(): async def receive_request( self, cred_ex_record: V20CredExRecord, cred_request_message: V20CredRequest ) -> None: - """Receive indy credential request.""" + """Receive anoncreds credential request.""" if not cred_ex_record.cred_offer: raise V20CredFormatError( - "Indy issue credential format cannot start from credential request" + "Anoncreds issue credential format cannot start from credential request" ) async def issue_credential( self, cred_ex_record: V20CredExRecord, retries: int = 5 ) -> CredFormatAttachment: - """Issue indy credential.""" + """Issue anoncreds credential.""" await self._check_uniqueness(cred_ex_record.cred_ex_id) + # For backwards compatibility, remove indy backup when indy format is retired + from ..indy.handler import IndyCredFormatHandler + + if cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format): + indy_handler = IndyCredFormatHandler(self.profile) + return await indy_handler.issue_credential(cred_ex_record, retries) + cred_offer = cred_ex_record.cred_offer.attachment( AnonCredsCredFormatHandler.format ) @@ -342,7 +357,7 @@ async def issue_credential( result = self.get_format_data(CRED_20_ISSUE, json.loads(cred_json)) async with self._profile.transaction() as txn: - detail_record = V20CredExRecordIndy( + detail_record = V20CredExRecordAnoncreds( cred_ex_id=cred_ex_record.cred_ex_id, rev_reg_id=rev_reg_def_id, cred_rev_id=cred_rev_id, @@ -371,7 +386,7 @@ async def issue_credential( async def receive_credential( self, cred_ex_record: V20CredExRecord, cred_issue_message: V20CredIssue ) -> None: - """Receive indy credential. + """Receive anoncreds credential. Validation is done in the store credential step. """ @@ -379,21 +394,33 @@ async def receive_credential( async def store_credential( self, cred_ex_record: V20CredExRecord, cred_id: Optional[str] = None ) -> None: - """Store indy credential.""" - cred = cred_ex_record.cred_issue.attachment(AnonCredsCredFormatHandler.format) + """Store anoncreds credential.""" + + # For backwards compatibility, remove indy backup when indy format is retired + from ..indy.handler import IndyCredFormatHandler + + cred = cred_ex_record.cred_issue.attachment( + AnonCredsCredFormatHandler.format + ) or cred_ex_record.cred_issue.attachment(IndyCredFormatHandler.format) rev_reg_def = None anoncreds_registry = self.profile.inject(AnonCredsRegistry) - cred_def_result = await anoncreds_registry.get_credential_definition( - self.profile, cred["cred_def_id"] - ) - if cred.get("rev_reg_id"): - rev_reg_def_result = ( - await anoncreds_registry.get_revocation_registry_definition( - self.profile, cred["rev_reg_id"] + try: + cred_def_result = await anoncreds_registry.get_credential_definition( + self.profile, cred["cred_def_id"] + ) + if cred.get("rev_reg_id"): + rev_reg_def_result = ( + await anoncreds_registry.get_revocation_registry_definition( + self.profile, cred["rev_reg_id"] + ) ) + rev_reg_def = rev_reg_def_result.revocation_registry + + except AnonCredsResolutionError: + return await IndyCredFormatHandler.store_credential( + self, cred_ex_record, cred_id ) - rev_reg_def = rev_reg_def_result.revocation_registry holder = AnonCredsHolder(self.profile) cred_offer_message = cred_ex_record.cred_offer diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py index 46606417fb..fed47beaf3 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py @@ -36,10 +36,10 @@ from ....messages.cred_request import V20CredRequest from ....messages.inner.cred_preview import V20CredAttrSpec, V20CredPreview from ....models.cred_ex_record import V20CredExRecord -from ....models.detail.indy import V20CredExRecordIndy +from ....models.detail.anoncreds import V20CredExRecordAnoncreds from ...handler import V20CredFormatError from .. import handler as test_module -from ..handler import LOGGER as INDY_LOGGER +from ..handler import LOGGER as ANONCREDS_LOGGER from ..handler import AnonCredsCredFormatHandler TEST_DID = "LjgpST2rjsoxYegQDRm7EL" @@ -108,7 +108,7 @@ "tailsLocation": TAILS_LOCAL, }, } -INDY_OFFER = { +ANONCREDS_OFFER = { "schema_id": SCHEMA_ID, "cred_def_id": CRED_DEF_ID, "key_correctness_proof": { @@ -131,7 +131,7 @@ }, "nonce": "1234567890", } -INDY_CRED_REQ = { +ANONCREDS_CRED_REQ = { "prover_did": TEST_DID, "cred_def_id": CRED_DEF_ID, "blinded_ms": { @@ -148,7 +148,7 @@ }, "nonce": "9876543210", } -INDY_CRED = { +ANONCREDS_CRED = { "schema_id": SCHEMA_ID, "cred_def_id": CRED_DEF_ID, "rev_reg_id": REV_REG_ID, @@ -232,9 +232,9 @@ async def asyncSetUp(self): async def test_validate_fields(self): # Test correct data self.handler.validate_fields(CRED_20_PROPOSAL, {"cred_def_id": CRED_DEF_ID}) - self.handler.validate_fields(CRED_20_OFFER, INDY_OFFER) - self.handler.validate_fields(CRED_20_REQUEST, INDY_CRED_REQ) - self.handler.validate_fields(CRED_20_ISSUE, INDY_CRED) + self.handler.validate_fields(CRED_20_OFFER, ANONCREDS_OFFER) + self.handler.validate_fields(CRED_20_REQUEST, ANONCREDS_CRED_REQ) + self.handler.validate_fields(CRED_20_ISSUE, ANONCREDS_CRED) # test incorrect proposal with self.assertRaises(ValidationError): @@ -244,31 +244,31 @@ async def test_validate_fields(self): # test incorrect offer with self.assertRaises(ValidationError): - offer = INDY_OFFER.copy() + offer = ANONCREDS_OFFER.copy() offer.pop("nonce") self.handler.validate_fields(CRED_20_OFFER, offer) # test incorrect request with self.assertRaises(ValidationError): - req = INDY_CRED_REQ.copy() + req = ANONCREDS_CRED_REQ.copy() req.pop("nonce") self.handler.validate_fields(CRED_20_REQUEST, req) # test incorrect cred with self.assertRaises(ValidationError): - cred = INDY_CRED.copy() + cred = ANONCREDS_CRED.copy() cred.pop("schema_id") self.handler.validate_fields(CRED_20_ISSUE, cred) async def test_get_indy_detail_record(self): cred_ex_id = "dummy" details_indy = [ - V20CredExRecordIndy( + V20CredExRecordAnoncreds( cred_ex_id=cred_ex_id, rev_reg_id="rr-id", cred_rev_id="0", ), - V20CredExRecordIndy( + V20CredExRecordAnoncreds( cred_ex_id=cred_ex_id, rev_reg_id="rr-id", cred_rev_id="1", @@ -278,7 +278,9 @@ async def test_get_indy_detail_record(self): await details_indy[0].save(session) await details_indy[1].save(session) # exercise logger warning on get() - with mock.patch.object(INDY_LOGGER, "warning", mock.MagicMock()) as mock_warning: + with mock.patch.object( + ANONCREDS_LOGGER, "warning", mock.MagicMock() + ) as mock_warning: assert await self.handler.get_detail_record(cred_ex_id) in details_indy mock_warning.assert_called_once() @@ -354,7 +356,7 @@ async def test_create_offer(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -379,7 +381,7 @@ async def test_create_offer(self): await self.session.storage.add_record(cred_def_record) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) (cred_format, attachment) = await self.handler.create_offer(cred_proposal) @@ -390,7 +392,7 @@ async def test_create_offer(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_OFFER + assert attachment.content == ANONCREDS_OFFER # assert data is encoded as base64 assert attachment.data.base64 @@ -417,7 +419,7 @@ async def test_create_offer_no_cache(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -446,7 +448,7 @@ async def test_create_offer_no_cache(self): await self.session.storage.add_record(cred_def_record) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) (cred_format, attachment) = await self.handler.create_offer(cred_proposal) @@ -457,7 +459,7 @@ async def test_create_offer_no_cache(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_OFFER + assert attachment.content == ANONCREDS_OFFER # assert data is encoded as base64 assert attachment.data.base64 @@ -480,7 +482,7 @@ async def test_create_offer_attr_mismatch(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -509,7 +511,7 @@ async def test_create_offer_attr_mismatch(self): await self.session.storage.add_record(cred_def_record) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) with mock.patch.object( IndyLedgerRequestsExecutor, @@ -526,7 +528,7 @@ async def test_create_offer_no_matching_sent_cred_def(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_PROPOSAL][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], @@ -534,7 +536,7 @@ async def test_create_offer_no_matching_sent_cred_def(self): ) self.issuer.create_credential_offer = mock.CoroutineMock( - return_value=json.dumps(INDY_OFFER) + return_value=json.dumps(ANONCREDS_OFFER) ) with self.assertRaises(V20CredFormatError) as context: @@ -557,11 +559,11 @@ async def test_create_request(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_ex_record = V20CredExRecord( cred_ex_id="dummy-id", @@ -574,7 +576,7 @@ async def test_create_request(self): cred_req_meta = {} self.holder.create_credential_request = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED_REQ), json.dumps(cred_req_meta)) + return_value=(json.dumps(ANONCREDS_CRED_REQ), json.dumps(cred_req_meta)) ) (cred_format, attachment) = await self.handler.create_request( @@ -582,14 +584,14 @@ async def test_create_request(self): ) self.holder.create_credential_request.assert_called_once_with( - INDY_OFFER, cred_def, holder_did + ANONCREDS_OFFER, cred_def, holder_did ) # assert identifier match assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_CRED_REQ + assert attachment.content == ANONCREDS_CRED_REQ # assert data is encoded as base64 assert attachment.data.base64 @@ -617,16 +619,18 @@ async def test_create_request_bad_state(self): with self.assertRaises(V20CredFormatError) as context: await self.handler.create_request(cred_ex_record) - assert "Indy issue credential format cannot start from credential request" in str( - context.exception + assert ( + "Anoncreds issue credential format cannot start from credential request" + in str(context.exception) ) cred_ex_record.state = None with self.assertRaises(V20CredFormatError) as context: await self.handler.create_request(cred_ex_record) - assert "Indy issue credential format cannot start from credential request" in str( - context.exception + assert ( + "Anoncreds issue credential format cannot start from credential request" + in str(context.exception) ) async def test_create_request_not_unique_x(self): @@ -658,8 +662,9 @@ async def test_receive_request_no_offer(self): with self.assertRaises(V20CredFormatError) as context: await self.handler.receive_request(cred_ex_record, cred_request_message) - assert "Indy issue credential format cannot start from credential request" in str( - context.exception + assert ( + "Anoncreds issue credential format cannot start from credential request" + in str(context.exception) ) @pytest.mark.skip(reason="Anoncreds-break") @@ -680,22 +685,22 @@ async def test_issue_credential_revocable(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -709,7 +714,7 @@ async def test_issue_credential_revocable(self): cred_rev_id = "1000" self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), cred_rev_id) + return_value=(json.dumps(ANONCREDS_CRED), cred_rev_id) ) with mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc: @@ -732,8 +737,8 @@ async def test_issue_credential_revocable(self): self.issuer.create_credential.assert_called_once_with( SCHEMA, - INDY_OFFER, - INDY_CRED_REQ, + ANONCREDS_OFFER, + ANONCREDS_CRED_REQ, attr_values, REV_REG_ID, "dummy-path", @@ -743,7 +748,7 @@ async def test_issue_credential_revocable(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_CRED + assert attachment.content == ANONCREDS_CRED # assert data is encoded as base64 assert attachment.data.base64 @@ -768,22 +773,22 @@ async def test_issue_credential_non_revocable(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -796,7 +801,7 @@ async def test_issue_credential_non_revocable(self): ) self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), None) + return_value=(json.dumps(ANONCREDS_CRED), None) ) self.ledger.get_credential_definition = mock.CoroutineMock( return_value=CRED_DEF_NR @@ -816,8 +821,8 @@ async def test_issue_credential_non_revocable(self): self.issuer.create_credential.assert_called_once_with( SCHEMA, - INDY_OFFER, - INDY_CRED_REQ, + ANONCREDS_OFFER, + ANONCREDS_CRED_REQ, attr_values, None, None, @@ -827,7 +832,7 @@ async def test_issue_credential_non_revocable(self): assert cred_format.attach_id == self.handler.format.api == attachment.ident # assert content of attachment is proposal data - assert attachment.content == INDY_CRED + assert attachment.content == ANONCREDS_CRED # assert data is encoded as base64 assert attachment.data.base64 @@ -867,22 +872,22 @@ async def test_issue_credential_no_active_rr_no_retries(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -895,7 +900,7 @@ async def test_issue_credential_no_active_rr_no_retries(self): ) self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), cred_rev_id) + return_value=(json.dumps(ANONCREDS_CRED), cred_rev_id) ) with mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc: @@ -926,22 +931,22 @@ async def test_issue_credential_no_active_rr_retry(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -954,7 +959,7 @@ async def test_issue_credential_no_active_rr_retry(self): ) self.issuer.create_credential = mock.CoroutineMock( - return_value=(json.dumps(INDY_CRED), cred_rev_id) + return_value=(json.dumps(ANONCREDS_CRED), cred_rev_id) ) with mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc: @@ -996,22 +1001,22 @@ async def test_issue_credential_rr_full(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_request = V20CredRequest( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_ex_record = V20CredExRecord( @@ -1075,11 +1080,11 @@ async def test_store_credential(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_offer.assign_thread_id(thread_id) cred_request = V20CredRequest( @@ -1087,22 +1092,22 @@ async def test_store_credential(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_issue = V20CredIssue( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_ISSUE][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - credentials_attach=[AttachDecorator.data_base64(INDY_CRED, ident="0")], + credentials_attach=[AttachDecorator.data_base64(ANONCREDS_CRED, ident="0")], ) stored_cx_rec = V20CredExRecord( @@ -1167,7 +1172,7 @@ async def test_store_credential(self): self.holder.store_credential.assert_called_once_with( CRED_DEF, - INDY_CRED, + ANONCREDS_CRED, cred_req_meta, {"pic": "image/jpeg"}, credential_id=cred_id, @@ -1198,11 +1203,11 @@ async def test_store_credential_holder_store_indy_error(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_OFFER][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - offers_attach=[AttachDecorator.data_base64(INDY_OFFER, ident="0")], + offers_attach=[AttachDecorator.data_base64(ANONCREDS_OFFER, ident="0")], ) cred_offer.assign_thread_id(thread_id) cred_request = V20CredRequest( @@ -1210,22 +1215,22 @@ async def test_store_credential_holder_store_indy_error(self): V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_REQUEST][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], + requests_attach=[AttachDecorator.data_base64(ANONCREDS_CRED_REQ, ident="0")], ) cred_issue = V20CredIssue( formats=[ V20CredFormat( attach_id="0", format_=ATTACHMENT_FORMAT[CRED_20_ISSUE][ - V20CredFormat.Format.INDY.api + V20CredFormat.Format.ANONCREDS.api ], ) ], - credentials_attach=[AttachDecorator.data_base64(INDY_CRED, ident="0")], + credentials_attach=[AttachDecorator.data_base64(ANONCREDS_CRED, ident="0")], ) stored_cx_rec = V20CredExRecord( diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py index ecadd98539..19a2857cf3 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/handler.py @@ -7,6 +7,7 @@ from marshmallow import RAISE +from ......askar.profile_anon import AskarAnoncredsProfile from ......cache.base import BaseCache from ......core.profile import Profile from ......indy.holder import IndyHolder, IndyHolderError @@ -14,7 +15,6 @@ from ......indy.models.cred import IndyCredentialSchema from ......indy.models.cred_abstract import IndyCredAbstractSchema from ......indy.models.cred_request import IndyCredRequestSchema -from ......ledger.base import BaseLedger from ......ledger.multiple_ledger.ledger_requests_executor import ( GET_CRED_DEF, GET_SCHEMA, @@ -105,10 +105,6 @@ async def get_detail_record(self, cred_ex_id: str) -> V20CredExRecordIndy: session, cred_ex_id ) - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return await self.anoncreds_handler.get_detail_record(cred_ex_id) - if len(records) > 1: LOGGER.warning( "Cred ex id %s has %d %s detail records: should be 1", @@ -140,9 +136,6 @@ def get_format_identifier(self, message_type: str) -> str: str: Issue credential attachment format identifier """ - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_identifier(message_type) return ATTACHMENT_FORMAT[message_type][IndyCredFormatHandler.format.api] @@ -162,9 +155,6 @@ def get_format_data(self, message_type: str, data: dict) -> CredFormatAttachment CredFormatAttachment: Credential format and attachment data objects """ - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_data(message_type, data) return ( V20CredFormat( @@ -192,7 +182,7 @@ async def create_proposal( self, cred_ex_record: V20CredExRecord, proposal_data: Mapping[str, str] ) -> Tuple[V20CredFormat, AttachDecorator]: """Create indy credential proposal.""" - # Temporary shim while the new anoncreds library integration is in progress + # Create the proposal with the anoncreds handler if agent is anoncreds capable if self.anoncreds_handler: return await self.anoncreds_handler.create_proposal( cred_ex_record, @@ -217,12 +207,12 @@ async def create_offer( ) -> CredFormatAttachment: """Create indy credential offer.""" - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return await self.anoncreds_handler.create_offer(cred_proposal_message) + if isinstance(self.profile, AskarAnoncredsProfile): + raise V20CredFormatError( + "This issuer is anoncreds capable. Please use the anonreds format." + ) issuer = self.profile.inject(IndyIssuer) - ledger = self.profile.inject(BaseLedger) cache = self.profile.inject_or(BaseCache) cred_def_id = await self._match_sent_cred_def_id( @@ -275,11 +265,38 @@ async def receive_offer( ) -> None: """Receive indy credential offer.""" + async def create_cred_request_result(self, cred_offer, holder_did, cred_def_id): + """Create credential request result.""" + multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) + else: + ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) + ledger = ( + await ledger_exec_inst.get_ledger_for_identifier( + cred_def_id, + txn_record_type=GET_CRED_DEF, + ) + )[1] + async with ledger: + cred_def = await ledger.get_credential_definition(cred_def_id) + + holder = self.profile.inject(IndyHolder) + request_json, metadata_json = await holder.create_credential_request( + cred_offer, cred_def, holder_did + ) + + return { + "request": json.loads(request_json), + "metadata": json.loads(metadata_json), + } + async def create_request( self, cred_ex_record: V20CredExRecord, request_data: Optional[Mapping] = None ) -> CredFormatAttachment: """Create indy credential request.""" - # Temporary shim while the new anoncreds library integration is in progress + + # Create the request with the anoncreds handler if agent is anoncreds capable if self.anoncreds_handler: return await self.anoncreds_handler.create_request( cred_ex_record, @@ -302,31 +319,6 @@ async def create_request( nonce = cred_offer["nonce"] cred_def_id = cred_offer["cred_def_id"] - async def _create(): - multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) - if multitenant_mgr: - ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) - else: - ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) - ledger = ( - await ledger_exec_inst.get_ledger_for_identifier( - cred_def_id, - txn_record_type=GET_CRED_DEF, - ) - )[1] - async with ledger: - cred_def = await ledger.get_credential_definition(cred_def_id) - - holder = self.profile.inject(IndyHolder) - request_json, metadata_json = await holder.create_credential_request( - cred_offer, cred_def, holder_did - ) - - return { - "request": json.loads(request_json), - "metadata": json.loads(metadata_json), - } - cache_key = f"credential_request::{cred_def_id}::{holder_did}::{nonce}" cred_req_result = None cache = self.profile.inject_or(BaseCache) @@ -335,10 +327,14 @@ async def _create(): if entry.result: cred_req_result = entry.result else: - cred_req_result = await _create() + cred_req_result = await self.create_cred_request_result( + cred_offer, holder_did, cred_def_id + ) await entry.set_result(cred_req_result, 3600) if not cred_req_result: - cred_req_result = await _create() + cred_req_result = await self.create_cred_request_result( + cred_offer, holder_did, cred_def_id + ) detail_record = V20CredExRecordIndy( cred_ex_id=cred_ex_record.cred_ex_id, @@ -354,7 +350,7 @@ async def receive_request( self, cred_ex_record: V20CredExRecord, cred_request_message: V20CredRequest ) -> None: """Receive indy credential request.""" - # Temporary shim while the new anoncreds library integration is in progress + # Receive the request with the anoncreds handler if agent is anoncreds capable if self.anoncreds_handler: return await self.anoncreds_handler.receive_request( cred_ex_record, @@ -445,9 +441,11 @@ async def issue_credential( await self._check_uniqueness(cred_ex_record.cred_ex_id) cred_offer = cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format) + from ..anoncreds.handler import AnonCredsCredFormatHandler + cred_request = cred_ex_record.cred_request.attachment( IndyCredFormatHandler.format - ) + ) or cred_ex_record.cred_request.attachment(AnonCredsCredFormatHandler.format) cred_values = cred_ex_record.cred_offer.credential_preview.attr_dict(decode=False) schema_id = cred_offer["schema_id"] cred_def_id = cred_offer["cred_def_id"] @@ -517,10 +515,14 @@ async def store_credential( ) -> None: """Store indy credential.""" # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: + if hasattr(self, "anoncreds_handler") and self.anoncreds_handler: return await self.anoncreds_handler.store_credential(cred_ex_record, cred_id) - cred = cred_ex_record.cred_issue.attachment(IndyCredFormatHandler.format) + from ..anoncreds.handler import AnonCredsCredFormatHandler + + cred = cred_ex_record.cred_issue.attachment( + IndyCredFormatHandler.format + ) or cred_ex_record.cred_issue.attachment(AnonCredsCredFormatHandler.format) rev_reg_def = None multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py index 9d74382d8d..7a9b1ca549 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/models/cred_detail_options.py @@ -6,8 +6,8 @@ from .......messaging.models.base import BaseModel, BaseModelSchema from .......messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, UUID4_EXAMPLE, ) @@ -109,13 +109,13 @@ class Meta: created = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "The date and time of the proof (with a maximum accuracy in seconds)." " Defaults to current system time" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py index ae8f23fa69..3ff75a5119 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py @@ -9,11 +9,11 @@ from .......anoncreds.holder import AnonCredsHolder, AnonCredsHolderError from .......anoncreds.issuer import AnonCredsIssuer -from .......anoncreds.models.anoncreds_cred_def import ( +from .......anoncreds.models.credential_definition import ( CredDef, GetCredDefResult, ) -from .......anoncreds.models.anoncreds_revocation import ( +from .......anoncreds.models.revocation import ( GetRevRegDefResult, RevRegDef, ) diff --git a/acapy_agent/protocols/issue_credential/v2_0/manager.py b/acapy_agent/protocols/issue_credential/v2_0/manager.py index 068f94a4bd..124e832c47 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/manager.py +++ b/acapy_agent/protocols/issue_credential/v2_0/manager.py @@ -591,8 +591,14 @@ async def receive_credential( ] handled_formats = [] - # check that we didn't receive any formats not present in the request - if set(issue_formats) - set(req_formats): + def _check_formats(): + """Allow indy issue fomat and anoncreds req format or matching formats.""" + return ( + issue_formats == [V20CredFormat.Format.INDY] + and req_formats == [V20CredFormat.Format.ANONCREDS] + ) or len(set(issue_formats) - set(req_formats)) == 0 + + if not _check_formats(): raise V20CredManagerError( "Received issue credential format(s) not present in credential " f"request: {set(issue_formats) - set(req_formats)}" diff --git a/acapy_agent/protocols/issue_credential/v2_0/message_types.py b/acapy_agent/protocols/issue_credential/v2_0/message_types.py index 668d2b7332..e34ce0385d 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/message_types.py +++ b/acapy_agent/protocols/issue_credential/v2_0/message_types.py @@ -37,21 +37,25 @@ # Format specifications ATTACHMENT_FORMAT = { CRED_20_PROPOSAL: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-filter@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred-filter@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc@v0.1", }, CRED_20_OFFER: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-abstract@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred-abstract@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc-offer@v0.1", }, CRED_20_REQUEST: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-req@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred-req@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc-request@v0.1", }, CRED_20_ISSUE: { + V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred@v2.0", V20CredFormat.Format.INDY.api: "hlindy/cred@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc@v0.1", diff --git a/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py b/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py index 0574d4736d..589dfcf579 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py +++ b/acapy_agent/protocols/issue_credential/v2_0/messages/cred_format.py @@ -11,6 +11,7 @@ from .....messaging.models.base import BaseModel, BaseModelSchema from .....messaging.valid import UUID4_EXAMPLE from .....utils.classloader import DeferLoad +from ..models.detail.anoncreds import V20CredExRecordAnoncreds from ..models.detail.indy import V20CredExRecordIndy from ..models.detail.ld_proof import V20CredExRecordLDProof @@ -31,6 +32,14 @@ class Meta: class Format(Enum): """Attachment format.""" + ANONCREDS = FormatSpec( + "anoncreds/", + V20CredExRecordAnoncreds, + DeferLoad( + "acapy_agent.protocols.issue_credential.v2_0" + ".formats.anoncreds.handler.AnonCredsCredFormatHandler" + ), + ) INDY = FormatSpec( "hlindy/", V20CredExRecordIndy, @@ -39,23 +48,6 @@ class Format(Enum): ".formats.indy.handler.IndyCredFormatHandler" ), ) - """ - Once we switch to anoncreds this will replace the above INDY definition. - - In the meantime there are some hardcoded references in the - "...formats.indy.handler.IndyCredFormatHandler" class. - - :: - - INDY = FormatSpec( - "hlindy/", - V20CredExRecordIndy, - DeferLoad( - "acapy_agent.protocols.issue_credential.v2_0" - ".formats.anoncreds.handler.AnonCredsCredFormatHandler" - ), - ) - """ LD_PROOF = FormatSpec( "aries/", V20CredExRecordLDProof, @@ -97,7 +89,9 @@ def aries(self) -> str: return self.value.aries @property - def detail(self) -> Union[V20CredExRecordIndy, V20CredExRecordLDProof]: + def detail( + self, + ) -> Union[V20CredExRecordIndy, V20CredExRecordLDProof, V20CredExRecordAnoncreds]: """Accessor for credential exchange detail class.""" return self.value.detail diff --git a/acapy_agent/protocols/issue_credential/v2_0/models/detail/anoncreds.py b/acapy_agent/protocols/issue_credential/v2_0/models/detail/anoncreds.py new file mode 100644 index 0000000000..f683ff68ca --- /dev/null +++ b/acapy_agent/protocols/issue_credential/v2_0/models/detail/anoncreds.py @@ -0,0 +1,131 @@ +"""Anoncreds specific credential exchange information with non-secrets storage.""" + +from typing import Any, Mapping, Optional, Sequence + +from marshmallow import EXCLUDE, fields + +from ......core.profile import ProfileSession +from ......messaging.models.base_record import BaseRecord, BaseRecordSchema +from ......messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, + ANONCREDS_REV_REG_ID_EXAMPLE, + UUID4_EXAMPLE, +) +from .. import UNENCRYPTED_TAGS + + +class V20CredExRecordAnoncreds(BaseRecord): + """Credential exchange anoncreds detail record.""" + + class Meta: + """V20CredExRecordAnoncreds metadata.""" + + schema_class = "V20CredExRecordAnoncredsSchema" + + RECORD_ID_NAME = "cred_ex_anoncreds_id" + RECORD_TYPE = "anoncreds_cred_ex_v20" + TAG_NAMES = {"~cred_ex_id"} if UNENCRYPTED_TAGS else {"cred_ex_id"} + RECORD_TOPIC = "issue_credential_v2_0_anoncreds" + + def __init__( + self, + cred_ex_anoncreds_id: Optional[str] = None, + *, + cred_ex_id: Optional[str] = None, + cred_id_stored: Optional[str] = None, + cred_request_metadata: Optional[Mapping] = None, + rev_reg_id: Optional[str] = None, + cred_rev_id: Optional[str] = None, + **kwargs, + ): + """Initialize anoncreds credential exchange record details.""" + super().__init__(cred_ex_anoncreds_id, **kwargs) + + self.cred_ex_id = cred_ex_id + self.cred_id_stored = cred_id_stored + self.cred_request_metadata = cred_request_metadata + self.rev_reg_id = rev_reg_id + self.cred_rev_id = cred_rev_id + + @property + def cred_ex_anoncreds_id(self) -> str: + """Accessor for the ID associated with this exchange.""" + return self._id + + @property + def record_value(self) -> dict: + """Accessor for the JSON record value generated for this credential exchange.""" + return { + prop: getattr(self, prop) + for prop in ( + "cred_id_stored", + "cred_request_metadata", + "rev_reg_id", + "cred_rev_id", + ) + } + + @classmethod + async def query_by_cred_ex_id( + cls, + session: ProfileSession, + cred_ex_id: str, + ) -> Sequence["V20CredExRecordAnoncreds"]: + """Retrieve credential exchange anoncreds detail record(s) by its cred ex id.""" + return await cls.query( + session=session, + tag_filter={"cred_ex_id": cred_ex_id}, + ) + + def __eq__(self, other: Any) -> bool: + """Comparison between records.""" + return super().__eq__(other) + + +class V20CredExRecordAnoncredsSchema(BaseRecordSchema): + """Credential exchange anoncreds detail record detail schema.""" + + class Meta: + """Credential exchange anoncreds detail record schema metadata.""" + + model_class = V20CredExRecordAnoncreds + unknown = EXCLUDE + + cred_ex_anoncreds_id = fields.Str( + required=False, + metadata={"description": "Record identifier", "example": UUID4_EXAMPLE}, + ) + cred_ex_id = fields.Str( + required=False, + metadata={ + "description": "Corresponding v2.0 credential exchange record identifier", + "example": UUID4_EXAMPLE, + }, + ) + cred_id_stored = fields.Str( + required=False, + metadata={ + "description": "Credential identifier stored in wallet", + "example": UUID4_EXAMPLE, + }, + ) + cred_request_metadata = fields.Dict( + required=False, + metadata={"description": "Credential request metadata for anoncreds holder"}, + ) + rev_reg_id = fields.Str( + required=False, + metadata={ + "description": "Revocation registry identifier", + "example": ANONCREDS_REV_REG_ID_EXAMPLE, + }, + ) + cred_rev_id = fields.Str( + required=False, + metadata={ + "description": ( + "Credential revocation identifier within revocation registry" + ), + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, + ) diff --git a/acapy_agent/protocols/issue_credential/v2_0/routes.py b/acapy_agent/protocols/issue_credential/v2_0/routes.py index 01cf9330d7..9128f7aeac 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/routes.py @@ -28,14 +28,16 @@ from ....messaging.models.openapi import OpenAPISchema from ....messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset from ....messaging.valid import ( + ANONCREDS_DID_EXAMPLE, + ANONCREDS_SCHEMA_ID_EXAMPLE, INDY_CRED_DEF_ID_EXAMPLE, INDY_CRED_DEF_ID_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, INDY_SCHEMA_ID_EXAMPLE, INDY_SCHEMA_ID_VALIDATE, - INDY_VERSION_EXAMPLE, - INDY_VERSION_VALIDATE, + MAJOR_MINOR_VERSION_EXAMPLE, + MAJOR_MINOR_VERSION_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, ) @@ -132,6 +134,36 @@ class V20CredStoreRequestSchema(OpenAPISchema): credential_id = fields.Str(required=False) +class V20CredFilterAnoncredsSchema(OpenAPISchema): + """Anoncreds credential filtration criteria.""" + + cred_def_id = fields.Str( + required=False, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_DID_EXAMPLE, + }, + ) + schema_id = fields.Str( + required=False, + metadata={ + "description": "Schema identifier", + "example": ANONCREDS_SCHEMA_ID_EXAMPLE, + }, + ) + issuer_id = fields.Str( + required=False, + metadata={ + "description": "Credential issuer DID", + "example": ANONCREDS_DID_EXAMPLE, + }, + ) + epoch = fields.Str( + required=False, + metadata={"description": "Credential epoch time", "example": "2021-08-24"}, + ) + + class V20CredFilterIndySchema(OpenAPISchema): """Indy credential filtration criteria.""" @@ -162,8 +194,11 @@ class V20CredFilterIndySchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, @@ -202,8 +237,11 @@ class V20CredFilterVCDISchema(OpenAPISchema): ) schema_version = fields.Str( required=False, - validate=INDY_VERSION_VALIDATE, - metadata={"description": "Schema version", "example": INDY_VERSION_EXAMPLE}, + validate=MAJOR_MINOR_VERSION_VALIDATE, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, ) issuer_did = fields.Str( required=False, @@ -215,6 +253,11 @@ class V20CredFilterVCDISchema(OpenAPISchema): class V20CredFilterSchema(OpenAPISchema): """Credential filtration criteria.""" + anoncreds = fields.Nested( + V20CredFilterAnoncredsSchema, + required=False, + metadata={"description": "Credential filter for anoncreds"}, + ) indy = fields.Nested( V20CredFilterIndySchema, required=False, @@ -946,11 +989,17 @@ async def _create_free_offer( ) cred_manager = V20CredManager(profile) - (cred_ex_record, cred_offer_message) = await cred_manager.create_offer( - cred_ex_record, - comment=comment, - replacement_id=replacement_id, - ) + try: + (cred_ex_record, cred_offer_message) = await cred_manager.create_offer( + cred_ex_record, + comment=comment, + replacement_id=replacement_id, + ) + except ValueError as err: + LOGGER.exception(f"Error creating credential offer: {err}") + async with profile.session() as session: + await cred_ex_record.save_error_state(session, reason=err) + raise web.HTTPBadRequest(reason=err) return (cred_ex_record, cred_offer_message) diff --git a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py index 5ca0854086..1359057136 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py @@ -149,9 +149,10 @@ async def test_credential_exchange_retrieve(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ - mock.MagicMock( # indy + mock.MagicMock( # anoncreds serialize=mock.MagicMock(return_value={"...": "..."}) ), + None, # indy None, # ld_proof None, # vc_di ] @@ -162,7 +163,8 @@ async def test_credential_exchange_retrieve(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, - "indy": {"...": "..."}, + "anoncreds": {"...": "..."}, + "indy": None, "ld_proof": None, "vc_di": None, } @@ -185,6 +187,9 @@ async def test_credential_exchange_retrieve_indy_ld_proof(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ + mock.MagicMock( # anoncreds + serialize=mock.MagicMock(return_value={"anon": "creds"}) + ), mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"in": "dy"}) ), @@ -202,6 +207,7 @@ async def test_credential_exchange_retrieve_indy_ld_proof(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": {"anon": "creds"}, "indy": {"in": "dy"}, "ld_proof": {"ld": "proof"}, "vc_di": {"vc": "di"}, @@ -1230,9 +1236,10 @@ async def test_credential_exchange_issue(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ - mock.MagicMock( # indy + mock.MagicMock( # anoncreds serialize=mock.MagicMock(return_value={"...": "..."}) ), + None, None, # ld_proof None, # vc_di ] @@ -1248,7 +1255,8 @@ async def test_credential_exchange_issue(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, - "indy": {"...": "..."}, + "anoncreds": {"...": "..."}, + "indy": None, "ld_proof": None, "vc_di": None, } @@ -1277,7 +1285,8 @@ async def test_credential_exchange_issue_vcdi(self): mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ - None, + None, # anoncreds + None, # indy None, # ld_proof mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"...": "..."}) @@ -1295,6 +1304,7 @@ async def test_credential_exchange_issue_vcdi(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": None, "indy": None, "ld_proof": None, "vc_di": {"...": "..."}, @@ -1498,6 +1508,7 @@ async def test_credential_exchange_store(self): ) mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ + None, # anoncreds mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"...": "..."}) ), @@ -1519,6 +1530,7 @@ async def test_credential_exchange_store(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": None, "indy": {"...": "..."}, "ld_proof": None, "vc_di": None, @@ -1575,6 +1587,7 @@ async def test_credential_exchange_store_bad_cred_id_json(self): mock_response.assert_called_once_with( { "cred_ex_record": mock_cx_rec.serialize.return_value, + "anoncreds": None, "indy": {"...": "..."}, "ld_proof": None, "vc_di": None, @@ -1678,6 +1691,7 @@ async def test_credential_exchange_store_x(self): ) mock_handler.return_value.get_detail_record = mock.CoroutineMock( side_effect=[ + None, # anoncreds mock.MagicMock( # indy serialize=mock.MagicMock(return_value={"...": "..."}) ), diff --git a/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py b/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py index 0052a78873..d1d73f8a72 100644 --- a/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py +++ b/acapy_agent/protocols/present_proof/anoncreds/pres_exch_handler.py @@ -1,4 +1,4 @@ -"""Utilities for dif presentation exchange attachment.""" +"""Utilities for anoncreds presentation exchange attachment.""" import json import logging @@ -6,14 +6,15 @@ from typing import Dict, Optional, Tuple, Union from ....anoncreds.holder import AnonCredsHolder, AnonCredsHolderError -from ....anoncreds.models.anoncreds_cred_def import CredDef -from ....anoncreds.models.anoncreds_revocation import RevRegDef -from ....anoncreds.models.anoncreds_schema import AnonCredsSchema +from ....anoncreds.models.credential_definition import CredDef +from ....anoncreds.models.revocation import RevRegDef +from ....anoncreds.models.schema import AnonCredsSchema +from ....anoncreds.models.utils import extract_non_revocation_intervals_from_proof_request from ....anoncreds.registry import AnonCredsRegistry from ....anoncreds.revocation import AnonCredsRevocation +from ....askar.profile_anon import AskarAnoncredsProfile from ....core.error import BaseError from ....core.profile import Profile -from ....indy.models.xform import indy_proof_req2non_revoc_intervals from ..v1_0.models.presentation_exchange import V10PresentationExchange from ..v2_0.messages.pres_format import V20PresFormat from ..v2_0.models.pres_exchange import V20PresExRecord @@ -22,7 +23,7 @@ class AnonCredsPresExchHandlerError(BaseError): - """Base class for Indy Presentation Exchange related errors.""" + """Base class for Anoncreds Presentation Exchange related errors.""" class AnonCredsPresExchHandler: @@ -39,7 +40,9 @@ def __init__( def _extract_proof_request(self, pres_ex_record): if isinstance(pres_ex_record, V20PresExRecord): - return pres_ex_record.pres_request.attachment(V20PresFormat.Format.INDY) + return pres_ex_record.pres_request.attachment( + V20PresFormat.Format.ANONCREDS + ) or pres_ex_record.pres_request.attachment(V20PresFormat.Format.INDY) elif isinstance(pres_ex_record, V10PresentationExchange): return pres_ex_record._presentation_request.ser @@ -229,10 +232,23 @@ async def return_presentation( pres_ex_record: Union[V10PresentationExchange, V20PresExRecord], requested_credentials: Optional[dict] = None, ) -> dict: - """Return Indy proof request as dict.""" + """Return Anoncreds proof request as dict.""" + + # If not anoncreds capable, try to use indy handler. This should be removed when + # indy filter is completely retired + if not isinstance(self._profile, AskarAnoncredsProfile): + from ..indy.pres_exch_handler import IndyPresExchHandler + + handler = IndyPresExchHandler(self._profile) + return await handler.return_presentation( + pres_ex_record, requested_credentials + ) + requested_credentials = requested_credentials or {} proof_request = self._extract_proof_request(pres_ex_record) - non_revoc_intervals = indy_proof_req2non_revoc_intervals(proof_request) + non_revoc_intervals = extract_non_revocation_intervals_from_proof_request( + proof_request + ) requested_referents = self._get_requested_referents( proof_request, requested_credentials, non_revoc_intervals @@ -253,12 +269,12 @@ async def return_presentation( self._set_timestamps(requested_credentials, requested_referents) - indy_proof_json = await self.holder.create_presentation( + proof_json = await self.holder.create_presentation( proof_request, requested_credentials, schemas, cred_defs, revocation_states, ) - indy_proof = json.loads(indy_proof_json) - return indy_proof + proof = json.loads(proof_json) + return proof diff --git a/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py b/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py index 9c510afc9a..b62701ced1 100644 --- a/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py +++ b/acapy_agent/protocols/present_proof/indy/pres_exch_handler.py @@ -55,6 +55,13 @@ async def return_presentation( proof_request = pres_ex_record.pres_request.attachment( V20PresFormat.Format.INDY ) + # If indy filter fails try anoncreds filter format. This is for a + # non-anoncreds agent that gets a anoncreds format proof request and + # should removed when indy format is fully retired. + if not proof_request: + proof_request = pres_ex_record.pres_request.attachment( + V20PresFormat.Format.ANONCREDS + ) elif isinstance(pres_ex_record, V10PresentationExchange): proof_request = pres_ex_record._presentation_request.ser non_revoc_intervals = indy_proof_req2non_revoc_intervals(proof_request) diff --git a/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py b/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py index afe923e8be..5c55474765 100644 --- a/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py @@ -4,8 +4,10 @@ from marshmallow import ValidationError from .....admin.request_context import AdminRequestContext +from .....anoncreds.models.presentation_request import ( + AnoncredsPresentationReqAttrSpecSchema, +) from .....indy.holder import IndyHolder -from .....indy.models.proof_request import IndyProofReqAttrSpecSchema from .....indy.verifier import IndyVerifier from .....ledger.base import BaseLedger from .....storage.error import StorageNotFoundError @@ -35,7 +37,7 @@ async def asyncSetUp(self): ) async def test_validate_proof_req_attr_spec(self): - aspec = IndyProofReqAttrSpecSchema() + aspec = AnoncredsPresentationReqAttrSpecSchema() aspec.validate_fields({"name": "attr0"}) aspec.validate_fields( { diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py index d5618f4a50..2c19d13443 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/anoncreds/handler.py @@ -1,4 +1,4 @@ -"""V2.0 present-proof indy presentation-exchange format handler.""" +"""V2.0 present-proof anoncreds presentation-exchange format handler.""" import json import logging @@ -7,12 +7,12 @@ from marshmallow import RAISE from ......anoncreds.holder import AnonCredsHolder +from ......anoncreds.models.predicate import Predicate +from ......anoncreds.models.presentation_request import AnoncredsPresentationRequestSchema +from ......anoncreds.models.proof import AnoncredsProofSchema +from ......anoncreds.models.utils import get_requested_creds_from_proof_request_preview from ......anoncreds.util import generate_pr_nonce from ......anoncreds.verifier import AnonCredsVerifier -from ......indy.models.predicate import Predicate -from ......indy.models.proof import IndyProofSchema -from ......indy.models.proof_request import IndyProofRequestSchema -from ......indy.models.xform import indy_proof_req_preview2indy_requested_creds from ......messaging.decorators.attach_decorator import AttachDecorator from ......messaging.util import canon from ....anoncreds.pres_exch_handler import AnonCredsPresExchHandler @@ -33,7 +33,7 @@ class AnonCredsPresExchangeHandler(V20PresFormatHandler): """Anoncreds presentation format handler.""" - format = V20PresFormat.Format.INDY + format = V20PresFormat.Format.ANONCREDS @classmethod def validate_fields(cls, message_type: str, attachment_data: Mapping): @@ -55,9 +55,9 @@ def validate_fields(cls, message_type: str, attachment_data: Mapping): """ mapping = { - PRES_20_REQUEST: IndyProofRequestSchema, - PRES_20_PROPOSAL: IndyProofRequestSchema, - PRES_20: IndyProofSchema, + PRES_20_REQUEST: AnoncredsPresentationRequestSchema, + PRES_20_PROPOSAL: AnoncredsPresentationRequestSchema, + PRES_20: AnoncredsProofSchema, } # Get schema class @@ -109,20 +109,20 @@ async def create_bound_request( A tuple (updated presentation exchange record, presentation request message) """ - indy_proof_request = pres_ex_record.pres_proposal.attachment( + proof_request = pres_ex_record.pres_proposal.attachment( AnonCredsPresExchangeHandler.format ) if request_data: - indy_proof_request["name"] = request_data.get("name", "proof-request") - indy_proof_request["version"] = request_data.get("version", "1.0") - indy_proof_request["nonce"] = ( + proof_request["name"] = request_data.get("name", "proof-request") + proof_request["version"] = request_data.get("version", "1.0") + proof_request["nonce"] = ( request_data.get("nonce") or await generate_pr_nonce() ) else: - indy_proof_request["name"] = "proof-request" - indy_proof_request["version"] = "1.0" - indy_proof_request["nonce"] = await generate_pr_nonce() - return self.get_format_data(PRES_20_REQUEST, indy_proof_request) + proof_request["name"] = "proof-request" + proof_request["version"] = "1.0" + proof_request["nonce"] = await generate_pr_nonce() + return self.get_format_data(PRES_20_REQUEST, proof_request) async def create_pres( self, @@ -131,45 +131,58 @@ async def create_pres( ) -> Tuple[V20PresFormat, AttachDecorator]: """Create a presentation.""" requested_credentials = {} + + # This is used for the fallback to indy format + from ..indy.handler import IndyPresExchangeHandler + if not request_data: try: proof_request = pres_ex_record.pres_request - indy_proof_request = proof_request.attachment( + # Fall back to indy format should be removed when indy format retired + proof_request = proof_request.attachment( AnonCredsPresExchangeHandler.format - ) - requested_credentials = await indy_proof_req_preview2indy_requested_creds( - indy_proof_request, - preview=None, - holder=AnonCredsHolder(self._profile), + ) or proof_request.attachment(IndyPresExchangeHandler.format) + requested_credentials = ( + await get_requested_creds_from_proof_request_preview( + proof_request, + holder=AnonCredsHolder(self._profile), + ) ) except ValueError as err: LOGGER.warning(f"{err}") - raise V20PresFormatHandlerError( - f"No matching Indy credentials found: {err}" - ) + raise V20PresFormatHandlerError(f"No matching credentials found: {err}") else: - if AnonCredsPresExchangeHandler.format.api in request_data: - indy_spec = request_data.get(AnonCredsPresExchangeHandler.format.api) + # Fall back to indy format should be removed when indy format retired + if ( + AnonCredsPresExchangeHandler.format.api in request_data + or IndyPresExchangeHandler.format.api in request_data + ): + spec = request_data.get( + AnonCredsPresExchangeHandler.format.api + ) or request_data.get(IndyPresExchangeHandler.format.api) requested_credentials = { - "self_attested_attributes": indy_spec["self_attested_attributes"], - "requested_attributes": indy_spec["requested_attributes"], - "requested_predicates": indy_spec["requested_predicates"], + "self_attested_attributes": spec["self_attested_attributes"], + "requested_attributes": spec["requested_attributes"], + "requested_predicates": spec["requested_predicates"], } - indy_handler = AnonCredsPresExchHandler(self._profile) - indy_proof = await indy_handler.return_presentation( + handler = AnonCredsPresExchHandler(self._profile) + presentation_proof = await handler.return_presentation( pres_ex_record=pres_ex_record, requested_credentials=requested_credentials, ) - return self.get_format_data(PRES_20, indy_proof) + return self.get_format_data(PRES_20, presentation_proof) async def receive_pres(self, message: V20Pres, pres_ex_record: V20PresExRecord): """Receive a presentation and check for presented values vs. proposal request.""" def _check_proof_vs_proposal(): """Check for bait and switch in presented values vs. proposal request.""" + from ..indy.handler import IndyPresExchangeHandler + + # Fall back to indy format should be removed when indy format retired proof_req = pres_ex_record.pres_request.attachment( AnonCredsPresExchangeHandler.format - ) + ) or pres_ex_record.pres_request.attachment(IndyPresExchangeHandler.format) # revealed attrs for reft, attr_spec in proof["requested_proof"]["revealed_attrs"].items(): @@ -256,7 +269,8 @@ def _check_proof_vs_proposal(): for req_restriction in req_restrictions: for k in list(req_restriction): # cannot modify en passant if k.startswith("attr::"): - req_restriction.pop(k) # let indy-sdk reject mismatch here + # let anoncreds-sdk reject mismatch here + req_restriction.pop(k) sub_proof_index = pred_spec["sub_proof_index"] for ge_proof in proof["proof"]["proofs"][sub_proof_index][ "primary_proof" @@ -313,10 +327,8 @@ async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord: """ pres_request_msg = pres_ex_record.pres_request - indy_proof_request = pres_request_msg.attachment( - AnonCredsPresExchangeHandler.format - ) - indy_proof = pres_ex_record.pres.attachment(AnonCredsPresExchangeHandler.format) + proof_request = pres_request_msg.attachment(AnonCredsPresExchangeHandler.format) + proof = pres_ex_record.pres.attachment(AnonCredsPresExchangeHandler.format) verifier = AnonCredsVerifier(self._profile) ( @@ -324,13 +336,13 @@ async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord: cred_defs, rev_reg_defs, rev_lists, - ) = await verifier.process_pres_identifiers(indy_proof["identifiers"]) + ) = await verifier.process_pres_identifiers(proof["identifiers"]) verifier = AnonCredsVerifier(self._profile) (verified, verified_msgs) = await verifier.verify_presentation( - indy_proof_request, - indy_proof, + proof_request, + proof, schemas, cred_defs, rev_reg_defs, diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/handler.py index c4abf9d4c2..7e4e421cb6 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/handler.py @@ -1,4 +1,4 @@ -"""present-proof-v2 format handler - supports DIF and INDY.""" +"""present-proof-v2 format handler - supports ANONCREDS, DIF and INDY.""" import logging from abc import ABC, abstractclassmethod, abstractmethod diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py index 306ed3b1af..bac3933919 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/indy/handler.py @@ -88,9 +88,6 @@ def get_format_identifier(self, message_type: str) -> str: str: Issue credential attachment format identifier """ - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_identifier(message_type) return ATTACHMENT_FORMAT[message_type][IndyPresExchangeHandler.format.api] @@ -98,9 +95,6 @@ def get_format_data( self, message_type: str, data: dict ) -> Tuple[V20PresFormat, AttachDecorator]: """Get presentation format and attach objects for use in pres_ex messages.""" - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return self.anoncreds_handler.get_format_data(message_type, data) return ( V20PresFormat( @@ -154,9 +148,12 @@ async def create_pres( request_data: Optional[dict] = None, ) -> Tuple[V20PresFormat, AttachDecorator]: """Create a presentation.""" - # Temporary shim while the new anoncreds library integration is in progress + if self.anoncreds_handler: - return await self.anoncreds_handler.create_pres(pres_ex_record, request_data) + return await self.anoncreds_handler.create_pres( + pres_ex_record, + request_data, + ) requested_credentials = {} if not request_data: @@ -349,8 +346,14 @@ async def verify_pres(self, pres_ex_record: V20PresExRecord) -> V20PresExRecord: return await self.anoncreds_handler.verify_pres(pres_ex_record) pres_request_msg = pres_ex_record.pres_request - indy_proof_request = pres_request_msg.attachment(IndyPresExchangeHandler.format) - indy_proof = pres_ex_record.pres.attachment(IndyPresExchangeHandler.format) + + # The `or` anoncreds format is for the indy <--> anoncreds compatibility + indy_proof_request = pres_request_msg.attachment( + IndyPresExchangeHandler.format + ) or pres_request_msg.attachment(AnonCredsPresExchangeHandler.format) + indy_proof = pres_ex_record.pres.attachment( + IndyPresExchangeHandler.format + ) or pres_ex_record.pres.attachment(AnonCredsPresExchangeHandler.format) indy_handler = IndyPresExchHandler(self._profile) ( schemas, diff --git a/acapy_agent/protocols/present_proof/v2_0/message_types.py b/acapy_agent/protocols/present_proof/v2_0/message_types.py index 97b8f063fc..5654ef7d42 100644 --- a/acapy_agent/protocols/present_proof/v2_0/message_types.py +++ b/acapy_agent/protocols/present_proof/v2_0/message_types.py @@ -32,14 +32,17 @@ # Format specifications ATTACHMENT_FORMAT = { PRES_20_PROPOSAL: { + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-req@v2.0", V20PresFormat.Format.INDY.api: "hlindy/proof-req@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/definitions@v1.0", }, PRES_20_REQUEST: { + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-req@v2.0", V20PresFormat.Format.INDY.api: "hlindy/proof-req@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/definitions@v1.0", }, PRES_20: { + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof@v2.0", V20PresFormat.Format.INDY.api: "hlindy/proof@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/submission@v1.0", }, diff --git a/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py b/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py index 5c55384c86..e65e98644f 100644 --- a/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py +++ b/acapy_agent/protocols/present_proof/v2_0/messages/pres_format.py @@ -30,6 +30,13 @@ class Meta: class Format(Enum): """Attachment format.""" + ANONCREDS = FormatSpec( + "anoncreds/", + DeferLoad( + "acapy_agent.protocols.present_proof.v2_0" + ".formats.anoncreds.handler.AnonCredsPresExchangeHandler" + ), + ) INDY = FormatSpec( "hlindy/", DeferLoad( @@ -37,19 +44,6 @@ class Format(Enum): ".formats.indy.handler.IndyPresExchangeHandler" ), ) - """ - To make the switch from indy to anoncreds replace the above with the following. - - :: - - INDY = FormatSpec( - "hlindy/", - DeferLoad( - "acapy_agent.protocols.present_proof.v2_0" - ".formats.anoncreds.handler.AnonCredsPresExchangeHandler" - ), - ) - """ DIF = FormatSpec( "dif/", DeferLoad( diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index 2edb0e4c08..b53188f118 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -16,6 +16,7 @@ from ....admin.decorators.auth import tenant_authentication from ....admin.request_context import AdminRequestContext from ....anoncreds.holder import AnonCredsHolder, AnonCredsHolderError +from ....anoncreds.models.presentation_request import AnoncredsPresentationRequestSchema from ....connections.models.conn_record import ConnRecord from ....indy.holder import IndyHolder, IndyHolderError from ....indy.models.cred_precis import IndyCredPrecisSchema @@ -118,6 +119,11 @@ class V20PresExRecordListSchema(OpenAPISchema): class V20PresProposalByFormatSchema(OpenAPISchema): """Schema for presentation proposal per format.""" + anoncreds = fields.Nested( + AnoncredsPresentationRequestSchema, + required=False, + metadata={"description": "Presentation proposal for anoncreds"}, + ) indy = fields.Nested( IndyProofRequestSchema, required=False, @@ -192,6 +198,11 @@ class V20PresProposalRequestSchema(AdminAPIMessageTracingSchema): class V20PresRequestByFormatSchema(OpenAPISchema): """Presentation request per format.""" + anoncreds = fields.Nested( + AnoncredsPresentationRequestSchema, + required=False, + metadata={"description": "Presentation proposal for anoncreds"}, + ) indy = fields.Nested( IndyProofRequestSchema, required=False, @@ -293,6 +304,11 @@ class V20PresentationSendRequestToProposalSchema(AdminAPIMessageTracingSchema): class V20PresSpecByFormatRequestSchema(AdminAPIMessageTracingSchema): """Presentation specification schema by format, for send-presentation request.""" + anoncreds = fields.Nested( + IndyPresSpecSchema, + required=False, + metadata={"description": "Presentation specification for anoncreds"}, + ) indy = fields.Nested( IndyPresSpecSchema, required=False, @@ -406,7 +422,10 @@ def _formats_attach(by_format: Mapping, msg_type: str, spec: str) -> Mapping: """Break out formats and proposals/requests/presentations for v2.0 messages.""" attach = [] for fmt_api, item_by_fmt in by_format.items(): - if fmt_api == V20PresFormat.Format.INDY.api: + if ( + fmt_api == V20PresFormat.Format.ANONCREDS.api + or fmt_api == V20PresFormat.Format.INDY.api + ): attach.append(AttachDecorator.data_base64(mapping=item_by_fmt, ident=fmt_api)) elif fmt_api == V20PresFormat.Format.DIF.api: attach.append(AttachDecorator.data_json(mapping=item_by_fmt, ident=fmt_api)) @@ -557,19 +576,24 @@ async def present_proof_credentials_list(request: web.BaseRequest): wallet_type = profile.settings.get_value("wallet.type") if wallet_type == "askar-anoncreds": - indy_holder = AnonCredsHolder(profile) + holder = AnonCredsHolder(profile) else: - indy_holder = profile.inject(IndyHolder) - indy_credentials = [] - # INDY + holder = profile.inject(IndyHolder) + credentials = [] + # ANONCREDS or INDY try: - indy_pres_request = pres_ex_record.by_format["pres_request"].get( - V20PresFormat.Format.INDY.api + # try anoncreds and fallback to indy + pres_request = pres_ex_record.by_format["pres_request"].get( + V20PresFormat.Format.ANONCREDS.api ) - if indy_pres_request: - indy_credentials = ( - await indy_holder.get_credentials_for_presentation_request_by_referent( - indy_pres_request, + if not pres_request: + pres_request = pres_ex_record.by_format["pres_request"].get( + V20PresFormat.Format.INDY.api + ) + if pres_request: + credentials = ( + await holder.get_credentials_for_presentation_request_by_referent( + pres_request, pres_referents, start, count, @@ -771,7 +795,7 @@ async def present_proof_credentials_list(request: web.BaseRequest): pres_ex_record, outbound_handler, ) - credentials = list(indy_credentials) + dif_cred_value_list + credentials = list(credentials) + dif_cred_value_list return web.json_response(credentials) @@ -911,8 +935,11 @@ async def present_proof_create_request(request: web.BaseRequest): comment = body.get("comment") pres_request_spec = body.get("presentation_request") - if pres_request_spec and V20PresFormat.Format.INDY.api in pres_request_spec: - await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if pres_request_spec: + if V20PresFormat.Format.INDY.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if V20PresFormat.Format.ANONCREDS.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.ANONCREDS.api]) pres_request_message = V20PresRequest( comment=comment, @@ -995,8 +1022,11 @@ async def present_proof_send_free_request(request: web.BaseRequest): comment = body.get("comment") pres_request_spec = body.get("presentation_request") - if pres_request_spec and V20PresFormat.Format.INDY.api in pres_request_spec: - await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if pres_request_spec: + if V20PresFormat.Format.INDY.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.INDY.api]) + if V20PresFormat.Format.ANONCREDS.api in pres_request_spec: + await _add_nonce(pres_request_spec[V20PresFormat.Format.ANONCREDS.api]) pres_request_message = V20PresRequest( comment=comment, will_confirm=True, @@ -1157,7 +1187,7 @@ async def present_proof_send_presentation(request: web.BaseRequest): outbound_handler = request["outbound_message_router"] pres_ex_id = request.match_info["pres_ex_id"] body = await request.json() - supported_formats = ["dif", "indy"] + supported_formats = ["anoncreds", "dif", "indy"] if not any(x in body for x in supported_formats): raise web.HTTPBadRequest( reason=( diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py index 0ee4f1ad38..78d93e01a7 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py @@ -74,7 +74,7 @@ ) ], ) -INDY_PROOF_REQ_NAME = { +ANONCREDS_PROOF_REQ_NAME = { "name": PROOF_REQ_NAME, "version": PROOF_REQ_VERSION, "nonce": PROOF_REQ_NONCE, @@ -100,7 +100,7 @@ } }, } -INDY_PROOF_REQ_NAMES = { +ANONCREDS_PROOF_REQ_NAMES = { "name": PROOF_REQ_NAME, "version": PROOF_REQ_VERSION, "nonce": PROOF_REQ_NONCE, @@ -121,7 +121,7 @@ } }, } -INDY_PROOF_REQ_SELFIE = { +ANONCREDS_PROOF_REQ_SELFIE = { "name": PROOF_REQ_NAME, "version": PROOF_REQ_VERSION, "nonce": PROOF_REQ_NONCE, @@ -133,7 +133,7 @@ "0_highscore_GE_uuid": {"name": "highScore", "p_type": ">=", "p_value": 1000000} }, } -INDY_PROOF = { +ANONCREDS_PROOF = { "proof": { "proofs": [ { @@ -252,7 +252,7 @@ } ], } -INDY_PROOF_NAMES = { +ANONCREDS_PROOF_NAMES = { "proof": { "proofs": [ { @@ -512,7 +512,9 @@ async def test_record_eq(self): async def test_create_exchange_for_proposal(self): proposal = V20PresProposal( formats=[ - V20PresFormat(attach_id="indy", format_=V20PresFormat.Format.INDY.aries) + V20PresFormat( + attach_id="anoncreds", format_=V20PresFormat.Format.ANONCREDS.aries + ) ] ) @@ -537,7 +539,9 @@ async def test_receive_proposal(self): connection_record = mock.MagicMock(connection_id=CONN_ID) proposal = V20PresProposal( formats=[ - V20PresFormat(attach_id="indy", format_=V20PresFormat.Format.INDY.aries) + V20PresFormat( + attach_id="anoncreds", format_=V20PresFormat.Format.ANONCREDS.aries + ) ] ) with mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: @@ -555,14 +559,14 @@ async def test_create_bound_request_a(self): proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec = V20PresExRecord( @@ -589,14 +593,14 @@ async def test_create_bound_request_b(self): proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec = V20PresExRecord( @@ -725,14 +729,16 @@ async def test_create_exchange_for_request(self): will_confirm=True, formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(mapping=INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64( + mapping=ANONCREDS_PROOF_REQ_NAME, ident="anoncreds" + ) ], ) pres_req.assign_thread_id("dummy") @@ -765,14 +771,14 @@ async def test_create_pres_indy(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -795,9 +801,9 @@ async def test_create_pres_indy(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAME, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAME, preview=None, holder=self.holder ) - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 2 assert len(req_creds["requested_predicates"]) == 1 @@ -813,9 +819,9 @@ async def test_create_pres_indy_and_dif(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ), V20PresFormat( @@ -826,7 +832,7 @@ async def test_create_pres_indy_and_dif(self): ), ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy"), + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds"), AttachDecorator.data_json(DIF_PRES_REQ, ident="dif"), ], ) @@ -857,9 +863,9 @@ async def test_create_pres_indy_and_dif(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAME, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAME, preview=None, holder=self.holder ) - request_data = {"indy": req_creds, "dif": DIF_PRES_REQ} + request_data = {"anoncreds": req_creds, "dif": DIF_PRES_REQ} assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 2 assert len(req_creds["requested_predicates"]) == 1 @@ -872,19 +878,19 @@ async def test_create_pres_indy_and_dif(self): @pytest.mark.skip(reason="Anoncreds-break") async def test_create_pres_proof_req_non_revoc_interval_none(self): - indy_proof_req_vcx = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req_vcx = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req_vcx["non_revoked"] = None # simulate interop with indy-vcx pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req_vcx, ident="indy") + AttachDecorator.data_base64(indy_proof_req_vcx, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -918,7 +924,7 @@ async def test_create_pres_proof_req_non_revoc_interval_none(self): req_creds = await indy_proof_req_preview2indy_requested_creds( indy_proof_req_vcx, preview=None, holder=self.holder ) - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 2 assert len(req_creds["requested_predicates"]) == 1 @@ -934,14 +940,14 @@ async def test_create_pres_self_asserted(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_SELFIE, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_SELFIE, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -965,9 +971,9 @@ async def test_create_pres_self_asserted(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_SELFIE, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_SELFIE, preview=None, holder=self.holder ) - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} assert len(req_creds["self_attested_attributes"]) == 3 assert not req_creds["requested_attributes"] @@ -991,14 +997,14 @@ async def test_create_pres_no_revocation(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -1042,10 +1048,10 @@ async def test_create_pres_no_revocation(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAME, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAME, preview=None, holder=self.holder ) request_data = { - "indy": { + "anoncreds": { "self_attested_attributes": req_creds["self_attested_attributes"], "requested_attributes": req_creds["requested_attributes"], "requested_predicates": req_creds["requested_predicates"], @@ -1062,7 +1068,7 @@ async def test_create_pres_no_revocation(self): for pred_reft_spec in req_creds["requested_predicates"].values(): pred_reft_spec["timestamp"] = 1234567890 request_data = { - "indy": { + "anoncreds": { "self_attested_attributes": req_creds["self_attested_attributes"], "requested_attributes": req_creds["requested_attributes"], "requested_predicates": req_creds["requested_predicates"], @@ -1076,14 +1082,14 @@ async def test_create_pres_bad_revoc_state(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -1147,14 +1153,14 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAMES, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -1228,12 +1234,12 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): ) req_creds = await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAMES, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAMES, preview=None, holder=self.holder ) assert not req_creds["self_attested_attributes"] assert len(req_creds["requested_attributes"]) == 1 assert len(req_creds["requested_predicates"]) == 1 - request_data = {"indy": req_creds} + request_data = {"anoncreds": req_creds} (px_rec_out, pres_msg) = await self.manager.create_pres( px_rec_in, request_data ) @@ -1244,14 +1250,14 @@ async def test_no_matching_creds_for_proof_req(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAMES, ident="anoncreds") ], ) V20PresExRecord(pres_request=pres_request.serialize()) @@ -1260,7 +1266,7 @@ async def test_no_matching_creds_for_proof_req(self): with self.assertRaises(ValueError): await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAMES, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAMES, preview=None, holder=self.holder ) get_creds = mock.CoroutineMock( @@ -1277,21 +1283,21 @@ async def test_no_matching_creds_for_proof_req(self): ) self.holder.get_credentials_for_presentation_request_by_referent = get_creds await indy_proof_req_preview2indy_requested_creds( - INDY_PROOF_REQ_NAMES, preview=None, holder=self.holder + ANONCREDS_PROOF_REQ_NAMES, preview=None, holder=self.holder ) async def test_no_matching_creds_indy_handler(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAMES, ident="anoncreds") ], ) px_rec_in = V20PresExRecord(pres_request=pres_request.serialize()) @@ -1311,44 +1317,50 @@ async def test_no_matching_creds_indy_handler(self): (px_rec_out, pres_msg) = await self.manager.create_pres( px_rec_in, request_data ) - assert "No matching Indy" in str(context.exception) + assert "AnonCreds interface requires AskarAnoncreds profile" in str( + context.exception + ) async def test_receive_pres(self): connection_record = mock.MagicMock(connection_id=CONN_ID) pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) pres.assign_thread_id("thread-id") @@ -1360,8 +1372,8 @@ async def test_receive_pres(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME - assert by_format.get("pres_request").get("indy") == INDY_PROOF_REQ_NAME + assert by_format.get("pres_proposal").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME + assert by_format.get("pres_request").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME with mock.patch.object( V20PresExRecord, "save", autospec=True @@ -1383,41 +1395,45 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req["requested_predicates"]["0_highscore_GE_uuid"]["restrictions"][0][ "attr::player::value" ] = "impostor" pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) pres.assign_thread_id("thread-id") @@ -1429,8 +1445,8 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME - assert by_format.get("pres_request").get("indy") == indy_proof_req + assert by_format.get("pres_proposal").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME + assert by_format.get("pres_request").get("anoncreds") == indy_proof_req with mock.patch.object( V20PresExRecord, "save", autospec=True @@ -1478,24 +1494,28 @@ async def test_receive_pres_indy_no_predicate_restrictions(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) pres.assign_thread_id("thread-id") @@ -1506,7 +1526,7 @@ async def test_receive_pres_indy_no_predicate_restrictions(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_request").get("indy") == indy_proof_req + assert by_format.get("pres_request").get("anoncreds") == indy_proof_req with mock.patch.object( V20PresExRecord, "save", autospec=True @@ -1538,7 +1558,7 @@ async def test_receive_pres_indy_no_attr_restrictions(self): }, "requested_predicates": {}, } - proof = deepcopy(INDY_PROOF) + proof = deepcopy(ANONCREDS_PROOF) proof["requested_proof"]["revealed_attrs"] = { "0_player_uuid": { "sub_proof_index": 0, @@ -1550,24 +1570,26 @@ async def test_receive_pres_indy_no_attr_restrictions(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(proof, ident="indy")], + presentations_attach=[AttachDecorator.data_base64(proof, ident="anoncreds")], ) pres.assign_thread_id("thread-id") @@ -1578,7 +1600,7 @@ async def test_receive_pres_indy_no_attr_restrictions(self): # cover by_format property by_format = px_rec_dummy.by_format - assert by_format.get("pres_request").get("indy") == indy_proof_req + assert by_format.get("pres_request").get("anoncreds") == indy_proof_req with mock.patch.object( V20PresExRecord, "save", autospec=True @@ -1597,44 +1619,48 @@ async def test_receive_pres_indy_no_attr_restrictions(self): async def test_receive_pres_bait_and_switch_attr_name(self): connection_record = mock.MagicMock(connection_id=CONN_ID) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req["requested_attributes"]["0_screencapture_uuid"]["restrictions"][0][ "attr::screenCapture::value" ] = "c2NyZWVuIGNhcHR1cmUgc2hvd2luZyBzY29yZSBpbiB0aGUgbWlsbGlvbnM=" pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( pres_proposal=pres_proposal.serialize(), @@ -1655,33 +1681,41 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1699,43 +1733,47 @@ async def test_receive_pres_bait_and_switch_attr_name(self): async def test_receive_pres_bait_and_switch_attr_names(self): connection_record = mock.MagicMock(connection_id=CONN_ID) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAMES) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAMES) indy_proof_req["requested_attributes"]["0_player_uuid"]["restrictions"][0][ "attr::screenCapture::value" ] = "c2NyZWVuIGNhcHR1cmUgc2hvd2luZyBzY29yZSBpbiB0aGUgbWlsbGlvbnM=" pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_NAMES, ident="anoncreds") ], ) @@ -1760,34 +1798,40 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_NAMES, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_NAMES, ident="anoncreds") ], ) @@ -1806,42 +1850,46 @@ async def test_receive_pres_bait_and_switch_attr_names(self): async def test_receive_pres_bait_and_switch_pred(self): connection_record = mock.MagicMock(connection_id=CONN_ID) - indy_proof_req = deepcopy(INDY_PROOF_REQ_NAME) + indy_proof_req = deepcopy(ANONCREDS_PROOF_REQ_NAME) indy_proof_req["requested_predicates"] = {} pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], proposals_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1867,33 +1915,41 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1919,33 +1975,41 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -1971,33 +2035,41 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_proposal = V20PresProposal( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_PROPOSAL][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], - proposals_attach=[AttachDecorator.data_base64(indy_proof_req, ident="indy")], + proposals_attach=[ + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") + ], ) pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], request_presentations_attach=[ - AttachDecorator.data_base64(indy_proof_req, ident="indy") + AttachDecorator.data_base64(indy_proof_req, ident="anoncreds") ], ) pres_x = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_dummy = V20PresExRecord( @@ -2020,25 +2092,29 @@ async def test_verify_pres(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ) ], will_confirm=True, request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy") + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds") ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ) ], - presentations_attach=[AttachDecorator.data_base64(INDY_PROOF, ident="indy")], + presentations_attach=[ + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds") + ], ) px_rec_in = V20PresExRecord( pres_request=pres_request, @@ -2063,9 +2139,9 @@ async def test_verify_pres_indy_and_dif(self): pres_request = V20PresRequest( formats=[ V20PresFormat( - attach_id="indy", + attach_id="anoncreds", format_=ATTACHMENT_FORMAT[PRES_20_REQUEST][ - V20PresFormat.Format.INDY.api + V20PresFormat.Format.ANONCREDS.api ], ), V20PresFormat( @@ -2077,15 +2153,17 @@ async def test_verify_pres_indy_and_dif(self): ], will_confirm=True, request_presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF_REQ_NAME, ident="indy"), + AttachDecorator.data_base64(ANONCREDS_PROOF_REQ_NAME, ident="anoncreds"), AttachDecorator.data_json(DIF_PRES_REQ, ident="dif"), ], ) pres = V20Pres( formats=[ V20PresFormat( - attach_id="indy", - format_=ATTACHMENT_FORMAT[PRES_20][V20PresFormat.Format.INDY.api], + attach_id="anoncreds", + format_=ATTACHMENT_FORMAT[PRES_20][ + V20PresFormat.Format.ANONCREDS.api + ], ), V20PresFormat( attach_id="dif", @@ -2093,7 +2171,7 @@ async def test_verify_pres_indy_and_dif(self): ), ], presentations_attach=[ - AttachDecorator.data_base64(INDY_PROOF, ident="indy"), + AttachDecorator.data_base64(ANONCREDS_PROOF, ident="anoncreds"), AttachDecorator.data_json(DIF_PRES, ident="dif"), ], ) diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py index af70cd2d0b..b1fb15ef7f 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py @@ -6,8 +6,10 @@ from marshmallow import ValidationError from .....admin.request_context import AdminRequestContext +from .....anoncreds.models.presentation_request import ( + AnoncredsPresentationReqAttrSpecSchema, +) from .....indy.holder import IndyHolder -from .....indy.models.proof_request import IndyProofReqAttrSpecSchema from .....indy.verifier import IndyVerifier from .....ledger.base import BaseLedger from .....storage.error import StorageNotFoundError @@ -221,7 +223,7 @@ async def test_validate(self): schema.validate_fields({"veres-one": {"no": "support"}}) async def test_validate_proof_req_attr_spec(self): - aspec = IndyProofReqAttrSpecSchema() + aspec = AnoncredsPresentationReqAttrSpecSchema() aspec.validate_fields({"name": "attr0"}) aspec.validate_fields( { diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py index 96c3da744e..faa4f0f278 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py @@ -8,8 +8,10 @@ from .....admin.request_context import AdminRequestContext from .....anoncreds.holder import AnonCredsHolder +from .....anoncreds.models.presentation_request import ( + AnoncredsPresentationReqAttrSpecSchema, +) from .....anoncreds.verifier import AnonCredsVerifier -from .....indy.models.proof_request import IndyProofReqAttrSpecSchema from .....ledger.base import BaseLedger from .....storage.error import StorageNotFoundError from .....storage.vc_holder.base import VCHolder @@ -223,7 +225,7 @@ async def test_validate(self): schema.validate_fields({"veres-one": {"no": "support"}}) async def test_validate_proof_req_attr_spec(self): - aspec = IndyProofReqAttrSpecSchema() + aspec = AnoncredsPresentationReqAttrSpecSchema() aspec.validate_fields({"name": "attr0"}) aspec.validate_fields( { diff --git a/acapy_agent/revocation_anoncreds/routes.py b/acapy_agent/revocation_anoncreds/routes.py index 928ef0ebd8..4c5b3bd8b0 100644 --- a/acapy_agent/revocation_anoncreds/routes.py +++ b/acapy_agent/revocation_anoncreds/routes.py @@ -24,7 +24,7 @@ ) from ..anoncreds.default.legacy_indy.registry import LegacyIndyRegistry from ..anoncreds.issuer import AnonCredsIssuerError -from ..anoncreds.models.anoncreds_revocation import RevRegDefState +from ..anoncreds.models.revocation import RevRegDefState from ..anoncreds.revocation import AnonCredsRevocation, AnonCredsRevocationError from ..anoncreds.routes import ( create_transaction_for_endorser_description, diff --git a/acapy_agent/revocation_anoncreds/tests/test_routes.py b/acapy_agent/revocation_anoncreds/tests/test_routes.py index 11d4ea25e3..4fef93761e 100644 --- a/acapy_agent/revocation_anoncreds/tests/test_routes.py +++ b/acapy_agent/revocation_anoncreds/tests/test_routes.py @@ -6,7 +6,7 @@ from aiohttp.web import HTTPNotFound from ...admin.request_context import AdminRequestContext -from ...anoncreds.models.anoncreds_revocation import RevRegDef, RevRegDefValue +from ...anoncreds.models.revocation import RevRegDef, RevRegDefValue from ...tests import mock from ...utils.testing import create_test_profile from .. import routes as test_module diff --git a/acapy_agent/vc/vc_ld/models/linked_data_proof.py b/acapy_agent/vc/vc_ld/models/linked_data_proof.py index c441ff5911..57853000c6 100644 --- a/acapy_agent/vc/vc_ld/models/linked_data_proof.py +++ b/acapy_agent/vc/vc_ld/models/linked_data_proof.py @@ -6,8 +6,8 @@ from ....messaging.models.base import BaseModel, BaseModelSchema from ....messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, UUID4_EXAMPLE, Uri, ) @@ -93,13 +93,13 @@ class Meta: created = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "The string value of an ISO8601 combined date and time string generated" " by the Signature Algorithm" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/vc/vc_ld/models/options.py b/acapy_agent/vc/vc_ld/models/options.py index 2d7adbe4e2..a939df56ac 100644 --- a/acapy_agent/vc/vc_ld/models/options.py +++ b/acapy_agent/vc/vc_ld/models/options.py @@ -5,8 +5,8 @@ from marshmallow import INCLUDE, Schema, fields from acapy_agent.messaging.valid import ( - INDY_ISO8601_DATETIME_EXAMPLE, - INDY_ISO8601_DATETIME_VALIDATE, + ISO8601_DATETIME_EXAMPLE, + ISO8601_DATETIME_VALIDATE, UUID4_EXAMPLE, ) @@ -124,13 +124,13 @@ class Meta: created = fields.Str( required=False, - validate=INDY_ISO8601_DATETIME_VALIDATE, + validate=ISO8601_DATETIME_VALIDATE, metadata={ "description": ( "The date and time of the proof (with a maximum accuracy in seconds)." " Defaults to current system time" ), - "example": INDY_ISO8601_DATETIME_EXAMPLE, + "example": ISO8601_DATETIME_EXAMPLE, }, ) diff --git a/acapy_agent/wallet/anoncreds_upgrade.py b/acapy_agent/wallet/anoncreds_upgrade.py index 12f2cb2dd3..ce944c75d7 100644 --- a/acapy_agent/wallet/anoncreds_upgrade.py +++ b/acapy_agent/wallet/anoncreds_upgrade.py @@ -21,15 +21,15 @@ CATEGORY_CRED_DEF_PRIVATE, CATEGORY_SCHEMA, ) -from ..anoncreds.models.anoncreds_cred_def import CredDef, CredDefState -from ..anoncreds.models.anoncreds_revocation import ( +from ..anoncreds.models.credential_definition import CredDef, CredDefState +from ..anoncreds.models.revocation import ( RevList, RevListState, RevRegDef, RevRegDefState, RevRegDefValue, ) -from ..anoncreds.models.anoncreds_schema import SchemaState +from ..anoncreds.models.schema import SchemaState from ..anoncreds.revocation import ( CATEGORY_REV_LIST, CATEGORY_REV_REG_DEF, diff --git a/acapy_agent/wallet/routes.py b/acapy_agent/wallet/routes.py index 00bc48cfb1..cf539d61ac 100644 --- a/acapy_agent/wallet/routes.py +++ b/acapy_agent/wallet/routes.py @@ -9,11 +9,10 @@ from aiohttp_apispec import docs, querystring_schema, request_schema, response_schema from marshmallow import fields, validate -from acapy_agent.connections.base_manager import BaseConnectionManager - from ..admin.decorators.auth import tenant_authentication from ..admin.request_context import AdminRequestContext from ..config.injection_context import InjectionContext +from ..connections.base_manager import BaseConnectionManager from ..connections.models.conn_record import ConnRecord from ..core.event_bus import Event, EventBus from ..core.profile import Profile @@ -35,12 +34,12 @@ GENERIC_DID_VALIDATE, INDY_DID_EXAMPLE, INDY_DID_VALIDATE, - INDY_RAW_PUBLIC_KEY_EXAMPLE, - INDY_RAW_PUBLIC_KEY_VALIDATE, JWT_EXAMPLE, JWT_VALIDATE, NON_SD_LIST_EXAMPLE, NON_SD_LIST_VALIDATE, + RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, + RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, SD_JWT_EXAMPLE, SD_JWT_VALIDATE, UUID4_EXAMPLE, @@ -95,10 +94,10 @@ class DIDSchema(OpenAPISchema): ) verkey = fields.Str( required=True, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Public verification key", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) posture = fields.Str( @@ -293,10 +292,10 @@ class DIDListQueryStringSchema(OpenAPISchema): ) verkey = fields.Str( required=False, - validate=INDY_RAW_PUBLIC_KEY_VALIDATE, + validate=RAW_ED25519_2018_PUBLIC_KEY_VALIDATE, metadata={ "description": "Verification key of interest", - "example": INDY_RAW_PUBLIC_KEY_EXAMPLE, + "example": RAW_ED25519_2018_PUBLIC_KEY_EXAMPLE, }, ) posture = fields.Str( diff --git a/demo/bdd_support/agent_backchannel_client.py b/demo/bdd_support/agent_backchannel_client.py index 5d116e2fea..fa6db011c7 100644 --- a/demo/bdd_support/agent_backchannel_client.py +++ b/demo/bdd_support/agent_backchannel_client.py @@ -143,11 +143,13 @@ def aries_container_issue_credential( the_container: AgentContainer, cred_def_id: str, cred_attrs: list, + filter_type: str = "indy", ): return run_coroutine( the_container.issue_credential, cred_def_id, cred_attrs, + filter_type=filter_type, ) @@ -167,11 +169,13 @@ def aries_container_request_proof( the_container: AgentContainer, proof_request: dict, explicit_revoc_required: bool = False, + is_anoncreds: bool = False, ): return run_coroutine( the_container.request_proof, proof_request, explicit_revoc_required=explicit_revoc_required, + is_anoncreds=is_anoncreds, ) diff --git a/demo/features/0453-issue-credential.feature b/demo/features/0453-issue-credential.feature index 3927bbf4d9..4f9b47e46d 100644 --- a/demo/features/0453-issue-credential.feature +++ b/demo/features/0453-issue-credential.feature @@ -30,7 +30,7 @@ Feature: RFC 0453 Aries agent issue credential | --public-did --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | driverslicense | Data_DL_NormalizedValues | | | | --public-did --wallet-type askar-anoncreds --cred-type vc_di | --wallet-type askar-anoncreds | driverslicense | Data_DL_NormalizedValues | | | - @Release @WalletType_Askar_AnonCreds @AltTests + @PR @Release @WalletType_Askar_AnonCreds Examples: | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Acme_extra | Bob_extra | | --public-did --wallet-type askar-anoncreds | | driverslicense | Data_DL_NormalizedValues | | | diff --git a/demo/features/steps/0453-issue-credential.py b/demo/features/steps/0453-issue-credential.py index 97106d3e1d..d96fdae10a 100644 --- a/demo/features/steps/0453-issue-credential.py +++ b/demo/features/steps/0453-issue-credential.py @@ -62,10 +62,9 @@ def step_impl(context, issuer, credential_data): agent = context.active_agents[issuer] cred_attrs = read_credential_data(context.schema_name, credential_data) + filter_type = "indy" if not is_anoncreds(agent) else "anoncreds" cred_exchange = aries_container_issue_credential( - agent["agent"], - context.cred_def_id, - cred_attrs, + agent["agent"], context.cred_def_id, cred_attrs, filter_type ) context.cred_attrs = cred_attrs diff --git a/demo/features/steps/0454-present-proof.py b/demo/features/steps/0454-present-proof.py index 984ee72e63..31e91930f5 100644 --- a/demo/features/steps/0454-present-proof.py +++ b/demo/features/steps/0454-present-proof.py @@ -34,7 +34,11 @@ def step_impl(context, verifier, request_for_proof, prover): "restrictions" ] = cred_def_restrictions - proof_exchange = aries_container_request_proof(agent["agent"], proof_request_info) + proof_exchange = aries_container_request_proof( + agent["agent"], + proof_request_info, + agent["agent"].wallet_type == "askar-anoncreds", + ) context.proof_request = proof_request_info context.proof_exchange = proof_exchange @@ -49,7 +53,10 @@ def step_impl(context, verifier, request_for_proof, prover): proof_request_info = read_proof_req_data(request_for_proof) proof_exchange = aries_container_request_proof( - agent["agent"], proof_request_info, explicit_revoc_required=True + agent["agent"], + proof_request_info, + explicit_revoc_required=True, + is_anoncreds=agent["agent"].wallet_type == "askar-anoncreds", ) context.proof_request = proof_request_info diff --git a/demo/features/steps/0586-sign-transaction.py b/demo/features/steps/0586-sign-transaction.py index bf5a8a0c3c..f8ade72f98 100644 --- a/demo/features/steps/0586-sign-transaction.py +++ b/demo/features/steps/0586-sign-transaction.py @@ -593,14 +593,15 @@ def step_impl(context, agent_name): agent["agent"], "/issue-credential-2.0/records/" + cred_exchange["cred_ex_id"] ) context.cred_exchange = cred_exchange + cred_exchange_format = cred_exchange.get("indy") or cred_exchange.get("anoncreds") agent_container_POST( agent["agent"], endpoint, data={ - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "cred_rev_id": cred_exchange_format["cred_rev_id"], "publish": False, - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], + "rev_reg_id": cred_exchange_format["rev_reg_id"], "connection_id": cred_exchange["cred_ex_record"]["connection_id"], }, ) @@ -627,11 +628,13 @@ def step_impl(context, agent_name): context.cred_exchange = cred_exchange connection_id = agent["agent"].agent.connection_id + cred_exchange_format = cred_exchange.get("indy") or cred_exchange.get("anoncreds") + # revoke the credential if not is_anoncreds(agent): data = { - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "rev_reg_id": cred_exchange_format["rev_reg_id"], + "cred_rev_id": cred_exchange_format["cred_rev_id"], "publish": False, "connection_id": cred_exchange["cred_ex_record"]["connection_id"], } @@ -642,9 +645,9 @@ def step_impl(context, agent_name): endpoint = "/revocation/revoke" else: data = { - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "cred_rev_id": cred_exchange_format["cred_rev_id"], "publish": False, - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], + "rev_reg_id": cred_exchange_format["rev_reg_id"], "connection_id": cred_exchange["cred_ex_record"]["connection_id"], "options": { "endorser_connection_id": connection_id, @@ -676,15 +679,17 @@ def step_impl(context, agent_name): else: endpoint = "/anoncreds/revocation/publish-revocations" + cred_exchange_format = context.cred_exchange.get("indy") or context.cred_exchange.get( + "anoncreds" + ) + # create rev_reg entry transaction created_rev_reg = agent_container_POST( agent["agent"], endpoint, data={ "rrid2crid": { - context.cred_exchange["indy"]["rev_reg_id"]: [ - context.cred_exchange["indy"]["cred_rev_id"] - ] + cred_exchange_format["rev_reg_id"]: [cred_exchange_format["cred_rev_id"]] } }, params={}, @@ -703,14 +708,15 @@ def step_impl(context, agent_name): agent = context.active_agents[agent_name] connection_id = agent["agent"].agent.connection_id + cred_exchange_format = context.cred_exchange.get("indy") or context.cred_exchange.get( + "anoncreds" + ) # create rev_reg entry transaction if not is_anoncreds(agent): data = { "rrid2crid": { - context.cred_exchange["indy"]["rev_reg_id"]: [ - context.cred_exchange["indy"]["cred_rev_id"] - ] + cred_exchange_format["rev_reg_id"]: [cred_exchange_format["cred_rev_id"]] } } params = { @@ -721,9 +727,7 @@ def step_impl(context, agent_name): else: data = { "rrid2crid": { - context.cred_exchange["indy"]["rev_reg_id"]: [ - context.cred_exchange["indy"]["cred_rev_id"] - ] + cred_exchange_format["rev_reg_id"]: [cred_exchange_format["cred_rev_id"]] }, "options": { "endorser_connection_id": connection_id, diff --git a/demo/features/upgrade.feature b/demo/features/upgrade.feature index 259c7a485a..557dd75646 100644 --- a/demo/features/upgrade.feature +++ b/demo/features/upgrade.feature @@ -19,10 +19,7 @@ Feature: ACA-Py Anoncreds Upgrade Then "Faber" has the proof verification fail Then "Bob" can verify the credential from "" was revoked And "" upgrades the wallet to anoncreds - And "Bob" has an issued credential from "" And "Bob" upgrades the wallet to anoncreds - And "Bob" has an issued credential from "" - When "Faber" sends a request for proof presentation to "Bob" Examples: | issuer | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Proof_request | diff --git a/demo/runners/agent_container.py b/demo/runners/agent_container.py index c2ad39fe5f..61b07f4ef7 100644 --- a/demo/runners/agent_container.py +++ b/demo/runners/agent_container.py @@ -36,6 +36,8 @@ log_timer, ) +from .support.agent import CRED_FORMAT_ANONCREDS + CRED_PREVIEW_TYPE = "https://didcomm.org/issue-credential/2.0/credential-preview" SELF_ATTESTED = os.getenv("SELF_ATTESTED") TAILS_FILE_COUNT = int(os.getenv("TAILS_FILE_COUNT", 100)) @@ -272,16 +274,25 @@ async def handle_issue_credential_v2_0(self, message): elif state == "offer-received": log_status("#15 After receiving credential offer, send credential request") + + def _should_send_request_without_data(message): + """Formats that do not require credential request data.""" + cred_offer_by_format = message["by_format"].get("cred_offer") + + return ( + not message.get("by_format") + or cred_offer_by_format.get("anoncreds") + or cred_offer_by_format.get("indy") + or cred_offer_by_format.get("vc_di") + ) + # Should wait for a tiny bit for the delete tests await asyncio.sleep(0.2) if not message.get("by_format"): # this should not happen, something hinky when running in IDE... # this will work if using indy payloads self.log(f"No 'by_format' in message: {message}") - await self.admin_POST( - f"/issue-credential-2.0/records/{cred_ex_id}/send-request" - ) - elif message["by_format"]["cred_offer"].get("indy"): + elif _should_send_request_without_data(message): await self.admin_POST( f"/issue-credential-2.0/records/{cred_ex_id}/send-request" ) @@ -294,10 +305,6 @@ async def handle_issue_credential_v2_0(self, message): await self.admin_POST( f"/issue-credential-2.0/records/{cred_ex_id}/send-request", data ) - elif message["by_format"]["cred_offer"].get("vc_di"): - await self.admin_POST( - f"/issue-credential-2.0/records/{cred_ex_id}/send-request" - ) elif state == "done": pass @@ -327,6 +334,26 @@ async def handle_issue_credential_v2_0_indy(self, message): self.log(f"Revocation registry ID: {rev_reg_id}") self.log(f"Credential revocation ID: {cred_rev_id}") + async def handle_issue_credential_v2_0_anoncreds(self, message): + rev_reg_id = message.get("rev_reg_id") + cred_rev_id = message.get("cred_rev_id") + cred_id_stored = message.get("cred_id_stored") + + if cred_id_stored: + cred_id = message["cred_id_stored"] + log_status(f"#18.1 Stored credential {cred_id} in wallet") + cred = await self.admin_GET(f"/credential/{cred_id}") + log_json(cred, label="Credential details:") + self.log("credential_id", cred_id) + self.log("cred_def_id", cred["cred_def_id"]) + self.log("schema_id", cred["schema_id"]) + # track last successfully received credential + self.last_credential_received = cred + + if rev_reg_id and cred_rev_id: + self.log(f"Revocation registry ID: {rev_reg_id}") + self.log(f"Credential revocation ID: {cred_rev_id}") + async def handle_issue_credential_v2_0_vc_di(self, message): self.log(f"Handle VC_DI Credential: message = {message}") @@ -442,16 +469,18 @@ async def handle_present_proof_v2_0(self, message): # this should not happen, something hinky when running in IDE... self.log(f"No 'by_format' in message: {message}") else: - pres_request_indy = ( - message["by_format"].get("pres_request", {}).get("indy") - ) - pres_request_dif = message["by_format"].get("pres_request", {}).get("dif") + pres_request_by_format = message["by_format"].get("pres_request", {}) + pres_request = pres_request_by_format.get( + "indy" + ) or pres_request_by_format.get("anoncreds") + + pres_request_dif = pres_request_by_format.get("dif") request = {} - if not pres_request_dif and not pres_request_indy: + if not pres_request_dif and not pres_request: raise Exception("Invalid presentation request received") - if pres_request_indy: + if pres_request: # include self-attested attributes (not included in credentials) creds_by_reft = {} revealed = {} @@ -463,7 +492,6 @@ async def handle_present_proof_v2_0(self, message): creds = await self.admin_GET( f"/present-proof-2.0/records/{pres_ex_id}/credentials" ) - # print(">>> creds:", creds) if creds: # select only indy credentials creds = [x for x in creds if "cred_info" in x] @@ -484,7 +512,7 @@ async def handle_present_proof_v2_0(self, message): # submit the proof wit one unrevealed revealed attribute revealed_flag = False - for referent in pres_request_indy["requested_attributes"]: + for referent in pres_request["requested_attributes"]: if referent in creds_by_reft: revealed[referent] = { "cred_id": creds_by_reft[referent]["cred_info"][ @@ -496,7 +524,7 @@ async def handle_present_proof_v2_0(self, message): else: self_attested[referent] = "my self-attested value" - for referent in pres_request_indy["requested_predicates"]: + for referent in pres_request["requested_predicates"]: if referent in creds_by_reft: predicates[referent] = { "cred_id": creds_by_reft[referent]["cred_info"][ @@ -504,15 +532,15 @@ async def handle_present_proof_v2_0(self, message): ] } - log_status("#25 Generate the indy proof") - indy_request = { - "indy": { + log_status("#25 Generate the proof") + request = { + "indy" if "indy" in pres_request_by_format else "anoncreds": { "requested_predicates": predicates, "requested_attributes": revealed, "self_attested_attributes": self_attested, } } - request.update(indy_request) + request.update(request) except ClientError: pass @@ -779,7 +807,7 @@ def __init__( # endorsers and authors need public DIDs (assume cred_type is Indy) if endorser_role == "author" or endorser_role == "endorser": self.public_did = True - self.cred_type = CRED_FORMAT_INDY + # self.cred_type = CRED_FORMAT_INDY self.reuse_connections = reuse_connections self.multi_use_invitations = multi_use_invitations @@ -938,7 +966,7 @@ async def create_schema_and_cred_def( ): if not self.public_did: raise Exception("Can't create a schema/cred def without a public DID :-(") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: # need to redister schema and cred def on the ledger self.cred_def_id = await self.agent.create_schema_and_cred_def( schema_name, @@ -981,20 +1009,26 @@ async def issue_credential( self, cred_def_id: str, cred_attrs: list, + filter_type: str = "indy", ): log_status("#13 Issue credential offer to X") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": cred_attrs, } + if filter_type == "indy": + _filter = {"indy": {"cred_def_id": cred_def_id}} + else: + _filter = {"anoncreds": {"cred_def_id": cred_def_id}} + offer_request = { "connection_id": self.agent.connection_id, "comment": f"Offer on cred def id {cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, - "filter": {"indy": {"cred_def_id": cred_def_id}}, + "filter": _filter, "trace": self.exchange_tracing, } cred_exchange = await self.agent.admin_POST( @@ -1041,11 +1075,13 @@ async def receive_credential( return matched - async def request_proof(self, proof_request, explicit_revoc_required: bool = False): + async def request_proof( + self, proof_request, explicit_revoc_required: bool = False, is_anoncreds=False + ): log_status("#20 Request proof of degree from alice") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: - indy_proof_request = { + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + proof_request = { "name": ( proof_request["name"] if "name" in proof_request else "Proof of stuff" ), @@ -1061,24 +1097,24 @@ async def request_proof(self, proof_request, explicit_revoc_required: bool = Fal # plug in revocation where requested in the supplied proof request non_revoked = {"to": int(time.time())} if "non_revoked" in proof_request: - indy_proof_request["non_revoked"] = non_revoked + proof_request["non_revoked"] = non_revoked non_revoked_supplied = True for attr in proof_request["requested_attributes"]: if "non_revoked" in proof_request["requested_attributes"][attr]: - indy_proof_request["requested_attributes"][attr][ - "non_revoked" - ] = non_revoked + proof_request["requested_attributes"][attr]["non_revoked"] = ( + non_revoked + ) non_revoked_supplied = True for pred in proof_request["requested_predicates"]: if "non_revoked" in proof_request["requested_predicates"][pred]: - indy_proof_request["requested_predicates"][pred][ - "non_revoked" - ] = non_revoked + proof_request["requested_predicates"][pred]["non_revoked"] = ( + non_revoked + ) non_revoked_supplied = True if not non_revoked_supplied and not explicit_revoc_required: # else just make it global - indy_proof_request["non_revoked"] = non_revoked + proof_request["non_revoked"] = non_revoked else: # make sure we are not leaking non-revoc requests @@ -1091,13 +1127,16 @@ async def request_proof(self, proof_request, explicit_revoc_required: bool = Fal if "non_revoked" in proof_request["requested_predicates"][pred]: del proof_request["requested_predicates"][pred]["non_revoked"] - log_status(f" >>> asking for proof for request: {indy_proof_request}") + log_status(f" >>> asking for proof for request: {proof_request}") + + if is_anoncreds: + presentation_request = {"anoncreds": proof_request} + else: + presentation_request = {"indy": proof_request} proof_request_web_request = { "connection_id": self.agent.connection_id, - "presentation_request": { - "indy": indy_proof_request, - }, + "presentation_request": presentation_request, "trace": self.exchange_tracing, } proof_exchange = await self.agent.admin_POST( @@ -1108,7 +1147,6 @@ async def request_proof(self, proof_request, explicit_revoc_required: bool = Fal elif self.cred_type == CRED_FORMAT_JSON_LD: # TODO create and send the json-ld proof request - pass return None else: @@ -1125,7 +1163,7 @@ async def verify_proof(self, proof_request): # log_status(f">>> last proof received: {self.agent.last_proof_received}") - if self.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if self.cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: # return verified status return self.agent.last_proof_received["verified"] @@ -1514,12 +1552,14 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non aip = 20 if "cred_type" in args and args.cred_type not in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: public_did = None aip = 20 elif "cred_type" in args and args.cred_type in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: @@ -1528,6 +1568,12 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non public_did = args.public_did if "public_did" in args else None cred_type = args.cred_type if "cred_type" in args else None + + # Set anoncreds agent to use anoncreds credential format + wallet_type = arg_file_dict.get("wallet-type") or args.wallet_type + if wallet_type == "askar-anoncreds": + cred_type = CRED_FORMAT_ANONCREDS + log_msg( f"Initializing demo agent {agent_ident} with AIP {aip} and credential type {cred_type}" ) @@ -1564,7 +1610,7 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non mediation=args.mediation, cred_type=cred_type, use_did_exchange=(aip == 20) if ("aip" in args) else args.did_exchange, - wallet_type=arg_file_dict.get("wallet-type") or args.wallet_type, + wallet_type=wallet_type, public_did=public_did, seed="random" if public_did else None, arg_file=arg_file, diff --git a/demo/runners/faber.py b/demo/runners/faber.py index 5cecf47d37..00cc9a2e98 100644 --- a/demo/runners/faber.py +++ b/demo/runners/faber.py @@ -17,6 +17,7 @@ create_agent_with_args, ) from runners.support.agent import ( # noqa:E402 + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_JSON_LD, CRED_FORMAT_VC_DI, @@ -111,7 +112,7 @@ def generate_credential_offer(self, aip, cred_type, cred_def_id, exchange_tracin return offer_request elif aip == 20: - if cred_type == CRED_FORMAT_INDY: + if cred_type == CRED_FORMAT_ANONCREDS or cred_type == CRED_FORMAT_INDY: self.cred_attrs[cred_def_id] = { "name": "Alice Smith", "date": "2018-05-28", @@ -127,12 +128,16 @@ def generate_credential_offer(self, aip, cred_type, cred_def_id, exchange_tracin for (n, v) in self.cred_attrs[cred_def_id].items() ], } + if cred_type == CRED_FORMAT_ANONCREDS: + _filter = {"anoncreds": {"cred_def_id": cred_def_id}} + else: + _filter = {"indy": {"cred_def_id": cred_def_id}} offer_request = { "connection_id": self.connection_id, "comment": f"Offer on cred def id {cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, - "filter": {"indy": {"cred_def_id": cred_def_id}}, + "filter": _filter, "trace": exchange_tracing, } return offer_request @@ -249,7 +254,7 @@ def generate_proof_request_web_request( "restrictions": [{"schema_name": "degree schema"}], } ] - indy_proof_request = { + proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { @@ -261,10 +266,10 @@ def generate_proof_request_web_request( } if revocation: - indy_proof_request["non_revoked"] = {"to": int(time.time())} + proof_request["non_revoked"] = {"to": int(time.time())} proof_request_web_request = { - "proof_request": indy_proof_request, + "proof_request": proof_request, "trace": exchange_tracing, } if not connectionless: @@ -272,7 +277,7 @@ def generate_proof_request_web_request( return proof_request_web_request elif aip == 20: - if cred_type == CRED_FORMAT_INDY: + if cred_type == CRED_FORMAT_ANONCREDS or cred_type == CRED_FORMAT_INDY: req_attrs = [ { "name": "name", @@ -312,7 +317,7 @@ def generate_proof_request_web_request( "restrictions": [{"schema_name": "degree schema"}], } ] - indy_proof_request = { + proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { @@ -325,14 +330,19 @@ def generate_proof_request_web_request( } if revocation: - indy_proof_request["non_revoked"] = {"to": int(time.time())} + proof_request["non_revoked"] = {"to": int(time.time())} + if cred_type == CRED_FORMAT_ANONCREDS: + presentation_request = {"anoncreds": proof_request} + else: + presentation_request = {"indy": proof_request} proof_request_web_request = { - "presentation_request": {"indy": indy_proof_request}, + "presentation_request": presentation_request, "trace": exchange_tracing, } if not connectionless: proof_request_web_request["connection_id"] = self.connection_id + return proof_request_web_request elif cred_type == CRED_FORMAT_VC_DI: @@ -537,7 +547,11 @@ async def main(args): "birthdate_dateint", "timestamp", ] - if faber_agent.cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + ]: faber_agent.public_did = True await faber_agent.initialize( the_agent=agent, @@ -569,6 +583,7 @@ async def main(args): exchange_tracing = False options = " (1) Issue Credential\n" if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: @@ -664,12 +679,14 @@ async def main(args): elif option == "1a": new_cred_type = await prompt( - "Enter credential type ({}, {}): ".format( + "Enter credential type ({}, {}, {}): ".format( + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ) ) if new_cred_type in [ + CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI, ]: @@ -689,7 +706,11 @@ async def main(args): ) elif faber_agent.aip == 20: - if faber_agent.cred_type == CRED_FORMAT_INDY: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + ]: offer_request = faber_agent.agent.generate_credential_offer( faber_agent.aip, faber_agent.cred_type, @@ -705,14 +726,6 @@ async def main(args): exchange_tracing, ) - elif faber_agent.cred_type == CRED_FORMAT_VC_DI: - offer_request = faber_agent.agent.generate_credential_offer( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.cred_def_id, - exchange_tracing, - ) - else: raise Exception( f"Error invalid credential type: {faber_agent.cred_type}" @@ -742,27 +755,12 @@ async def main(args): pass elif faber_agent.aip == 20: - if faber_agent.cred_type == CRED_FORMAT_INDY: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - ) - ) - - elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - ) - ) - - elif faber_agent.cred_type == CRED_FORMAT_VC_DI: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + CRED_FORMAT_JSON_LD, + ]: proof_request_web_request = ( faber_agent.agent.generate_proof_request_web_request( faber_agent.aip, @@ -771,7 +769,6 @@ async def main(args): exchange_tracing, ) ) - else: raise Exception( "Error invalid credential type:" + faber_agent.cred_type @@ -819,28 +816,12 @@ async def main(args): qr.print_ascii(invert=True) elif faber_agent.aip == 20: - if faber_agent.cred_type == CRED_FORMAT_INDY: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - connectionless=True, - ) - ) - elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: - proof_request_web_request = ( - faber_agent.agent.generate_proof_request_web_request( - faber_agent.aip, - faber_agent.cred_type, - faber_agent.revocation, - exchange_tracing, - connectionless=True, - ) - ) - - elif faber_agent.cred_type == CRED_FORMAT_VC_DI: + if faber_agent.cred_type in [ + CRED_FORMAT_ANONCREDS, + CRED_FORMAT_INDY, + CRED_FORMAT_VC_DI, + CRED_FORMAT_JSON_LD, + ]: proof_request_web_request = ( faber_agent.agent.generate_proof_request_web_request( faber_agent.aip, diff --git a/demo/runners/support/agent.py b/demo/runners/support/agent.py index 2905ad4912..5d1e10ccd6 100644 --- a/demo/runners/support/agent.py +++ b/demo/runners/support/agent.py @@ -70,6 +70,7 @@ WALLET_TYPE_ASKAR = "askar" WALLET_TYPE_ANONCREDS = "askar-anoncreds" +CRED_FORMAT_ANONCREDS = "anoncreds" CRED_FORMAT_INDY = "indy" CRED_FORMAT_JSON_LD = "json-ld" CRED_FORMAT_VC_DI = "vc_di" @@ -672,7 +673,7 @@ async def register_did( role: str = "TRUST_ANCHOR", cred_type: str = CRED_FORMAT_INDY, ): - if cred_type in [CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: + if cred_type in [CRED_FORMAT_ANONCREDS, CRED_FORMAT_INDY, CRED_FORMAT_VC_DI]: # if registering a did for issuing indy credentials, publish the did on the ledger self.log(f"Registering {self.ident} ...") if not ledger_url: diff --git a/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml b/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml index 247a0b7daf..6e0a757fbd 100644 --- a/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml +++ b/scenarios/examples/anoncreds_issuance_and_revocation/docker-compose.yml @@ -1,22 +1,26 @@ services: - alice: + agency: image: acapy-test ports: - "3001:3001" command: > start - --label Alice + --label Agency --inbound-transport http 0.0.0.0 3000 --outbound-transport http - --endpoint http://alice:3000 + --endpoint http://agency:3000 --admin 0.0.0.0 3001 --admin-insecure-mode --tails-server-base-url http://tails:6543 --genesis-url http://test.bcovrin.vonx.io/genesis - --wallet-type askar-anoncreds - --wallet-name alice + --wallet-type askar + --wallet-name agency --wallet-key insecure --auto-provision + --multitenant + --multitenant-admin + --jwt-secret insecure + --multitenancy-config wallet_type=single-wallet-askar key_derivation_method=RAW --log-level info --debug-webhooks --notify-revocation @@ -30,22 +34,50 @@ tails: condition: service_started - bob: + holder_anoncreds: image: acapy-test ports: - "3002:3001" command: > start - --label Bob + --label Holder-Anoncreds --inbound-transport http 0.0.0.0 3000 --outbound-transport http - --endpoint http://bob:3000 + --endpoint http://holder_anoncreds:3000 --admin 0.0.0.0 3001 --admin-insecure-mode --tails-server-base-url http://tails:6543 --genesis-url http://test.bcovrin.vonx.io/genesis --wallet-type askar-anoncreds - --wallet-name bob + --wallet-name holder_anoncreds + --wallet-key insecure + --auto-provision + --log-level info + --debug-webhooks + --monitor-revocation-notification + healthcheck: + test: curl -s -o /dev/null -w '%{http_code}' "http://localhost:3001/status/live" | grep "200" > /dev/null + start_period: 30s + interval: 7s + timeout: 5s + retries: 5 + + holder_indy: + image: acapy-test + ports: + - "3003:3001" + command: > + start + --label Holder-Indy + --inbound-transport http 0.0.0.0 3000 + --outbound-transport http + --endpoint http://holder_indy:3000 + --admin 0.0.0.0 3001 + --admin-insecure-mode + --tails-server-base-url http://tails:6543 + --genesis-url http://test.bcovrin.vonx.io/genesis + --wallet-type askar + --wallet-name holder_indy --wallet-key insecure --auto-provision --log-level info @@ -63,15 +95,18 @@ build: context: ../.. environment: - - ALICE=http://alice:3001 - - BOB=http://bob:3001 + - AGENCY=http://agency:3001 + - HOLDER_ANONCREDS=http://holder_anoncreds:3001 + - HOLDER_INDY=http://holder_indy:3001 volumes: - ./example.py:/usr/src/app/example.py:ro,z command: python -m example depends_on: - alice: + agency: + condition: service_healthy + holder_anoncreds: condition: service_healthy - bob: + holder_indy: condition: service_healthy tails: diff --git a/scenarios/examples/anoncreds_issuance_and_revocation/example.py b/scenarios/examples/anoncreds_issuance_and_revocation/example.py index 6d7d1a1bd2..05a68c395a 100644 --- a/scenarios/examples/anoncreds_issuance_and_revocation/example.py +++ b/scenarios/examples/anoncreds_issuance_and_revocation/example.py @@ -7,23 +7,30 @@ import json from dataclasses import dataclass from os import getenv -from secrets import token_hex +from secrets import randbelow, token_hex +from typing import Any, Dict, List, Mapping, Optional, Tuple, Type, Union +from uuid import uuid4 from acapy_controller import Controller -from acapy_controller.controller import Minimal +from acapy_controller.controller import Minimal, MinType from acapy_controller.logging import logging_to_stdout -from acapy_controller.models import V20PresExRecord, V20PresExRecordList +from acapy_controller.models import ( + CreateWalletResponse, + V20CredExRecordIndy, + V20PresExRecord, + V20PresExRecordList, +) from acapy_controller.protocols import ( DIDResult, didexchange, - indy_issue_credential_v2, - indy_present_proof_v2, + indy_anoncred_credential_artifacts, params, ) from aiohttp import ClientSession -ALICE = getenv("ALICE", "http://alice:3001") -BOB = getenv("BOB", "http://bob:3001") +AGENCY = getenv("AGENCY", "http://agency:3001") +HOLDER_ANONCREDS = getenv("HOLDER_ANONCREDS", "http://holder_anoncreds:3001") +HOLDER_INDY = getenv("HOLDER_INDY", "http://holder_indy:3001") def summary(presentation: V20PresExRecord) -> str: @@ -33,7 +40,9 @@ def summary(presentation: V20PresExRecord) -> str: { "state": presentation.state, "verified": presentation.verified, - "presentation_request": request.dict(by_alias=True) if request else None, + "presentation_request": request.model_dump(by_alias=True) + if request + else None, }, indent=2, sort_keys=True, @@ -41,32 +50,395 @@ def summary(presentation: V20PresExRecord) -> str: @dataclass -class SchemaResult(Minimal): +class SchemaResultAnoncreds(Minimal): """Schema result.""" schema_state: dict @dataclass -class CredDefResult(Minimal): +class CredDefResultAnoncreds(Minimal): """Credential definition result.""" credential_definition_state: dict +@dataclass +class V20CredExRecord(Minimal): + """V2.0 credential exchange record.""" + + state: str + cred_ex_id: str + connection_id: str + thread_id: str + + +@dataclass +class V20CredExRecordFormat(Minimal): + """V2.0 credential exchange record anoncreds.""" + + rev_reg_id: Optional[str] = None + cred_rev_id: Optional[str] = None + + +@dataclass +class V20CredExRecordDetail(Minimal): + """V2.0 credential exchange record detail.""" + + cred_ex_record: V20CredExRecord + details: Optional[V20CredExRecordFormat] = None + + +@dataclass +class ProofRequest(Minimal): + """Proof request.""" + + requested_attributes: Dict[str, Any] + requested_predicates: Dict[str, Any] + + +@dataclass +class PresSpec(Minimal): + """Presentation specification.""" + + requested_attributes: Dict[str, Any] + requested_predicates: Dict[str, Any] + self_attested_attributes: Dict[str, Any] + + +@dataclass +class CredInfo(Minimal): + """Credential information.""" + + referent: str + attrs: Dict[str, Any] + + +@dataclass +class CredPrecis(Minimal): + """Credential precis.""" + + cred_info: CredInfo + presentation_referents: List[str] + + @classmethod + def deserialize(cls: Type[MinType], value: Mapping[str, Any]) -> MinType: + """Deserialize the credential precis.""" + value = dict(value) + if cred_info := value.get("cred_info"): + value["cred_info"] = CredInfo.deserialize(cred_info) + return super().deserialize(value) + + +@dataclass +class Settings(Minimal): + """Settings information.""" + + +def auto_select_credentials_for_presentation_request( + presentation_request: Union[ProofRequest, dict], + relevant_creds: List[CredPrecis], +) -> PresSpec: + """Select credentials to use for presentation automatically.""" + if isinstance(presentation_request, dict): + presentation_request = ProofRequest.deserialize(presentation_request) + + requested_attributes = {} + for pres_referrent in presentation_request.requested_attributes.keys(): + for cred_precis in relevant_creds: + if pres_referrent in cred_precis.presentation_referents: + requested_attributes[pres_referrent] = { + "cred_id": cred_precis.cred_info.referent, + "revealed": True, + } + requested_predicates = {} + for pres_referrent in presentation_request.requested_predicates.keys(): + for cred_precis in relevant_creds: + if pres_referrent in cred_precis.presentation_referents: + requested_predicates[pres_referrent] = { + "cred_id": cred_precis.cred_info.referent, + } + + return PresSpec.deserialize( + { + "requested_attributes": requested_attributes, + "requested_predicates": requested_predicates, + "self_attested_attributes": {}, + } + ) + + +async def issue_credential_v2( + issuer: Controller, + holder: Controller, + issuer_connection_id: str, + holder_connection_id: str, + cred_def_id: str, + attributes: Mapping[str, str], +) -> Tuple[V20CredExRecordDetail, V20CredExRecordDetail]: + """Issue an credential using issue-credential/2.0. + + Issuer and holder should already be connected. + """ + + is_issuer_anoncreds = (await issuer.get("/settings", response=Settings)).get( + "wallet.type" + ) == "askar-anoncreds" + is_holder_anoncreds = (await holder.get("/settings", response=Settings)).get( + "wallet.type" + ) == "askar-anoncreds" + + if is_issuer_anoncreds: + _filter = {"anoncreds": {"cred_def_id": cred_def_id}} + else: + _filter = {"indy": {"cred_def_id": cred_def_id}} + issuer_cred_ex = await issuer.post( + "/issue-credential-2.0/send-offer", + json={ + "auto_issue": False, + "auto_remove": False, + "comment": "Credential from minimal example", + "trace": False, + "connection_id": issuer_connection_id, + "filter": _filter, + "credential_preview": { + "type": "issue-credential-2.0/2.0/credential-preview", # pyright: ignore + "attributes": [ + { + "mime_type": None, + "name": name, + "value": value, + } + for name, value in attributes.items() + ], + }, + }, + response=V20CredExRecord, + ) + issuer_cred_ex_id = issuer_cred_ex.cred_ex_id + + holder_cred_ex = await holder.event_with_values( + topic="issue_credential_v2_0", + event_type=V20CredExRecord, + connection_id=holder_connection_id, + state="offer-received", + ) + holder_cred_ex_id = holder_cred_ex.cred_ex_id + + await holder.post( + f"/issue-credential-2.0/records/{holder_cred_ex_id}/send-request", + response=V20CredExRecord, + ) + + await issuer.event_with_values( + topic="issue_credential_v2_0", + cred_ex_id=issuer_cred_ex_id, + state="request-received", + ) + + await issuer.post( + f"/issue-credential-2.0/records/{issuer_cred_ex_id}/issue", + json={}, + response=V20CredExRecordDetail, + ) + + await holder.event_with_values( + topic="issue_credential_v2_0", + cred_ex_id=holder_cred_ex_id, + state="credential-received", + ) + + await holder.post( + f"/issue-credential-2.0/records/{holder_cred_ex_id}/store", + json={}, + response=V20CredExRecordDetail, + ) + issuer_cred_ex = await issuer.event_with_values( + topic="issue_credential_v2_0", + event_type=V20CredExRecord, + cred_ex_id=issuer_cred_ex_id, + state="done", + ) + issuer_indy_record = await issuer.event_with_values( + topic="issue_credential_v2_0_anoncreds" + if is_issuer_anoncreds + else "issue_credential_v2_0_indy", + event_type=V20CredExRecordIndy, + ) + + holder_cred_ex = await holder.event_with_values( + topic="issue_credential_v2_0", + event_type=V20CredExRecord, + cred_ex_id=holder_cred_ex_id, + state="done", + ) + holder_indy_record = await holder.event_with_values( + topic="issue_credential_v2_0_anoncreds" + if is_holder_anoncreds + else "issue_credential_v2_0_indy", + event_type=V20CredExRecordIndy, + ) + + return ( + V20CredExRecordDetail(cred_ex_record=issuer_cred_ex, details=issuer_indy_record), + V20CredExRecordDetail( + cred_ex_record=holder_cred_ex, + details=holder_indy_record, + ), + ) + + +async def present_proof_v2( + holder: Controller, + verifier: Controller, + holder_connection_id: str, + verifier_connection_id: str, + *, + name: Optional[str] = None, + version: Optional[str] = None, + comment: Optional[str] = None, + requested_attributes: Optional[List[Mapping[str, Any]]] = None, + requested_predicates: Optional[List[Mapping[str, Any]]] = None, + non_revoked: Optional[Mapping[str, int]] = None, +): + """Present an credential using present proof v2.""" + + is_verifier_anoncreds = (await verifier.get("/settings", response=Settings)).get( + "wallet.type" + ) == "askar-anoncreds" + + attrs = { + "name": name or "proof", + "version": version or "0.1.0", + "nonce": str(randbelow(10**10)), + "requested_attributes": { + str(uuid4()): attr for attr in requested_attributes or [] + }, + "requested_predicates": { + str(uuid4()): pred for pred in requested_predicates or [] + }, + "non_revoked": (non_revoked if non_revoked else None), + } + + if is_verifier_anoncreds: + presentation_request = { + "anoncreds": attrs, + } + else: + presentation_request = { + "indy": attrs, + } + verifier_pres_ex = await verifier.post( + "/present-proof-2.0/send-request", + json={ + "auto_verify": False, + "comment": comment or "Presentation request from minimal", + "connection_id": verifier_connection_id, + "presentation_request": presentation_request, + "trace": False, + }, + response=V20PresExRecord, + ) + verifier_pres_ex_id = verifier_pres_ex.pres_ex_id + + holder_pres_ex = await holder.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + connection_id=holder_connection_id, + state="request-received", + ) + assert holder_pres_ex.pres_request + holder_pres_ex_id = holder_pres_ex.pres_ex_id + + relevant_creds = await holder.get( + f"/present-proof-2.0/records/{holder_pres_ex_id}/credentials", + response=List[CredPrecis], + ) + assert holder_pres_ex.by_format.pres_request + proof_request = holder_pres_ex.by_format.pres_request.get( + "anoncreds" + ) or holder_pres_ex.by_format.pres_request.get("indy") + pres_spec = auto_select_credentials_for_presentation_request( + proof_request, relevant_creds + ) + if is_verifier_anoncreds: + proof = {"anoncreds": pres_spec.serialize()} + else: + proof = {"indy": pres_spec.serialize()} + await holder.post( + f"/present-proof-2.0/records/{holder_pres_ex_id}/send-presentation", + json=proof, + response=V20PresExRecord, + ) + + await verifier.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + pres_ex_id=verifier_pres_ex_id, + state="presentation-received", + ) + await verifier.post( + f"/present-proof-2.0/records/{verifier_pres_ex_id}/verify-presentation", + json={}, + response=V20PresExRecord, + ) + verifier_pres_ex = await verifier.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + pres_ex_id=verifier_pres_ex_id, + state="done", + ) + + holder_pres_ex = await holder.event_with_values( + topic="present_proof_v2_0", + event_type=V20PresExRecord, + pres_ex_id=holder_pres_ex_id, + state="done", + ) + + return holder_pres_ex, verifier_pres_ex + + async def main(): """Test Controller protocols.""" - async with Controller(base_url=ALICE) as alice, Controller(base_url=BOB) as bob: + issuer_name = "issuer" + token_hex(8) + async with Controller(base_url=AGENCY) as agency: + issuer = await agency.post( + "/multitenancy/wallet", + json={ + "label": issuer_name, + "wallet_name": issuer_name, + "wallet_type": "askar", + }, + response=CreateWalletResponse, + ) + + async with Controller( + base_url=AGENCY, + wallet_id=issuer.wallet_id, + subwallet_token=issuer.token, + ) as issuer, Controller(base_url=HOLDER_ANONCREDS) as holder_anoncreds, Controller( + base_url=HOLDER_INDY + ) as holder_indy: + """ + This section of the test script demonstrates the issuance, presentation and + revocation of a credential where both the issuer is not anoncreds capable + (wallet type askar) and the holder is anoncreds capable + (wallet type askar-anoncreds). + """ + # Connecting - alice_conn, bob_conn = await didexchange(alice, bob) + issuer_conn_with_anoncreds_holder, holder_anoncreds_conn = await didexchange( + issuer, holder_anoncreds + ) # Issuance prep - config = (await alice.get("/status/config"))["config"] + config = (await issuer.get("/status/config"))["config"] genesis_url = config.get("ledger.genesis_url") - public_did = (await alice.get("/wallet/did/public", response=DIDResult)).result + public_did = (await issuer.get("/wallet/did/public", response=DIDResult)).result if not public_did: public_did = ( - await alice.post( + await issuer.post( "/wallet/did/create", json={"method": "sov", "options": {"key_type": "ed25519"}}, response=DIDResult, @@ -87,21 +459,154 @@ async def main(): ) as resp: assert resp.ok - await alice.post("/wallet/did/public", params=params(did=public_did.did)) + await issuer.post("/wallet/did/public", params=params(did=public_did.did)) + + _, cred_def = await indy_anoncred_credential_artifacts( + issuer, + ["firstname", "lastname"], + support_revocation=True, + ) + + # Issue a credential + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_anoncreds, + issuer_conn_with_anoncreds_holder.connection_id, + holder_anoncreds_conn.connection_id, + cred_def.credential_definition_id, + {"firstname": "Anoncreds", "lastname": "Holder"}, + ) + + # Present the the credential's attributes + await present_proof_v2( + holder_anoncreds, + issuer, + holder_anoncreds_conn.connection_id, + issuer_conn_with_anoncreds_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + + # Revoke credential + await issuer.post( + url="/revocation/revoke", + json={ + "connection_id": issuer_conn_with_anoncreds_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, + "publish": True, + "notify": True, + "notify_version": "v1_0", + }, + ) + + await holder_anoncreds.record(topic="revocation-notification") + + """ + This section of the test script demonstrates the issuance, presentation and + revocation of a credential where the issuer and holder are not anoncreds + capable. Both are askar wallet type. + """ + + # Connecting + issuer_conn_with_indy_holder, holder_indy_conn = await didexchange( + issuer, holder_indy + ) + + # Issue a credential + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_indy, + issuer_conn_with_indy_holder.connection_id, + holder_indy_conn.connection_id, + cred_def.credential_definition_id, + {"firstname": "Indy", "lastname": "Holder"}, + ) + + # Present the the credential's attributes + await present_proof_v2( + holder_indy, + issuer, + holder_indy_conn.connection_id, + issuer_conn_with_indy_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + # Query presentations + presentations = await issuer.get( + "/present-proof-2.0/records", + response=V20PresExRecordList, + ) + + # Presentation summary + for _, pres in enumerate(presentations.results): + print(summary(pres)) + + # Revoke credential + await issuer.post( + url="/revocation/revoke", + json={ + "connection_id": issuer_conn_with_indy_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, + "publish": True, + "notify": True, + "notify_version": "v1_0", + }, + ) + + await holder_indy.record(topic="revocation-notification") - schema = await alice.post( + """ + Upgrade the issuer tenant to anoncreds capable wallet type. When upgrading a + tenant the agent doesn't require a restart. That is why the test is done + with multitenancy + """ + await issuer.post( + "/anoncreds/wallet/upgrade", + params={ + "wallet_name": issuer_name, + }, + ) + + # Wait for the upgrade to complete + await asyncio.sleep(2) + + """ + Do issuance and presentation again after the upgrade. This time the issuer is + an anoncreds capable wallet (wallet type askar-anoncreds). + """ + # Presentation for anoncreds capable holder on existing credential + await present_proof_v2( + holder_anoncreds, + issuer, + holder_anoncreds_conn.connection_id, + issuer_conn_with_anoncreds_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + + # Presentation for indy capable holder on existing credential + await present_proof_v2( + holder_indy, + issuer, + holder_indy_conn.connection_id, + issuer_conn_with_indy_holder.connection_id, + requested_attributes=[{"name": "firstname"}], + ) + + # Create a new schema and cred def with different attributes on new + # anoncreds endpoints + schema = await issuer.post( "/anoncreds/schema", json={ "schema": { "name": "anoncreds-test-" + token_hex(8), "version": "1.0", - "attrNames": ["firstname", "lastname"], + "attrNames": ["middlename"], "issuerId": public_did.did, } }, - response=SchemaResult, + response=SchemaResultAnoncreds, ) - cred_def = await alice.post( + cred_def = await issuer.post( "/anoncreds/credential-definition", json={ "credential_definition": { @@ -109,77 +614,73 @@ async def main(): "schemaId": schema.schema_state["schema_id"], "tag": token_hex(8), }, - "options": { - "revocation_registry_size": 2000, - "support_revocation": True, - }, + "options": {"support_revocation": True, "revocation_registry_size": 10}, }, - response=CredDefResult, + response=CredDefResultAnoncreds, ) - # Issue a credential - alice_cred_ex, _ = await indy_issue_credential_v2( - alice, - bob, - alice_conn.connection_id, - bob_conn.connection_id, + # Issue a new credential to anoncreds holder + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_anoncreds, + issuer_conn_with_anoncreds_holder.connection_id, + holder_anoncreds_conn.connection_id, cred_def.credential_definition_state["credential_definition_id"], - {"firstname": "Bob", "lastname": "Builder"}, + {"middlename": "Anoncreds"}, ) - - # Present the the credential's attributes - await indy_present_proof_v2( - bob, - alice, - bob_conn.connection_id, - alice_conn.connection_id, - requested_attributes=[{"name": "firstname"}], + # Presentation for anoncreds capable holder + await present_proof_v2( + holder_anoncreds, + issuer, + holder_anoncreds_conn.connection_id, + issuer_conn_with_anoncreds_holder.connection_id, + requested_attributes=[{"name": "middlename"}], ) - # Revoke credential - await alice.post( + await issuer.post( url="/anoncreds/revocation/revoke", json={ - "connection_id": alice_conn.connection_id, - "rev_reg_id": alice_cred_ex.indy.rev_reg_id, - "cred_rev_id": alice_cred_ex.indy.cred_rev_id, + "connection_id": issuer_conn_with_anoncreds_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, "publish": True, "notify": True, "notify_version": "v1_0", }, ) + await holder_anoncreds.record(topic="revocation-notification") - await bob.record(topic="revocation-notification") - - # Request proof, no interval - await indy_present_proof_v2( - bob, - alice, - bob_conn.connection_id, - alice_conn.connection_id, - requested_attributes=[ - { - "name": "firstname", - "restrictions": [ - { - "cred_def_id": cred_def.credential_definition_state[ - "credential_definition_id" - ] - } - ], - } - ], + # Issue a new credential to indy holder + issuer_cred_ex, _ = await issue_credential_v2( + issuer, + holder_indy, + issuer_conn_with_indy_holder.connection_id, + holder_indy_conn.connection_id, + cred_def.credential_definition_state["credential_definition_id"], + {"middlename": "Indy"}, ) - - # Query presentations - presentations = await alice.get( - "/present-proof-2.0/records", - response=V20PresExRecordList, + # Presentation for indy holder + await present_proof_v2( + holder_indy, + issuer, + holder_indy_conn.connection_id, + issuer_conn_with_indy_holder.connection_id, + requested_attributes=[{"name": "middlename"}], + ) + # Revoke credential + await issuer.post( + url="/anoncreds/revocation/revoke", + json={ + "connection_id": issuer_conn_with_indy_holder.connection_id, + "rev_reg_id": issuer_cred_ex.details.rev_reg_id, + "cred_rev_id": issuer_cred_ex.details.cred_rev_id, + "publish": True, + "notify": True, + "notify_version": "v1_0", + }, ) - # Presentation summary - for i, pres in enumerate(presentations.results): - print(summary(pres)) + await holder_indy.record(topic="revocation-notification") if __name__ == "__main__": From ddfcfdc17683bf65a95c80b5896b3deb8ffbb06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emiliano=20Su=C3=B1=C3=A9?= Date: Wed, 20 Nov 2024 14:18:52 -0800 Subject: [PATCH 059/152] Fix handling of base_wallet_routes startup parameter in auth decorator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emiliano Suñé --- acapy_agent/admin/decorators/auth.py | 29 ++++++++++++++++++++++++++++ acapy_agent/admin/server.py | 25 +----------------------- acapy_agent/admin/tests/test_auth.py | 24 +++++++++++++++++++++++ 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/acapy_agent/admin/decorators/auth.py b/acapy_agent/admin/decorators/auth.py index 818f297d40..6d673a19f9 100644 --- a/acapy_agent/admin/decorators/auth.py +++ b/acapy_agent/admin/decorators/auth.py @@ -1,6 +1,8 @@ """Authentication decorators for the admin API.""" import functools +import re +from typing import Optional, Pattern, Sequence, cast from aiohttp import web @@ -48,6 +50,8 @@ def tenant_authentication(handler): - check for a valid bearer token in the Autorization header if running in multi-tenant mode - check for a valid x-api-key header if running in single-tenant mode + - check if the base wallet has access to teh requested path if running + in multi-tenant mode """ @functools.wraps(handler) @@ -61,11 +65,15 @@ async def tenant_auth(request): ) insecure_mode = bool(profile.settings.get("admin.admin_insecure_mode")) multitenant_enabled = profile.settings.get("multitenant.enabled") + base_wallet_allowed_route = _base_wallet_route_access( + profile.settings.get("multitenant.base_wallet_routes"), request.path + ) # CORS fix: allow OPTIONS method access to paths without a token if ( (multitenant_enabled and authorization_header) or (not multitenant_enabled and valid_key) + or (multitenant_enabled and valid_key and base_wallet_allowed_route) or insecure_mode or request.method == "OPTIONS" ): @@ -78,3 +86,24 @@ async def tenant_auth(request): ) return tenant_auth + + +def _base_wallet_route_access(additional_routes: str, request_path: str) -> bool: + """Check if request path matches additional routes.""" + additional_routes_pattern = _build_additional_routes_pattern(additional_routes) + return _matches_additional_routes(additional_routes_pattern, request_path) + + +def _build_additional_routes_pattern(pattern_string: str) -> Optional[Pattern]: + """Build pattern from string.""" + base_wallet_routes = cast(Sequence[str], pattern_string) + if base_wallet_routes: + return re.compile("^(?:" + "|".join(base_wallet_routes) + ")") + return None + + +def _matches_additional_routes(pattern: Pattern, path: str) -> bool: + """Matches request path to provided pattern.""" + if pattern and path: + return bool(pattern.match(path)) + return False diff --git a/acapy_agent/admin/server.py b/acapy_agent/admin/server.py index 84650ed11b..111d2f2a52 100644 --- a/acapy_agent/admin/server.py +++ b/acapy_agent/admin/server.py @@ -5,7 +5,7 @@ import re import warnings import weakref -from typing import Callable, Coroutine, Optional, Pattern, Sequence, cast +from typing import Callable, Coroutine, Optional import aiohttp_cors import jwt @@ -280,29 +280,6 @@ def __init__( self.websocket_queues = {} self.site = None self.multitenant_manager = context.inject_or(BaseMultitenantManager) - self._additional_route_pattern: Optional[Pattern] = None - - @property - def additional_routes_pattern(self) -> Optional[Pattern]: - """Pattern for configured additional routes to permit base wallet to access.""" - if self._additional_route_pattern: - return self._additional_route_pattern - - base_wallet_routes = self.context.settings.get("multitenant.base_wallet_routes") - base_wallet_routes = cast(Sequence[str], base_wallet_routes) - if base_wallet_routes: - self._additional_route_pattern = re.compile( - "^(?:" + "|".join(base_wallet_routes) + ")" - ) - return None - - def _matches_additional_routes(self, path: str) -> bool: - """Path matches additional_routes_pattern.""" - pattern = self.additional_routes_pattern - if pattern: - return bool(pattern.match(path)) - - return False async def make_application(self) -> web.Application: """Get the aiohttp application instance.""" diff --git a/acapy_agent/admin/tests/test_auth.py b/acapy_agent/admin/tests/test_auth.py index 1ebd0cd171..7be0549866 100644 --- a/acapy_agent/admin/tests/test_auth.py +++ b/acapy_agent/admin/tests/test_auth.py @@ -133,3 +133,27 @@ async def test_multi_tenant_valid_auth_header(self): decor_func = tenant_authentication(self.decorated_handler) await decor_func(self.request) self.decorated_handler.assert_called_once_with(self.request) + + async def test_base_wallet_additional_route_allowed(self): + self.profile.settings["multitenant.base_wallet_routes"] = "/extra-route" + self.request = mock.MagicMock( + __getitem__=lambda _, k: self.request_dict[k], + headers={"x-api-key": "admin_api_key"}, + method="POST", + path="/extra-route", + ) + decor_func = tenant_authentication(self.decorated_handler) + await decor_func(self.request) + self.decorated_handler.assert_called_once_with(self.request) + + async def test_base_wallet_additional_route_denied(self): + self.profile.settings["multitenant.base_wallet_routes"] = "/wrong-extra-route" + self.request = mock.MagicMock( + __getitem__=lambda _, k: self.request_dict[k], + headers={"x-api-key": "admin_api_key"}, + method="POST", + path="/extra-route", + ) + decor_func = tenant_authentication(self.decorated_handler) + with self.assertRaises(web.HTTPUnauthorized): + await decor_func(self.request) From 84a9f3304dde4dfecee93732847820a5405b3f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emiliano=20Su=C3=B1=C3=A9?= Date: Wed, 20 Nov 2024 19:19:25 -0800 Subject: [PATCH 060/152] Restore --base-wallet-extra-routes argument functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emiliano Suñé --- acapy_agent/admin/decorators/auth.py | 11 +++++------ acapy_agent/admin/tests/test_auth.py | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/acapy_agent/admin/decorators/auth.py b/acapy_agent/admin/decorators/auth.py index 6d673a19f9..6e9f1597a8 100644 --- a/acapy_agent/admin/decorators/auth.py +++ b/acapy_agent/admin/decorators/auth.py @@ -2,7 +2,7 @@ import functools import re -from typing import Optional, Pattern, Sequence, cast +from typing import Optional, Pattern from aiohttp import web @@ -95,11 +95,10 @@ def _base_wallet_route_access(additional_routes: str, request_path: str) -> bool def _build_additional_routes_pattern(pattern_string: str) -> Optional[Pattern]: - """Build pattern from string.""" - base_wallet_routes = cast(Sequence[str], pattern_string) - if base_wallet_routes: - return re.compile("^(?:" + "|".join(base_wallet_routes) + ")") - return None + """Build pattern from space delimited list of paths.""" + # create array and add word boundary to avoid false positives + paths = pattern_string.split(" ") + return re.compile("^((?:)" + "|".join(paths) + ")$") def _matches_additional_routes(pattern: Pattern, path: str) -> bool: diff --git a/acapy_agent/admin/tests/test_auth.py b/acapy_agent/admin/tests/test_auth.py index 7be0549866..73680a1b00 100644 --- a/acapy_agent/admin/tests/test_auth.py +++ b/acapy_agent/admin/tests/test_auth.py @@ -147,12 +147,12 @@ async def test_base_wallet_additional_route_allowed(self): self.decorated_handler.assert_called_once_with(self.request) async def test_base_wallet_additional_route_denied(self): - self.profile.settings["multitenant.base_wallet_routes"] = "/wrong-extra-route" + self.profile.settings["multitenant.base_wallet_routes"] = "/extra-route" self.request = mock.MagicMock( __getitem__=lambda _, k: self.request_dict[k], headers={"x-api-key": "admin_api_key"}, method="POST", - path="/extra-route", + path="/extra-route-wrong", ) decor_func = tenant_authentication(self.decorated_handler) with self.assertRaises(web.HTTPUnauthorized): From 0257d78af7b23abeb77a7ee68ef06e6710c76f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emiliano=20Su=C3=B1=C3=A9?= Date: Thu, 21 Nov 2024 10:42:15 -0800 Subject: [PATCH 061/152] Correctly handle null value for --base-wallet-routes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emiliano Suñé --- acapy_agent/admin/decorators/auth.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/acapy_agent/admin/decorators/auth.py b/acapy_agent/admin/decorators/auth.py index 6e9f1597a8..9c12d7f75c 100644 --- a/acapy_agent/admin/decorators/auth.py +++ b/acapy_agent/admin/decorators/auth.py @@ -97,8 +97,10 @@ def _base_wallet_route_access(additional_routes: str, request_path: str) -> bool def _build_additional_routes_pattern(pattern_string: str) -> Optional[Pattern]: """Build pattern from space delimited list of paths.""" # create array and add word boundary to avoid false positives - paths = pattern_string.split(" ") - return re.compile("^((?:)" + "|".join(paths) + ")$") + if pattern_string: + paths = pattern_string.split(" ") + return re.compile("^((?:)" + "|".join(paths) + ")$") + return None def _matches_additional_routes(pattern: Pattern, path: str) -> bool: From 88be79091ffbbe8ad06534953ba991d36fc50e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emiliano=20Su=C3=B1=C3=A9?= Date: Thu, 21 Nov 2024 11:34:00 -0800 Subject: [PATCH 062/152] Fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emiliano Suñé --- acapy_agent/admin/decorators/auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acapy_agent/admin/decorators/auth.py b/acapy_agent/admin/decorators/auth.py index 9c12d7f75c..3d1f209893 100644 --- a/acapy_agent/admin/decorators/auth.py +++ b/acapy_agent/admin/decorators/auth.py @@ -50,7 +50,7 @@ def tenant_authentication(handler): - check for a valid bearer token in the Autorization header if running in multi-tenant mode - check for a valid x-api-key header if running in single-tenant mode - - check if the base wallet has access to teh requested path if running + - check if the base wallet has access to the requested path if running in multi-tenant mode """ From 2d4212ae2cc88ef885d61b0eae28997b4e2a7dd5 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Fri, 22 Nov 2024 15:27:04 -0800 Subject: [PATCH 063/152] Fix subwallet anoncreds upgrade check (#3345) Signed-off-by: jamshale --- acapy_agent/core/conductor.py | 14 +------------- acapy_agent/wallet/anoncreds_upgrade.py | 1 + 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index d9db66ad7a..9935b6f745 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -856,19 +856,7 @@ async def check_for_valid_wallet_type(self, profile): async def check_for_wallet_upgrades_in_progress(self): """Check for upgrade and upgrade if needed.""" - - # We need to use the correct multitenant manager for single vs multiple wallets - # here because the multitenant provider hasn't been initialized yet. - manager_type = self.context.settings.get_value( - "multitenant.wallet_type", default="basic" - ).lower() - - manager_class = MultitenantManagerProvider.MANAGER_TYPES.get( - manager_type, manager_type - ) - - multitenant_mgr = self.context.inject_or(manager_class) - if multitenant_mgr: + if self.context.settings.get_value("multitenant.enabled"): subwallet_profiles = await get_subwallet_profiles_from_storage( self.root_profile ) diff --git a/acapy_agent/wallet/anoncreds_upgrade.py b/acapy_agent/wallet/anoncreds_upgrade.py index ce944c75d7..4261acf0eb 100644 --- a/acapy_agent/wallet/anoncreds_upgrade.py +++ b/acapy_agent/wallet/anoncreds_upgrade.py @@ -699,6 +699,7 @@ async def check_upgrade_completion_loop(profile: Profile, is_subwallet=False): UpgradeInProgressSingleton().remove_wallet(profile.name) if is_subwallet: await upgrade_subwallet(profile) + await finish_upgrade(profile) LOGGER.info( f"""Upgrade of subwallet {profile.settings.get('wallet.name')} has completed. Profile is now askar-anoncreds""" # noqa: E501 ) From 799cd646477264580e082a4ce315bff4093e9290 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Mon, 25 Nov 2024 11:16:34 -0800 Subject: [PATCH 064/152] Fix/universal resolver (#3354) * Update universal resolver response handling Signed-off-by: jamshale * Update universal resolver unit test Signed-off-by: jamshale * Add reverse compatibility handling Signed-off-by: jamshale --------- Signed-off-by: jamshale --- .../resolver/default/tests/test_universal.py | 24 +++++++++++++++++++ acapy_agent/resolver/default/universal.py | 16 +++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/acapy_agent/resolver/default/tests/test_universal.py b/acapy_agent/resolver/default/tests/test_universal.py index 36b2cc73db..c516ac7068 100644 --- a/acapy_agent/resolver/default/tests/test_universal.py +++ b/acapy_agent/resolver/default/tests/test_universal.py @@ -119,6 +119,7 @@ async def test_fetch_resolver_props(mock_client_session: MockClientSession): @pytest.mark.asyncio async def test_get_supported_did_regex(): + # Old response format props = {"example": {"http": {"pattern": "match a test string"}}} with mock.patch.object( UniversalResolver, @@ -128,6 +129,29 @@ async def test_get_supported_did_regex(): pattern = await UniversalResolver()._get_supported_did_regex() assert pattern.fullmatch("match a test string") + # Example response from dev universal resolver 1.0 + props = { + "^(did:sov:(?:(?:\\w[-\\w]*(?::\\w[-\\w]*)*):)?(?:[1-9A-HJ-NP-Za-km-z]{21,22}))$": { + "libIndyPath": "", + "openParallel": "false", + "poolVersions": "_;2;test;2;builder;2;danube;2;idunion;2;idunion:test;2;indicio;2;indicio:test;2;indicio:demo;2;nxd;2;findy:test;2;bcovrin;2;bcovrin:test;2;bcovrin:dev;2;candy;2;candy:test;2;candy:dev;2", + "submitterDidSeeds": "_;_;test;_;builder;_;danube;_;idunion;_;idunion:test;_;indicio;_;indicio:test;_;indicio:demo;_;nxd;_;findy:test;_;bcovrin;_;bcovrin:test;_;bcovrin:dev;_;candy;_;candy:test;_;candy:dev;_", + "http": { + "resolveUri": "http://driver-did-sov:8080/1.0/identifiers/", + "propertiesUri": "http://driver-did-sov:8080/1.0/properties", + }, + "walletNames": "_;w1;test;w2;builder;w3;danube;w4;idunion;w5;idunion:test;w6;indicio;w7;indicio:test;w8;indicio:demo;w9;nxd;w11;findy:test;w12;bcovrin;w13;bcovrin:test;w14;bcovrin:dev;w15;candy;w16;candy:test;w17;candy:dev;w18", + "poolConfigs": "_;./sovrin/_.txn;test;./sovrin/test.txn;builder;./sovrin/builder.txn;danube;./sovrin/danube.txn;idunion;./sovrin/idunion.txn;idunion:test;./sovrin/idunion-test.txn;indicio;./sovrin/indicio.txn;indicio:test;./sovrin/indicio-test.txn;indicio:demo;./sovrin/indicio-demo.txn;nxd;./sovrin/nxd.txn;bcovrin:test;./sovrin/bcovrin-test.txn;candy;./sovrin/candy.txn;candy:test;./sovrin/candy-test.txn;candy:dev;./sovrin/candy-dev.txn", + } + } + with mock.patch.object( + UniversalResolver, + "_fetch_resolver_props", + mock.CoroutineMock(return_value=props), + ): + pattern = await UniversalResolver()._get_supported_did_regex() + assert pattern.match("did:sov:WRfXPg8dantKVubE3HX8pw") + def test_compile_supported_did_regex(): patterns = ["one", "two", "three"] diff --git a/acapy_agent/resolver/default/universal.py b/acapy_agent/resolver/default/universal.py index 4d359a9a6e..8d4b1eb1d8 100644 --- a/acapy_agent/resolver/default/universal.py +++ b/acapy_agent/resolver/default/universal.py @@ -110,8 +110,16 @@ async def _fetch_resolver_props(self) -> dict: "Failed to retrieve resolver properties: " + await resp.text() ) - async def _get_supported_did_regex(self) -> Pattern: + async def _get_supported_did_regex(self): props = await self._fetch_resolver_props() - return _compile_supported_did_regex( - driver["http"]["pattern"] for driver in props.values() - ) + + def _get_patterns(): + """Handle both old and new properties responses.""" + patterns = list(props.values())[0].get("http", {}).get("pattern") + if not patterns: + return props.keys() + else: + return [driver["http"]["pattern"] for driver in props.values()] + + patterns = _get_patterns() + return _compile_supported_did_regex(patterns) From b0a1e675bc04c2db6bd8a538a96081ae87fbaced Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:44:57 -0800 Subject: [PATCH 065/152] chore(deps-dev): Bump ruff from 0.7.4 to 0.8.0 (#3348) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.4 to 0.8.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.7.4...0.8.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com> --- poetry.lock | 44 +++++++++++++++++++++++--------------------- pyproject.toml | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/poetry.lock b/poetry.lock index 465055db55..bd70d367bf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiofiles" @@ -1325,6 +1325,8 @@ optional = false python-versions = "*" files = [ {file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"}, + {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"}, + {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"}, ] [package.dependencies] @@ -2598,29 +2600,29 @@ test = ["hypothesis (==5.19.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "ruff" -version = "0.7.4" +version = "0.8.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478"}, - {file = "ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63"}, - {file = "ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06"}, - {file = "ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd"}, - {file = "ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a"}, - {file = "ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac"}, - {file = "ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6"}, - {file = "ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f"}, - {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"}, + {file = "ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea"}, + {file = "ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b"}, + {file = "ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3"}, + {file = "ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd"}, + {file = "ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426"}, + {file = "ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468"}, + {file = "ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f"}, + {file = "ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6"}, + {file = "ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44"}, ] [[package]] @@ -3139,4 +3141,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "543d20028efad5a9d798071ba86e9d1ab39b202fe1afaa27f8f4c7f656f1d7cc" +content-hash = "bbb6160407926b8aceeceeb69268118c018e71a0857eefa9e3567b09d4088f15" diff --git a/pyproject.toml b/pyproject.toml index 7de97f37b3..557927eca2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,7 @@ canonicaljson = "^2.0.0" [tool.poetry.group.dev.dependencies] pre-commit = "~3.8.0" # Sync with version in .pre-commit-config.yaml -ruff = "0.7.4" +ruff = "0.8.0" sphinx = "^5.3.0" sphinx-rtd-theme = ">=0.4.3" From b5e79fb1c948a5873c57f7a3e04ef208640add46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:51:30 -0800 Subject: [PATCH 066/152] chore(deps): Bump mkdocs-material from 9.5.44 to 9.5.46 (#3352) Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.44 to 9.5.46. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.44...9.5.46) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mkdocs-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs-requirements.txt b/mkdocs-requirements.txt index eb1ee40600..a6d710f6af 100644 --- a/mkdocs-requirements.txt +++ b/mkdocs-requirements.txt @@ -1,3 +1,3 @@ -mkdocs-material==9.5.44 +mkdocs-material==9.5.46 mike==2.1.3 From 1613ed02c281ae5d6ac60673c7e4bdc65789202d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:18:27 -0800 Subject: [PATCH 067/152] chore(deps): Bump uuid-utils from 0.9.0 to 0.10.0 (#3351) Bumps [uuid-utils](https://github.com/aminalaee/uuid-utils) from 0.9.0 to 0.10.0. - [Release notes](https://github.com/aminalaee/uuid-utils/releases) - [Commits](https://github.com/aminalaee/uuid-utils/compare/0.9.0...0.10.0) --- updated-dependencies: - dependency-name: uuid-utils dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 109 ++++++++++++++----------------------------------- pyproject.toml | 2 +- 2 files changed, 31 insertions(+), 80 deletions(-) diff --git a/poetry.lock b/poetry.lock index bd70d367bf..1c0f343a8a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2901,87 +2901,38 @@ files = [ [[package]] name = "uuid-utils" -version = "0.9.0" +version = "0.10.0" description = "Drop-in replacement for Python UUID in Rust" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "uuid_utils-0.9.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:28da15c275ef06a759efe0fcba7c58eab8ae2217f7a7f66289dee6ae332605a0"}, - {file = "uuid_utils-0.9.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:81144165068e84a1ac8b92f23bfc961e5b5dbb89ddcff70c5e7d096ae07a439c"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:362695ed7756b1b89d9a2dd193fe2523ca1d4a31235606f7cb516a322789ffc4"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:36cb70e29f5749b554ae06f1a88926c9b47d5b48004b6903fb7ea47e8b398080"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa39a95eb67e2b98a61d4e64ddf622ee902fe9142b579921ab3e9027472f5080"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9b7029044d40f66366cebb6a94ecb04d8c0a745029561552d527ac52dc0deb9"}, - {file = "uuid_utils-0.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c883c6f815d2af344dab585d7b16a77410fcb1f6c097e6ad0384bd12cd84e16e"}, - {file = "uuid_utils-0.9.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:be5f83e9002a43aac868fa9cbc73f28cfb0b4e8b14f5a449fef04fea31bf2904"}, - {file = "uuid_utils-0.9.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8f84b0fd38df8a211230b8bbd02d5e7e631f1d35c1ba67efb895f80c7d9215aa"}, - {file = "uuid_utils-0.9.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:89cc342b061d8e3f669b8aaeb8d9e2973407c93aaa675dc6a59e985feda2805c"}, - {file = "uuid_utils-0.9.0-cp310-none-win32.whl", hash = "sha256:3d5554f44aeab9706770169316897f79089b51a061800684b7f29bccf663ad0f"}, - {file = "uuid_utils-0.9.0-cp310-none-win_amd64.whl", hash = "sha256:db35df169f17617129cc070e3a8fba00598ee55adcbe22c79b2c2f306eeb3b9e"}, - {file = "uuid_utils-0.9.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:cdb7224fb8b1f18edcd4357f83fcbe33b9f82ac392095e5d9e0e05336d65d587"}, - {file = "uuid_utils-0.9.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5312449ea5427a94edab3aebf2cff8f99a3112f273dd9d5919e332bc4e6a031f"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d6837677217b3d0aa375f8aa7b89935c3ebf2ee5e1667be50b2090741684baa"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:402e522f62ceb8344f579e37f9a25c9274d484675afd71ad725ddd61ced7cd36"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e24a27724b2289d66d75358ffecf698ae36816458897cfdec972e6ede1ead328"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db04420c0b1a99f3160ddc90ba52986484ce8304b54586ea161133f755a4605b"}, - {file = "uuid_utils-0.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:152f3c1a0634558e329b64ff4a9592ee83b722e3fdc214f648f851fa14163c36"}, - {file = "uuid_utils-0.9.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5710b6ca95966f80125f48dad9e3d70ef99f48dd892bec3cb38673d087a7d71a"}, - {file = "uuid_utils-0.9.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3b9b9cf0cc544ef552c955bc2caaecf5e38cc8ed65e23f208b0dcdb6d37719e"}, - {file = "uuid_utils-0.9.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6d715b6321d4728a1aa0d5e26a338c97aaba2bf337f3ef9804ef5027f07de61d"}, - {file = "uuid_utils-0.9.0-cp311-none-win32.whl", hash = "sha256:3b61b0543404c99f7f23fb556b69090bc58358e8bd9d570381722221281f3706"}, - {file = "uuid_utils-0.9.0-cp311-none-win_amd64.whl", hash = "sha256:b4bdd9e80c92b1f253e66392e1d6ad0ec4926d5c7e2de3d852ee6fed1939f58b"}, - {file = "uuid_utils-0.9.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:9cfcfb222f62612bea58bdec32b6842d9636fca53ca4579f88c1b620b1c4cbf7"}, - {file = "uuid_utils-0.9.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7253039ecfa534b3177b3225764cede9c6dae5db572e17d8582dd7cc5b3af484"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fb6e792ae1e3a7bf9d357f87dcf628923d0881f1d13a9cba826b848ca1774b1"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fbea3bb9ad319de7f69d6a60b6921acaa97d577aaeceb247b1ff4a8a92b3aa6a"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09043b3f48e20d631c7a81030be8c4f6ea9a6d44cccda8cbbdc1ad18da301c89"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9ba2681f5f177f800e40f5a0f09ed03c49f4290a245e4273d21cb48a7e88969"}, - {file = "uuid_utils-0.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:866811473f3d9dc38c02dd08e076e333b9e4d41ce952353941b49d0724d2327b"}, - {file = "uuid_utils-0.9.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:14aa9917ef11bd0ee1648237dddbf33aa0459e609ebe2f9202ffb259ca80f763"}, - {file = "uuid_utils-0.9.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:22cae83bc486a6c12b38239eb0546f2f81c81c34fcf833f84c2c7cd0cab1ad8f"}, - {file = "uuid_utils-0.9.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9513399045169435563c284caba0f1802748b02f27c95769426b7a00ed246e1"}, - {file = "uuid_utils-0.9.0-cp312-none-win_amd64.whl", hash = "sha256:284e6d24ba659d003bd47fcfc404d374c7807983407d4d61f26c80a3b7f4cb41"}, - {file = "uuid_utils-0.9.0-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:fd3d09c53d5a96c78c77211786fa25bbdbe031566b927383c10ab81a27c7e431"}, - {file = "uuid_utils-0.9.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:2b052d01176d2d1afa476ebe158eae052e265c92110d987d5801f0c3c1c8852a"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e636a9603dc04e15b8305129619b2b45843f883e58355c91dc6cc22d51dde8"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37d2f9ec3a99caf29531fe257b7906f8a5946a3ee7000c744d73e5187a2542a1"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ace932d10a83141d22c42287a0c707cfa41522ecb797f17e63820f09688c6d7"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:843ec54337233d5f99a99b156ba5be5659f5ea193db8287035bf85d6a6a00c58"}, - {file = "uuid_utils-0.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f16a60ef4ddf9fe16fcd4793f83932d2b5198af6873d0a0478acfe0bd19d8e2f"}, - {file = "uuid_utils-0.9.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:901da31d61f78ec8df96741326541ae7af156a2628ca82ccf2806bcee257de1a"}, - {file = "uuid_utils-0.9.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:fad20ba28a11f2b33f06b2d7e0e77be73a8c3a41de833a123c6d93025d463b4b"}, - {file = "uuid_utils-0.9.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c5c30716a0dcffd1a7a66853f5a8372a276d454510f48fc7e4c39c13212bb1f6"}, - {file = "uuid_utils-0.9.0-cp38-none-win32.whl", hash = "sha256:2912c9a810e74cb3abaebd0fdfa5b1f202cf60a8f0fec9cc76117dab6c42cb77"}, - {file = "uuid_utils-0.9.0-cp38-none-win_amd64.whl", hash = "sha256:b55bcffc260356c84a09ac3a391e2442ad4df0beaaf71670d4e8ffd8b7328e75"}, - {file = "uuid_utils-0.9.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:08aec826a8ed4d3baab29d144ad634091e5accabcb88dfa0a834b9ba9e74930f"}, - {file = "uuid_utils-0.9.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e7de8fcf3d22e299582ab61c67390abdf37cc7d5b330066c3f792a082167c419"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8de8da71bc5a6a527952648357acca8d6d1717bbbc044304c5a9cf53eb06568c"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce3ef96aa6ba760e1d0481ed076fe9e8f0386e27c7039bc6ffa377c98979fae7"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69dd8c0d622e4e40b1b993a2e452bbed21127b97f8e4a3fdbde6e5f556253265"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4600d5dcd9d0759be4bc580daf6d521da99a825a25db3d492abcbb12f6dc98f6"}, - {file = "uuid_utils-0.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:067d5f36ccc70896c76a9dafc8220a942db0e42ab58b84c43208e0ff84c1bdf0"}, - {file = "uuid_utils-0.9.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7a23d20f08636899a1b24394a12a2c469262af56d5279dbac1c6b14b059e5d4b"}, - {file = "uuid_utils-0.9.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6a2cbc5da89f0e701d2b80df0e6b30da16a0adcd2883da3d3e1f7aac1f046c1c"}, - {file = "uuid_utils-0.9.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bbf93bdd3c8a3e3b2b2f82ad4dfafcd2aaecc1d6ec924fd5da2b712ab324ee51"}, - {file = "uuid_utils-0.9.0-cp39-none-win32.whl", hash = "sha256:9d9b3ba5be11a017c568e904eac76f6cd6f82f956ca65ffbaa73ee8d7cdbe13b"}, - {file = "uuid_utils-0.9.0-cp39-none-win_amd64.whl", hash = "sha256:b3e494547cfef124f0c51831a303bfc0278e3c33b9ab9d9db90d94728d9871c2"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:98c7c7b414b405b547c9bc1f972513b3a0bfb3dca248c89c623ab60efdd36ad8"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7b75241666cae4bc5786e6c68e862ccf4e15b2f98c81e47a6b0a85c907b7b6fa"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf6b43723a2d4af21c07fec98385a97e2023a808fd6eaf4296a163bffca76cf5"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c260bb9a9fdd484cadc437cdb26ad07d66c8049a365c4ef49c9f09d7ed9ac2e"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4605c6326a7914d1b59c548f0ae4ef119619fe09c3ab4f07d99f3fbec39d470"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d498673249826ce7c47aa481709a5dd647bbff764fb64370bc691c7e43c7a2a1"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a37c48cba2f4eb6182a3857d045aa1420fa9878bfd268f6855fce7293a006677"}, - {file = "uuid_utils-0.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:eeb9c56d401e4a422ae7fd818ef1376bda384ae0bed86e339c9a256c6b10d252"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:33dd97e9c59891fbfb4e4a11596c42cc3d10774b843daaf75316d036a0a07799"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5e67fc3c6def9d62de4caf19529bd8044e821eb2f5c39821cfd011940f96394"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:241ab8ddb76ef8d4294c09cd6045dd62a1aa46acf8ff0a017796a54a530a87ae"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a9a16d2af4b4ad59d4cef7f43ba33644353b12769fafabf6e1663aa230cca38"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:897a167659d30a8431a094533bcb58d2b16005f7456408bd40f3e5872e1b2f46"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b4f56ab5ce19697552df9689c24c742054e8fd8e2ef8c26f9b8393f6d7ae893"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b219d9341de117e2e608f3fe08e31480ad60fb6128f8fffd2151ba88e53508c"}, - {file = "uuid_utils-0.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b5c08de8a94181c0ba209a8b8275993499f424b57958bea6c39739311526fd18"}, - {file = "uuid_utils-0.9.0.tar.gz", hash = "sha256:239f45b7e71d0ea61e3a4957aa4b8f3b49bfb009cf768d11c3f464787dbb737f"}, + {file = "uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d5a4508feefec62456cd6a41bcdde458d56827d908f226803b886d22a3d5e63"}, + {file = "uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dbefc2b9113f9dfe56bdae58301a2b3c53792221410d422826f3d1e3e6555fe7"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc49c33edf87d1ec8112a9b43e4cf55326877716f929c165a2cc307d31c73d5"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0636b6208f69d5a4e629707ad2a89a04dfa8d1023e1999181f6830646ca048a1"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc06452856b724df9dedfc161c3582199547da54aeb81915ec2ed54f92d19b0"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:263b2589111c61decdd74a762e8f850c9e4386fb78d2cf7cb4dfc537054cda1b"}, + {file = "uuid_utils-0.10.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a558db48b7096de6b4d2d2210d82bba8586a6d55f99106b03bb7d01dc5c5bcd6"}, + {file = "uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:807465067f3c892514230326ac71a79b28a8dfe2c88ecd2d5675fc844f3c76b5"}, + {file = "uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:57423d4a2b9d7b916de6dbd75ba85465a28f9578a89a97f7d3e098d9aa4e5d4a"}, + {file = "uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:76d8d660f18ff6b767e319b1b5f927350cd92eafa4831d7ef5b57fdd1d91f974"}, + {file = "uuid_utils-0.10.0-cp39-abi3-win32.whl", hash = "sha256:6c11a71489338837db0b902b75e1ba7618d5d29f05fde4f68b3f909177dbc226"}, + {file = "uuid_utils-0.10.0-cp39-abi3-win_amd64.whl", hash = "sha256:11c55ae64f6c0a7a0c741deae8ca2a4eaa11e9c09dbb7bec2099635696034cf7"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:acea543dfc7b87df749e3e814c54ac739a82ff5e3800d25bd25a3e00599e1554"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0767eefa7b1e96f06cfa9b95758d286240c01bbf19e9d8f1b6043cdbe76cc639"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973fe4bb5258fd2ccb144d8b40c2d3158f16cc856a20527f8b40d14b2ae1dee9"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:71b8505b67a0d77d0fbd765d8463094a8f447677125da7647bec7ea0b99406f0"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6bdcb1211bb61476cbef12a87101fa48243e20ed82b2bd324c816b1b5826bd5e"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c5247f1df040aae71ea313819b563debe69bca7086a2cc6a3ac0eaddd3dadac"}, + {file = "uuid_utils-0.10.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a50bd29ef89660b93aa07ffa95ac691a0e12832375030569a8bd5c9272f3b8e6"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a778cd9d8f995b94bba6e51f3ebee5b338fd834b0c4ecc8f932bd23e29db3e19"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d3d5b5c5ed66ff923961b9ebb902232cd67f6a7ec6b6f7a58e05e00ff44e3c7f"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:789ed6335225326c66f5d6162649bed978105a85f232be7811387c395c226801"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:05d1aa7b944b719eb1ee472435ae5444a3f8a00eb6350e3b1d1217d738477d33"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa8d8559c2d25d6ac87e0adeee601d2c91ec40b357ab780bcf79061cc23324e6"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0badcbfe3c72b5b30d59c2b12f120923127abd95a0d2aa64ddc1234e495abc2"}, + {file = "uuid_utils-0.10.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a7c1c494012335113748815156c5b6234c59b0fe0d3a8eede1b1a46f7e25a69"}, + {file = "uuid_utils-0.10.0.tar.gz", hash = "sha256:5db0e1890e8f008657ffe6ded4d9459af724ab114cfe82af1557c87545301539"}, ] [[package]] @@ -3141,4 +3092,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "bbb6160407926b8aceeceeb69268118c018e71a0857eefa9e3567b09d4088f15" +content-hash = "0ad79fb5601c4fea9a3e7d4f978e0b0085a76b49f7934a1814e04922c2029d80" diff --git a/pyproject.toml b/pyproject.toml index 557927eca2..5ab3ec2d4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ requests = "~2.32.3" rlp = "4.0.1" unflatten = "~0.2" sd-jwt = "^0.10.3" -uuid_utils = "^0.9.0" +uuid_utils = "^0.10.0" # did libraries did-peer-2 = "^0.1.2" From b8283d74262859311cd520df29739a6d44d8e736 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:59:05 -0800 Subject: [PATCH 068/152] chore(deps-dev): Bump debugpy from 1.8.8 to 1.8.9 (#3350) Bumps [debugpy](https://github.com/microsoft/debugpy) from 1.8.8 to 1.8.9. - [Release notes](https://github.com/microsoft/debugpy/releases) - [Commits](https://github.com/microsoft/debugpy/compare/v1.8.8...v1.8.9) --- updated-dependencies: - dependency-name: debugpy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 56 +++++++++++++++++++++++++------------------------- pyproject.toml | 2 +- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1c0f343a8a..4265229219 100644 --- a/poetry.lock +++ b/poetry.lock @@ -812,37 +812,37 @@ cython = ["cython"] [[package]] name = "debugpy" -version = "1.8.8" +version = "1.8.9" description = "An implementation of the Debug Adapter Protocol for Python" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.8-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:e59b1607c51b71545cb3496876544f7186a7a27c00b436a62f285603cc68d1c6"}, - {file = "debugpy-1.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6531d952b565b7cb2fbd1ef5df3d333cf160b44f37547a4e7cf73666aca5d8d"}, - {file = "debugpy-1.8.8-cp310-cp310-win32.whl", hash = "sha256:b01f4a5e5c5fb1d34f4ccba99a20ed01eabc45a4684f4948b5db17a319dfb23f"}, - {file = "debugpy-1.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:535f4fb1c024ddca5913bb0eb17880c8f24ba28aa2c225059db145ee557035e9"}, - {file = "debugpy-1.8.8-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:c399023146e40ae373753a58d1be0a98bf6397fadc737b97ad612886b53df318"}, - {file = "debugpy-1.8.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09cc7b162586ea2171eea055985da2702b0723f6f907a423c9b2da5996ad67ba"}, - {file = "debugpy-1.8.8-cp311-cp311-win32.whl", hash = "sha256:eea8821d998ebeb02f0625dd0d76839ddde8cbf8152ebbe289dd7acf2cdc6b98"}, - {file = "debugpy-1.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:d4483836da2a533f4b1454dffc9f668096ac0433de855f0c22cdce8c9f7e10c4"}, - {file = "debugpy-1.8.8-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:0cc94186340be87b9ac5a707184ec8f36547fb66636d1029ff4f1cc020e53996"}, - {file = "debugpy-1.8.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64674e95916e53c2e9540a056e5f489e0ad4872645399d778f7c598eacb7b7f9"}, - {file = "debugpy-1.8.8-cp312-cp312-win32.whl", hash = "sha256:5c6e885dbf12015aed73770f29dec7023cb310d0dc2ba8bfbeb5c8e43f80edc9"}, - {file = "debugpy-1.8.8-cp312-cp312-win_amd64.whl", hash = "sha256:19ffbd84e757a6ca0113574d1bf5a2298b3947320a3e9d7d8dc3377f02d9f864"}, - {file = "debugpy-1.8.8-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:705cd123a773d184860ed8dae99becd879dfec361098edbefb5fc0d3683eb804"}, - {file = "debugpy-1.8.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890fd16803f50aa9cb1a9b9b25b5ec321656dd6b78157c74283de241993d086f"}, - {file = "debugpy-1.8.8-cp313-cp313-win32.whl", hash = "sha256:90244598214bbe704aa47556ec591d2f9869ff9e042e301a2859c57106649add"}, - {file = "debugpy-1.8.8-cp313-cp313-win_amd64.whl", hash = "sha256:4b93e4832fd4a759a0c465c967214ed0c8a6e8914bced63a28ddb0dd8c5f078b"}, - {file = "debugpy-1.8.8-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:143ef07940aeb8e7316de48f5ed9447644da5203726fca378f3a6952a50a9eae"}, - {file = "debugpy-1.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f95651bdcbfd3b27a408869a53fbefcc2bcae13b694daee5f1365b1b83a00113"}, - {file = "debugpy-1.8.8-cp38-cp38-win32.whl", hash = "sha256:26b461123a030e82602a750fb24d7801776aa81cd78404e54ab60e8b5fecdad5"}, - {file = "debugpy-1.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3cbf1833e644a3100eadb6120f25be8a532035e8245584c4f7532937edc652a"}, - {file = "debugpy-1.8.8-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:53709d4ec586b525724819dc6af1a7703502f7e06f34ded7157f7b1f963bb854"}, - {file = "debugpy-1.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a9c013077a3a0000e83d97cf9cc9328d2b0bbb31f56b0e99ea3662d29d7a6a2"}, - {file = "debugpy-1.8.8-cp39-cp39-win32.whl", hash = "sha256:ffe94dd5e9a6739a75f0b85316dc185560db3e97afa6b215628d1b6a17561cb2"}, - {file = "debugpy-1.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5c0e5a38c7f9b481bf31277d2f74d2109292179081f11108e668195ef926c0f9"}, - {file = "debugpy-1.8.8-py2.py3-none-any.whl", hash = "sha256:ec684553aba5b4066d4de510859922419febc710df7bba04fe9e7ef3de15d34f"}, - {file = "debugpy-1.8.8.zip", hash = "sha256:e6355385db85cbd666be703a96ab7351bc9e6c61d694893206f8001e22aee091"}, + {file = "debugpy-1.8.9-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:cfe1e6c6ad7178265f74981edf1154ffce97b69005212fbc90ca22ddfe3d017e"}, + {file = "debugpy-1.8.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada7fb65102a4d2c9ab62e8908e9e9f12aed9d76ef44880367bc9308ebe49a0f"}, + {file = "debugpy-1.8.9-cp310-cp310-win32.whl", hash = "sha256:c36856343cbaa448171cba62a721531e10e7ffb0abff838004701454149bc037"}, + {file = "debugpy-1.8.9-cp310-cp310-win_amd64.whl", hash = "sha256:17c5e0297678442511cf00a745c9709e928ea4ca263d764e90d233208889a19e"}, + {file = "debugpy-1.8.9-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:b74a49753e21e33e7cf030883a92fa607bddc4ede1aa4145172debc637780040"}, + {file = "debugpy-1.8.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d22dacdb0e296966d7d74a7141aaab4bec123fa43d1a35ddcb39bf9fd29d70"}, + {file = "debugpy-1.8.9-cp311-cp311-win32.whl", hash = "sha256:8138efff315cd09b8dcd14226a21afda4ca582284bf4215126d87342bba1cc66"}, + {file = "debugpy-1.8.9-cp311-cp311-win_amd64.whl", hash = "sha256:ff54ef77ad9f5c425398efb150239f6fe8e20c53ae2f68367eba7ece1e96226d"}, + {file = "debugpy-1.8.9-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:957363d9a7a6612a37458d9a15e72d03a635047f946e5fceee74b50d52a9c8e2"}, + {file = "debugpy-1.8.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e565fc54b680292b418bb809f1386f17081d1346dca9a871bf69a8ac4071afe"}, + {file = "debugpy-1.8.9-cp312-cp312-win32.whl", hash = "sha256:3e59842d6c4569c65ceb3751075ff8d7e6a6ada209ceca6308c9bde932bcef11"}, + {file = "debugpy-1.8.9-cp312-cp312-win_amd64.whl", hash = "sha256:66eeae42f3137eb428ea3a86d4a55f28da9bd5a4a3d369ba95ecc3a92c1bba53"}, + {file = "debugpy-1.8.9-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:957ecffff80d47cafa9b6545de9e016ae8c9547c98a538ee96ab5947115fb3dd"}, + {file = "debugpy-1.8.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1efbb3ff61487e2c16b3e033bc8595aea578222c08aaf3c4bf0f93fadbd662ee"}, + {file = "debugpy-1.8.9-cp313-cp313-win32.whl", hash = "sha256:7c4d65d03bee875bcb211c76c1d8f10f600c305dbd734beaed4077e902606fee"}, + {file = "debugpy-1.8.9-cp313-cp313-win_amd64.whl", hash = "sha256:e46b420dc1bea64e5bbedd678148be512442bc589b0111bd799367cde051e71a"}, + {file = "debugpy-1.8.9-cp38-cp38-macosx_14_0_x86_64.whl", hash = "sha256:472a3994999fe6c0756945ffa359e9e7e2d690fb55d251639d07208dbc37caea"}, + {file = "debugpy-1.8.9-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365e556a4772d7d0d151d7eb0e77ec4db03bcd95f26b67b15742b88cacff88e9"}, + {file = "debugpy-1.8.9-cp38-cp38-win32.whl", hash = "sha256:54a7e6d3014c408eb37b0b06021366ee985f1539e12fe49ca2ee0d392d9ceca5"}, + {file = "debugpy-1.8.9-cp38-cp38-win_amd64.whl", hash = "sha256:8e99c0b1cc7bf86d83fb95d5ccdc4ad0586d4432d489d1f54e4055bcc795f693"}, + {file = "debugpy-1.8.9-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:7e8b079323a56f719977fde9d8115590cb5e7a1cba2fcee0986ef8817116e7c1"}, + {file = "debugpy-1.8.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6953b335b804a41f16a192fa2e7851bdcfd92173cbb2f9f777bb934f49baab65"}, + {file = "debugpy-1.8.9-cp39-cp39-win32.whl", hash = "sha256:7e646e62d4602bb8956db88b1e72fe63172148c1e25c041e03b103a25f36673c"}, + {file = "debugpy-1.8.9-cp39-cp39-win_amd64.whl", hash = "sha256:3d9755e77a2d680ce3d2c5394a444cf42be4a592caaf246dbfbdd100ffcf7ae5"}, + {file = "debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899"}, + {file = "debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e"}, ] [[package]] @@ -3092,4 +3092,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "0ad79fb5601c4fea9a3e7d4f978e0b0085a76b49f7934a1814e04922c2029d80" +content-hash = "abc6c8d75193033d767c0a9422a991ed7fd65a10deb77fe64377c0a3716cc99d" diff --git a/pyproject.toml b/pyproject.toml index 5ab3ec2d4a..5a505ccd5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,7 +84,7 @@ pytest-asyncio = "^0.24.0" pytest-cov = "^5.0.0" pytest-ruff = "^0.4.1" pytest-xdist = "^3.6.1" -debugpy = "^1.8.8" +debugpy = "^1.8.9" [tool.poetry.extras] askar = ["aries-askar", "indy-credx", "indy-vdr", "anoncreds"] From 249ac73b03d1a3039ee58225ac09091acdaf6bb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 13:28:57 -0800 Subject: [PATCH 069/152] chore(deps): Bump aiohttp from 3.11.2 to 3.11.7 (#3349) Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.11.2 to 3.11.7. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.11.2...v3.11.7) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 156 ++++++++++++++++++++++++------------------------- pyproject.toml | 2 +- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4265229219..2ec25c70e1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -24,87 +24,87 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.2" +version = "3.11.7" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:783741f534c14957fbe657d62a34b947ec06db23d45a2fd4a8aeb73d9c84d7e6"}, - {file = "aiohttp-3.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:435f7a08d8aa42371a94e7c141205a9cb092ba551084b5e0c57492e6673601a3"}, - {file = "aiohttp-3.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c681f34e2814bc6e1eef49752b338061b94a42c92734d0be9513447d3f83718c"}, - {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73a664478ae1ea011b5a710fb100b115ca8b2146864fa0ce4143ff944df714b8"}, - {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1d06c8fd8b453c3e553c956bd3b8395100401060430572174bb7876dd95ad49"}, - {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b1f4844909321ef2c1cee50ddeccbd6018cd8c8d1ddddda3f553e94a5859497"}, - {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdc6f8dce09281ae534eaf08a54f0d38612398375f28dad733a8885f3bf9b978"}, - {file = "aiohttp-3.11.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2d942421cf3a1d1eceae8fa192f1fbfb74eb9d3e207d35ad2696bd2ce2c987c"}, - {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:08ebe7a1d6c1e5ca766d68407280d69658f5f98821c2ba6c41c63cabfed159af"}, - {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2793d3297f3e49015140e6d3ea26142c967e07998e2fb00b6ee8d041138fbc4e"}, - {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4a23475d8d5c56e447b7752a1e2ac267c1f723f765e406c81feddcd16cdc97bc"}, - {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:556564d89e2f4a6e8fe000894c03e4e84cf0b6cfa5674e425db122633ee244d1"}, - {file = "aiohttp-3.11.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:57993f406ce3f114b2a6756d7809be3ffd0cc40f33e8f8b9a4aa1b027fd4e3eb"}, - {file = "aiohttp-3.11.2-cp310-cp310-win32.whl", hash = "sha256:177b000efaf8d2f7012c649e8aee5b0bf488677b1162be5e7511aa4f9d567607"}, - {file = "aiohttp-3.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:ff5d22eece44528023254b595c670dfcf9733ac6af74c4b6cb4f6a784dc3870c"}, - {file = "aiohttp-3.11.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:50e0aee4adc9abcd2109c618a8d1b2c93b85ac277b24a003ab147d91e068b06d"}, - {file = "aiohttp-3.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9aa4e68f1e4f303971ec42976fb170204fb5092de199034b57199a1747e78a2d"}, - {file = "aiohttp-3.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d84930b4145991214602372edd7305fc76b700220db79ac0dd57d3afd0f0a1ca"}, - {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ec8afd362356b8798c8caa806e91deb3f0602d8ffae8e91d2d3ced2a90c35e"}, - {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb0544a0e8294a5a5e20d3cacdaaa9a911d7c0a9150f5264aef36e7d8fdfa07e"}, - {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7b0a1618060e3f5aa73d3526ca2108a16a1b6bf86612cd0bb2ddcbef9879d06"}, - {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d878a0186023ac391861958035174d0486f3259cabf8fd94e591985468da3ea"}, - {file = "aiohttp-3.11.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e33a7eddcd07545ccf5c3ab230f60314a17dc33e285475e8405e26e21f02660"}, - {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4d7fad8c456d180a6d2f44c41cfab4b80e2e81451815825097db48b8293f59d5"}, - {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d954ba0eae7f33884d27dc00629ca4389d249eb8d26ca07c30911257cae8c96"}, - {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:afa55e863224e664a782effa62245df73fdfc55aee539bed6efacf35f6d4e4b7"}, - {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:10a5f91c319d9d4afba812f72984816b5fcd20742232ff7ecc1610ffbf3fc64d"}, - {file = "aiohttp-3.11.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6e8e19a80ba194db5c06915a9df23c0c06e0e9ca9a4db9386a6056cca555a027"}, - {file = "aiohttp-3.11.2-cp311-cp311-win32.whl", hash = "sha256:9c8d1db4f65bbc9d75b7b271d68fb996f1c8c81a525263862477d93611856c2d"}, - {file = "aiohttp-3.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:2adb967454e10e69478ba4a8d8afbba48a7c7a8619216b7c807f8481cc66ddfb"}, - {file = "aiohttp-3.11.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f833a80d9de9307d736b6af58c235b17ef7f90ebea7b9c49cd274dec7a66a2f1"}, - {file = "aiohttp-3.11.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:382f853516664d2ebfc75dc01da4a10fdef5edcb335fe7b45cf471ce758ecb18"}, - {file = "aiohttp-3.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d3a2bcf6c81639a165da93469e1e0aff67c956721f3fa9c0560f07dd1e505116"}, - {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de3b4d5fb5d69749104b880a157f38baeea7765c93d9cd3837cedd5b84729e10"}, - {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a90a0dc4b054b5af299a900bf950fe8f9e3e54322bc405005f30aa5cacc5c98"}, - {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32334f35824811dd20a12cc90825d000e6b50faaeaa71408d42269151a66140d"}, - {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cba0b8d25aa2d450762f3dd6df85498f5e7c3ad0ddeb516ef2b03510f0eea32"}, - {file = "aiohttp-3.11.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bbb2dbc2701ab7e9307ca3a8fa4999c5b28246968e0a0202a5afabf48a42e22"}, - {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97fba98fc5d9ccd3d33909e898d00f2494d6a9eec7cbda3d030632e2c8bb4d00"}, - {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0ebdf5087e2ce903d8220cc45dcece90c2199ae4395fd83ca616fcc81010db2c"}, - {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:122768e3ae9ce74f981b46edefea9c6e5a40aea38aba3ac50168e6370459bf20"}, - {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5587da333b7d280a312715b843d43e734652aa382cba824a84a67c81f75b338b"}, - {file = "aiohttp-3.11.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:85de9904bc360fd29a98885d2bfcbd4e02ab33c53353cb70607f2bea2cb92468"}, - {file = "aiohttp-3.11.2-cp312-cp312-win32.whl", hash = "sha256:b470de64d17156c37e91effc109d3b032b39867000e2c126732fe01d034441f9"}, - {file = "aiohttp-3.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:3f617a48b70f4843d54f52440ea1e58da6bdab07b391a3a6aed8d3b311a4cc04"}, - {file = "aiohttp-3.11.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d90b5a3b0f32a5fecf5dd83d828713986c019585f5cddf40d288ff77f366615"}, - {file = "aiohttp-3.11.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d23854e5867650d40cba54d49956aad8081452aa80b2cf0d8c310633f4f48510"}, - {file = "aiohttp-3.11.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:486273d3b5af75a80c31c311988931bdd2a4b96a74d5c7f422bad948f99988ef"}, - {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9075313f8e41b481e4cb10af405054564b0247dc335db5398ed05f8ec38787e2"}, - {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44b69c69c194ffacbc50165911cf023a4b1b06422d1e1199d3aea82eac17004e"}, - {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b339d91ac9060bd6ecdc595a82dc151045e5d74f566e0864ef3f2ba0887fec42"}, - {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64e8f5178958a9954043bc8cd10a5ae97352c3f2fc99aa01f2aebb0026010910"}, - {file = "aiohttp-3.11.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3129151378f858cdc4a0a4df355c9a0d060ab49e2eea7e62e9f085bac100551b"}, - {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:14eb6c628432720e41b4fab1ada879d56cfe7034159849e083eb536b4c2afa99"}, - {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e57a10aacedcf24666f4c90d03e599f71d172d1c5e00dcf48205c445806745b0"}, - {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:66e58a2e8c7609a3545c4b38fb8b01a6b8346c4862e529534f7674c5265a97b8"}, - {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9b6d15adc9768ff167614ca853f7eeb6ee5f1d55d5660e3af85ce6744fed2b82"}, - {file = "aiohttp-3.11.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2914061f5ca573f990ec14191e6998752fa8fe50d518e3405410353c3f44aa5d"}, - {file = "aiohttp-3.11.2-cp313-cp313-win32.whl", hash = "sha256:1c2496182e577042e0e07a328d91c949da9e77a2047c7291071e734cd7a6e780"}, - {file = "aiohttp-3.11.2-cp313-cp313-win_amd64.whl", hash = "sha256:cccb2937bece1310c5c0163d0406aba170a2e5fb1f0444d7b0e7fdc9bd6bb713"}, - {file = "aiohttp-3.11.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:994cb893936dd2e1803655ae8667a45066bfd53360b148e22b4e3325cc5ea7a3"}, - {file = "aiohttp-3.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3666c750b73ce463a413692e3a57c60f7089e2d9116a2aa5a0f0eaf2ae325148"}, - {file = "aiohttp-3.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6ad9a7d2a3a0f235184426425f80bd3b26c66b24fd5fddecde66be30c01ebe6e"}, - {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c979fc92aba66730b66099cd5becb42d869a26c0011119bc1c2478408a8bf7a"}, - {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:766d0ebf8703d28f854f945982aa09224d5a27a29594c70d921c43c3930fe7ac"}, - {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79efd1ee3827b2f16797e14b1e45021206c3271249b4d0025014466d416d7413"}, - {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d6e069b882c1fdcbe5577dc4be372eda705180197140577a4cddb648c29d22e"}, - {file = "aiohttp-3.11.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e9a766c346b2ed7e88937919d84ed64b4ef489dad1d8939f806ee52901dc142"}, - {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2b02a68b9445c70d7f5c8b578c5f5e5866b1d67ca23eb9e8bc8658ae9e3e2c74"}, - {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:374baefcb1b6275f350da605951f5f02487a9bc84a574a7d5b696439fabd49a3"}, - {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d2f991c18132f3e505c108147925372ffe4549173b7c258cf227df1c5977a635"}, - {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:34f37c59b12bc3afc52bab6fcd9cd3be82ff01c4598a84cbea934ccb3a9c54a0"}, - {file = "aiohttp-3.11.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:33af11eca7bb0f5c6ffaf5e7d9d2336c2448f9c6279b93abdd6f3c35f9ee321f"}, - {file = "aiohttp-3.11.2-cp39-cp39-win32.whl", hash = "sha256:83a70e22e0f6222effe7f29fdeba6c6023f9595e59a0479edacfbd7de4b77bb7"}, - {file = "aiohttp-3.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:c28c1677ea33ccb8b14330560094cc44d3ff4fad617a544fd18beb90403fe0f1"}, - {file = "aiohttp-3.11.2.tar.gz", hash = "sha256:68d1f46f9387db3785508f5225d3acbc5825ca13d9c29f2b5cce203d5863eb79"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bedb1f6cb919af3b6353921c71281b1491f948ca64408871465d889b4ee1b66"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f5022504adab881e2d801a88b748ea63f2a9d130e0b2c430824682a96f6534be"}, + {file = "aiohttp-3.11.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e22d1721c978a6494adc824e0916f9d187fa57baeda34b55140315fa2f740184"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e993676c71288618eb07e20622572b1250d8713e7e00ab3aabae28cb70f3640d"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13a05db87d3b241c186d0936808d0e4e12decc267c617d54e9c643807e968b6"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ba8d043fed7ffa117024d7ba66fdea011c0e7602327c6d73cacaea38abe4491"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda3ed0a7869d2fa16aa41f9961ade73aa2c2e3b2fcb0a352524e7b744881889"}, + {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43bfd25113c1e98aec6c70e26d5f4331efbf4aa9037ba9ad88f090853bf64d7f"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3dd3e7e7c9ef3e7214f014f1ae260892286647b3cf7c7f1b644a568fd410f8ca"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78c657ece7a73b976905ab9ec8be9ef2df12ed8984c24598a1791c58ce3b4ce4"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:db70a47987e34494b451a334605bee57a126fe8d290511349e86810b4be53b01"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9e67531370a3b07e49b280c1f8c2df67985c790ad2834d1b288a2f13cd341c5f"}, + {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9202f184cc0582b1db15056f2225ab4c1e3dac4d9ade50dd0613ac3c46352ac2"}, + {file = "aiohttp-3.11.7-cp310-cp310-win32.whl", hash = "sha256:2257bdd5cf54a4039a4337162cd8048f05a724380a2283df34620f55d4e29341"}, + {file = "aiohttp-3.11.7-cp310-cp310-win_amd64.whl", hash = "sha256:b7215bf2b53bc6cb35808149980c2ae80a4ae4e273890ac85459c014d5aa60ac"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08"}, + {file = "aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884"}, + {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d"}, + {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720"}, + {file = "aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847"}, + {file = "aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea"}, + {file = "aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129"}, + {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124"}, + {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd"}, + {file = "aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8"}, + {file = "aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68"}, + {file = "aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da"}, + {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791"}, + {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52"}, + {file = "aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e"}, + {file = "aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:17829f37c0d31d89aa6b8b010475a10233774771f9b6dc2cc352ea4f8ce95d9a"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d6177077a31b1aecfc3c9070bd2f11419dbb4a70f30f4c65b124714f525c2e48"}, + {file = "aiohttp-3.11.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:badda65ac99555791eed75e234afb94686ed2317670c68bff8a4498acdaee935"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de6466b9d742b4ee56fe1b2440706e225eb48c77c63152b1584864a236e7a50"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b0cc74d5a882c9dacaeeccc1444f0233212b6f5be8bc90833feef1e1ce14b9"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c7af3e50e5903d21d7b935aceed901cc2475463bc16ddd5587653548661fdb"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c63f898f683d1379b9be5afc3dd139e20b30b0b1e0bf69a3fc3681f364cf1629"}, + {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdadc3f6a32d6eca45f9a900a254757fd7855dfb2d8f8dcf0e88f0fae3ff8eb1"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d329300fb23e14ed1f8c6d688dfd867d1dcc3b1d7cd49b7f8c5b44e797ce0932"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5578cf40440eafcb054cf859964bc120ab52ebe0e0562d2b898126d868749629"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7b2f8107a3c329789f3c00b2daad0e35f548d0a55cda6291579136622099a46e"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:43dd89a6194f6ab02a3fe36b09e42e2df19c211fc2050ce37374d96f39604997"}, + {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d2fa6fc7cc865d26ff42480ac9b52b8c9b7da30a10a6442a9cdf429de840e949"}, + {file = "aiohttp-3.11.7-cp39-cp39-win32.whl", hash = "sha256:a7d9a606355655617fee25dd7e54d3af50804d002f1fd3118dd6312d26692d70"}, + {file = "aiohttp-3.11.7-cp39-cp39-win_amd64.whl", hash = "sha256:53c921b58fdc6485d6b2603e0132bb01cd59b8f0620ffc0907f525e0ba071687"}, + {file = "aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668"}, ] [package.dependencies] @@ -3092,4 +3092,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "abc6c8d75193033d767c0a9422a991ed7fd65a10deb77fe64377c0a3716cc99d" +content-hash = "c9121c319eb42db81805bec50a15a153e7ef4f8bef5231a6b12a7a74b4ffe290" diff --git a/pyproject.toml b/pyproject.toml index 5a505ccd5c..de8a3531bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ repository = "https://github.com/openwallet-foundation/acapy" [tool.poetry.dependencies] python = "^3.12" -aiohttp = "~3.11.2" +aiohttp = "~3.11.7" aiohttp-apispec-acapy = "~3.0.2" aiohttp-cors = "~0.7.0" apispec = "^6.6.0" From 51ba3e7db127357a4b50d00834cbce9637fe5d23 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 27 Nov 2024 13:17:23 +0200 Subject: [PATCH 070/152] :rewind: Revert `trace` log changes, and move to debug level Signed-off-by: ff137 --- acapy_agent/config/default_context.py | 20 ++-- acapy_agent/config/logging/configurator.py | 5 - acapy_agent/config/logging/utils.py | 102 ---------------- acapy_agent/config/tests/test_logging.py | 130 --------------------- acapy_agent/core/conductor.py | 93 +++++++-------- acapy_agent/core/plugin_registry.py | 84 +++++++------ acapy_agent/utils/classloader.py | 54 ++++----- 7 files changed, 120 insertions(+), 368 deletions(-) delete mode 100644 acapy_agent/config/logging/utils.py diff --git a/acapy_agent/config/default_context.py b/acapy_agent/config/default_context.py index 35ee02a184..8f28b0eaee 100644 --- a/acapy_agent/config/default_context.py +++ b/acapy_agent/config/default_context.py @@ -5,7 +5,6 @@ from ..anoncreds.registry import AnonCredsRegistry from ..cache.base import BaseCache from ..cache.in_memory import InMemoryCache -from ..config.logging.utils import add_trace_level from ..core.event_bus import EventBus from ..core.goal_code_registry import GoalCodeRegistry from ..core.plugin_registry import PluginRegistry @@ -30,7 +29,6 @@ from .provider import CachedProvider, ClassProvider LOGGER = logging.getLogger(__name__) -add_trace_level() # Allow trace logs from this module class DefaultContextBuilder(ContextBuilder): @@ -38,14 +36,14 @@ class DefaultContextBuilder(ContextBuilder): async def build_context(self) -> InjectionContext: """Build the base injection context; set DIDComm prefix to emit.""" - LOGGER.trace("Building new injection context with settings: %s", self.settings) + LOGGER.debug("Building new injection context") context = InjectionContext(settings=self.settings) context.settings.set_default("default_label", "Aries Cloud Agent") if context.settings.get("timing.enabled"): timing_log = context.settings.get("timing.log_file") - LOGGER.trace("Enabling timing collector with log file: %s", timing_log) + LOGGER.debug("Enabling timing collector with log file: %s", timing_log) collector = Collector(log_path=timing_log) context.injector.bind_instance(Collector, collector) @@ -87,13 +85,13 @@ async def build_context(self) -> InjectionContext: async def bind_providers(self, context: InjectionContext): """Bind various class providers.""" - LOGGER.trace("Begin binding providers to context") + LOGGER.debug("Begin binding providers to context") context.injector.bind_provider(ProfileManager, ProfileManagerProvider()) wallet_type = self.settings.get("wallet.type") if wallet_type == "askar-anoncreds": - LOGGER.trace("Using AnonCreds tails server") + LOGGER.debug("Using AnonCreds tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -101,7 +99,7 @@ async def bind_providers(self, context: InjectionContext): ), ) else: - LOGGER.trace("Using Indy tails server") + LOGGER.debug("Using Indy tails server") context.injector.bind_provider( BaseTailsServer, ClassProvider( @@ -124,7 +122,7 @@ async def bind_providers(self, context: InjectionContext): async def load_plugins(self, context: InjectionContext): """Set up plugin registry and load plugins.""" - LOGGER.trace("Initializing plugin registry") + LOGGER.debug("Initializing plugin registry") plugin_registry = PluginRegistry( blocklist=self.settings.get("blocked_plugins", []) ) @@ -164,7 +162,7 @@ async def load_plugins(self, context: InjectionContext): def register_plugins(plugins: list[str], plugin_type: str): """Register a group of plugins with logging.""" - LOGGER.trace("Registering %s plugins", plugin_type) + LOGGER.debug("Registering %s plugins", plugin_type) for plugin in plugins: plugin_registry.register_plugin(plugin) @@ -177,7 +175,7 @@ def register_anoncreds_plugins(): register_plugins(default_plugins, "default") if context.settings.get("multitenant.admin_enabled"): - LOGGER.trace("Multitenant admin enabled - registering additional plugins") + LOGGER.debug("Multitenant admin enabled - registering additional plugins") plugin_registry.register_plugin("acapy_agent.multitenant.admin") register_askar_plugins() register_anoncreds_plugins() @@ -189,7 +187,7 @@ def register_anoncreds_plugins(): # Register external plugins for plugin_path in self.settings.get("external_plugins", []): - LOGGER.trace("Registering external plugin: %s", plugin_path) + LOGGER.debug("Registering external plugin: %s", plugin_path) plugin_registry.register_plugin(plugin_path) # Register message protocols diff --git a/acapy_agent/config/logging/configurator.py b/acapy_agent/config/logging/configurator.py index fb9e2cb347..128ccf5e49 100644 --- a/acapy_agent/config/logging/configurator.py +++ b/acapy_agent/config/logging/configurator.py @@ -31,14 +31,9 @@ from .timed_rotating_file_multi_process_handler import ( TimedRotatingFileMultiProcessHandler, ) -from .utils import add_trace_level - LOGGER = logging.getLogger(__name__) -# Add TRACE level to logging before any configuration -add_trace_level() - def load_resource(path: str, encoding: Optional[str] = None): """Open a resource file located in a python package or the local filesystem. diff --git a/acapy_agent/config/logging/utils.py b/acapy_agent/config/logging/utils.py deleted file mode 100644 index 10092d261a..0000000000 --- a/acapy_agent/config/logging/utils.py +++ /dev/null @@ -1,102 +0,0 @@ -"""Logging utilities.""" - -import logging -from functools import partial, partialmethod -from typing import Optional - -LOGGER = logging.getLogger(__name__) -_TRACE_LEVEL_ADDED = False - - -def add_logging_level( - level_name: str, level_num: int, method_name: Optional[str] = None -) -> None: - """Add a custom logging level to the `logging` module. - - Comprehensively adds a new logging level to the `logging` module and the - currently configured logging class. - - `level_name` becomes an attribute of the `logging` module with the value - `level_num`. - `methodName` becomes a convenience method for both `logging` itself - and the class returned by `logging.getLoggerClass()` (usually just - `logging.Logger`). - If `methodName` is not specified, `levelName.lower()` is used. - - To avoid accidental clobberings of existing attributes, this method will - raise an `AttributeError` if the level name is already an attribute of the - `logging` module or if the method name is already present - - Example: - ------- - >>> add_logging_level('TRACE', logging.DEBUG - 5) - >>> logging.getLogger(__name__).setLevel('TRACE') - >>> logging.getLogger(__name__).trace('that worked') - >>> logging.trace('so did this') - >>> logging.TRACE - 5 - - References: - - https://stackoverflow.com/a/35804945 - """ - if not method_name: - method_name = level_name.lower() - - if hasattr(logging, level_name): - raise AttributeError(f"{level_name} already defined in logging module") - if hasattr(logging, method_name): - raise AttributeError(f"{method_name} already defined in logging module") - if hasattr(logging.getLoggerClass(), method_name): - raise AttributeError(f"{method_name} already defined in logger class") - - # Add the new logging level - logging.addLevelName(level_num, level_name) - setattr(logging, level_name, level_num) - setattr( - logging.getLoggerClass(), - method_name, - partialmethod(logging.getLoggerClass().log, level_num), - ) - setattr(logging, method_name, partial(logging.log, level_num)) - - -def add_trace_level() -> None: - """Add the TRACE level to the logging module safely. - - This function adds a TRACE level to the logging module if it hasn't been added yet. - It handles the case where TRACE is already defined, avoiding duplicate additions. - - Returns: - None - """ - global _TRACE_LEVEL_ADDED - - if _TRACE_LEVEL_ADDED: - return - - TRACE_LEVEL_NUM = logging.DEBUG - 5 - TRACE_LEVEL_NAME = "TRACE" - TRACE_METHOD_NAME = "trace" - - # Check if TRACE level is already defined - level_exists = ( - hasattr(logging, TRACE_LEVEL_NAME) - and getattr(logging, TRACE_LEVEL_NAME) == TRACE_LEVEL_NUM - ) - - method_exists = hasattr(logging, TRACE_METHOD_NAME) and callable( - getattr(logging, TRACE_METHOD_NAME) - ) - - if not level_exists or not method_exists: - try: - add_logging_level(TRACE_LEVEL_NAME, TRACE_LEVEL_NUM, TRACE_METHOD_NAME) - LOGGER.debug("%s level added to logging module.", TRACE_LEVEL_NAME) - except AttributeError as e: - LOGGER.warning("%s level already exists: %s", TRACE_LEVEL_NAME, e) - else: - LOGGER.debug( - "%s level is already present in the logging module.", TRACE_LEVEL_NAME - ) - - _TRACE_LEVEL_ADDED = True diff --git a/acapy_agent/config/tests/test_logging.py b/acapy_agent/config/tests/test_logging.py index 446395003d..cf23074568 100644 --- a/acapy_agent/config/tests/test_logging.py +++ b/acapy_agent/config/tests/test_logging.py @@ -1,11 +1,9 @@ import contextlib -import logging from io import BufferedReader, StringIO, TextIOWrapper from tempfile import NamedTemporaryFile from unittest import IsolatedAsyncioTestCase, mock from ..logging import configurator as test_module -from ..logging import utils class TestLoggingConfigurator(IsolatedAsyncioTestCase): @@ -164,131 +162,3 @@ def test_load_resource(self): mock_files.return_value.joinpath.assert_called_once_with("def") mock_resource_path.open.assert_called_once_with("rb") assert result == mock_resource_handle # Verify the returned binary stream - - -class TestLoggingUtils(IsolatedAsyncioTestCase): - def setUp(self): - """Set up test environment by backing up logging states and resetting TRACE level.""" - # Backup existing logging attributes (e.g., DEBUG, INFO) - self.original_levels = { - attr: getattr(logging, attr) for attr in dir(logging) if attr.isupper() - } - - # Backup existing logger class methods (e.g., debug, info) - self.original_logger_methods = { - attr: getattr(logging.getLoggerClass(), attr, None) - for attr in dir(logging.getLoggerClass()) - if not attr.startswith("_") - } - - # Remove TRACE level and 'trace' method if they exist - if hasattr(logging, "TRACE"): - delattr(logging, "TRACE") - if hasattr(logging.getLoggerClass(), "trace"): - delattr(logging.getLoggerClass(), "trace") - - # Patch the TRACE_LEVEL_ADDED flag to False before each test - self.trace_level_added_patcher = mock.patch( - "acapy_agent.config.logging.utils._TRACE_LEVEL_ADDED", False - ) - self.mock_trace_level_added = self.trace_level_added_patcher.start() - - def tearDown(self): - """Restore original logging states after each test.""" - # Stop patching TRACE_LEVEL_ADDED - self.trace_level_added_patcher.stop() - - # Restore original logging level attributes - for attr, value in self.original_levels.items(): - setattr(logging, attr, value) - - # Identify and remove any new uppercase attributes added during tests (e.g., TRACE) - current_levels = {attr for attr in dir(logging) if attr.isupper()} - for attr in current_levels - set(self.original_levels.keys()): - delattr(logging, attr) - - # Restore original logger class methods - LoggerClass = logging.getLoggerClass() - for attr, value in self.original_logger_methods.items(): - if value is not None: - setattr(LoggerClass, attr, value) - else: - if hasattr(LoggerClass, attr): - delattr(LoggerClass, attr) - - # Identify and remove any new logger methods added during tests (e.g., trace) - current_methods = {attr for attr in dir(LoggerClass) if not attr.startswith("_")} - for attr in current_methods - set(self.original_logger_methods.keys()): - delattr(LoggerClass, attr) - - @mock.patch("acapy_agent.config.logging.utils.LOGGER") - @mock.patch("acapy_agent.config.logging.utils.logging.addLevelName") - def test_add_logging_level_success(self, mock_add_level_name, mock_logger): - utils.add_logging_level("CUSTOM", 2) - - mock_add_level_name.assert_called_once_with(2, "CUSTOM") - self.assertTrue(hasattr(logging, "CUSTOM")) - self.assertEqual(logging.CUSTOM, 2) - - logger = logging.getLogger(__name__) - self.assertTrue(hasattr(logger, "custom")) - self.assertTrue(callable(logger.custom)) - - self.assertTrue(hasattr(logging, "custom")) - self.assertTrue(callable(logging.custom)) - - def test_add_logging_level_existing_level_name(self): - # Add a level named 'DEBUG' which already exists - with self.assertRaises(AttributeError) as context: - utils.add_logging_level("DEBUG", 15) - self.assertIn("DEBUG already defined in logging module", str(context.exception)) - - def test_add_logging_level_existing_method_name(self): - # Add a logging method that already exists ('debug') - with self.assertRaises(AttributeError) as context: - utils.add_logging_level("CUSTOM", 25, method_name="debug") - self.assertIn("debug already defined in logging module", str(context.exception)) - - @mock.patch("acapy_agent.config.logging.utils.add_logging_level") - @mock.patch("acapy_agent.config.logging.utils.LOGGER") - def test_add_trace_level_new(self, mock_logger, mock_add_logging_level): - # Ensure _TRACE_LEVEL_ADDED is False - utils.add_trace_level() - - mock_add_logging_level.assert_called_once_with( - "TRACE", logging.DEBUG - 5, "trace" - ) - - # Verify logger.debug was called - mock_logger.debug.assert_called_with("%s level added to logging module.", "TRACE") - - # Check that _TRACE_LEVEL_ADDED is now True - self.assertTrue(utils._TRACE_LEVEL_ADDED) - - @mock.patch("acapy_agent.config.logging.utils.LOGGER") - @mock.patch( - "acapy_agent.config.logging.utils.add_logging_level", - side_effect=AttributeError("TRACE already exists"), - ) - def test_add_trace_level_already_exists_exception( - self, mock_add_logging_level, mock_logger - ): - utils.add_trace_level() - - # Verify logger.warning was called - mock_logger.warning.assert_called_with( - "%s level already exists: %s", "TRACE", mock_add_logging_level.side_effect - ) - - @mock.patch("acapy_agent.config.logging.utils.LOGGER") - @mock.patch("acapy_agent.config.logging.utils.add_logging_level") - def test_add_trace_level_already_present(self, mock_add_logging_level, mock_logger): - # Manually set _TRACE_LEVEL_ADDED to True to simulate already added TRACE level - with mock.patch("acapy_agent.config.logging.utils._TRACE_LEVEL_ADDED", True): - utils.add_trace_level() - - # add_logging_level should not be called since TRACE level is already added - mock_add_logging_level.assert_not_called() - - # Verify logger.debug was not called - mock_logger.debug.assert_not_called() diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index c3da908e49..fd04b4e36c 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -27,7 +27,6 @@ load_multiple_genesis_transactions_from_config, ) from ..config.logging import LoggingConfigurator -from ..config.logging.utils import add_trace_level from ..config.provider import ClassProvider from ..config.wallet import wallet_config from ..core.profile import Profile @@ -83,8 +82,6 @@ from .util import SHUTDOWN_EVENT_TOPIC, STARTUP_EVENT_TOPIC LOGGER = logging.getLogger(__name__) -add_trace_level() # Allow trace logs from this module - # Refer ACA-Py issue #2197 # When the from version is not found DEFAULT_ACAPY_VERSION = "v0.7.5" @@ -127,7 +124,7 @@ async def setup(self): LOGGER.debug("Starting setup of the Conductor") context = await self.context_builder.build_context() - LOGGER.trace("Context built successfully") + LOGGER.debug("Context built successfully") if self.force_agent_anoncreds: LOGGER.debug( @@ -153,15 +150,15 @@ async def setup(self): await get_genesis_transactions(context.settings) # Configure the root profile - LOGGER.trace("Configuring the root profile and setting up public DID") + LOGGER.debug("Configuring the root profile and setting up public DID") self.root_profile, self.setup_public_did = await wallet_config(context) context = self.root_profile.context - LOGGER.trace("Root profile configured successfully") + LOGGER.debug("Root profile configured successfully") # Multiledger Setup ledger_config_list = context.settings.get("ledger.ledger_config_list") if ledger_config_list and len(ledger_config_list) > 0: - LOGGER.trace("Setting up multiledger manager") + LOGGER.debug("Setting up multiledger manager") context.injector.bind_provider( BaseMultipleLedgerManager, MultiIndyLedgerManagerProvider(self.root_profile), @@ -177,7 +174,7 @@ async def setup(self): self.root_profile.BACKEND_NAME == "askar" and ledger.BACKEND_NAME == "indy-vdr" ): - LOGGER.trace("Binding IndyCredxVerifier for 'askar' backend.") + LOGGER.debug("Binding IndyCredxVerifier for 'askar' backend.") context.injector.bind_provider( IndyVerifier, ClassProvider( @@ -189,7 +186,7 @@ async def setup(self): self.root_profile.BACKEND_NAME == "askar-anoncreds" and ledger.BACKEND_NAME == "indy-vdr" ): - LOGGER.trace( + LOGGER.debug( "Binding IndyCredxVerifier for 'askar-anoncreds' backend." ) context.injector.bind_provider( @@ -228,7 +225,7 @@ async def setup(self): context.injector.bind_instance( InboundTransportManager, self.inbound_transport_manager ) - LOGGER.trace("Inbound transports registered successfully.") + LOGGER.debug("Inbound transports registered successfully.") # Register all outbound transports LOGGER.debug("Setting up outbound transports.") @@ -236,46 +233,46 @@ async def setup(self): self.root_profile, self.handle_not_delivered ) await self.outbound_transport_manager.setup() - LOGGER.trace("Outbound transports registered successfully.") + LOGGER.debug("Outbound transports registered successfully.") # Initialize dispatcher - LOGGER.trace("Initializing dispatcher.") + LOGGER.debug("Initializing dispatcher.") self.dispatcher = Dispatcher(self.root_profile) await self.dispatcher.setup() - LOGGER.trace("Dispatcher initialized successfully.") + LOGGER.debug("Dispatcher initialized successfully.") wire_format = context.inject_or(BaseWireFormat) if wire_format and hasattr(wire_format, "task_queue"): wire_format.task_queue = self.dispatcher.task_queue - LOGGER.trace("Wire format task queue bound to dispatcher.") + LOGGER.debug("Wire format task queue bound to dispatcher.") # Bind manager for multitenancy related tasks if context.settings.get("multitenant.enabled"): - LOGGER.trace("Multitenant is enabled. Binding MultitenantManagerProvider.") + LOGGER.debug("Multitenant is enabled. Binding MultitenantManagerProvider.") context.injector.bind_provider( BaseMultitenantManager, MultitenantManagerProvider(self.root_profile) ) # Bind route manager provider - LOGGER.trace("Binding RouteManagerProvider.") + LOGGER.debug("Binding RouteManagerProvider.") context.injector.bind_provider( RouteManager, RouteManagerProvider(self.root_profile) ) # Bind OobMessageProcessor to be able to receive and process unencrypted messages - LOGGER.trace("Binding OobMessageProcessor.") + LOGGER.debug("Binding OobMessageProcessor.") context.injector.bind_instance( OobMessageProcessor, OobMessageProcessor(inbound_message_router=self.inbound_message_router), ) # Bind default PyLD document loader - LOGGER.trace("Binding default DocumentLoader.") + LOGGER.debug("Binding default DocumentLoader.") context.injector.bind_instance(DocumentLoader, DocumentLoader(self.root_profile)) # Admin API if context.settings.get("admin.enabled"): - LOGGER.trace("Admin API is enabled. Attempting to register admin server.") + LOGGER.debug("Admin API is enabled. Attempting to register admin server.") try: admin_host = context.settings.get("admin.host", "0.0.0.0") admin_port = context.settings.get("admin.port", "80") @@ -299,7 +296,7 @@ async def setup(self): # Fetch stats collector, if any collector = context.inject_or(Collector) if collector: - LOGGER.trace("Stats collector found. Wrapping methods for collection.") + LOGGER.debug("Stats collector found. Wrapping methods for collection.") # add stats to our own methods collector.wrap( self, @@ -318,35 +315,35 @@ async def setup(self): "find_inbound_connection", ), ) - LOGGER.trace("Methods wrapped with stats collector.") + LOGGER.debug("Methods wrapped with stats collector.") async def start(self) -> None: """Start the agent.""" LOGGER.debug("Starting the Conductor agent.") context = self.root_profile.context await self.check_for_valid_wallet_type(self.root_profile) - LOGGER.trace("Wallet type validated.") + LOGGER.debug("Wallet type validated.") if not context.settings.get("transport.disabled"): # Start up transports if enabled try: - LOGGER.trace("Transport not disabled. Starting inbound transports.") + LOGGER.debug("Transport not disabled. Starting inbound transports.") await self.inbound_transport_manager.start() - LOGGER.trace("Inbound transports started successfully.") + LOGGER.debug("Inbound transports started successfully.") except Exception: LOGGER.exception("Unable to start inbound transports.") raise try: - LOGGER.trace("Starting outbound transports.") + LOGGER.debug("Starting outbound transports.") await self.outbound_transport_manager.start() - LOGGER.trace("Outbound transports started successfully.") + LOGGER.debug("Outbound transports started successfully.") except Exception: LOGGER.exception("Unable to start outbound transports.") raise # Start up Admin server if self.admin_server: - LOGGER.trace("Admin server present. Starting admin server.") + LOGGER.debug("Admin server present. Starting admin server.") try: await self.admin_server.start() LOGGER.debug("Admin server started successfully.") @@ -360,7 +357,7 @@ async def start(self) -> None: self.admin_server.outbound_message_router, ) context.injector.bind_instance(BaseResponder, responder) - LOGGER.trace("Admin responder bound to injector.") + LOGGER.debug("Admin responder bound to injector.") # Get agent label default_label = context.settings.get("default_label") @@ -389,7 +386,7 @@ async def start(self) -> None: from_version_storage = None from_version = None agent_version = f"v{__version__}" - LOGGER.trace("Recording ACA-Py version in wallet if needed.") + LOGGER.debug("Recording ACA-Py version in wallet if needed.") async with self.root_profile.session() as session: storage: BaseStorage = session.context.inject(BaseStorage) try: @@ -409,7 +406,7 @@ async def start(self) -> None: force_upgrade_flag = ( self.root_profile.settings.get("upgrade.force_upgrade") or False ) - LOGGER.trace( + LOGGER.debug( "Force upgrade flag: %s, From version config: %s", force_upgrade_flag, from_version_config, @@ -425,12 +422,12 @@ async def start(self) -> None: from_version = from_version_storage else: from_version = from_version_config - LOGGER.trace( + LOGGER.debug( "Determined from_version based on force_upgrade: %s", from_version ) else: from_version = from_version_storage or from_version_config - LOGGER.trace("Determined from_version: %s", from_version) + LOGGER.debug("Determined from_version: %s", from_version) if not from_version: LOGGER.warning( @@ -442,13 +439,13 @@ async def start(self) -> None: ) from_version = DEFAULT_ACAPY_VERSION self.root_profile.settings.set_value("upgrade.from_version", from_version) - LOGGER.trace("Set upgrade.from_version to default: %s", from_version) + LOGGER.debug("Set upgrade.from_version to default: %s", from_version) config_available_list = get_upgrade_version_list( config_path=self.root_profile.settings.get("upgrade.config_path"), from_version=from_version, ) - LOGGER.trace("Available upgrade versions: %s", config_available_list) + LOGGER.debug("Available upgrade versions: %s", config_available_list) if len(config_available_list) >= 1: LOGGER.info("Upgrade configurations available. Initiating upgrade.") @@ -521,7 +518,6 @@ async def start(self) -> None: qr.add_data(invite_url) qr.print_ascii(invert=True) del mgr - LOGGER.trace("Invitation created and QR code printed.") except Exception: LOGGER.exception("Error creating invitation.") @@ -548,9 +544,6 @@ async def start(self) -> None: qr.add_data(invite_url) qr.print_ascii(invert=True) del mgr - LOGGER.trace( - "Connections protocol invitation created and QR code printed." - ) except Exception: LOGGER.exception("Error creating connections protocol invitation.") @@ -579,7 +572,7 @@ async def start(self) -> None: mediation_connections_invite = context.settings.get( "mediation.connections_invite", False ) - LOGGER.trace( + LOGGER.debug( "Mediation connections invite flag: %s", mediation_connections_invite ) invitation_handler = ( @@ -590,7 +583,7 @@ async def start(self) -> None: if not mediation_invite_record.used: # clear previous mediator configuration before establishing a new one - LOGGER.trace( + LOGGER.debug( "Mediation invite not used. " "Clearing default mediator before accepting new invite." ) @@ -612,7 +605,7 @@ async def start(self) -> None: await MediationInviteStore( session.context.inject(BaseStorage) ).mark_default_invite_as_used() - LOGGER.trace("Marked mediation invite as used.") + LOGGER.debug("Marked mediation invite as used.") await record.metadata_set( session, MediationManager.SEND_REQ_AFTER_CONNECTION, True @@ -620,11 +613,11 @@ async def start(self) -> None: await record.metadata_set( session, MediationManager.SET_TO_DEFAULT_ON_GRANTED, True ) - LOGGER.trace("Set mediation metadata after connection.") + LOGGER.debug("Set mediation metadata after connection.") LOGGER.info("Attempting to connect to mediator...") del mgr - LOGGER.trace("Mediation manager deleted after setting up mediator.") + LOGGER.debug("Mediation manager deleted after setting up mediator.") except Exception: LOGGER.exception("Error accepting mediation invitation.") @@ -638,7 +631,7 @@ async def start(self) -> None: ) # notify protocols of startup status - LOGGER.trace("Notifying protocols of startup status.") + LOGGER.debug("Notifying protocols of startup status.") await self.root_profile.notify(STARTUP_EVENT_TOPIC, {}) LOGGER.debug("Startup notification sent.") @@ -653,16 +646,16 @@ async def stop(self, timeout=1.0): shutdown = TaskQueue() if self.dispatcher: - LOGGER.trace("Initiating shutdown of dispatcher.") + LOGGER.debug("Initiating shutdown of dispatcher.") shutdown.run(self.dispatcher.complete()) if self.admin_server: - LOGGER.trace("Initiating shutdown of admin server.") + LOGGER.debug("Initiating shutdown of admin server.") shutdown.run(self.admin_server.stop()) if self.inbound_transport_manager: - LOGGER.trace("Initiating shutdown of inbound transport manager.") + LOGGER.debug("Initiating shutdown of inbound transport manager.") shutdown.run(self.inbound_transport_manager.stop()) if self.outbound_transport_manager: - LOGGER.trace("Initiating shutdown of outbound transport manager.") + LOGGER.debug("Initiating shutdown of outbound transport manager.") shutdown.run(self.outbound_transport_manager.stop()) if self.root_profile: @@ -671,12 +664,12 @@ async def stop(self, timeout=1.0): if multitenant_mgr: LOGGER.debug("Closing multitenant profiles.") for profile in multitenant_mgr.open_profiles: - LOGGER.trace("Closing profile: %s", profile.name) + LOGGER.debug("Closing profile: %s", profile.name) shutdown.run(profile.close()) LOGGER.debug("Closing root profile.") shutdown.run(self.root_profile.close()) - LOGGER.trace("Waiting for shutdown tasks to complete with timeout=%f.", timeout) + LOGGER.debug("Waiting for shutdown tasks to complete with timeout=%f.", timeout) await shutdown.complete(timeout) LOGGER.info("Conductor agent stopped successfully.") diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 542203c819..4b6b31d99e 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -6,7 +6,6 @@ from typing import Optional, Sequence, Set from ..config.injection_context import InjectionContext -from ..config.logging.utils import add_trace_level from ..core.event_bus import EventBus from ..utils.classloader import ClassLoader, ModuleLoadError from .error import ProtocolDefinitionValidationError @@ -14,7 +13,6 @@ from .protocol_registry import ProtocolRegistry LOGGER = logging.getLogger(__name__) -add_trace_level() # Allow trace logs from this module class PluginRegistry: @@ -132,7 +130,7 @@ def register_plugin(self, module_name: str) -> Optional[ModuleType]: if self._is_valid_plugin(mod, module_name): self._plugins[module_name] = mod - LOGGER.trace("Registered plugin: %s", module_name) + LOGGER.debug("Registered plugin: %s", module_name) return mod LOGGER.debug("Failed to register plugin: %s", module_name) @@ -141,7 +139,7 @@ def register_plugin(self, module_name: str) -> Optional[ModuleType]: def _is_already_registered(self, module_name: str) -> bool: """Check if the plugin is already registered.""" if module_name in self._plugins: - LOGGER.trace("Plugin %s is already registered.", module_name) + LOGGER.debug("Plugin %s is already registered.", module_name) return True return False @@ -165,7 +163,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: """Validate the plugin based on various criteria.""" # Check if the plugin has a 'setup' method if hasattr(mod, "setup"): - LOGGER.trace("Plugin %s has a 'setup' method.", module_name) + LOGGER.debug("Plugin %s has a 'setup' method.", module_name) return True # Check for 'routes' or 'message_types' modules @@ -174,7 +172,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: routes = ClassLoader.load_module("routes", module_name) message_types = ClassLoader.load_module("message_types", module_name) if routes or message_types: - LOGGER.trace("Plugin %s has 'routes' or 'message_types'.", module_name) + LOGGER.debug("Plugin %s has 'routes' or 'message_types'.", module_name) return True # Check for 'definition' module with 'versions' attribute @@ -196,7 +194,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: # Validate the 'versions' attribute try: self.validate_version(definition.versions, module_name) - LOGGER.trace("Plugin %s has valid versions.", module_name) + LOGGER.debug("Plugin %s has valid versions.", module_name) return True except ProtocolDefinitionValidationError as e: LOGGER.error( @@ -208,7 +206,7 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: def register_package(self, package_name: str) -> Sequence[ModuleType]: """Register all modules (sub-packages) under a given package name.""" - LOGGER.trace("Registering package: %s", package_name) + LOGGER.debug("Registering package: %s", package_name) try: module_names = ClassLoader.scan_subpackages(package_name) except ModuleLoadError: @@ -219,28 +217,28 @@ def register_package(self, package_name: str) -> Sequence[ModuleType]: for module_name in module_names: # Skip any module whose last segment is 'tests' if module_name.split(".")[-1] == "tests": - LOGGER.trace("Skipping test module: %s", module_name) + LOGGER.debug("Skipping test module: %s", module_name) continue plugin = self.register_plugin(module_name) if plugin: registered_plugins.append(plugin) else: - LOGGER.trace("Failed to register %s under %s", module_name, package_name) + LOGGER.debug("Failed to register %s under %s", module_name, package_name) return registered_plugins async def init_context(self, context: InjectionContext) -> None: """Call plugin setup methods on the current context.""" - LOGGER.trace("Initializing plugin context for %d plugins", len(self._plugins)) + LOGGER.debug("Initializing plugin context for %d plugins", len(self._plugins)) for plugin in self._plugins.values(): plugin_name = plugin.__name__ if hasattr(plugin, "setup"): - LOGGER.trace("Running setup for plugin: %s", plugin_name) + LOGGER.debug("Running setup for plugin: %s", plugin_name) await plugin.setup(context) else: - LOGGER.trace( + LOGGER.debug( "Loading protocols for plugin without setup: %s", plugin_name ) await self.load_protocols(context, plugin) @@ -259,55 +257,55 @@ async def load_protocol_version( goal_code_registry = context.inject(GoalCodeRegistry) module_name = mod.__name__ - LOGGER.trace("Loading protocol version for module: %s", module_name) + LOGGER.debug("Loading protocol version for module: %s", module_name) if hasattr(mod, "MESSAGE_TYPES"): - LOGGER.trace("Registering message types for: %s", module_name) + LOGGER.debug("Registering message types for: %s", module_name) protocol_registry.register_message_types( mod.MESSAGE_TYPES, version_definition=version_definition ) if hasattr(mod, "CONTROLLERS"): - LOGGER.trace("Registering controllers for: %s", module_name) + LOGGER.debug("Registering controllers for: %s", module_name) protocol_registry.register_controllers(mod.CONTROLLERS) goal_code_registry.register_controllers(mod.CONTROLLERS) async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> None: """For modules that don't implement setup, register protocols manually.""" plugin_name = plugin.__name__ - LOGGER.trace("Loading protocols for plugin: %s", plugin_name) + LOGGER.debug("Loading protocols for plugin: %s", plugin_name) # If this module contains message_types, then assume that # this is a valid module of the old style (not versioned) try: message_types_path = f"{plugin_name}.message_types" - LOGGER.trace("Attempting to load message types from: %s", message_types_path) + LOGGER.debug("Attempting to load message types from: %s", message_types_path) mod = ClassLoader.load_module(message_types_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin module message types: %s", e) return if mod: - LOGGER.trace("Found non-versioned message types for: %s", plugin_name) + LOGGER.debug("Found non-versioned message types for: %s", plugin_name) await self.load_protocol_version(context, mod) else: # Otherwise, try check for definition.py for versioned protocol packages try: definition_path = f"{plugin_name}.definition" - LOGGER.trace("Attempting to load definition from: %s", definition_path) + LOGGER.debug("Attempting to load definition from: %s", definition_path) definition = ClassLoader.load_module(definition_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin definition module: %s", e) return if definition: - LOGGER.trace("Loading versioned protocols for: %s", plugin_name) + LOGGER.debug("Loading versioned protocols for: %s", plugin_name) for protocol_version in definition.versions: version_path = ( f"{plugin_name}.{protocol_version['path']}.message_types" ) try: - LOGGER.trace("Loading message types from: %s", version_path) + LOGGER.debug("Loading message types from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error( @@ -324,20 +322,20 @@ async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> async def register_admin_routes(self, app) -> None: """Call route registration methods on the current context.""" - LOGGER.trace("Registering admin routes for %d plugins", len(self._plugins)) + LOGGER.debug("Registering admin routes for %d plugins", len(self._plugins)) for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.trace("Processing routes for plugin: %s", plugin_name) + LOGGER.debug("Processing routes for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. - LOGGER.trace("Loading versioned routes for: %s", plugin_name) + LOGGER.debug("Loading versioned routes for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.trace("Loading routes from: %s", version_path) + LOGGER.debug("Loading routes from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error( @@ -346,25 +344,25 @@ async def register_admin_routes(self, app) -> None: continue if mod and hasattr(mod, "register"): - LOGGER.trace("Registering routes for: %s", plugin_name) + LOGGER.debug("Registering routes for: %s", plugin_name) await mod.register(app) else: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.trace("Loading non-versioned routes from: %s", routes_path) + LOGGER.debug("Loading non-versioned routes from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading admin routes from %s: %s", routes_path, e) continue if mod and hasattr(mod, "register"): - LOGGER.trace("Registering routes for: %s", plugin_name) + LOGGER.debug("Registering routes for: %s", plugin_name) await mod.register(app) def register_protocol_events(self, context: InjectionContext) -> None: """Call route register_events methods on the current context.""" - LOGGER.trace("Registering protocol events for %d plugins", len(self._plugins)) + LOGGER.debug("Registering protocol events for %d plugins", len(self._plugins)) event_bus = context.inject_or(EventBus) if not event_bus: @@ -373,74 +371,74 @@ def register_protocol_events(self, context: InjectionContext) -> None: for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.trace("Processing events for plugin: %s", plugin_name) + LOGGER.debug("Processing events for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. - LOGGER.trace("Loading versioned events for: %s", plugin_name) + LOGGER.debug("Loading versioned events for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.trace("Loading events from: %s", version_path) + LOGGER.debug("Loading events from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error("Error loading events from %s: %s", version_path, e) continue if mod and hasattr(mod, "register_events"): - LOGGER.trace("Registering events from: %s", version_path) + LOGGER.debug("Registering events from: %s", version_path) mod.register_events(event_bus) else: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.trace("Loading non-versioned events from: %s", routes_path) + LOGGER.debug("Loading non-versioned events from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading events from %s: %s", routes_path, e) continue if mod and hasattr(mod, "register_events"): - LOGGER.trace("Registering events from: %s", version_path) + LOGGER.debug("Registering events from: %s", version_path) mod.register_events(event_bus) def post_process_routes(self, app) -> None: """Call route binary file response OpenAPI fixups if applicable.""" - LOGGER.trace("Post-processing routes for %d plugins", len(self._plugins)) + LOGGER.debug("Post-processing routes for %d plugins", len(self._plugins)) for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.trace("Post-processing routes for plugin: %s", plugin_name) + LOGGER.debug("Post-processing routes for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Set binary file responses for routes that are in a versioned package. - LOGGER.trace("Processing versioned routes for: %s", plugin_name) + LOGGER.debug("Processing versioned routes for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.trace("Loading routes from: %s", version_path) + LOGGER.debug("Loading routes from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error("Error loading routes from %s: %s", version_path, e) continue if mod and hasattr(mod, "post_process_routes"): - LOGGER.trace("Post-processing routes for %s", plugin_name) + LOGGER.debug("Post-processing routes for %s", plugin_name) mod.post_process_routes(app) else: # Set binary file responses for routes not in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.trace("Loading non-versioned routes from: %s", routes_path) + LOGGER.debug("Loading non-versioned routes from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading routes from %s: %s", routes_path, e) continue if mod and hasattr(mod, "post_process_routes"): - LOGGER.trace("Post-processing routes for %s", plugin_name) + LOGGER.debug("Post-processing routes for %s", plugin_name) mod.post_process_routes(app) def __repr__(self) -> str: diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index e257abdb3a..b91b65a630 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -8,11 +8,9 @@ from types import ModuleType from typing import Optional, Sequence, Type -from ..config.logging.utils import add_trace_level from ..core.error import BaseError LOGGER = logging.getLogger(__name__) -add_trace_level() # Allow trace logs from this module class ModuleLoadError(BaseError): @@ -43,49 +41,53 @@ def load_module( ModuleLoadError: If there was an error loading the module """ - LOGGER.trace("Attempting to load module: %s with package: %s", mod_path, package) + LOGGER.debug( + "Attempting to load module: %s%s", + mod_path, + f" with package: {package}" if package else "", + ) if package: - LOGGER.trace("Preloading parent package: %s", package) + LOGGER.debug("Preloading parent package: %s", package) # preload parent package if not cls.load_module(package): - LOGGER.trace("Failed to preload parent package: %s", package) + LOGGER.debug("Failed to preload parent package: %s", package) return None # must treat as a relative import if not mod_path.startswith("."): mod_path = f".{mod_path}" - LOGGER.trace("Adjusted mod_path for relative import: %s", mod_path) + LOGGER.debug("Adjusted mod_path for relative import: %s", mod_path) full_path = resolve_name(mod_path, package) - LOGGER.trace("Resolved full module path: %s", full_path) + LOGGER.debug("Resolved full module path: %s", full_path) if full_path in sys.modules: - LOGGER.trace("Module %s is already loaded", full_path) + LOGGER.debug("Module %s is already loaded", full_path) return sys.modules[full_path] if "." in mod_path: parent_mod_path, mod_name = mod_path.rsplit(".", 1) - LOGGER.trace( + LOGGER.debug( "Parent module path: %s, Module name: %s", parent_mod_path, mod_name ) if parent_mod_path and parent_mod_path[-1] != ".": parent_mod = cls.load_module(parent_mod_path, package) if not parent_mod: - LOGGER.trace("Failed to load parent module: %s", parent_mod_path) + LOGGER.debug("Failed to load parent module: %s", parent_mod_path) return None package = parent_mod.__name__ mod_path = f".{mod_name}" - LOGGER.trace("Adjusted mod_path after loading parent: %s", mod_path) + LOGGER.debug("Adjusted mod_path after loading parent: %s", mod_path) # Load the module spec first - LOGGER.trace("Finding spec for module: %s with package: %s", mod_path, package) + LOGGER.debug("Finding spec for module: %s with package: %s", mod_path, package) spec = find_spec(mod_path, package) if not spec: - LOGGER.trace("Module spec not found for: %s", mod_path) + LOGGER.debug("Module spec not found for: %s", mod_path) return None try: - LOGGER.trace("Importing module: %s with package: %s", mod_path, package) + LOGGER.debug("Importing module: %s with package: %s", mod_path, package) return import_module(mod_path, package) except ModuleNotFoundError as e: LOGGER.warning("Module %s not found during import", full_path) @@ -114,7 +116,7 @@ def load_class( """ - LOGGER.trace( + LOGGER.debug( "Attempting to load class: %s with default_module: %s and package: %s", class_name, default_module, @@ -124,14 +126,14 @@ def load_class( if "." in class_name: # import module and find class mod_path, class_name = class_name.rsplit(".", 1) - LOGGER.trace( + LOGGER.debug( "Extracted module path: %s, class name: %s from full class path", mod_path, class_name, ) elif default_module: mod_path = default_module - LOGGER.trace("No module in class name, using default_module: %s", mod_path) + LOGGER.debug("No module in class name, using default_module: %s", mod_path) else: LOGGER.warning( "Cannot resolve class name %s with no default module", class_name @@ -160,7 +162,7 @@ def load_class( raise ClassNotFoundError( f"Resolved value is not a class: {mod_path}.{class_name}" ) - LOGGER.trace("Successfully loaded class %s from module %s", class_name, mod_path) + LOGGER.debug("Successfully loaded class %s from module %s", class_name, mod_path) return resolved @classmethod @@ -183,7 +185,7 @@ def load_subclass_of( """ - LOGGER.trace( + LOGGER.debug( "Attempting to load subclass of %s from module %s with package %s", base_class.__name__, mod_path, @@ -201,7 +203,7 @@ def load_subclass_of( # Find the first declared class that inherits from the base_class try: - LOGGER.trace( + LOGGER.debug( "Inspecting classes in module %s for subclasses of %s", mod_path, base_class.__name__, @@ -211,13 +213,13 @@ def load_subclass_of( for name, obj in inspect.getmembers(mod, inspect.isclass) if issubclass(obj, base_class) and obj is not base_class ) - LOGGER.trace( + LOGGER.debug( "Found subclass %s of base class %s", imported_class.__name__, base_class.__name__, ) except StopIteration: - LOGGER.trace( + LOGGER.debug( "No subclass of %s found in module %s", base_class.__name__, mod_path, @@ -233,14 +235,14 @@ def scan_subpackages(cls, package: str) -> Sequence[str]: LOGGER.debug("Scanning subpackages under package %s", package) if "." in package: package, sub_pkg = package.split(".", 1) - LOGGER.trace("Extracted main package: %s, sub-package: %s", package, sub_pkg) + LOGGER.debug("Extracted main package: %s, sub-package: %s", package, sub_pkg) else: sub_pkg = "." - LOGGER.trace("No sub-package provided, defaulting to %s", sub_pkg) + LOGGER.debug("No sub-package provided, defaulting to %s", sub_pkg) try: package_path = resources.files(package) - LOGGER.trace("Found package path: %s", package_path) + LOGGER.debug("Found package path: %s", package_path) except FileNotFoundError: LOGGER.warning("Package %s not found during subpackage scan", package) raise ModuleLoadError(f"Undefined package {package}") @@ -252,12 +254,10 @@ def scan_subpackages(cls, package: str) -> Sequence[str]: found = [] joiner = "" if sub_pkg == "." else f"{sub_pkg}." sub_path = package_path / sub_pkg - LOGGER.trace("Iterating over items in sub-package path: %s", sub_path) for item in sub_path.iterdir(): if (item / "__init__.py").exists(): subpackage = f"{package}.{joiner}{item.name}" found.append(subpackage) - LOGGER.trace("Found sub-package: %s", subpackage) LOGGER.debug("Total sub-packages found under %s: %s", package, found) return found From 523d42944f11171edc45c3c1f15f2671d49d9802 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 27 Nov 2024 13:25:37 +0200 Subject: [PATCH 071/152] :sparkles: Add caching to ClassLoader.load_module Signed-off-by: ff137 --- acapy_agent/utils/classloader.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index b91b65a630..83c5648179 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -3,6 +3,7 @@ import inspect import logging import sys +from functools import lru_cache from importlib import import_module, resources from importlib.util import find_spec, resolve_name from types import ModuleType @@ -25,6 +26,7 @@ class ClassLoader: """Class used to load classes from modules dynamically.""" @classmethod + @lru_cache def load_module( cls, mod_path: str, package: Optional[str] = None ) -> Optional[ModuleType]: From a2b32ce5c96dd5e790c705c1252a7b6a1fc81b3d Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 27 Nov 2024 13:41:16 +0200 Subject: [PATCH 072/152] :art: Improve log Signed-off-by: ff137 --- acapy_agent/utils/classloader.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 83c5648179..ca40073cc2 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -119,10 +119,10 @@ def load_class( """ LOGGER.debug( - "Attempting to load class: %s with default_module: %s and package: %s", + "Attempting to load class: %s%s%s", class_name, - default_module, - package, + f", with default_module: {default_module}" if default_module else "", + f", with package: {package}" if package else "", ) if "." in class_name: From eb52b05a97f2fcfe6e69cdebf8f8da4cd8b073d1 Mon Sep 17 00:00:00 2001 From: Mourits de Beer <31511766+ff137@users.noreply.github.com> Date: Wed, 27 Nov 2024 20:11:12 +0200 Subject: [PATCH 073/152] :art: Sync Ruff version in configs and apply formatting (#3358) * :arrow_up: Upgrade ruff version in pre-commit config and lint workflow Signed-off-by: ff137 * :art: Apply ruff formatting Signed-off-by: ff137 * :arrow_up: Upgrade pre-commit hook version Signed-off-by: ff137 --------- Signed-off-by: ff137 --- .github/workflows/format.yml | 2 +- .pre-commit-config.yaml | 4 +- acapy_agent/commands/tests/test_help.py | 18 +- acapy_agent/commands/tests/test_provision.py | 43 +- acapy_agent/commands/tests/test_start.py | 51 +- acapy_agent/commands/tests/test_upgrade.py | 526 ++++--- acapy_agent/config/tests/test_ledger.py | 102 +- acapy_agent/config/tests/test_logging.py | 7 +- acapy_agent/config/tests/test_wallet.py | 94 +- .../connections/tests/test_base_manager.py | 183 ++- acapy_agent/core/tests/test_conductor.py | 1326 ++++++++++------- acapy_agent/core/tests/test_dispatcher.py | 68 +- acapy_agent/core/tests/test_oob_processor.py | 25 +- acapy_agent/indy/tests/test_verifier.py | 11 +- .../tests/test_indy_vdr_manager.py | 52 +- acapy_agent/ledger/tests/test_indy_vdr.py | 62 +- acapy_agent/ledger/tests/test_routes.py | 100 +- .../tests/test_routes.py | 44 +- .../messaging/jsonld/tests/test_routes.py | 42 +- .../messaging/schemas/tests/test_routes.py | 44 +- .../multitenant/admin/tests/test_routes.py | 73 +- acapy_agent/multitenant/tests/test_base.py | 74 +- acapy_agent/multitenant/tests/test_manager.py | 9 +- .../multitenant/tests/test_route_manager.py | 49 +- .../tests/test_single_wallet_askar_manager.py | 26 +- .../actionmenu/v1_0/tests/test_routes.py | 111 +- .../basicmessage/v1_0/tests/test_routes.py | 38 +- .../connections/v1_0/tests/test_manager.py | 411 ++--- .../connections/v1_0/tests/test_routes.py | 272 ++-- .../test_keylist_update_response_handler.py | 9 +- .../tests/test_mediation_grant_handler.py | 34 +- .../v1_0/tests/test_mediation_manager.py | 26 +- .../v1_0/tests/test_route_manager.py | 168 ++- .../v1_0/tests/test_routes.py | 623 ++++---- .../did_rotate/v1_0/tests/test_manager.py | 9 +- .../didexchange/v1_0/tests/test_manager.py | 705 +++++---- .../didexchange/v1_0/tests/test_routes.py | 130 +- .../v1_0/handlers/tests/test_query_handler.py | 13 +- .../discovery/v1_0/tests/test_manager.py | 126 +- .../discovery/v1_0/tests/test_routes.py | 62 +- .../tests/test_disclosures_handler.py | 38 +- .../handlers/tests/test_queries_handler.py | 13 +- .../discovery/v2_0/tests/test_manager.py | 180 ++- .../discovery/v2_0/tests/test_routes.py | 62 +- .../v1_0/tests/test_manager.py | 18 +- .../v1_0/tests/test_routes.py | 569 ++++--- .../introduction/v0_1/tests/test_routes.py | 11 +- .../tests/test_credential_issue_handler.py | 11 +- .../tests/test_credential_offer_handler.py | 11 +- .../tests/test_credential_proposal_handler.py | 11 +- .../tests/test_credential_request_handler.py | 20 +- .../models/tests/test_credential_exchange.py | 11 +- .../v1_0/tests/test_manager.py | 218 +-- .../v1_0/tests/test_routes.py | 563 +++---- .../formats/anoncreds/tests/test_handler.py | 35 +- .../v2_0/formats/indy/tests/test_handler.py | 35 +- .../formats/ld_proof/tests/test_handler.py | 92 +- .../handlers/tests/test_cred_offer_handler.py | 26 +- .../tests/test_cred_proposal_handler.py | 26 +- .../tests/test_cred_request_handler.py | 44 +- .../v2_0/models/tests/test_cred_ex_record.py | 11 +- .../v2_0/tests/test_manager.py | 258 ++-- .../v2_0/tests/test_routes.py | 719 ++++----- .../out_of_band/v1_0/tests/test_manager.py | 451 +++--- .../out_of_band/v1_0/tests/test_routes.py | 80 +- .../dif/tests/test_pres_exch_handler.py | 162 +- .../test_presentation_request_handler.py | 130 +- .../v1_0/models/tests/test_record.py | 11 +- .../present_proof/v1_0/tests/test_manager.py | 197 +-- .../present_proof/v1_0/tests/test_routes.py | 782 +++++----- .../v2_0/formats/dif/tests/test_handler.py | 36 +- .../tests/test_pres_request_handler.py | 221 +-- .../v2_0/models/tests/test_record.py | 11 +- .../present_proof/v2_0/tests/test_manager.py | 375 +++-- .../v2_0/tests/test_manager_anoncreds.py | 375 +++-- .../present_proof/v2_0/tests/test_routes.py | 546 ++++--- .../v2_0/tests/test_routes_anoncreds.py | 546 ++++--- .../handlers/tests/test_forward_handler.py | 16 +- .../trustping/v1_0/tests/test_routes.py | 34 +- .../default/tests/test_legacy_peer.py | 19 +- .../tests/test_issuer_rev_reg_record.py | 46 +- .../models/tests/test_revocation_registry.py | 12 +- acapy_agent/revocation/tests/test_indy.py | 17 +- acapy_agent/revocation/tests/test_manager.py | 224 +-- acapy_agent/revocation/tests/test_routes.py | 521 ++++--- .../tests/test_manager.py | 114 +- .../revocation_anoncreds/tests/test_routes.py | 215 +-- acapy_agent/settings/tests/test_routes.py | 11 +- .../storage/tests/test_askar_storage.py | 134 +- acapy_agent/tests/test_main.py | 10 +- .../transport/inbound/tests/test_session.py | 18 +- .../transport/outbound/tests/test_manager.py | 39 +- .../transport/queue/tests/test_basic_queue.py | 34 +- acapy_agent/utils/tests/test_classloader.py | 9 +- acapy_agent/utils/tests/test_task_queue.py | 9 +- acapy_agent/vc/vc_ld/tests/test_manager.py | 21 +- .../wallet/tests/test_anoncreds_upgrade.py | 24 +- acapy_agent/wallet/tests/test_crypto.py | 13 +- 98 files changed, 8145 insertions(+), 6072 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 74302d3ee4..1f7584e464 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -17,5 +17,5 @@ jobs: - name: Ruff Format and Lint Check uses: chartboost/ruff-action@v1 with: - version: 0.5.7 + version: 0.8.0 args: "format --check" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9b9edb79c9..9374f5f431 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook - rev: v9.16.0 + rev: v9.18.0 hooks: - id: commitlint stages: [commit-msg] @@ -8,7 +8,7 @@ repos: additional_dependencies: ['@commitlint/config-conventional'] - repo: https://github.com/astral-sh/ruff-pre-commit # Ensure this is synced with pyproject.toml - rev: v0.5.7 + rev: v0.8.0 hooks: # Run the linter - id: ruff diff --git a/acapy_agent/commands/tests/test_help.py b/acapy_agent/commands/tests/test_help.py index 562b371ee2..1e1360328f 100644 --- a/acapy_agent/commands/tests/test_help.py +++ b/acapy_agent/commands/tests/test_help.py @@ -5,11 +5,10 @@ class TestHelp(IsolatedAsyncioTestCase): def test_exec_help(self): - with mock.patch.object( - command.ArgumentParser, "print_help" - ) as mock_print_help, mock.patch( - "builtins.print", mock.MagicMock() - ) as mock_print: + with ( + mock.patch.object(command.ArgumentParser, "print_help") as mock_print_help, + mock.patch("builtins.print", mock.MagicMock()) as mock_print, + ): command.execute([]) mock_print_help.assert_called_once() @@ -17,10 +16,9 @@ def test_exec_help(self): mock_print.assert_called_once_with(command.__version__) def test_main(self): - with mock.patch.object( - command, "__name__", "__main__" - ) as mock_name, mock.patch.object( - command, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(command, "__name__", "__main__") as mock_name, + mock.patch.object(command, "execute", mock.MagicMock()) as mock_execute, + ): command.main() mock_execute.assert_called_once diff --git a/acapy_agent/commands/tests/test_provision.py b/acapy_agent/commands/tests/test_provision.py index 65d0d488bd..ed50bb9eb8 100644 --- a/acapy_agent/commands/tests/test_provision.py +++ b/acapy_agent/commands/tests/test_provision.py @@ -21,17 +21,20 @@ def test_bad_calls(self): async def test_provision_ledger_configured(self): profile = mock.MagicMock(close=mock.CoroutineMock()) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + test_module, "ledger_config", mock.CoroutineMock(return_value=True) ), - ), mock.patch.object( - test_module, "ledger_config", mock.CoroutineMock(return_value=True) ): await test_module.provision({}) @@ -44,9 +47,10 @@ async def test_provision_config_x(self): await test_module.provision({}) def test_main(self): - with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(test_module, "__name__", "__main__"), + mock.patch.object(test_module, "execute", mock.MagicMock()) as mock_execute, + ): test_module.main() mock_execute.assert_called_once @@ -55,12 +59,13 @@ async def test_provision_should_store_provided_mediation_invite(self): mediation_invite = "test-invite" test_profile = await create_test_profile() - with mock.patch.object( - test_module.MediationInviteStore, "store" - ) as invite_store, mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock(return_value=(test_profile, mock.MagicMock())), + with ( + mock.patch.object(test_module.MediationInviteStore, "store") as invite_store, + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock(return_value=(test_profile, mock.MagicMock())), + ), ): # when await test_module.provision({"mediation.invite": mediation_invite}) diff --git a/acapy_agent/commands/tests/test_start.py b/acapy_agent/commands/tests/test_start.py index 451ab584bb..cac10b8df6 100644 --- a/acapy_agent/commands/tests/test_start.py +++ b/acapy_agent/commands/tests/test_start.py @@ -25,22 +25,23 @@ async def test_start_shutdown_app(self): await test_module.shutdown_app(mock_conductor) def test_exec_start(self): - with mock.patch.object( - # Normally this would be a CoroutineMock. However, it is awaited by - # run_loop, which is mocked out. So we mock it as a MagicMock. - test_module, - "start_app", - mock.MagicMock(), - ) as start_app, mock.patch.object( - test_module, "run_loop" - ) as run_loop, mock.patch.object( - # Same here as note above - test_module, - "shutdown_app", - mock.MagicMock(), - ) as shutdown_app, mock.patch.object( - test_module, "uvloop", mock.MagicMock() - ) as mock_uvloop: + with ( + mock.patch.object( + # Normally this would be a CoroutineMock. However, it is awaited by + # run_loop, which is mocked out. So we mock it as a MagicMock. + test_module, + "start_app", + mock.MagicMock(), + ) as start_app, + mock.patch.object(test_module, "run_loop") as run_loop, + mock.patch.object( + # Same here as note above + test_module, + "shutdown_app", + mock.MagicMock(), + ) as shutdown_app, + mock.patch.object(test_module, "uvloop", mock.MagicMock()) as mock_uvloop, + ): mock_uvloop.install = mock.MagicMock() test_module.execute( [ @@ -102,11 +103,10 @@ async def test_run_loop_init_x(self): startup_call = startup() shutdown = mock.CoroutineMock() shutdown_call = shutdown() - with mock.patch.object( - test_module, "asyncio", autospec=True - ) as mock_asyncio, mock.patch.object( - test_module, "LOGGER", autospec=True - ) as mock_logger: + with ( + mock.patch.object(test_module, "asyncio", autospec=True) as mock_asyncio, + mock.patch.object(test_module, "LOGGER", autospec=True) as mock_logger, + ): test_module.run_loop(startup_call, shutdown_call) mock_add = mock_asyncio.get_event_loop.return_value.add_signal_handler mock_add.assert_called_once() @@ -135,10 +135,9 @@ async def test_run_loop_init_x(self): mock_logger.exception.assert_called_once() def test_main(self): - with mock.patch.object( - test_module, "__name__", "__main__" - ) as mock_name, mock.patch.object( - test_module, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(test_module, "__name__", "__main__") as mock_name, + mock.patch.object(test_module, "execute", mock.MagicMock()) as mock_execute, + ): test_module.main() mock_execute.assert_called_once diff --git a/acapy_agent/commands/tests/test_upgrade.py b/acapy_agent/commands/tests/test_upgrade.py index 51a33640a3..41728221c8 100644 --- a/acapy_agent/commands/tests/test_upgrade.py +++ b/acapy_agent/commands/tests/test_upgrade.py @@ -47,20 +47,24 @@ def test_bad_calls(self): test_module.execute(["bad"]) async def test_upgrade_storage_from_version_included(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( settings={ "upgrade.config_path": "./acapy_agent/commands/default_version_upgrade_config.yml", @@ -69,20 +73,24 @@ async def test_upgrade_storage_from_version_included(self): ) async def test_upgrade_storage_missing_from_version(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade(settings={}) async def test_upgrade_from_version(self): @@ -91,11 +99,14 @@ async def test_upgrade_from_version(self): "upgrade.from_version": "v0.7.2", } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -109,11 +120,14 @@ async def test_upgrade_all_subwallets(self): "upgrade.page_size": 1, } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -131,11 +145,14 @@ async def test_upgrade_specified_subwallets(self): "upgrade.force_upgrade": True, } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -148,11 +165,14 @@ async def test_upgrade_specified_subwallets(self): "upgrade.page_size": 1, } ) - with mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): await test_module.upgrade( profile=self.profile, ) @@ -164,29 +184,32 @@ async def test_upgrade_callable(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ] + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ] + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - } + } + ), ), ): await test_module.upgrade( @@ -202,30 +225,33 @@ async def test_upgrade_callable_named_tag(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ] + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ] + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "fix_issue_rev_reg": {"fix_issue_rev_reg_records": True}, - } + "fix_issue_rev_reg": {"fix_issue_rev_reg_records": True}, + } + ), ), ): await test_module.upgrade( @@ -265,20 +291,24 @@ async def test_upgrade_missing_from_version(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()): + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + ): with self.assertRaises(UpgradeError) as ctx: await test_module.upgrade( settings={ @@ -296,30 +326,33 @@ async def test_upgrade_x_callable_not_set(self): type_filter="acapy_version", tag_query={} ) await storage.delete_record(version_storage_record) - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ] + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ] + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "v0.6.0": {"update_existing_records_b": True}, - } + "v0.6.0": {"update_existing_records_b": True}, + } + ), ), ): with self.assertRaises(UpgradeError) as ctx: @@ -331,28 +364,31 @@ async def test_upgrade_x_callable_not_set(self): assert "No function specified for" in str(ctx.exception) async def test_upgrade_x_class_not_found(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.Invalid" - ], - } - }, - } + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.Invalid" + ], + } + }, + } + ), ), ): with self.assertRaises(UpgradeError) as ctx: @@ -364,28 +400,34 @@ async def test_upgrade_x_class_not_found(self): assert "Unknown Record type" in str(ctx.exception) async def test_execute(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), + ), + mock.patch.object( + ConnRecord, + "query", + mock.CoroutineMock(return_value=[ConnRecord()]), + ), + mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), + mock.patch.object( + asyncio, "get_event_loop", mock.MagicMock() + ) as mock_get_event_loop, + mock.patch.object( + # Normally, this would be a CoroutingMock. However, the coroutine + # is awaited by run_until_complete, which is mocked out. + # Use MagicMock to prevent unawaited coroutine warnings. + test_module, + "upgrade", + mock.MagicMock(), ), - ), mock.patch.object( - ConnRecord, - "query", - mock.CoroutineMock(return_value=[ConnRecord()]), - ), mock.patch.object(ConnRecord, "save", mock.CoroutineMock()), mock.patch.object( - asyncio, "get_event_loop", mock.MagicMock() - ) as mock_get_event_loop, mock.patch.object( - # Normally, this would be a CoroutingMock. However, the coroutine - # is awaited by run_until_complete, which is mocked out. - # Use MagicMock to prevent unawaited coroutine warnings. - test_module, - "upgrade", - mock.MagicMock(), ): mock_get_event_loop.return_value = mock.MagicMock( run_until_complete=mock.MagicMock(), @@ -401,28 +443,31 @@ async def test_execute(self): ) async def test_upgrade_x_invalid_record_type(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_exch_record_path": [ - "acapy_agent.connections.models.connection_target.ConnectionTarget" - ], + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_exch_record_path": [ + "acapy_agent.connections.models.connection_target.ConnectionTarget" + ], + } } } - } + ), ), ): with self.assertRaises(UpgradeError) as ctx: @@ -434,35 +479,38 @@ async def test_upgrade_x_invalid_record_type(self): assert "Only BaseRecord can be resaved" in str(ctx.exception) async def test_upgrade_force(self): - with mock.patch.object( - test_module, - "wallet_config", - mock.CoroutineMock( - return_value=( - self.profile, - mock.CoroutineMock(did="public DID", verkey="verkey"), - ) + with ( + mock.patch.object( + test_module, + "wallet_config", + mock.CoroutineMock( + return_value=( + self.profile, + mock.CoroutineMock(did="public DID", verkey="verkey"), + ) + ), ), - ), mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ], + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ], + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "v0.7.3": { - "update_existing_records": True, - }, - "v0.7.1": { - "update_existing_records": False, - }, - } + "v0.7.3": { + "update_existing_records": True, + }, + "v0.7.1": { + "update_existing_records": False, + }, + } + ), ), ): await test_module.upgrade( @@ -511,9 +559,10 @@ async def test_upgrade_x_params(self): assert "upgrade requires either profile or settings" in str(ctx.exception) def test_main(self): - with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "execute", mock.MagicMock() - ) as mock_execute: + with ( + mock.patch.object(test_module, "__name__", "__main__"), + mock.patch.object(test_module, "execute", mock.MagicMock()) as mock_execute, + ): test_module.main() mock_execute.assert_called_once @@ -711,30 +760,31 @@ async def test_upgrade_explicit_check(self): await test_module.upgrade(profile=self.profile) assert "Explicit upgrade flag with critical value found" in str(ctx.exception) - with mock.patch.object( - test_module, "LOGGER", mock.MagicMock() - ) as mock_logger, mock.patch.object( - test_module.yaml, - "safe_load", - mock.MagicMock( - return_value={ - "v0.7.2": { - "resave_records": { - "base_record_path": [ - "acapy_agent.connections.models.conn_record.ConnRecord" - ], + with ( + mock.patch.object(test_module, "LOGGER", mock.MagicMock()) as mock_logger, + mock.patch.object( + test_module.yaml, + "safe_load", + mock.MagicMock( + return_value={ + "v0.7.2": { + "resave_records": { + "base_record_path": [ + "acapy_agent.connections.models.conn_record.ConnRecord" + ], + }, + "update_existing_records": True, }, - "update_existing_records": True, - }, - "v0.7.3": { - "update_existing_records": True, - "explicit_upgrade": "warning", - }, - "v0.7.1": { - "update_existing_records": True, - "explicit_upgrade": "warning", - }, - } + "v0.7.3": { + "update_existing_records": True, + "explicit_upgrade": "warning", + }, + "v0.7.1": { + "update_existing_records": True, + "explicit_upgrade": "warning", + }, + } + ), ), ): await test_module.upgrade(profile=self.profile) diff --git a/acapy_agent/config/tests/test_ledger.py b/acapy_agent/config/tests/test_ledger.py index 5c2940305b..813e9c5d88 100644 --- a/acapy_agent/config/tests/test_ledger.py +++ b/acapy_agent/config/tests/test_ledger.py @@ -317,11 +317,14 @@ async def test_load_multiple_genesis_transactions_from_config_a(self): }, ], } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -412,11 +415,14 @@ async def test_load_multiple_genesis_transactions_from_config_b(self): ], "ledger.genesis_url": "http://localhost:9000/genesis", } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -474,11 +480,14 @@ async def test_load_multiple_genesis_transactions_config_error_a(self): }, ], } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -537,11 +546,14 @@ async def test_load_multiple_genesis_transactions_multiple_write(self): }, ] } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.return_value = mock.MagicMock( __enter__=mock.MagicMock( return_value=mock.MagicMock( @@ -596,11 +608,14 @@ async def test_load_multiple_genesis_transactions_from_config_io_x(self): }, ], } - with mock.patch.object( - test_module, - "fetch_genesis_transactions", - mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), - ), mock.patch("builtins.open", mock.MagicMock()) as mock_open: + with ( + mock.patch.object( + test_module, + "fetch_genesis_transactions", + mock.CoroutineMock(return_value=TEST_GENESIS_TXNS), + ), + mock.patch("builtins.open", mock.MagicMock()) as mock_open, + ): mock_open.side_effect = IOError("no read permission") with self.assertRaises(test_module.ConfigError): await test_module.load_multiple_genesis_transactions_from_config(settings) @@ -629,31 +644,38 @@ async def test_ledger_accept_taa_tty(self, mock_stdout): "aml_record": {"aml": ["wallet_agreement", "on_file"]}, } - with mock.patch.object( - test_module, "use_asyncio_event_loop", mock.MagicMock() - ), mock.patch.object( - test_module.prompt_toolkit, "prompt", mock.CoroutineMock() - ) as mock_prompt: + with ( + mock.patch.object(test_module, "use_asyncio_event_loop", mock.MagicMock()), + mock.patch.object( + test_module.prompt_toolkit, "prompt", mock.CoroutineMock() + ) as mock_prompt, + ): mock_prompt.side_effect = EOFError() assert not await test_module.accept_taa( None, self.profile, taa_info, provision=False ) - with mock.patch.object( - test_module, "use_asyncio_event_loop", mock.MagicMock() - ) as mock_use_aio_loop, mock.patch.object( - test_module.prompt_toolkit, "prompt", mock.CoroutineMock() - ) as mock_prompt: + with ( + mock.patch.object( + test_module, "use_asyncio_event_loop", mock.MagicMock() + ) as mock_use_aio_loop, + mock.patch.object( + test_module.prompt_toolkit, "prompt", mock.CoroutineMock() + ) as mock_prompt, + ): mock_prompt.return_value = "x" assert not await test_module.accept_taa( None, self.profile, taa_info, provision=False ) - with mock.patch.object( - test_module, "use_asyncio_event_loop", mock.MagicMock() - ) as mock_use_aio_loop, mock.patch.object( - test_module.prompt_toolkit, "prompt", mock.CoroutineMock() - ) as mock_prompt: + with ( + mock.patch.object( + test_module, "use_asyncio_event_loop", mock.MagicMock() + ) as mock_use_aio_loop, + mock.patch.object( + test_module.prompt_toolkit, "prompt", mock.CoroutineMock() + ) as mock_prompt, + ): mock_ledger = mock.MagicMock(accept_txn_author_agreement=mock.CoroutineMock()) mock_prompt.return_value = "" assert await test_module.accept_taa( diff --git a/acapy_agent/config/tests/test_logging.py b/acapy_agent/config/tests/test_logging.py index cf23074568..0f027b2124 100644 --- a/acapy_agent/config/tests/test_logging.py +++ b/acapy_agent/config/tests/test_logging.py @@ -126,9 +126,10 @@ def test_load_resource(self): assert result is None # Testing package resource access with encoding (text mode) - with mock.patch("importlib.resources.files") as mock_files, mock.patch( - "io.TextIOWrapper", mock.MagicMock() - ) as mock_text_io_wrapper: + with ( + mock.patch("importlib.resources.files") as mock_files, + mock.patch("io.TextIOWrapper", mock.MagicMock()) as mock_text_io_wrapper, + ): # Setup the mocks mock_resource_path = mock.MagicMock() mock_files.return_value.joinpath.return_value = mock_resource_path diff --git a/acapy_agent/config/tests/test_wallet.py b/acapy_agent/config/tests/test_wallet.py index 3fbcae8593..6f360dcf06 100644 --- a/acapy_agent/config/tests/test_wallet.py +++ b/acapy_agent/config/tests/test_wallet.py @@ -67,10 +67,13 @@ async def test_wallet_config_existing_replace(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -106,10 +109,13 @@ async def test_wallet_config_existing_open(self): self.context.injector.bind_instance(ProfileManager, MockManager(self.profile)) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -135,10 +141,11 @@ async def test_wallet_config_auto_provision(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - MockManager, "open", mock.CoroutineMock() - ) as mock_mgr_open, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object(MockManager, "open", mock.CoroutineMock()) as mock_mgr_open, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_mgr_open.side_effect = test_module.ProfileNotFoundError() @@ -180,12 +187,15 @@ async def test_wallet_config_bad_seed_x(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, - "seed_to_did", - mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), - ), mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, + "seed_to_did", + mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), + ), + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): with self.assertRaises(test_module.ConfigError): await test_module.wallet_config(self.context, provision=True) @@ -206,10 +216,13 @@ async def test_wallet_config_seed_local(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -230,12 +243,15 @@ async def test_wallet_config_seed_public(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, - "seed_to_did", - mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), - ), mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, + "seed_to_did", + mock.MagicMock(return_value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"), + ), + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): await test_module.wallet_config(self.context, provision=True) @@ -249,10 +265,13 @@ async def test_wallet_config_seed_no_public_did(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - test_module, "seed_to_did", mock.MagicMock() - ) as mock_seed_to_did, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "seed_to_did", mock.MagicMock() + ) as mock_seed_to_did, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_seed_to_did.return_value = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" @@ -275,10 +294,13 @@ async def test_wallet_config_for_key_derivation_method(self): ) self.injector.bind_instance(BaseWallet, mock_wallet) - with mock.patch.object( - MockManager, "provision", mock.CoroutineMock() - ) as mock_mgr_provision, mock.patch.object( - test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + with ( + mock.patch.object( + MockManager, "provision", mock.CoroutineMock() + ) as mock_mgr_provision, + mock.patch.object( + test_module, "add_or_update_version_to_storage", mock.CoroutineMock() + ), ): mock_mgr_provision.return_value = self.profile diff --git a/acapy_agent/connections/tests/test_base_manager.py b/acapy_agent/connections/tests/test_base_manager.py index 84089929ca..12aa05d8a7 100644 --- a/acapy_agent/connections/tests/test_base_manager.py +++ b/acapy_agent/connections/tests/test_base_manager.py @@ -1190,11 +1190,14 @@ async def test_resolve_inbound_connection(self): mock_conn = mock.MagicMock() mock_conn.connection_id = "dummy" - with mock.patch.object( - AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() - ) as mock_wallet_get_local_did_for_verkey, mock.patch.object( - self.manager, "find_connection", mock.CoroutineMock() - ) as mock_mgr_find_conn: + with ( + mock.patch.object( + AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() + ) as mock_wallet_get_local_did_for_verkey, + mock.patch.object( + self.manager, "find_connection", mock.CoroutineMock() + ) as mock_mgr_find_conn, + ): mock_wallet_get_local_did_for_verkey.return_value = DIDInfo( self.test_did, self.test_verkey, @@ -1216,11 +1219,14 @@ async def test_resolve_inbound_connection_injector_error(self): mock_conn = mock.MagicMock() mock_conn.connection_id = "dummy" - with mock.patch.object( - AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() - ) as mock_wallet_get_local_did_for_verkey, mock.patch.object( - self.manager, "find_connection", mock.CoroutineMock() - ) as mock_mgr_find_conn: + with ( + mock.patch.object( + AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() + ) as mock_wallet_get_local_did_for_verkey, + mock.patch.object( + self.manager, "find_connection", mock.CoroutineMock() + ) as mock_mgr_find_conn, + ): mock_wallet_get_local_did_for_verkey.side_effect = InjectionError() mock_mgr_find_conn.return_value = mock_conn @@ -1236,11 +1242,14 @@ async def test_resolve_inbound_connection_wallet_not_found_error(self): mock_conn = mock.MagicMock() mock_conn.connection_id = "dummy" - with mock.patch.object( - AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() - ) as mock_wallet_get_local_did_for_verkey, mock.patch.object( - self.manager, "find_connection", mock.CoroutineMock() - ) as mock_mgr_find_conn: + with ( + mock.patch.object( + AskarWallet, "get_local_did_for_verkey", mock.CoroutineMock() + ) as mock_wallet_get_local_did_for_verkey, + mock.patch.object( + self.manager, "find_connection", mock.CoroutineMock() + ) as mock_mgr_find_conn, + ): mock_wallet_get_local_did_for_verkey.side_effect = WalletNotFoundError() mock_mgr_find_conn.return_value = mock_conn @@ -1339,11 +1348,14 @@ async def test_get_connection_targets_retrieve_connection(self): retrieve_invitation=mock.CoroutineMock(return_value=conn_invite), ) - with mock.patch.object( - ConnectionTarget, "serialize", autospec=True - ) as mock_conn_target_ser, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id: + with ( + mock.patch.object( + ConnectionTarget, "serialize", autospec=True + ) as mock_conn_target_ser, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn mock_conn_target_ser.return_value = {"serialized": "value"} targets = await self.manager.get_connection_targets( @@ -1383,13 +1395,17 @@ async def test_get_connection_targets_from_cache(self): state=ConnRecord.State.COMPLETED.rfc160, ) - with mock.patch.object( - ConnectionTarget, "serialize", autospec=True - ) as mock_conn_target_ser, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - self.manager, "fetch_connection_targets", mock.CoroutineMock() - ) as mock_fetch_connection_targets: + with ( + mock.patch.object( + ConnectionTarget, "serialize", autospec=True + ) as mock_conn_target_ser, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + self.manager, "fetch_connection_targets", mock.CoroutineMock() + ) as mock_fetch_connection_targets, + ): mock_fetch_connection_targets.return_value = [ConnectionTarget()] mock_conn_rec_retrieve_by_id.return_value = mock_conn mock_conn_target_ser.return_value = {"serialized": "value"} @@ -1428,13 +1444,17 @@ async def test_get_connection_targets_no_cache(self): state=ConnRecord.State.COMPLETED.rfc160, ) - with mock.patch.object( - ConnectionTarget, "serialize", autospec=True - ) as mock_conn_target_ser, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - self.manager, "fetch_connection_targets", mock.CoroutineMock() - ) as mock_fetch_connection_targets: + with ( + mock.patch.object( + ConnectionTarget, "serialize", autospec=True + ) as mock_conn_target_ser, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + self.manager, "fetch_connection_targets", mock.CoroutineMock() + ) as mock_fetch_connection_targets, + ): mock_fetch_connection_targets.return_value = [ConnectionTarget()] mock_conn_rec_retrieve_by_id.return_value = mock_conn mock_conn_target_ser.return_value = {"serialized": "value"} @@ -1522,9 +1542,12 @@ async def test_create_static_connection_multitenant(self): self.multitenant_mgr.get_default_mediator.return_value = None self.route_manager.route_static = mock.CoroutineMock() - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, self.test_verkey, @@ -1552,11 +1575,15 @@ async def test_create_static_connection_multitenant_auto_disclose_features(self) ) self.multitenant_mgr.get_default_mediator.return_value = None self.route_manager.route_static = mock.CoroutineMock() - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, self.test_verkey, @@ -1581,12 +1608,15 @@ async def test_create_static_connection_multitenant_mediator(self): default_mediator = mock.MagicMock() self.route_manager.route_static = mock.CoroutineMock() - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - BaseConnectionManager, "create_did_document" - ) as create_did_document, mock.patch.object( - BaseConnectionManager, "store_did_document" + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + BaseConnectionManager, "create_did_document" + ) as create_did_document, + mock.patch.object(BaseConnectionManager, "store_did_document"), ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, @@ -1675,11 +1705,14 @@ async def test_find_connection_retrieve_by_did(self): async def test_find_connection_retrieve_by_did_auto_disclose_features(self): self.context.update_settings({"auto_disclose_features": True}) - with mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + ): mock_conn_retrieve_by_did.return_value = mock.MagicMock( state=ConnRecord.State.RESPONSE.rfc23, save=mock.CoroutineMock(), @@ -1695,11 +1728,14 @@ async def test_find_connection_retrieve_by_did_auto_disclose_features(self): mock_proactive_disclose_features.assert_called_once() async def test_find_connection_retrieve_by_invitation_key(self): - with mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + ): mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() mock_conn_retrieve_by_invitation_msg_id.return_value = mock.MagicMock( state=ConnRecord.State.RESPONSE, @@ -1714,11 +1750,14 @@ async def test_find_connection_retrieve_by_invitation_key(self): assert conn_rec async def test_find_connection_retrieve_none_by_invitation_key(self): - with mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - ConnRecord, "retrieve_by_invitation_key", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + ConnRecord, "retrieve_by_invitation_key", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + ): mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() mock_conn_retrieve_by_invitation_msg_id.return_value = None @@ -1732,13 +1771,17 @@ async def test_find_connection_retrieve_none_by_invitation_key(self): async def test_get_endpoints(self): conn_id = "dummy" - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - AskarWallet, "get_local_did", autospec=True - ) as mock_wallet_get_local_did, mock.patch.object( - self.manager, "get_connection_targets", mock.CoroutineMock() - ) as mock_get_conn_targets: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object( + AskarWallet, "get_local_did", autospec=True + ) as mock_wallet_get_local_did, + mock.patch.object( + self.manager, "get_connection_targets", mock.CoroutineMock() + ) as mock_get_conn_targets, + ): mock_retrieve.return_value = mock.MagicMock() mock_wallet_get_local_did.return_value = mock.MagicMock( metadata={"endpoint": "localhost:8020"} diff --git a/acapy_agent/core/tests/test_conductor.py b/acapy_agent/core/tests/test_conductor.py index 875623deee..6b66d1fa73 100644 --- a/acapy_agent/core/tests/test_conductor.py +++ b/acapy_agent/core/tests/test_conductor.py @@ -120,26 +120,32 @@ async def test_startup_version_record_exists(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] - ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger: + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + ): await conductor.setup() mock_inbound_mgr.return_value.setup.assert_awaited_once() @@ -178,24 +184,29 @@ async def test_startup_version_no_upgrade_add_record(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] - ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -218,26 +229,34 @@ async def test_startup_version_force_upgrade(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] - ), - ), mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -255,27 +274,36 @@ async def test_startup_version_force_upgrade(self): await conductor.stop() test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), - ), mock.patch.object(test_module, "ledger_config"), mock.patch.object( - test_module.Conductor, "check_for_valid_wallet_type" + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, + ), + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), + ), + mock.patch.object(test_module, "ledger_config"), + mock.patch.object(test_module.Conductor, "check_for_valid_wallet_type"), ): await conductor.setup() mock_inbound_mgr.return_value.registered_transports = {} @@ -290,35 +318,46 @@ async def test_startup_version_record_not_exists(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, + ), + mock.patch.object( + BaseStorage, + "find_record", + mock.CoroutineMock( + side_effect=[mock.MagicMock(value="askar"), StorageNotFoundError()] + ), + ), + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), + ), + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False - ), mock.patch.object( - BaseStorage, - "find_record", - mock.CoroutineMock( - side_effect=[mock.MagicMock(value="askar"), StorageNotFoundError()] - ), - ), mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock(return_value=["v0.8.0-rc1", "v8.0.0", "v0.8.1-rc1"]), - ), mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) @@ -348,20 +387,23 @@ async def test_startup_admin_server_x(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ), mock.patch.object( - test_module, "AdminServer", mock.MagicMock() - ) as mock_admin_server: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object(test_module, "LoggingConfigurator", autospec=True), + mock.patch.object( + test_module, "AdminServer", mock.MagicMock() + ) as mock_admin_server, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -375,21 +417,29 @@ async def test_startup_no_public_did(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "LoggingConfigurator", autospec=True + ) as mock_logger, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "LoggingConfigurator", autospec=True - ) as mock_logger, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): mock_outbound_mgr.return_value.registered_transports = {} mock_outbound_mgr.return_value.enqueue_message = mock.CoroutineMock() @@ -422,19 +472,26 @@ async def test_stats(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): mock_inbound_mgr.return_value.sessions = ["dummy"] mock_outbound_mgr.return_value.outbound_buffer = [ @@ -466,16 +523,19 @@ async def test_inbound_message_handler(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -504,26 +564,32 @@ async def test_inbound_message_handler_ledger_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - conductor.dispatcher, "queue_message", autospec=True - ) as mock_dispatch_q, mock.patch.object( - conductor.admin_server, "notify_fatal_error", mock.MagicMock() - ) as mock_notify: + with ( + mock.patch.object( + conductor.dispatcher, "queue_message", autospec=True + ) as mock_dispatch_q, + mock.patch.object( + conductor.admin_server, "notify_fatal_error", mock.MagicMock() + ) as mock_notify, + ): mock_dispatch_q.side_effect = test_module.LedgerConfigError("ledger down") message_body = "{}" @@ -583,16 +649,19 @@ async def test_outbound_message_handler_with_target(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -623,18 +692,22 @@ async def test_outbound_message_handler_with_connection(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as conn_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as conn_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -672,16 +745,19 @@ async def test_outbound_message_handler_with_verkey_no_target(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -717,16 +793,19 @@ async def test_handle_nots(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", mock.MagicMock() - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", mock.MagicMock() + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), enqueue_message=mock.CoroutineMock(), @@ -743,11 +822,12 @@ async def test_handle_nots(self): conductor.handle_not_returned(conductor.root_profile, message) - with mock.patch.object( - test_module, "ConnectionManager" - ) as mock_conn_mgr, mock.patch.object( - conductor.dispatcher, "run_task", mock.MagicMock() - ) as mock_run_task: + with ( + mock.patch.object(test_module, "ConnectionManager") as mock_conn_mgr, + mock.patch.object( + conductor.dispatcher, "run_task", mock.MagicMock() + ) as mock_run_task, + ): # Normally this should be a coroutine mock; however, the coroutine # is awaited by dispatcher.run_task, which is mocked here. MagicMock # to prevent unawaited coroutine warning. @@ -795,25 +875,31 @@ async def test_handle_not_returned_ledger_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - conductor.dispatcher, "run_task", mock.MagicMock() - ) as mock_dispatch_run, mock.patch.object( - conductor.admin_server, "notify_fatal_error", mock.MagicMock() - ) as mock_notify: + with ( + mock.patch.object( + conductor.dispatcher, "run_task", mock.MagicMock() + ) as mock_dispatch_run, + mock.patch.object( + conductor.admin_server, "notify_fatal_error", mock.MagicMock() + ) as mock_notify, + ): mock_dispatch_run.side_effect = test_module.LedgerConfigError( "No such ledger" ) @@ -837,28 +923,35 @@ async def test_queue_outbound_ledger_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as conn_mgr, mock.patch.object( - conductor.dispatcher, "run_task", mock.MagicMock() - ) as mock_dispatch_run, mock.patch.object( - conductor.admin_server, "notify_fatal_error", mock.MagicMock() - ) as mock_notify: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as conn_mgr, + mock.patch.object( + conductor.dispatcher, "run_task", mock.MagicMock() + ) as mock_dispatch_run, + mock.patch.object( + conductor.admin_server, "notify_fatal_error", mock.MagicMock() + ) as mock_notify, + ): # Normally this should be a coroutine mock; however, the coroutine # is awaited by dispatcher.run_task, which is mocked here. MagicMock # to prevent unawaited coroutine warning. @@ -886,16 +979,19 @@ async def test_admin(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -903,9 +999,10 @@ async def test_admin(self): admin = conductor.context.inject(BaseAdminServer) assert admin is conductor.admin_server - with mock.patch.object( - admin, "start", autospec=True - ) as admin_start, mock.patch.object(admin, "stop", autospec=True) as admin_stop: + with ( + mock.patch.object(admin, "start", autospec=True) as admin_start, + mock.patch.object(admin, "stop", autospec=True) as admin_stop, + ): await conductor.start() admin_start.assert_awaited_once_with() @@ -925,16 +1022,19 @@ async def test_admin_startx(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -942,13 +1042,12 @@ async def test_admin_startx(self): admin = conductor.context.inject(BaseAdminServer) assert admin is conductor.admin_server - with mock.patch.object( - admin, "start", autospec=True - ) as admin_start, mock.patch.object( - admin, "stop", autospec=True - ) as admin_stop, mock.patch.object( - test_module, "OutOfBandManager" - ) as oob_mgr, mock.patch.object(test_module, "ConnectionManager") as conn_mgr: + with ( + mock.patch.object(admin, "start", autospec=True) as admin_start, + mock.patch.object(admin, "stop", autospec=True) as admin_stop, + mock.patch.object(test_module, "OutOfBandManager") as oob_mgr, + mock.patch.object(test_module, "ConnectionManager") as conn_mgr, + ): admin_start.side_effect = KeyError("trouble") oob_mgr.return_value.create_invitation = mock.CoroutineMock( side_effect=KeyError("double trouble") @@ -967,16 +1066,19 @@ async def test_setup_collector(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -989,18 +1091,20 @@ async def test_start_static(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1017,20 +1121,21 @@ async def test_start_x_in(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "InboundTransportManager" - ) as mock_intx_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object(test_module, "InboundTransportManager") as mock_intx_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_intx_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), start=mock.CoroutineMock(side_effect=KeyError("trouble")), @@ -1050,18 +1155,18 @@ async def test_start_x_out_a(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "OutboundTransportManager" - ) as mock_outx_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object(test_module, "OutboundTransportManager") as mock_outx_mgr, + ): mock_outx_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), start=mock.CoroutineMock(side_effect=KeyError("trouble")), @@ -1078,18 +1183,18 @@ async def test_start_x_out_b(self): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "ConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "OutboundTransportManager" - ) as mock_outx_mgr: + mock.patch.object(test_module, "ConnectionManager") as mock_mgr, + mock.patch.object(test_module, "OutboundTransportManager") as mock_outx_mgr, + ): mock_outx_mgr.return_value = mock.MagicMock( setup=mock.CoroutineMock(), start=mock.CoroutineMock(side_effect=KeyError("trouble")), @@ -1123,16 +1228,19 @@ async def test_dispatch_complete_non_fatal_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1165,16 +1273,19 @@ async def test_dispatch_complete_fatal_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1203,16 +1314,20 @@ async def test_print_invite_connection(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch("sys.stdout", new=StringIO()) as captured, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch("sys.stdout", new=StringIO()) as captured, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1231,16 +1346,19 @@ async def test_clear_default_mediator(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1262,34 +1380,41 @@ async def test_set_default_mediator(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - test_module, - "MediationManager", - return_value=mock.MagicMock(set_default_mediator_by_id=mock.CoroutineMock()), - ) as mock_mgr, mock.patch.object( - MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, - "LOGGER", - mock.MagicMock( - exception=mock.MagicMock( - side_effect=Exception("This method should not have been called") - ) + with ( + mock.patch.object( + test_module, + "MediationManager", + return_value=mock.MagicMock( + set_default_mediator_by_id=mock.CoroutineMock() + ), + ) as mock_mgr, + mock.patch.object(MediationRecord, "retrieve_by_id", mock.CoroutineMock()), + mock.patch.object( + test_module, + "LOGGER", + mock.MagicMock( + exception=mock.MagicMock( + side_effect=Exception("This method should not have been called") + ) + ), ), ): await conductor.start() @@ -1303,26 +1428,32 @@ async def test_set_default_mediator_x(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=Exception()), - ), mock.patch.object(test_module, "LOGGER") as mock_logger: + with ( + mock.patch.object( + MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=Exception()), + ), + mock.patch.object(test_module, "LOGGER") as mock_logger, + ): await conductor.start() await conductor.stop() mock_logger.exception.assert_called_once() @@ -1341,16 +1472,19 @@ async def test_webhook_router(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1386,16 +1520,19 @@ async def test_shutdown_multitenant_profiles(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1456,16 +1593,19 @@ async def test_mediator_invitation_0160(self, mock_from_url, _): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1473,18 +1613,24 @@ async def test_mediator_invitation_0160(self, mock_from_url, _): mock_conn_record = mock.MagicMock() - with mock.patch.object( - test_module, - "ConnectionManager", - mock.MagicMock( - return_value=mock.MagicMock( - receive_invitation=mock.CoroutineMock(return_value=mock_conn_record) - ) + with ( + mock.patch.object( + test_module, + "ConnectionManager", + mock.MagicMock( + return_value=mock.MagicMock( + receive_invitation=mock.CoroutineMock( + return_value=mock_conn_record + ) + ) + ), + ) as mock_mgr, + mock.patch.object(mock_conn_record, "metadata_set", mock.CoroutineMock()), + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ) as mock_mgr, mock.patch.object( - mock_conn_record, "metadata_set", mock.CoroutineMock() - ), mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): await conductor.start() await conductor.stop() @@ -1502,16 +1648,19 @@ async def test_mediator_invitation_0434(self, mock_from_url, _): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1537,16 +1686,21 @@ async def test_mediator_invitation_0434(self, mock_from_url, _): state=OobRecord.STATE_INITIAL, ) - with mock.patch.object( - test_module, - "OutOfBandManager", - mock.MagicMock( - return_value=mock.MagicMock( - receive_invitation=mock.CoroutineMock(return_value=oob_record) - ) + with ( + mock.patch.object( + test_module, + "OutOfBandManager", + mock.MagicMock( + return_value=mock.MagicMock( + receive_invitation=mock.CoroutineMock(return_value=oob_record) + ) + ), + ) as mock_mgr, + mock.patch.object( + test_module, + "upgrade_wallet_to_anoncreds_if_requested", + return_value=False, ), - ) as mock_mgr, mock.patch.object( - test_module, "upgrade_wallet_to_anoncreds_if_requested", return_value=False ): assert not conductor.root_profile.settings["mediation.connections_invite"] await conductor.start() @@ -1572,16 +1726,19 @@ async def test_mediation_invitation_should_use_stored_invitation( conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1598,12 +1755,14 @@ async def test_mediation_invitation_should_use_stored_invitation( ) # when - with mock.patch.object( - test_module, "ConnectionManager", return_value=connection_manager_mock - ), mock.patch.object( - mock_conn_record, "metadata_set", mock.CoroutineMock() - ), mock.patch.object( - test_module, "MediationManager", return_value=mock_mediation_manager + with ( + mock.patch.object( + test_module, "ConnectionManager", return_value=connection_manager_mock + ), + mock.patch.object(mock_conn_record, "metadata_set", mock.CoroutineMock()), + mock.patch.object( + test_module, "MediationManager", return_value=mock_mediation_manager + ), ): await conductor.start() await conductor.stop() @@ -1627,16 +1786,19 @@ async def test_mediation_invitation_should_not_create_connection_for_old_invitat conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1665,26 +1827,32 @@ async def test_mediator_invitation_x(self, _): conductor = test_module.Conductor(builder) test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr: + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } await conductor.setup() - with mock.patch.object( - test_module.ConnectionInvitation, - "from_url", - mock.MagicMock(side_effect=Exception()), - ) as mock_from_url, mock.patch.object(test_module, "LOGGER") as mock_logger: + with ( + mock.patch.object( + test_module.ConnectionInvitation, + "from_url", + mock.MagicMock(side_effect=Exception()), + ) as mock_from_url, + mock.patch.object(test_module, "LOGGER") as mock_logger, + ): await conductor.start() await conductor.stop() mock_from_url.assert_called_once_with("test-invite") @@ -1711,22 +1879,28 @@ async def test_setup_ledger_both_multiple_and_base(self): BaseLedger, mock.MagicMock(BaseLedger, autospec=True) ) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, - "load_multiple_genesis_transactions_from_config", - mock.CoroutineMock(), - ) as mock_multiple_genesis_load, mock.patch.object( - test_module, "get_genesis_transactions", mock.CoroutineMock() - ) as mock_genesis_load, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object(test_module, "ledger_config"): + mock.patch.object( + test_module, + "load_multiple_genesis_transactions_from_config", + mock.CoroutineMock(), + ) as mock_multiple_genesis_load, + mock.patch.object( + test_module, "get_genesis_transactions", mock.CoroutineMock() + ) as mock_genesis_load, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object(test_module, "ledger_config"), + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1741,18 +1915,23 @@ async def test_setup_ledger_only_base(self): test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "get_genesis_transactions", mock.CoroutineMock() - ) as mock_genesis_load, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object(test_module, "ledger_config"): + mock.patch.object( + test_module, "get_genesis_transactions", mock.CoroutineMock() + ) as mock_genesis_load, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object(test_module, "ledger_config"), + ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) } @@ -1765,21 +1944,26 @@ async def test_startup_storage_type_anoncreds_and_config_askar_re_calls_setup(se test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), + ), + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) @@ -1811,27 +1995,33 @@ async def test_startup_storage_type_does_not_exist_and_existing_agent_then_set_t test_profile = await create_test_profile(None, await builder.build_context()) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) @@ -1866,27 +2056,33 @@ async def test_startup_storage_type_does_not_exist_and_new_anoncreds_agent( test_settings, await builder.build_context() ) - with mock.patch.object( - test_module, - "wallet_config", - return_value=( - test_profile, - DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + with ( + mock.patch.object( + test_module, + "wallet_config", + return_value=( + test_profile, + DIDInfo("did", "verkey", metadata={}, method=SOV, key_type=ED25519), + ), ), - ), mock.patch.object( - test_module, "InboundTransportManager", autospec=True - ) as mock_inbound_mgr, mock.patch.object( - test_module, "OutboundTransportManager", autospec=True - ) as mock_outbound_mgr, mock.patch.object( - test_module, - "get_upgrade_version_list", - mock.MagicMock( - return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + mock.patch.object( + test_module, "InboundTransportManager", autospec=True + ) as mock_inbound_mgr, + mock.patch.object( + test_module, "OutboundTransportManager", autospec=True + ) as mock_outbound_mgr, + mock.patch.object( + test_module, + "get_upgrade_version_list", + mock.MagicMock( + return_value=["v0.7.4", "0.7.5", "v0.8.0-rc1", "v8.0.0", "v0.8.1-rc2"] + ), + ), + mock.patch.object( + test_module, + "upgrade", + mock.CoroutineMock(), ), - ), mock.patch.object( - test_module, - "upgrade", - mock.CoroutineMock(), ): mock_outbound_mgr.return_value.registered_transports = { "test": mock.MagicMock(schemes=["http"]) diff --git a/acapy_agent/core/tests/test_dispatcher.py b/acapy_agent/core/tests/test_dispatcher.py index c352192f19..b941e584e3 100644 --- a/acapy_agent/core/tests/test_dispatcher.py +++ b/acapy_agent/core/tests/test_dispatcher.py @@ -105,11 +105,14 @@ async def test_dispatch(self): "@type": DIDCommPrefix.qualify_current(StubAgentMessage.Meta.message_type) } - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ) as handler_mock, mock.patch.object( - test_module, "BaseConnectionManager", autospec=True - ) as conn_mgr_mock: + with ( + mock.patch.object( + StubAgentMessageHandler, "handle", autospec=True + ) as handler_mock, + mock.patch.object( + test_module, "BaseConnectionManager", autospec=True + ) as conn_mgr_mock, + ): conn_mgr_mock.return_value = mock.MagicMock( find_inbound_connection=mock.CoroutineMock( return_value=mock.MagicMock(connection_id="dummy") @@ -148,10 +151,11 @@ async def test_dispatch_versioned_message(self): "@type": DIDCommPrefix.qualify_current(StubAgentMessage.Meta.message_type) } - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ) as handler_mock, mock.patch.object( - test_module, "BaseConnectionManager", autospec=True + with ( + mock.patch.object( + StubAgentMessageHandler, "handle", autospec=True + ) as handler_mock, + mock.patch.object(test_module, "BaseConnectionManager", autospec=True), ): await dispatcher.queue_message( dispatcher.profile, make_inbound(message), rcv.send @@ -217,11 +221,12 @@ async def test_dispatch_versioned_message_message_class_deserialize_x(self): rcv = Receiver() message = {"@type": "doc/proto-name/1.1/no-such-message-type"} - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ), mock.patch.object( - registry, "resolve_message_class", mock.MagicMock() - ) as mock_resolve: + with ( + mock.patch.object(StubAgentMessageHandler, "handle", autospec=True), + mock.patch.object( + registry, "resolve_message_class", mock.MagicMock() + ) as mock_resolve, + ): mock_resolve.return_value = mock.MagicMock( deserialize=mock.MagicMock(side_effect=test_module.BaseModelError()) ) @@ -258,10 +263,11 @@ async def test_dispatch_versioned_message_handle_greater_succeeds(self): "@type": DIDCommPrefix.qualify_current(StubV1_2AgentMessage.Meta.message_type) } - with mock.patch.object( - StubAgentMessageHandler, "handle", autospec=True - ) as handler_mock, mock.patch.object( - test_module, "BaseConnectionManager", autospec=True + with ( + mock.patch.object( + StubAgentMessageHandler, "handle", autospec=True + ) as handler_mock, + mock.patch.object(test_module, "BaseConnectionManager", autospec=True), ): await dispatcher.queue_message( dispatcher.profile, make_inbound(message), rcv.send @@ -393,12 +399,13 @@ async def test_create_send_outbound(self): outbound_message = await responder.create_outbound( json.dumps(message.serialize()) ) - with mock.patch.object( - responder, "_send", mock.CoroutineMock() - ), mock.patch.object( - test_module.BaseResponder, - "conn_rec_active_state_check", - mock.CoroutineMock(return_value=True), + with ( + mock.patch.object(responder, "_send", mock.CoroutineMock()), + mock.patch.object( + test_module.BaseResponder, + "conn_rec_active_state_check", + mock.CoroutineMock(return_value=True), + ), ): await responder.send_outbound(outbound_message) @@ -418,12 +425,13 @@ async def test_create_send_outbound_with_msg_attrs(self): message = StubAgentMessage() responder = test_module.DispatcherResponder(context, message, None) outbound_message = await responder.create_outbound(message) - with mock.patch.object( - responder, "_send", mock.CoroutineMock() - ), mock.patch.object( - test_module.BaseResponder, - "conn_rec_active_state_check", - mock.CoroutineMock(return_value=True), + with ( + mock.patch.object(responder, "_send", mock.CoroutineMock()), + mock.patch.object( + test_module.BaseResponder, + "conn_rec_active_state_check", + mock.CoroutineMock(return_value=True), + ), ): await responder.send_outbound( message=outbound_message, diff --git a/acapy_agent/core/tests/test_oob_processor.py b/acapy_agent/core/tests/test_oob_processor.py index f3a9541f78..4b3e85bedb 100644 --- a/acapy_agent/core/tests/test_oob_processor.py +++ b/acapy_agent/core/tests/test_oob_processor.py @@ -426,17 +426,20 @@ async def test_find_oob_record_for_inbound_message_sender_connection_id_no_match mock_retrieve.assert_called_once_with(ANY, {"invi_msg_id": "the-pthid"}) # Connection id is not the same, state is AWAIT_RESPONSE. oob has connection_id - with mock.patch.object( - OobRecord, - "retrieve_by_tag_filter", - mock.CoroutineMock(return_value=self.oob_record), - ) as mock_retrieve, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock( - return_value=mock.MagicMock(delete_record=mock.CoroutineMock()) - ), - ) as mock_retrieve_conn: + with ( + mock.patch.object( + OobRecord, + "retrieve_by_tag_filter", + mock.CoroutineMock(return_value=self.oob_record), + ) as mock_retrieve, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock( + return_value=mock.MagicMock(delete_record=mock.CoroutineMock()) + ), + ) as mock_retrieve_conn, + ): self.oob_record.role = OobRecord.ROLE_SENDER self.oob_record.state = OobRecord.STATE_AWAIT_RESPONSE self.context.connection_record = mock.MagicMock( diff --git a/acapy_agent/indy/tests/test_verifier.py b/acapy_agent/indy/tests/test_verifier.py index c038daa3d3..54762cb636 100644 --- a/acapy_agent/indy/tests/test_verifier.py +++ b/acapy_agent/indy/tests/test_verifier.py @@ -436,11 +436,12 @@ async def test_check_timestamps(self): proof_req_x = deepcopy(INDY_PROOF_REQ_NAME) proof_req_x["non_revoked"] = {"from": 1600000000, "to": 1600001000} proof_x["identifiers"][0]["timestamp"] = 1579890000 - with mock.patch.object( - test_module, "LOGGER", mock.MagicMock() - ) as mock_logger, mock.patch.object( - IndyLedgerRequestsExecutor, "get_ledger_for_identifier" - ) as mock_get_ledger: + with ( + mock.patch.object(test_module, "LOGGER", mock.MagicMock()) as mock_logger, + mock.patch.object( + IndyLedgerRequestsExecutor, "get_ledger_for_identifier" + ) as mock_get_ledger, + ): mock_get_ledger.return_value = (None, self.ledger) pre_logger_calls = mock_logger.info.call_count await self.verifier.check_timestamps( diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py b/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py index a64f20a8b7..c567b33cf2 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py @@ -239,11 +239,14 @@ async def test_get_ledger_by_did_not_self_cert( "verkey": "ABUF7uxYTxZ6qYdZ4G9e1Gi", } ) - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = get_nym_reply mock_wait.return_value = mock_submit.return_value @@ -354,11 +357,14 @@ async def test_get_ledger_by_did_not_self_cert_not_self_cert_prod( ): get_nym_reply = deepcopy(GET_NYM_INDY_VDR_REPLY) get_nym_reply["data"]["verkey"] = "ABUF7uxYTxZ6qYdZ4G9e1Gi" - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = get_nym_reply mock_wait.return_value = mock_submit.return_value @@ -425,11 +431,14 @@ async def test_get_ledger_by_did_not_self_cert_non_prod( ) get_nym_reply = deepcopy(GET_NYM_REPLY) get_nym_reply["result"]["data"]["verkey"] = "ABUF7uxYTxZ6qYdZ4G9e1Gi" - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = get_nym_reply mock_wait.return_value = mock_submit.return_value @@ -450,11 +459,14 @@ async def test_get_ledger_by_did_not_self_cert_non_prod( async def test_lookup_did_in_configured_ledgers_x( self, mock_submit, mock_build_get_nym_req, mock_close, mock_open ): - with mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() - ) as mock_verify_spv_proof: + with ( + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object( + test_module.SubTrie, "verify_spv_proof", mock.CoroutineMock() + ) as mock_verify_spv_proof, + ): mock_build_get_nym_req.return_value = mock.MagicMock() mock_submit.return_value = GET_NYM_INDY_VDR_REPLY mock_wait.return_value = mock_submit.return_value diff --git a/acapy_agent/ledger/tests/test_indy_vdr.py b/acapy_agent/ledger/tests/test_indy_vdr.py index 927498c707..9b0ee8ce3c 100644 --- a/acapy_agent/ledger/tests/test_indy_vdr.py +++ b/acapy_agent/ledger/tests/test_indy_vdr.py @@ -51,10 +51,12 @@ async def open(): async def close(): ledger.pool.handle = None - with mock.patch.object(ledger.pool, "open", open), mock.patch.object( - ledger.pool, "close", close - ), mock.patch.object( - ledger, "is_ledger_read_only", mock.CoroutineMock(return_value=False) + with ( + mock.patch.object(ledger.pool, "open", open), + mock.patch.object(ledger.pool, "close", close), + mock.patch.object( + ledger, "is_ledger_read_only", mock.CoroutineMock(return_value=False) + ), ): yield ledger @@ -338,14 +340,17 @@ async def test_send_schema_ledger_read_only( async with ledger: ledger.pool.read_only = True - with mock.patch.object( - ledger, - "check_existing_schema", - mock.CoroutineMock(return_value=False), - ), mock.patch.object( - ledger, - "is_ledger_read_only", - mock.CoroutineMock(return_value=True), + with ( + mock.patch.object( + ledger, + "check_existing_schema", + mock.CoroutineMock(return_value=False), + ), + mock.patch.object( + ledger, + "is_ledger_read_only", + mock.CoroutineMock(return_value=True), + ), ): with pytest.raises(LedgerError): await ledger.create_and_send_schema( @@ -768,25 +773,28 @@ async def test_update_endpoint_for_did_calls_attr_json(self, ledger: IndyVdrLedg test_did = await wallet.create_public_did(SOV, ED25519) async with ledger: - with mock.patch.object( - ledger, - "_construct_attr_json", - mock.CoroutineMock( - return_value=json.dumps( - { - "endpoint": { + with ( + mock.patch.object( + ledger, + "_construct_attr_json", + mock.CoroutineMock( + return_value=json.dumps( + { "endpoint": { - "endpoint": "https://url", - "routingKeys": [], + "endpoint": { + "endpoint": "https://url", + "routingKeys": [], + } } } - } - ) + ) + ), + ) as mock_construct_attr_json, + mock.patch.object( + ledger, + "get_all_endpoints_for_did", + mock.CoroutineMock(return_value={}), ), - ) as mock_construct_attr_json, mock.patch.object( - ledger, - "get_all_endpoints_for_did", - mock.CoroutineMock(return_value={}), ): await ledger.update_endpoint_for_did( test_did.did, diff --git a/acapy_agent/ledger/tests/test_routes.py b/acapy_agent/ledger/tests/test_routes.py index 00adc0952b..70e1092b56 100644 --- a/acapy_agent/ledger/tests/test_routes.py +++ b/acapy_agent/ledger/tests/test_routes.py @@ -134,13 +134,16 @@ async def test_get_verkey_multitenant(self): IndyLedgerRequestsExecutor, self.mock_ledger_requests_executor, ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as json_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as json_response, + ): self.ledger.get_key_for_did.return_value = self.test_verkey result = await test_module.get_did_verkey(self.request) json_response.assert_called_once_with( @@ -208,13 +211,16 @@ async def test_get_endpoint_multitenant(self): mock.MagicMock(MultitenantManager, autospec=True), ) self.request.query = {"did": self.test_did} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as json_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as json_response, + ): self.ledger.get_endpoint_for_did.return_value = self.test_endpoint result = await test_module.get_did_endpoint(self.request) json_response.assert_called_once_with( @@ -327,13 +333,17 @@ async def test_register_nym_create_transaction_for_endorser(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -371,13 +381,17 @@ async def test_register_nym_create_transaction_for_endorser_no_public_did(self): } self.profile.context.settings["endorser.author"] = True - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -414,11 +428,14 @@ async def test_register_nym_create_transaction_for_endorser_storage_x(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock(side_effect=test_module.StorageError()) ) @@ -583,13 +600,16 @@ async def test_get_nym_role_multitenant(self): ) self.request.query = {"did": self.test_did} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as json_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as json_response, + ): self.ledger.get_nym_role.return_value = Role.USER result = await test_module.get_nym_role(self.request) json_response.assert_called_once_with( diff --git a/acapy_agent/messaging/credential_definitions/tests/test_routes.py b/acapy_agent/messaging/credential_definitions/tests/test_routes.py index 93ad921c48..65fb61e0b1 100644 --- a/acapy_agent/messaging/credential_definitions/tests/test_routes.py +++ b/acapy_agent/messaging/credential_definitions/tests/test_routes.py @@ -103,13 +103,17 @@ async def test_send_credential_definition_create_transaction_for_endorser(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -152,11 +156,14 @@ async def test_send_credential_definition_create_transaction_for_endorser_storag "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -356,11 +363,14 @@ async def test_get_credential_definition_multitenant(self): mock.MagicMock(MultitenantManager, autospec=True), ) self.request.match_info = {"cred_def_id": CRED_DEF_ID} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): result = await test_module.credential_definitions_get_credential_definition( self.request ) diff --git a/acapy_agent/messaging/jsonld/tests/test_routes.py b/acapy_agent/messaging/jsonld/tests/test_routes.py index 992b907a49..a98d0818f2 100644 --- a/acapy_agent/messaging/jsonld/tests/test_routes.py +++ b/acapy_agent/messaging/jsonld/tests/test_routes.py @@ -353,13 +353,13 @@ async def test_verify_credential(self): mock_response.assert_called_once_with({"valid": True}) # expected response # compact, expand take a LONG TIME: do them once above, mock for error cases - with mock.patch.object( - jsonld, "compact", mock.MagicMock() - ) as mock_compact, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_expand, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(jsonld, "compact", mock.MagicMock()) as mock_compact, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_expand, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_expand.return_value = [mock.MagicMock()] mock_compact.return_value = { "@context": "...", @@ -388,13 +388,13 @@ async def test_verify_credential(self): result = await test_module.verify(self.request) assert "error" in json.loads(result) - with mock.patch.object( - jsonld, "compact", mock.MagicMock() - ) as mock_compact, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_expand, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(jsonld, "compact", mock.MagicMock()) as mock_compact, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_expand, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_expand.return_value = [mock.MagicMock()] mock_compact.return_value = { "@context": "...", @@ -503,13 +503,13 @@ async def test_sign_credential(self): # compact, expand take a LONG TIME: do them once above, mock for error cases posted_request = deepcopy(POSTED_REQUEST) self.request.json = mock.CoroutineMock(return_value=posted_request) - with mock.patch.object( - jsonld, "compact", mock.MagicMock() - ) as mock_compact, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_expand, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(jsonld, "compact", mock.MagicMock()) as mock_compact, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_expand, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_expand.return_value = [mock.MagicMock()] mock_compact.return_value = {} # drop all attributes mock_response.side_effect = lambda x: json.dumps(x) diff --git a/acapy_agent/messaging/schemas/tests/test_routes.py b/acapy_agent/messaging/schemas/tests/test_routes.py index eb29c9cf31..a84a05171d 100644 --- a/acapy_agent/messaging/schemas/tests/test_routes.py +++ b/acapy_agent/messaging/schemas/tests/test_routes.py @@ -104,13 +104,17 @@ async def test_send_schema_create_transaction_for_endorser(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -155,11 +159,14 @@ async def test_send_schema_create_transaction_for_endorser_storage_x(self): "conn_id": "dummy", } - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_record=mock.CoroutineMock(side_effect=test_module.StorageError()) ) @@ -339,11 +346,14 @@ async def test_get_schema_multitenant(self): mock.MagicMock(MultitenantManager, autospec=True), ) self.request.match_info = {"schema_id": SCHEMA_ID} - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): result = await test_module.schemas_get_schema(self.request) assert result == mock_response.return_value mock_response.assert_called_once_with( diff --git a/acapy_agent/multitenant/admin/tests/test_routes.py b/acapy_agent/multitenant/admin/tests/test_routes.py index 823d8704aa..4ec0ba142a 100644 --- a/acapy_agent/multitenant/admin/tests/test_routes.py +++ b/acapy_agent/multitenant/admin/tests/test_routes.py @@ -51,11 +51,12 @@ async def test_format_wallet_record_removes_wallet_key(self): assert "wallet.key" not in formatted["settings"] async def test_wallets_list(self): - with mock.patch.object( - test_module, "WalletRecord", autospec=True - ) as mock_wallet_record, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "WalletRecord", autospec=True + ) as mock_wallet_record, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): wallets = [ mock.MagicMock( serialize=mock.MagicMock( @@ -110,11 +111,12 @@ async def test_wallets_list_x(self): async def test_wallets_list_query(self): self.request.query = {"wallet_name": "test"} - with mock.patch.object( - test_module, "WalletRecord", autospec=True - ) as mock_wallet_record, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "WalletRecord", autospec=True + ) as mock_wallet_record, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): wallets = [ mock.MagicMock( serialize=mock.MagicMock( @@ -654,11 +656,12 @@ async def test_wallet_get(self): return_value={"settings": {}, "wallet_id": "dummy"} ) - with mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_wallet_record_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_wallet_record_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_wallet_record_retrieve_by_id.return_value = mock_wallet_record await test_module.wallet_get(self.request) @@ -698,11 +701,12 @@ async def test_wallet_create_token_managed(self): return_value={"settings": {}, "wallet_id": "dummy"} ) - with mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_wallet_record_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_wallet_record_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_wallet_record_retrieve_by_id.return_value = mock_wallet_record mock_multitenant_mgr = mock.AsyncMock(BaseMultitenantManager, autospec=True) mock_multitenant_mgr.create_auth_token = mock.CoroutineMock( @@ -727,11 +731,12 @@ async def test_wallet_create_token_unmanaged(self): return_value={"settings": {}, "wallet_id": "dummy"} ) - with mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_wallet_record_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_wallet_record_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_wallet_record_retrieve_by_id.return_value = mock_wallet_record mock_multitenant_mgr = mock.AsyncMock(BaseMultitenantManager, autospec=True) mock_multitenant_mgr.create_auth_token = mock.CoroutineMock( @@ -803,10 +808,11 @@ async def test_wallet_remove_managed(self): BaseMultitenantManager, mock_multitenant_mgr ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ), ): result = await test_module.wallet_remove(self.request) @@ -822,10 +828,11 @@ async def test_wallet_remove_unmanaged(self): self.profile.context.injector.bind_instance( BaseMultitenantManager, mock_multitenant_mgr ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock() + ), ): result = await test_module.wallet_remove(self.request) diff --git a/acapy_agent/multitenant/tests/test_base.py b/acapy_agent/multitenant/tests/test_base.py index 88834434f0..dbfb40a85c 100644 --- a/acapy_agent/multitenant/tests/test_base.py +++ b/acapy_agent/multitenant/tests/test_base.py @@ -210,11 +210,10 @@ async def test_create_wallet_saves_wallet_record_creates_profile(self): mock_route_manager.route_verkey = mock.CoroutineMock() self.context.injector.bind_instance(RouteManager, mock_route_manager) - with mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save, mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile: + with ( + mock.patch.object(WalletRecord, "save") as wallet_record_save, + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + ): get_wallet_profile.return_value = await create_test_profile() wallet_record = await self.manager.create_wallet( @@ -247,13 +246,11 @@ async def test_create_wallet_adds_wallet_route(self): mock_route_manager = mock.MagicMock() mock_route_manager.route_verkey = mock.CoroutineMock() - with mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save, mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile, mock.patch.object( - BaseWallet, "get_public_did" - ) as get_public_did: + with ( + mock.patch.object(WalletRecord, "save") as wallet_record_save, + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + mock.patch.object(BaseWallet, "get_public_did") as get_public_did, + ): mock_profile = await create_test_profile() mock_profile.context.injector.bind_instance(RouteManager, mock_route_manager) get_wallet_profile.return_value = mock_profile @@ -277,11 +274,10 @@ async def test_create_wallet_adds_wallet_route(self): assert wallet_record.wallet_key == "test_key" async def test_update_wallet(self): - with mock.patch.object( - WalletRecord, "retrieve_by_id" - ) as retrieve_by_id, mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save: + with ( + mock.patch.object(WalletRecord, "retrieve_by_id") as retrieve_by_id, + mock.patch.object(WalletRecord, "save") as wallet_record_save, + ): wallet_id = "test-wallet-id" retrieve_by_id.return_value = WalletRecord( wallet_id=wallet_id, @@ -315,17 +311,15 @@ async def test_remove_wallet_fails_no_wallet_key_but_required(self): await self.manager.remove_wallet("test") async def test_remove_wallet_removes_profile_wallet_storage_records(self): - with mock.patch.object( - WalletRecord, "retrieve_by_id" - ) as retrieve_by_id, mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile, mock.patch.object( - self.manager, "remove_wallet_profile" - ) as remove_wallet_profile, mock.patch.object( - WalletRecord, "delete_record" - ) as wallet_delete_record, mock.patch.object( - AskarStorage, "delete_all_records" - ) as delete_all_records: + with ( + mock.patch.object(WalletRecord, "retrieve_by_id") as retrieve_by_id, + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + mock.patch.object( + self.manager, "remove_wallet_profile" + ) as remove_wallet_profile, + mock.patch.object(WalletRecord, "delete_record") as wallet_delete_record, + mock.patch.object(AskarStorage, "delete_all_records") as delete_all_records, + ): wallet_record = WalletRecord( wallet_id="test", key_management_mode=WalletRecord.MODE_UNMANAGED, @@ -555,10 +549,9 @@ async def test_get_profile_for_token_managed_wallet_x_iat_no_match(self): algorithm="HS256", ) - with mock.patch.object( - self.manager, "get_wallet_profile" - ) as get_wallet_profile, self.assertRaises( - MultitenantManagerError, msg="Token not valid" + with ( + mock.patch.object(self.manager, "get_wallet_profile") as get_wallet_profile, + self.assertRaises(MultitenantManagerError, msg="Token not valid"), ): await self.manager.get_profile_for_token(self.profile.context, token) @@ -632,12 +625,15 @@ async def test_get_wallets_by_message(self): async def test_get_profile_for_key(self): mock_wallet = mock.MagicMock() mock_wallet.requires_external_key = False - with mock.patch.object( - self.manager, - "_get_wallet_by_key", - mock.CoroutineMock(return_value=mock_wallet), - ), mock.patch.object( - self.manager, "get_wallet_profile", mock.CoroutineMock() - ) as mock_get_wallet_profile: + with ( + mock.patch.object( + self.manager, + "_get_wallet_by_key", + mock.CoroutineMock(return_value=mock_wallet), + ), + mock.patch.object( + self.manager, "get_wallet_profile", mock.CoroutineMock() + ) as mock_get_wallet_profile, + ): profile = await self.manager.get_profile_for_key(self.context, "test-verkey") assert profile == mock_get_wallet_profile.return_value diff --git a/acapy_agent/multitenant/tests/test_manager.py b/acapy_agent/multitenant/tests/test_manager.py index 7cd92e5bc7..cc633d2e09 100644 --- a/acapy_agent/multitenant/tests/test_manager.py +++ b/acapy_agent/multitenant/tests/test_manager.py @@ -169,11 +169,10 @@ async def side_effect(context, provision): assert profile.settings.get("mediation.clear") is True async def test_update_wallet_update_wallet_profile(self): - with mock.patch.object( - WalletRecord, "retrieve_by_id" - ) as retrieve_by_id, mock.patch.object( - WalletRecord, "save" - ) as wallet_record_save: + with ( + mock.patch.object(WalletRecord, "retrieve_by_id") as retrieve_by_id, + mock.patch.object(WalletRecord, "save") as wallet_record_save, + ): wallet_id = "test-wallet-id" wallet_profile = await create_test_profile() self.manager._profiles.put("test-wallet-id", wallet_profile) diff --git a/acapy_agent/multitenant/tests/test_route_manager.py b/acapy_agent/multitenant/tests/test_route_manager.py index 3a3218199d..4dad3d9dce 100644 --- a/acapy_agent/multitenant/tests/test_route_manager.py +++ b/acapy_agent/multitenant/tests/test_route_manager.py @@ -61,11 +61,16 @@ async def test_route_for_key_sub_mediator_no_base_mediator( mediation_id="test-mediation-id", connection_id="test-mediator-conn-id" ) - with mock.patch.object( - route_manager, "get_base_wallet_mediator", mock.CoroutineMock(return_value=None) - ), mock.patch.object( - RoutingManager, "create_route_record", mock.CoroutineMock() - ) as mock_create_route_record: + with ( + mock.patch.object( + route_manager, + "get_base_wallet_mediator", + mock.CoroutineMock(return_value=None), + ), + mock.patch.object( + RoutingManager, "create_route_record", mock.CoroutineMock() + ) as mock_create_route_record, + ): keylist_update = await route_manager._route_for_key( sub_profile, TEST_VERKEY, @@ -102,13 +107,16 @@ async def test_route_for_key_sub_mediator_and_base_mediator( connection_id="test-base-mediator-conn-id", ) - with mock.patch.object( - route_manager, - "get_base_wallet_mediator", - mock.CoroutineMock(return_value=base_mediation_record), - ), mock.patch.object( - RoutingManager, "create_route_record", mock.CoroutineMock() - ) as mock_create_route_record: + with ( + mock.patch.object( + route_manager, + "get_base_wallet_mediator", + mock.CoroutineMock(return_value=base_mediation_record), + ), + mock.patch.object( + RoutingManager, "create_route_record", mock.CoroutineMock() + ) as mock_create_route_record, + ): keylist_update = await route_manager._route_for_key( sub_profile, TEST_VERKEY, @@ -142,13 +150,16 @@ async def test_route_for_key_base_mediator_no_sub_mediator( connection_id="test-base-mediator-conn-id", ) - with mock.patch.object( - route_manager, - "get_base_wallet_mediator", - mock.CoroutineMock(return_value=base_mediation_record), - ), mock.patch.object( - RoutingManager, "create_route_record", mock.CoroutineMock() - ) as mock_create_route_record: + with ( + mock.patch.object( + route_manager, + "get_base_wallet_mediator", + mock.CoroutineMock(return_value=base_mediation_record), + ), + mock.patch.object( + RoutingManager, "create_route_record", mock.CoroutineMock() + ) as mock_create_route_record, + ): keylist_update = await route_manager._route_for_key( sub_profile, TEST_VERKEY, diff --git a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py index 6ac3cbb77f..322a8517ec 100644 --- a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py @@ -43,11 +43,14 @@ async def test_get_wallet_profile_should_open_store_and_return_profile_with_wall }, ) - with mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" - ) as wallet_config, mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile", - ) as AskarProfile: + with ( + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" + ) as wallet_config, + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile", + ) as AskarProfile, + ): sub_wallet_profile_context = InjectionContext() sub_wallet_profile = AskarProfile(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context @@ -115,11 +118,14 @@ async def test_get_anoncreds_wallet_profile_should_open_store_and_return_anoncre }, ) - with mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" - ) as wallet_config, mock.patch( - "acapy_agent.multitenant.single_wallet_askar_manager.AskarAnoncredsProfile", - ) as AskarAnoncredsProfile: + with ( + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.wallet_config" + ) as wallet_config, + mock.patch( + "acapy_agent.multitenant.single_wallet_askar_manager.AskarAnoncredsProfile", + ) as AskarAnoncredsProfile, + ): sub_wallet_profile_context = InjectionContext() sub_wallet_profile = AskarAnoncredsProfile(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context diff --git a/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py b/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py index 1b76449de6..268a252711 100644 --- a/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/actionmenu/v1_0/tests/test_routes.py @@ -73,13 +73,13 @@ async def test_actionmenu_perform(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Perform", autospec=True - ) as mock_perform, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True) as mock_perform, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() await test_module.actionmenu_perform(self.request) @@ -93,9 +93,12 @@ async def test_actionmenu_perform_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate storage not found (bad connection id) mock_conn_record.retrieve_by_id = mock.CoroutineMock( side_effect=StorageNotFoundError @@ -108,9 +111,12 @@ async def test_actionmenu_perform_conn_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate connection not ready mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_conn_record.retrieve_by_id.return_value.is_ready = False @@ -122,13 +128,13 @@ async def test_actionmenu_request(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "MenuRequest", autospec=True - ) as menu_request, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "MenuRequest", autospec=True) as menu_request, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() await test_module.actionmenu_request(self.request) @@ -142,9 +148,12 @@ async def test_actionmenu_request_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate storage not found (bad connection id) mock_conn_record.retrieve_by_id = mock.CoroutineMock( side_effect=StorageNotFoundError @@ -157,9 +166,12 @@ async def test_actionmenu_request_conn_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object(test_module, "Perform", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Perform", autospec=True), + ): # Emulate connection not ready mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_conn_record.retrieve_by_id.return_value.is_ready = False @@ -171,13 +183,13 @@ async def test_actionmenu_send(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_menu.deserialize = mock.MagicMock() @@ -192,11 +204,12 @@ async def test_actionmenu_send_deserialize_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + ): mock_conn_record.retrieve_by_id = mock.CoroutineMock() mock_menu.deserialize = mock.MagicMock( side_effect=test_module.BaseModelError("cannot deserialize") @@ -209,11 +222,12 @@ async def test_actionmenu_send_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + ): mock_menu.deserialize = mock.MagicMock() # Emulate storage not found (bad connection id) @@ -228,11 +242,12 @@ async def test_actionmenu_send_conn_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_record, mock.patch.object( - test_module, "Menu", autospec=True - ) as mock_menu: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_record, + mock.patch.object(test_module, "Menu", autospec=True) as mock_menu, + ): mock_menu.deserialize = mock.MagicMock() # Emulate connection not ready diff --git a/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py b/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py index cd15506fd4..736ae633d7 100644 --- a/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/basicmessage/v1_0/tests/test_routes.py @@ -33,13 +33,15 @@ async def test_connections_send_message(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": self.test_conn_id} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_connection_record, mock.patch.object( - test_module, "BasicMessage", autospec=True - ) as mock_basic_message, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_connection_record, + mock.patch.object( + test_module, "BasicMessage", autospec=True + ) as mock_basic_message, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_connection_record.retrieve_by_id = mock.CoroutineMock() await test_module.connections_send_message(self.request) @@ -50,10 +52,11 @@ async def test_connections_send_message_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": self.test_conn_id} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_connection_record, mock.patch.object( - test_module, "BasicMessage", autospec=True + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_connection_record, + mock.patch.object(test_module, "BasicMessage", autospec=True), ): # Emulate storage not found (bad connection id) mock_connection_record.retrieve_by_id = mock.CoroutineMock( @@ -67,11 +70,14 @@ async def test_connections_send_message_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"conn_id": self.test_conn_id} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_connection_record, mock.patch.object( - test_module, "BasicMessage", autospec=True - ) as mock_basic_message: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_connection_record, + mock.patch.object( + test_module, "BasicMessage", autospec=True + ) as mock_basic_message, + ): # Emulate connection not ready mock_connection_record.retrieve_by_id = mock.CoroutineMock() mock_connection_record.retrieve_by_id.return_value.is_ready = False diff --git a/acapy_agent/protocols/connections/v1_0/tests/test_manager.py b/acapy_agent/protocols/connections/v1_0/tests/test_manager.py index a96363dc00..eb2c5b7f6d 100644 --- a/acapy_agent/protocols/connections/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/connections/v1_0/tests/test_manager.py @@ -412,14 +412,18 @@ async def test_create_request_multitenant(self): endpoint=self.test_mediator_endpoint, ) - with mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, @@ -465,14 +469,16 @@ async def test_create_request_mediation_id(self): # Ensure the path with new did creation is hit record.my_did = None - with mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - AskarWallet, "create_local_did" - ) as create_local_did, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object(AskarWallet, "create_local_did") as create_local_did, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): did_info = DIDInfo( did=self.test_did, @@ -516,14 +522,16 @@ async def test_create_request_default_mediator(self): # Ensure the path with new did creation is hit record.my_did = None - with mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - AskarWallet, "create_local_did" - ) as create_local_did, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object(AskarWallet, "create_local_did") as create_local_did, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): did_info = DIDInfo( did=self.test_did, @@ -565,18 +573,18 @@ async def test_receive_request_public_did_oob_invite(self): ) self.context.update_settings({"public_invites": True}) - with mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = ConnRecord() conn_rec = await self.manager.receive_request(mock_request, receipt) @@ -606,18 +614,19 @@ async def test_receive_request_public_did_unsolicited_fails(self): ) self.context.update_settings({"public_invites": True}) - with self.assertRaises(ConnectionManagerError), mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + self.assertRaises(ConnectionManagerError), + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = None await self.manager.receive_request(mock_request, receipt) @@ -646,20 +655,20 @@ async def test_receive_request_public_did_conn_invite(self): mock_connection_record.attach_request = mock.CoroutineMock() self.context.update_settings({"public_invites": True}) - with mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, - "retrieve_by_invitation_msg_id", - mock.CoroutineMock(return_value=mock_connection_record), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, + "retrieve_by_invitation_msg_id", + mock.CoroutineMock(return_value=mock_connection_record), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): conn_rec = await self.manager.receive_request(mock_request, receipt) assert conn_rec @@ -685,18 +694,18 @@ async def test_receive_request_public_did_unsolicited(self): self.context.update_settings({"public_invites": True}) self.context.update_settings({"requests_through_public_did": True}) - with mock.patch.object( - ConnRecord, "connection_id", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "connection_id", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = None conn_rec = await self.manager.receive_request(mock_request, receipt) @@ -721,11 +730,12 @@ async def test_receive_request_public_did_no_did_doc(self): ) self.context.update_settings({"public_invites": True}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object(ConnRecord, "retrieve_request", autospec=True): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + ): with self.assertRaises(ConnectionManagerError): await self.manager.receive_request(mock_request, receipt) @@ -749,11 +759,12 @@ async def test_receive_request_public_did_wrong_did(self): ) self.context.update_settings({"public_invites": True}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object(ConnRecord, "retrieve_request", autospec=True): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + ): with self.assertRaises(ConnectionManagerError): await self.manager.receive_request(mock_request, receipt) @@ -775,13 +786,13 @@ async def test_receive_request_public_did_no_public_invites(self): ) self.context.update_settings({"public_invites": False}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): with self.assertRaises(ConnectionManagerError): await self.manager.receive_request(mock_request, receipt) @@ -807,16 +818,17 @@ async def test_receive_request_public_did_no_auto_accept(self): self.context.update_settings( {"public_invites": True, "debug.auto_accept_requests": False} ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "attach_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_id", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_invitation_msg_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnRecord, "attach_request", autospec=True), + mock.patch.object(ConnRecord, "retrieve_by_id", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_invitation_msg_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_invitation_msg_id, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_invitation_msg_id.return_value = ConnRecord() conn_rec = await self.manager.receive_request(mock_request, receipt) @@ -828,11 +840,13 @@ async def test_receive_request_public_did_no_auto_accept(self): async def test_create_response(self): conn_rec = ConnRecord(state=ConnRecord.State.REQUEST.rfc160) - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnectionResponse, "sign_field", autospec=True - ), mock.patch.object(conn_rec, "metadata_get", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + mock.patch.object(conn_rec, "metadata_get", mock.CoroutineMock()), + ): await self.manager.create_response(conn_rec, "http://10.20.30.40:5060/") async def test_create_response_multitenant(self): @@ -849,22 +863,25 @@ async def test_create_response_multitenant(self): endpoint=self.test_mediator_endpoint, ) - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "save", autospec=True - ), mock.patch.object( - ConnRecord, "metadata_get", mock.CoroutineMock(return_value=False) - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object( - ConnectionResponse, "sign_field", autospec=True - ), mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "metadata_get", mock.CoroutineMock(return_value=False) + ), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), ): mock_wallet_create_local_did.return_value = DIDInfo( self.test_did, @@ -921,21 +938,24 @@ async def test_create_response_mediation(self): # Ensure the path with new did creation is hit record.my_did = None - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "save", autospec=True - ), mock.patch.object( - record, "metadata_get", mock.CoroutineMock(return_value=False) - ), mock.patch.object( - ConnectionManager, "create_did_document", autospec=True - ) as create_did_document, mock.patch.object( - AskarWallet, "create_local_did" - ) as create_local_did, mock.patch.object( - self.route_manager, - "mediation_records_for_connection", - mock.CoroutineMock(return_value=[mediation_record]), - ), mock.patch.object( - record, "retrieve_request", autospec=True - ), mock.patch.object(ConnectionResponse, "sign_field", autospec=True): + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + record, "metadata_get", mock.CoroutineMock(return_value=False) + ), + mock.patch.object( + ConnectionManager, "create_did_document", autospec=True + ) as create_did_document, + mock.patch.object(AskarWallet, "create_local_did") as create_local_did, + mock.patch.object( + self.route_manager, + "mediation_records_for_connection", + mock.CoroutineMock(return_value=[mediation_record]), + ), + mock.patch.object(record, "retrieve_request", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + ): did_info = DIDInfo( did=self.test_did, verkey=self.test_verkey, @@ -964,12 +984,14 @@ async def test_create_response_auto_send_mediation_request(self): ) conn_rec.my_did = None - with mock.patch.object(ConnRecord, "log_state", autospec=True), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnectionResponse, "sign_field", autospec=True - ), mock.patch.object( - conn_rec, "metadata_get", mock.CoroutineMock(return_value=True) + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object(ConnectionResponse, "sign_field", autospec=True), + mock.patch.object( + conn_rec, "metadata_get", mock.CoroutineMock(return_value=True) + ), ): await self.manager.create_response(conn_rec) @@ -988,11 +1010,16 @@ async def test_accept_response_find_by_thread_id(self): mock_response.verify_signed_field = mock.CoroutineMock(return_value="sig_verkey") receipt = MessageReceipt(recipient_did=self.test_did, recipient_did_public=True) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), @@ -1017,13 +1044,19 @@ async def test_accept_response_not_found_by_thread_id_receipt_has_sender_did(sel receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.return_value = mock.MagicMock( did=self.test_target_did, @@ -1051,11 +1084,15 @@ async def test_accept_response_not_found_by_thread_id_nor_receipt_sender_did(sel receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() @@ -1072,9 +1109,12 @@ async def test_accept_response_find_by_thread_id_bad_state(self): receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( state=ConnRecord.State.ABANDONED.rfc23 ) @@ -1091,9 +1131,12 @@ async def test_accept_response_find_by_thread_id_no_connection_did_doc(self): receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), @@ -1113,9 +1156,12 @@ async def test_accept_response_find_by_thread_id_did_mismatch(self): receipt = MessageReceipt(sender_did=self.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), @@ -1135,10 +1181,14 @@ async def test_accept_response_verify_invitation_key_sign_failure(self): mock_response.verify_signed_field = mock.CoroutineMock(side_effect=ValueError) receipt = MessageReceipt(recipient_did=self.test_did, recipient_did_public=True) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, @@ -1162,11 +1212,16 @@ async def test_accept_response_auto_send_mediation_request(self): mock_response.verify_signed_field = mock.CoroutineMock(return_value="sig_verkey") receipt = MessageReceipt(recipient_did=self.test_did, recipient_did_public=True) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ), mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()): + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ), + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=self.test_target_did, did_doc=mock.MagicMock(did=self.test_target_did), diff --git a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py index 46f32714eb..917c795c5f 100644 --- a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py @@ -146,11 +146,12 @@ async def test_connections_retrieve(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock(return_value={"hello": "world"}) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec await test_module.connections_retrieve(self.request) @@ -159,11 +160,12 @@ async def test_connections_retrieve(self): async def test_connections_endpoints(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr_cls.return_value = mock.MagicMock( get_endpoints=mock.CoroutineMock( return_value=("localhost:8080", "1.2.3.4:8081") @@ -180,9 +182,12 @@ async def test_connections_endpoints(self): async def test_connections_endpoints_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_mgr_cls.return_value = mock.MagicMock( get_endpoints=mock.CoroutineMock(side_effect=StorageNotFoundError()) ) @@ -201,13 +206,15 @@ async def test_connections_metadata(self): self.request.match_info = {"conn_id": "dummy"} mock_conn_rec = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ) as mock_metadata_get_all, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + mock_conn_rec, "metadata_get_all", mock.CoroutineMock() + ) as mock_metadata_get_all, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get_all.return_value = {"hello": "world"} @@ -220,15 +227,16 @@ async def test_connections_metadata_get_single(self): mock_conn_rec = mock.MagicMock() self.request.query = {"key": "test"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ), mock.patch.object( - mock_conn_rec, "metadata_get", mock.CoroutineMock() - ) as mock_metadata_get, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(mock_conn_rec, "metadata_get_all", mock.CoroutineMock()), + mock.patch.object( + mock_conn_rec, "metadata_get", mock.CoroutineMock() + ) as mock_metadata_get, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get.return_value = {"test": "value"} @@ -240,11 +248,15 @@ async def test_connections_metadata_x(self): self.request.match_info = {"conn_id": "dummy"} mock_conn_rec = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ) as mock_metadata_get_all, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + mock_conn_rec, "metadata_get_all", mock.CoroutineMock() + ) as mock_metadata_get_all, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get_all.side_effect = StorageNotFoundError() @@ -262,15 +274,18 @@ async def test_connections_metadata_set(self): return_value={"metadata": {"hello": "world"}} ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ) as mock_metadata_get_all, mock.patch.object( - mock_conn_rec, "metadata_set", mock.CoroutineMock() - ) as mock_metadata_set, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + mock_conn_rec, "metadata_get_all", mock.CoroutineMock() + ) as mock_metadata_get_all, + mock.patch.object( + mock_conn_rec, "metadata_set", mock.CoroutineMock() + ) as mock_metadata_set, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_get_all.return_value = {"hello": "world"} @@ -285,13 +300,16 @@ async def test_connections_metadata_set_x(self): return_value={"metadata": {"hello": "world"}} ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - mock_conn_rec, "metadata_get_all", mock.CoroutineMock() - ), mock.patch.object( - mock_conn_rec, "metadata_set", mock.CoroutineMock() - ) as mock_metadata_set, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(mock_conn_rec, "metadata_get_all", mock.CoroutineMock()), + mock.patch.object( + mock_conn_rec, "metadata_set", mock.CoroutineMock() + ) as mock_metadata_set, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_metadata_set.side_effect = StorageNotFoundError() @@ -343,11 +361,12 @@ async def test_connections_create_invitation(self): "multi_use": "true", } - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr.return_value.create_invitation = mock.CoroutineMock( return_value=( mock.MagicMock( # connection record @@ -450,13 +469,15 @@ async def test_connections_receive_invitation(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnectionInvitation, "deserialize", autospec=True - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnectionInvitation, "deserialize", autospec=True + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr.return_value.receive_invitation = mock.CoroutineMock( return_value=mock_conn_rec ) @@ -474,10 +495,11 @@ async def test_connections_receive_invitation_bad(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnectionInvitation, "deserialize", autospec=True - ) as mock_inv_deser, mock.patch.object( - test_module, "ConnectionManager", autospec=True + with ( + mock.patch.object( + test_module.ConnectionInvitation, "deserialize", autospec=True + ) as mock_inv_deser, + mock.patch.object(test_module, "ConnectionManager", autospec=True), ): mock_inv_deser.side_effect = test_module.BaseModelError() @@ -501,11 +523,14 @@ async def test_connections_receive_invitation_x_bad_mediation_id(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnectionInvitation, "deserialize", autospec=True - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr: + with ( + mock.patch.object( + test_module.ConnectionInvitation, "deserialize", autospec=True + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + ): mock_conn_mgr.return_value.receive_invitation = mock.CoroutineMock( side_effect=StorageNotFoundError() ) @@ -523,13 +548,15 @@ async def test_connections_accept_invitation(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_conn_mgr.return_value.create_request = mock.CoroutineMock() @@ -550,11 +577,14 @@ async def test_connections_accept_invitation_not_found(self): async def test_connections_accept_invitation_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + ): mock_conn_mgr.return_value.create_request = mock.CoroutineMock( side_effect=test_module.ConnectionManagerError() ) @@ -566,11 +596,14 @@ async def test_connections_accept_invitation_x_bad_mediation_id(self): self.request.match_info = {"conn_id": "dummy"} self.request.query["mediation_id"] = "some-id" - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + ): mock_conn_mgr.return_value.create_request = mock.CoroutineMock( side_effect=StorageNotFoundError() ) @@ -587,13 +620,15 @@ async def test_connections_accept_request(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_conn_mgr.return_value.create_response = mock.CoroutineMock() @@ -614,11 +649,15 @@ async def test_connections_accept_request_not_found(self): async def test_connections_accept_request_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_conn_mgr.return_value.create_response = mock.CoroutineMock( side_effect=test_module.ConnectionManagerError() ) @@ -631,11 +670,12 @@ async def test_connections_remove(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.delete_record = mock.CoroutineMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec await test_module.connections_remove(self.request) @@ -650,11 +690,12 @@ async def test_connections_remove_cache_key(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.delete_record = mock.CoroutineMock() assert (await cache.get("conn_rec_state::dummy")) == "active" - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec await test_module.connections_remove(self.request) @@ -714,11 +755,12 @@ async def test_connections_create_static(self): mock_their_info.did = "their_did" mock_their_info.verkey = "their_verkey" - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_conn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_conn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_mgr.return_value.create_static_connection = mock.CoroutineMock( return_value=(mock_my_info, mock_their_info, mock_conn_rec) ) diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py index 8f7dbcc25d..4d32ebc819 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_keylist_update_response_handler.py @@ -57,11 +57,10 @@ async def test_handler_no_active_connection(self): async def test_handler(self): handler, responder = KeylistUpdateResponseHandler(), MockResponder() - with mock.patch.object( - MediationManager, "store_update_results" - ) as mock_store, mock.patch.object( - handler, "notify_keylist_updated" - ) as mock_notify: + with ( + mock.patch.object(MediationManager, "store_update_results") as mock_store, + mock.patch.object(handler, "notify_keylist_updated") as mock_notify, + ): await handler.handle(self.context, responder) mock_store.assert_called_once_with(TEST_CONN_ID, self.updated) mock_notify.assert_called_once_with( diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py index 79b2ab6ae2..e494e4c83a 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/handlers/tests/test_mediation_grant_handler.py @@ -78,13 +78,16 @@ async def test_handler_connection_has_set_to_default_meta( handler, responder = MediationGrantHandler(), MockResponder() record = MediationRecord(connection_id=TEST_CONN_ID) await record.save(session) - with mock.patch.object( - context.connection_record, - "metadata_get", - mock.CoroutineMock(return_value=True), - ), mock.patch.object( - test_module, "MediationManager", autospec=True - ) as mock_mediation_manager: + with ( + mock.patch.object( + context.connection_record, + "metadata_get", + mock.CoroutineMock(return_value=True), + ), + mock.patch.object( + test_module, "MediationManager", autospec=True + ) as mock_mediation_manager, + ): await handler.handle(context, responder) mock_mediation_manager.return_value.set_default_mediator.assert_called_once_with( record @@ -127,12 +130,15 @@ async def test_handler_connection_no_set_to_default( handler, responder = MediationGrantHandler(), MockResponder() record = MediationRecord(connection_id=TEST_CONN_ID) await record.save(session) - with mock.patch.object( - context.connection_record, - "metadata_get", - mock.CoroutineMock(return_value=False), - ), mock.patch.object( - test_module, "MediationManager", autospec=True - ) as mock_mediation_manager: + with ( + mock.patch.object( + context.connection_record, + "metadata_get", + mock.CoroutineMock(return_value=False), + ), + mock.patch.object( + test_module, "MediationManager", autospec=True + ) as mock_mediation_manager, + ): await handler.handle(context, responder) mock_mediation_manager.return_value.set_default_mediator.assert_not_called() diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py index 9bd237c9c0..c0ef5c6855 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_mediation_manager.py @@ -397,21 +397,27 @@ async def test_store_update_results( ), ] - with mock.patch.object( - RouteRecord, "query", mock.CoroutineMock() - ) as mock_route_rec_query, mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ) as mock_logger_error: + with ( + mock.patch.object( + RouteRecord, "query", mock.CoroutineMock() + ) as mock_route_rec_query, + mock.patch.object( + test_module.LOGGER, "error", mock.MagicMock() + ) as mock_logger_error, + ): mock_route_rec_query.side_effect = StorageNotFoundError("no record") await manager.store_update_results(TEST_CONN_ID, results) mock_logger_error.assert_called_once() - with mock.patch.object( - RouteRecord, "query", mock.CoroutineMock() - ) as mock_route_rec_query, mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ) as mock_logger_error: + with ( + mock.patch.object( + RouteRecord, "query", mock.CoroutineMock() + ) as mock_route_rec_query, + mock.patch.object( + test_module.LOGGER, "error", mock.MagicMock() + ) as mock_logger_error, + ): mock_route_rec_query.return_value = [ mock.MagicMock(delete_record=mock.CoroutineMock()) ] * 2 diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py index 5ff5b4ac5b..86d9cc6bff 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py @@ -78,13 +78,14 @@ async def test_get_or_create_my_did_no_did( ): conn_record.my_did = None mock_did_info = mock.MagicMock() - with mock.patch.object( - AskarWallet, - "create_local_did", - mock.CoroutineMock(return_value=mock_did_info), - ) as mock_create_local_did, mock.patch.object( - conn_record, "save", mock.CoroutineMock() - ) as mock_save: + with ( + mock.patch.object( + AskarWallet, + "create_local_did", + mock.CoroutineMock(return_value=mock_did_info), + ) as mock_create_local_did, + mock.patch.object(conn_record, "save", mock.CoroutineMock()) as mock_save, + ): info = await route_manager.get_or_create_my_did(profile, conn_record) assert mock_did_info == info mock_create_local_did.assert_called_once() @@ -110,12 +111,15 @@ async def test_mediation_record_for_connection_mediation_id( profile: Profile, route_manager: RouteManager, conn_record: ConnRecord ): mediation_record = MediationRecord(mediation_id="test-mediation-id") - with mock.patch.object( - route_manager, - "mediation_record_if_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_mediation_record_if_id, mock.patch.object( - route_manager, "save_mediator_for_connection", mock.CoroutineMock() + with ( + mock.patch.object( + route_manager, + "mediation_record_if_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_mediation_record_if_id, + mock.patch.object( + route_manager, "save_mediator_for_connection", mock.CoroutineMock() + ), ): assert await route_manager.mediation_records_for_connection( profile, conn_record, mediation_record.mediation_id @@ -133,12 +137,15 @@ async def test_mediation_record_for_connection_mediation_metadata( conn_record.metadata_get.return_value = { MediationManager.METADATA_ID: mediation_record.mediation_id } - with mock.patch.object( - route_manager, - "mediation_record_if_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_mediation_record_if_id, mock.patch.object( - route_manager, "save_mediator_for_connection", mock.CoroutineMock() + with ( + mock.patch.object( + route_manager, + "mediation_record_if_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_mediation_record_if_id, + mock.patch.object( + route_manager, "save_mediator_for_connection", mock.CoroutineMock() + ), ): assert await route_manager.mediation_records_for_connection( profile, conn_record, "another-mediation-id" @@ -153,12 +160,15 @@ async def test_mediation_record_for_connection_default( profile: Profile, route_manager: RouteManager, conn_record: ConnRecord ): mediation_record = MediationRecord(mediation_id="test-mediation-id") - with mock.patch.object( - route_manager, - "mediation_record_if_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_mediation_record_if_id, mock.patch.object( - route_manager, "save_mediator_for_connection", mock.CoroutineMock() + with ( + mock.patch.object( + route_manager, + "mediation_record_if_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_mediation_record_if_id, + mock.patch.object( + route_manager, "save_mediator_for_connection", mock.CoroutineMock() + ), ): assert await route_manager.mediation_records_for_connection( profile, conn_record, None, or_default=True @@ -210,13 +220,16 @@ async def test_mediation_record_if_id_with_id_and_default( mediation_record = MediationRecord( mediation_id="test-mediation-id", state=MediationRecord.STATE_GRANTED ) - with mock.patch.object( - MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_retrieve_by_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock() - ) as mock_get_default_mediator: + with ( + mock.patch.object( + MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_retrieve_by_id, + mock.patch.object( + MediationManager, "get_default_mediator", mock.CoroutineMock() + ) as mock_get_default_mediator, + ): actual = await route_manager.mediation_record_if_id( profile, mediation_id=mediation_record.mediation_id, or_default=True ) @@ -233,13 +246,16 @@ async def test_mediation_record_if_id_without_id_and_default( mediation_record = MediationRecord( mediation_id="test-mediation-id", state=MediationRecord.STATE_GRANTED ) - with mock.patch.object( - MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id, mock.patch.object( - MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=mediation_record), - ) as mock_get_default_mediator: + with ( + mock.patch.object( + MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + mock.patch.object( + MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=mediation_record), + ) as mock_get_default_mediator, + ): actual = await route_manager.mediation_record_if_id( profile, mediation_id=None, or_default=True ) @@ -253,11 +269,16 @@ async def test_mediation_record_if_id_without_id_and_no_default( profile: Profile, route_manager: RouteManager, ): - with mock.patch.object( - MediationRecord, "retrieve_by_id", mock.CoroutineMock(return_value=None) - ) as mock_retrieve_by_id, mock.patch.object( - MediationManager, "get_default_mediator", mock.CoroutineMock(return_value=None) - ) as mock_get_default_mediator: + with ( + mock.patch.object( + MediationRecord, "retrieve_by_id", mock.CoroutineMock(return_value=None) + ) as mock_retrieve_by_id, + mock.patch.object( + MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=None), + ) as mock_get_default_mediator, + ): assert ( await route_manager.mediation_record_if_id( profile, mediation_id=None, or_default=True @@ -319,21 +340,24 @@ async def test_route_connection_state_inviter_replace_key_none( mock_did_info = mock.MagicMock(DIDInfo) conn_record.invitation_key = TEST_RECORD_VERKEY - with mock.patch.object( - route_manager, - "get_or_create_my_did", - mock.CoroutineMock(return_value=mock_did_info), - ), mock.patch.object( - AskarWallet, - "get_public_did", - mock.CoroutineMock( - return_value=DIDInfo( - TEST_RECORD_DID, - TEST_RECORD_VERKEY, - None, - method=SOV, - key_type=ED25519, - ) + with ( + mock.patch.object( + route_manager, + "get_or_create_my_did", + mock.CoroutineMock(return_value=mock_did_info), + ), + mock.patch.object( + AskarWallet, + "get_public_did", + mock.CoroutineMock( + return_value=DIDInfo( + TEST_RECORD_DID, + TEST_RECORD_VERKEY, + None, + method=SOV, + key_type=ED25519, + ) + ), ), ): await route_manager.route_connection_as_inviter( @@ -355,11 +379,14 @@ async def test_route_connection_state_invitee( mediation_record = MediationRecord(mediation_id="test-mediation-id") conn_record.state = "invitation" conn_record.their_role = "responder" - with mock.patch.object( - route_manager, "route_connection_as_invitee", mock.CoroutineMock() - ) as mock_route_connection_as_invitee, mock.patch.object( - route_manager, "route_connection_as_inviter", mock.CoroutineMock() - ) as mock_route_connection_as_inviter: + with ( + mock.patch.object( + route_manager, "route_connection_as_invitee", mock.CoroutineMock() + ) as mock_route_connection_as_invitee, + mock.patch.object( + route_manager, "route_connection_as_inviter", mock.CoroutineMock() + ) as mock_route_connection_as_inviter, + ): await route_manager.route_connection(profile, conn_record, [mediation_record]) mock_route_connection_as_invitee.assert_called_once() mock_route_connection_as_inviter.assert_not_called() @@ -372,11 +399,14 @@ async def test_route_connection_state_inviter( mediation_record = MediationRecord(mediation_id="test-mediation-id") conn_record.state = "request" conn_record.their_role = "requester" - with mock.patch.object( - route_manager, "route_connection_as_invitee", mock.CoroutineMock() - ) as mock_route_connection_as_invitee, mock.patch.object( - route_manager, "route_connection_as_inviter", mock.CoroutineMock() - ) as mock_route_connection_as_inviter: + with ( + mock.patch.object( + route_manager, "route_connection_as_invitee", mock.CoroutineMock() + ) as mock_route_connection_as_invitee, + mock.patch.object( + route_manager, "route_connection_as_inviter", mock.CoroutineMock() + ) as mock_route_connection_as_inviter, + ): await route_manager.route_connection(profile, conn_record, [mediation_record]) mock_route_connection_as_inviter.assert_called_once() mock_route_connection_as_invitee.assert_not_called() diff --git a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py index 773f31fbc6..cf0eda45ab 100644 --- a/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/coordinate_mediation/v1_0/tests/test_routes.py @@ -71,13 +71,14 @@ def test_mediation_sort_key(self): async def test_list_mediation_requests(self): self.request.query = {} - with mock.patch.object( - test_module.MediationRecord, - "query", - mock.CoroutineMock(return_value=[self.mock_record]), - ) as mock_query, mock.patch.object( - test_module.web, "json_response" - ) as json_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "query", + mock.CoroutineMock(return_value=[self.mock_record]), + ) as mock_query, + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.list_mediation_requests(self.request) json_response.assert_called_once_with( {"results": [self.mock_record.serialize.return_value]} @@ -89,13 +90,14 @@ async def test_list_mediation_requests_filters(self): "state": MediationRecord.STATE_GRANTED, "conn_id": "test-conn-id", } - with mock.patch.object( - test_module.MediationRecord, - "query", - mock.CoroutineMock(return_value=[self.mock_record]), - ) as mock_query, mock.patch.object( - test_module.web, "json_response" - ) as json_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "query", + mock.CoroutineMock(return_value=[self.mock_record]), + ) as mock_query, + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.list_mediation_requests(self.request) json_response.assert_called_once_with( {"results": [self.mock_record.serialize.return_value]} @@ -114,53 +116,63 @@ async def test_list_mediation_requests_x(self): await test_module.list_mediation_requests(self.request) async def test_list_mediation_requests_no_records(self): - with mock.patch.object( - test_module, - "MediationRecord", - mock.MagicMock(query=mock.CoroutineMock(return_value=[])), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + test_module, + "MediationRecord", + mock.MagicMock(query=mock.CoroutineMock(return_value=[])), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.list_mediation_requests(self.request) mock_response.assert_called_once_with({"results": []}) async def test_retrieve_mediation_request(self): - with mock.patch.object( - test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_mediation_record_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_mediation_record_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mediation_record_retrieve.return_value = self.mock_record await test_module.retrieve_mediation_request(self.request) mock_response.assert_called_once_with(self.mock_record.serialize.return_value) mock_mediation_record_retrieve.assert_called() async def test_retrieve_mediation_request_x_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPNotFound + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPNotFound), ): await test_module.retrieve_mediation_request(self.request) async def test_retrieve_mediation_request_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPBadRequest + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPBadRequest), ): await test_module.retrieve_mediation_request(self.request) async def test_delete_mediation_request(self): - with mock.patch.object( - test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_mediation_record_retrieve, mock.patch.object( - self.mock_record, "delete_record", mock.CoroutineMock() - ) as mock_delete_record, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_mediation_record_retrieve, + mock.patch.object( + self.mock_record, "delete_record", mock.CoroutineMock() + ) as mock_delete_record, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mediation_record_retrieve.return_value = self.mock_record await test_module.delete_mediation_request(self.request) mock_response.assert_called_once_with(self.mock_record.serialize.return_value) @@ -168,38 +180,45 @@ async def test_delete_mediation_request(self): mock_delete_record.assert_called() async def test_delete_mediation_request_x_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPNotFound + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPNotFound), ): await test_module.delete_mediation_request(self.request) async def test_delete_mediation_request_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object(test_module.web, "json_response"), self.assertRaises( - test_module.web.HTTPBadRequest + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object(test_module.web, "json_response"), + self.assertRaises(test_module.web.HTTPBadRequest), ): await test_module.delete_mediation_request(self.request) async def test_request_mediation(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module, "MediationManager", autospec=True - ) as mock_med_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module.MediationRecord, - "exists_for_connection_id", - mock.CoroutineMock(return_value=False), - ), mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "MediationManager", autospec=True + ) as mock_med_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module.MediationRecord, + "exists_for_connection_id", + mock.CoroutineMock(return_value=False), + ), + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), ): mock_med_mgr.return_value.prepare_request = mock.CoroutineMock( return_value=( @@ -218,52 +237,68 @@ async def test_request_mediation(self): async def test_request_mediation_x_conn_not_ready(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock.MagicMock(is_ready=False)), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock.MagicMock(is_ready=False)), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.request_mediation(self.request) async def test_request_mediation_x_already_exists(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module.MediationRecord, - "exists_for_connection_id", - mock.CoroutineMock(return_value=True), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object( + test_module.MediationRecord, + "exists_for_connection_id", + mock.CoroutineMock(return_value=True), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.request_mediation(self.request) async def test_request_mediation_x_conn_not_found(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.request_mediation(self.request) async def test_request_mediation_x_storage_error(self): body = {} self.request.json.return_value = body - with mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.request_mediation(self.request) async def test_mediation_request_grant_role_server(self): self.mock_record.role = MediationRecord.ROLE_SERVER - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.mediation_request_grant(self.request) mock_response.assert_called_once_with( self.mock_record.serialize.return_value, status=201 @@ -272,36 +307,48 @@ async def test_mediation_request_grant_role_server(self): async def test_mediation_request_grant_role_client_x(self): self.mock_record.role = MediationRecord.ROLE_CLIENT - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.mediation_request_grant(self.request) async def test_mediation_request_grant_x_rec_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.mediation_request_grant(self.request) async def test_mediation_request_grant_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.mediation_request_grant(self.request) async def test_mediation_request_deny_role_server(self): self.mock_record.role = MediationRecord.ROLE_SERVER - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.mediation_request_deny(self.request) mock_response.assert_called_once_with( self.mock_record.serialize.return_value, status=201 @@ -310,10 +357,11 @@ async def test_mediation_request_deny_role_server(self): async def test_mediation_request_deny_role_client_x(self): self.mock_record.role = MediationRecord.ROLE_CLIENT - with mock.patch.object( - test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_mediation_record_retrieve, mock.patch.object( - test_module.web, "json_response" + with ( + mock.patch.object( + test_module.MediationRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_mediation_record_retrieve, + mock.patch.object(test_module.web, "json_response"), ): mock_mediation_record_retrieve.return_value = mock.MagicMock( role=MediationRecord.ROLE_CLIENT @@ -322,19 +370,25 @@ async def test_mediation_request_deny_role_client_x(self): await test_module.mediation_request_deny(self.request) async def test_mediation_request_deny_x_rec_not_found(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.mediation_request_deny(self.request) async def test_mediation_request_deny_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.mediation_request_deny(self.request) async def test_get_keylist(self): @@ -348,17 +402,19 @@ async def test_get_keylist(self): ) ] - with mock.patch.object( - test_module.RouteRecord, - "query", - mock.CoroutineMock(return_value=query_results), - ) as mock_query, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=session), - ) as mock_session, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.RouteRecord, + "query", + mock.CoroutineMock(return_value=query_results), + ) as mock_query, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=session), + ) as mock_session, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.get_keylist(self.request) mock_response.assert_called_once_with( {"results": [{"serialized": "route record"}]}, status=200 @@ -370,27 +426,32 @@ async def test_get_keylist(self): async def test_get_keylist_no_matching_records(self): session = await self.profile.session() - with mock.patch.object( - test_module.RouteRecord, - "query", - mock.CoroutineMock(return_value=[]), - ) as mock_query, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=session), - ) as mock_session, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.RouteRecord, + "query", + mock.CoroutineMock(return_value=[]), + ) as mock_query, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=session), + ) as mock_session, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.get_keylist(self.request) mock_query.assert_called_once_with(mock_session.return_value, {}) mock_response.assert_called_once_with({"results": []}, status=200) async def test_get_keylist_storage_error(self): - with mock.patch.object( - test_module.RouteRecord, - "query", - mock.CoroutineMock(side_effect=test_module.StorageError), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.RouteRecord, + "query", + mock.CoroutineMock(side_effect=test_module.StorageError), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.get_keylist(self.request) async def test_send_keylist_update(self): @@ -421,18 +482,23 @@ async def test_send_keylist_update(self): self.request.json.return_value = body - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock( - return_value=mock.MagicMock( - state=MediationRecord.STATE_GRANTED, connection_id="test-conn-id" - ) + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock( + return_value=mock.MagicMock( + state=MediationRecord.STATE_GRANTED, connection_id="test-conn-id" + ) + ), + ), + mock.patch.object( + test_module.web, + "json_response", + mock.MagicMock( + side_effect=lambda *args, **kwargs: [*args, *kwargs.values()] + ), ), - ), mock.patch.object( - test_module.web, - "json_response", - mock.MagicMock(side_effect=lambda *args, **kwargs: [*args, *kwargs.values()]), ): results, status = await test_module.send_keylist_update(self.request) assert results["updates"] == body_with_didkey["updates"] @@ -461,15 +527,18 @@ async def test_send_keylist_update_bad_mediation_state(self): ] } - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock( - return_value=mock.MagicMock( - state=MediationRecord.STATE_DENIED, connection_id="test-conn-id" - ) + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock( + return_value=mock.MagicMock( + state=MediationRecord.STATE_DENIED, connection_id="test-conn-id" + ) + ), ), - ), self.assertRaises(test_module.web.HTTPBadRequest): + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.send_keylist_update(self.request) async def test_send_keylist_update_bad_updates(self): @@ -486,11 +555,14 @@ async def test_send_keylist_update_x_no_mediation_rec(self): }, ] } - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.send_keylist_update(self.request) async def test_send_keylist_update_x_storage_error(self): @@ -503,28 +575,33 @@ async def test_send_keylist_update_x_storage_error(self): ] } - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.send_keylist_update(self.request) @mock.patch.object(test_module, "MediationManager", autospec=True) async def test_send_keylist_query(self, mock_manager): self.request.json.return_value = {"filter": {"test": "filter"}} self.request.query = {"paginate_limit": 10, "paginate_offset": 20} - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object( - mock_manager.return_value, - "prepare_keylist_query", - mock.CoroutineMock(), - ) as mock_prepare_keylist_query, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object( + mock_manager.return_value, + "prepare_keylist_query", + mock.CoroutineMock(), + ) as mock_prepare_keylist_query, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): await test_module.send_keylist_query(self.request) mock_prepare_keylist_query.assert_called_once_with( filter_={"test": "filter"}, paginate_limit=10, paginate_offset=20 @@ -536,29 +613,36 @@ async def test_send_keylist_query(self, mock_manager): ) async def test_send_keylist_query_x_no_mediation_record(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), - ), self.assertRaises(test_module.web.HTTPNotFound): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), + self.assertRaises(test_module.web.HTTPNotFound), + ): await test_module.send_keylist_query(self.request) async def test_send_keylist_query_x_storage_error(self): - with mock.patch.object( - test_module.MediationRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), self.assertRaises(test_module.web.HTTPBadRequest): + with ( + mock.patch.object( + test_module.MediationRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + self.assertRaises(test_module.web.HTTPBadRequest), + ): await test_module.send_keylist_query(self.request) async def test_get_default_mediator(self): self.request.query = {} - with mock.patch.object( - test_module.web, "json_response" - ) as json_response, mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=self.mock_record), + with ( + mock.patch.object(test_module.web, "json_response") as json_response, + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=self.mock_record), + ), ): await test_module.get_default_mediator(self.request) json_response.assert_called_once_with( @@ -568,12 +652,13 @@ async def test_get_default_mediator(self): async def test_get_empty_default_mediator(self): self.request.query = {} - with mock.patch.object( - test_module.web, "json_response" - ) as json_response, mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=None), + with ( + mock.patch.object(test_module.web, "json_response") as json_response, + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=None), + ), ): await test_module.get_default_mediator(self.request) json_response.assert_called_once_with( @@ -583,10 +668,13 @@ async def test_get_empty_default_mediator(self): async def test_get_default_mediator_storage_error(self): self.request.query = {} - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(side_effect=test_module.StorageNotFoundError()), + ), ): with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.get_default_mediator(self.request) @@ -596,15 +684,19 @@ async def test_set_default_mediator(self): "mediation_id": "fake_id", } self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object( - test_module.MediationManager, - "set_default_mediator_by_id", - mock.CoroutineMock(), - ), mock.patch.object(test_module.web, "json_response") as json_response: + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object( + test_module.MediationManager, + "set_default_mediator_by_id", + mock.CoroutineMock(), + ), + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.set_default_mediator(self.request) json_response.assert_called_once_with( self.mock_record.serialize.return_value, @@ -616,29 +708,37 @@ async def test_set_default_mediator_storage_error(self): "mediation_id": "bad_id", } self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object( - test_module.MediationManager, - "set_default_mediator_by_id", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object( + test_module.MediationManager, + "set_default_mediator_by_id", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object(test_module.web, "json_response"), + ): with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.set_default_mediator(self.request) async def test_clear_default_mediator(self): self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(return_value=self.mock_record), - ), mock.patch.object( - test_module.MediationManager, - "clear_default_mediator", - mock.CoroutineMock(), - ), mock.patch.object(test_module.web, "json_response") as json_response: + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(return_value=self.mock_record), + ), + mock.patch.object( + test_module.MediationManager, + "clear_default_mediator", + mock.CoroutineMock(), + ), + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.clear_default_mediator(self.request) json_response.assert_called_once_with( self.mock_record.serialize.return_value, @@ -647,15 +747,19 @@ async def test_clear_default_mediator(self): async def test_clear_default_mediator_storage_error(self): self.request.query = {} - with mock.patch.object( - test_module.MediationManager, - "get_default_mediator", - mock.CoroutineMock(side_effect=test_module.StorageError()), - ), mock.patch.object( - test_module.MediationManager, - "clear_default_mediator", - mock.CoroutineMock(), - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.MediationManager, + "get_default_mediator", + mock.CoroutineMock(side_effect=test_module.StorageError()), + ), + mock.patch.object( + test_module.MediationManager, + "clear_default_mediator", + mock.CoroutineMock(), + ), + mock.patch.object(test_module.web, "json_response"), + ): with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.clear_default_mediator(self.request) @@ -673,9 +777,12 @@ async def test_update_keylist_for_connection(self): ) mock_route_manager.mediation_record_for_connection = mock.CoroutineMock() self.context.injector.bind_instance(RouteManager, mock_route_manager) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object(test_module.web, "json_response") as json_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module.web, "json_response") as json_response, + ): await test_module.update_keylist_for_connection(self.request) json_response.assert_called_once_with({"mock": "serialized"}, status=200) diff --git a/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py b/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py index b4bc7cd6d5..cf72da930e 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py @@ -92,9 +92,12 @@ async def test_receive_rotate_x(self): RotateProblemReport(problem_items=[{"did": test_to_did}]) ) - with mock.patch.object( - self.manager, "_ensure_supported_did", side_effect=test_problem_report - ), mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send: + with ( + mock.patch.object( + self.manager, "_ensure_supported_did", side_effect=test_problem_report + ), + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): await self.manager.receive_rotate( mock_conn_record, Rotate(to_did=test_to_did) ) diff --git a/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py b/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py index 57c8752e23..5dae863727 100644 --- a/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/didexchange/v1_0/tests/test_manager.py @@ -174,13 +174,15 @@ async def test_receive_invitation(self): ) await mediation_record.save(session) - with mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator, mock.patch.object( - AdminResponder, "send_reply" - ) as mock_send_reply: + with ( + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + mock.patch.object(AdminResponder, "send_reply") as mock_send_reply, + ): mock_get_default_mediator.return_value = mediation_record invi_rec = await self.oob_manager.create_invitation( my_endpoint="testendpoint", @@ -206,15 +208,18 @@ async def test_receive_invitation_oob_public_did(self): ED25519, ) public_did_info = await wallet.get_public_did() - with mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator, mock.patch.object( - self.manager, "resolve_connection_targets", mock.CoroutineMock() - ) as mock_resolve_targets, mock.patch.object( - AdminResponder, "send_reply" - ) as mock_send_reply: + with ( + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + mock.patch.object( + self.manager, "resolve_connection_targets", mock.CoroutineMock() + ) as mock_resolve_targets, + mock.patch.object(AdminResponder, "send_reply") as mock_send_reply, + ): mock_resolve_targets.return_value = [ mock.MagicMock(recipient_keys=["test"]) ] @@ -289,11 +294,14 @@ async def test_create_request_implicit(self): ) await mediation_record.save(session) - with mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator: + with ( + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + ): mock_get_default_mediator.return_value = mediation_record mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) @@ -370,8 +378,11 @@ async def test_create_request_implicit_x_public_already_connected(self): SOV, ED25519, ) - with self.assertRaises(DIDXManagerError) as context, mock.patch.object( - test_module.ConnRecord, "retrieve_by_did", mock.CoroutineMock() + with ( + self.assertRaises(DIDXManagerError) as context, + mock.patch.object( + test_module.ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ), ): await self.manager.create_request_implicit( their_public_did=TestConfig.test_target_did, @@ -414,13 +425,17 @@ async def test_create_request_multitenant(self): {"multitenant.enabled": True, "wallet.id": "test_wallet"} ) - with mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did, mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco: + with ( + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + ): mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) ) @@ -625,24 +640,35 @@ async def test_receive_request_explicit_public_did(self): STATE_REQUEST = ConnRecord.State.REQUEST self.profile.context.update_settings({"public_invites": True}) ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ) as mock_response, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - MediationManager, "prepare_request", autospec=True - ) as mock_mediation_mgr_prep_req, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + test_module, "DIDXResponse", autospec=True + ) as mock_response, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + MediationManager, "prepare_request", autospec=True + ) as mock_mediation_mgr_prep_req, + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) @@ -760,27 +786,36 @@ async def test_receive_request_public_did_no_did_doc_attachment(self): STATE_REQUEST = ConnRecord.State.REQUEST self.profile.context.update_settings({"public_invites": True}) ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ) as mock_response, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value=DIDDoc(TestConfig.test_did)), - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - self.manager, - "record_keys_for_resolvable_did", - mock.CoroutineMock(), - ), mock.patch.object( - MediationManager, "prepare_request", autospec=True - ) as mock_mediation_mgr_prep_req: + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + test_module, "DIDXResponse", autospec=True + ) as mock_response, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock(return_value=DIDDoc(TestConfig.test_did)), + ), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + self.manager, + "record_keys_for_resolvable_did", + mock.CoroutineMock(), + ), + mock.patch.object( + MediationManager, "prepare_request", autospec=True + ) as mock_mediation_mgr_prep_req, + ): mock_create_did_doc.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={}) ) @@ -856,11 +891,14 @@ async def test_receive_request_public_did_no_did_doc_attachment_no_did(self): STATE_REQUEST = ConnRecord.State.REQUEST self.profile.context.update_settings({"public_invites": True}) ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture: + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + ): mock_conn_record = mock.MagicMock( accept=ACCEPT_AUTO, my_did=None, @@ -964,16 +1002,21 @@ async def test_receive_request_public_did_x_wrong_did(self): self.profile.context.update_settings({"public_invites": True}) mock_conn_rec_state_request = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "LjgpST2rjsoxYegQDRm7EL"}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock(return_value={"id": "LjgpST2rjsoxYegQDRm7EL"}), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_record = mock.MagicMock( accept=ConnRecord.ACCEPT_MANUAL, @@ -1028,14 +1071,18 @@ async def test_receive_request_public_did_x_did_doc_attach_bad_sig(self): self.profile.context.update_settings({"public_invites": True}) mock_conn_rec_state_request = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(side_effect=DIDXManagerError), + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock(side_effect=DIDXManagerError), + ), ): mock_conn_record = mock.MagicMock( accept=ConnRecord.ACCEPT_MANUAL, @@ -1088,14 +1135,13 @@ async def test_receive_request_public_did_no_public_invites(self): ) self.profile.context.update_settings({"public_invites": False}) - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ), mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() + with ( + mock.patch.object(test_module, "ConnRecord", mock.MagicMock()), + mock.patch.object(test_module, "AttachDecorator", autospec=True), + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ), ): with self.assertRaises(DIDXManagerError) as context: await self.manager.receive_request( @@ -1133,22 +1179,28 @@ async def test_receive_request_public_did_no_auto_accept(self): {"public_invites": True, "debug.auto_accept_requests": False} ) mock_conn_rec_state_request = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ), mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ), mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object(test_module, "AttachDecorator", autospec=True), + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ), + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_record = mock.MagicMock( accept=ConnRecord.ACCEPT_MANUAL, @@ -1213,16 +1265,23 @@ async def test_receive_request_implicit_public_did_not_enabled(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_did_posture.get = mock.MagicMock( return_value=test_module.DIDPosture.PUBLIC @@ -1279,16 +1338,23 @@ async def test_receive_request_implicit_public_did(self): ACCEPT_AUTO = ConnRecord.ACCEPT_AUTO STATE_REQUEST = ConnRecord.State.REQUEST - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "DIDPosture", autospec=True - ) as mock_did_posture, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "DIDPosture", autospec=True + ) as mock_did_posture, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_did_posture.get = mock.MagicMock( return_value=test_module.DIDPosture.PUBLIC @@ -1363,18 +1429,26 @@ async def test_receive_request_peer_did(self): ) self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - test_module, "ConnRecord", mock.MagicMock() - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ) as mock_response, mock.patch.object( - self.manager, - "verify_diddoc", - mock.CoroutineMock(return_value={"id": "did:sov:" + TestConfig.test_did}), - ), mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "ConnRecord", mock.MagicMock() + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + test_module, "DIDXResponse", autospec=True + ) as mock_response, + mock.patch.object( + self.manager, + "verify_diddoc", + mock.CoroutineMock( + return_value={"id": "did:sov:" + TestConfig.test_did} + ), + ), + mock.patch.object( + self.manager, "store_did_document", mock.CoroutineMock() + ), ): mock_conn_rec_cls.retrieve_by_invitation_msg_id = mock.CoroutineMock( return_value=mock_conn @@ -1451,15 +1525,19 @@ async def test_receive_request_peer_did_not_found_x(self): async def test_create_response(self): conn_rec = ConnRecord(connection_id="dummy", state=ConnRecord.State.REQUEST.rfc23) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + ): mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( @@ -1499,15 +1577,17 @@ async def test_create_response_mediation_id(self): await record.save(session) await record.attach_invitation(session, invi) - with mock.patch.object( - ConnRecord, "log_state", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - record, "metadata_get", mock.CoroutineMock(return_value=False) - ), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco: + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + record, "metadata_get", mock.CoroutineMock(return_value=False) + ), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + ): mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( data=mock.MagicMock(sign=mock.CoroutineMock()) @@ -1548,12 +1628,13 @@ async def test_create_response_mediation_id_invalid_conn_state(self): await record.save(session) await record.attach_invitation(session, invi) - with mock.patch.object( - ConnRecord, "log_state", autospec=True - ), mock.patch.object( - ConnRecord, "retrieve_request", autospec=True - ), mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - record, "metadata_get", mock.CoroutineMock(return_value=False) + with ( + mock.patch.object(ConnRecord, "log_state", autospec=True), + mock.patch.object(ConnRecord, "retrieve_request", autospec=True), + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + record, "metadata_get", mock.CoroutineMock(return_value=False) + ), ): with self.assertRaises(DIDXManagerError) as context: await self.manager.create_response( @@ -1571,15 +1652,19 @@ async def test_create_response_multitenant(self): } ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request" - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - AskarWallet, "create_local_did", autospec=True - ) as mock_wallet_create_local_did: + with ( + mock.patch.object(test_module.ConnRecord, "retrieve_request"), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + AskarWallet, "create_local_did", autospec=True + ) as mock_wallet_create_local_did, + ): mock_wallet_create_local_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -1604,17 +1689,22 @@ async def test_create_response_conn_rec_my_did(self): state=ConnRecord.State.REQUEST.rfc23, ) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc, mock.patch.object( - AskarWallet, "get_local_did", mock.CoroutineMock() - ) as mock_get_loc_did: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + mock.patch.object( + AskarWallet, "get_local_did", mock.CoroutineMock() + ) as mock_get_loc_did, + ): mock_get_loc_did.return_value = self.did_info mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( @@ -1635,11 +1725,15 @@ async def test_create_response_inkind_peer_did_2(self): self.profile.context.update_settings({"emit_did_peer_2": False}) - with mock.patch.object( - self.manager, "create_did_peer_2", mock.CoroutineMock() - ) as mock_create_did_peer_2, mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + self.manager, "create_did_peer_2", mock.CoroutineMock() + ) as mock_create_did_peer_2, + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + ): mock_create_did_peer_2.return_value = DIDInfo( TestConfig.test_did_peer_2, TestConfig.test_verkey, @@ -1663,11 +1757,15 @@ async def test_create_response_inkind_peer_did_4(self): self.profile.context.update_settings({"emit_did_peer_4": False}) - with mock.patch.object( - self.manager, "create_did_peer_4", mock.CoroutineMock() - ) as mock_create_did_peer_4, mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + self.manager, "create_did_peer_4", mock.CoroutineMock() + ) as mock_create_did_peer_4, + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + ): mock_create_did_peer_4.return_value = DIDInfo( TestConfig.test_did_peer_4, TestConfig.test_verkey, @@ -1691,11 +1789,15 @@ async def test_create_response_peer_1_gets_peer_4(self): self.profile.context.update_settings({"emit_did_peer_4": False}) - with mock.patch.object( - self.manager, "create_did_peer_4", mock.CoroutineMock() - ) as mock_create_did_peer_4, mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()): + with ( + mock.patch.object( + self.manager, "create_did_peer_4", mock.CoroutineMock() + ) as mock_create_did_peer_4, + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + ): mock_create_did_peer_4.return_value = DIDInfo( TestConfig.test_did_peer_4, TestConfig.test_verkey, @@ -1731,15 +1833,19 @@ async def test_create_response_use_public_did(self): conn_rec = ConnRecord(connection_id="dummy", state=ConnRecord.State.REQUEST.rfc23) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + ): mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( @@ -1754,15 +1860,19 @@ async def test_create_response_use_public_did(self): async def test_create_response_use_public_did_x_no_public_did(self): conn_rec = ConnRecord(connection_id="dummy", state=ConnRecord.State.REQUEST.rfc23) - with mock.patch.object( - test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() - ), mock.patch.object(conn_rec, "save", mock.CoroutineMock()), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_deco, mock.patch.object( - test_module, "DIDXResponse", autospec=True - ), mock.patch.object( - self.manager, "create_did_document", mock.CoroutineMock() - ) as mock_create_did_doc: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_request", mock.CoroutineMock() + ), + mock.patch.object(conn_rec, "save", mock.CoroutineMock()), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_deco, + mock.patch.object(test_module, "DIDXResponse", autospec=True), + mock.patch.object( + self.manager, "create_did_document", mock.CoroutineMock() + ) as mock_create_did_doc, + ): mock_create_did_doc.return_value = mock.MagicMock(serialize=mock.MagicMock()) mock_attach_deco.data_base64 = mock.MagicMock( return_value=mock.MagicMock( @@ -1798,12 +1908,15 @@ async def test_accept_response_find_by_thread_id(self): recipient_did_public=True, ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=TestConfig.test_target_did, @@ -1856,14 +1969,18 @@ async def test_accept_response_find_by_thread_id_auto_disclose_features(self): ) self.context.update_settings({"auto_disclose_features": True}) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=TestConfig.test_target_did, @@ -1912,12 +2029,15 @@ async def test_accept_response_not_found_by_thread_id_receipt_has_sender_did(sel receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.return_value = mock.MagicMock( @@ -1958,11 +2078,15 @@ async def test_accept_response_not_found_by_thread_id_nor_receipt_sender_did(sel receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_did", mock.CoroutineMock() - ) as mock_conn_retrieve_by_did: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_did", mock.CoroutineMock() + ) as mock_conn_retrieve_by_did, + ): mock_conn_retrieve_by_req_id.side_effect = StorageNotFoundError() mock_conn_retrieve_by_did.side_effect = StorageNotFoundError() @@ -1984,9 +2108,12 @@ async def test_accept_response_find_by_thread_id_bad_state(self): receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id: + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( state=ConnRecord.State.ABANDONED.rfc23 ) @@ -2007,14 +2134,20 @@ async def test_accept_response_find_by_thread_id_no_did_doc_attached(self): recipient_did_public=True, ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - DIDDoc, "deserialize", mock.MagicMock() - ) as mock_did_doc_deser, mock.patch.object( - self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object( + DIDDoc, "deserialize", mock.MagicMock() + ) as mock_did_doc_deser, + mock.patch.object( + self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + ), ): mock_did_doc_deser.return_value = mock.MagicMock( did=TestConfig.test_target_did @@ -2047,14 +2180,20 @@ async def test_accept_response_find_by_thread_id_no_did_doc_attached_no_did(self recipient_did_public=True, ) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - DIDDoc, "deserialize", mock.MagicMock() - ) as mock_did_doc_deser, mock.patch.object( - self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object( + DIDDoc, "deserialize", mock.MagicMock() + ) as mock_did_doc_deser, + mock.patch.object( + self.manager, "record_keys_for_resolvable_did", mock.CoroutineMock() + ), ): mock_did_doc_deser.return_value = mock.MagicMock( did=TestConfig.test_target_did @@ -2092,12 +2231,15 @@ async def test_accept_response_find_by_thread_id_did_mismatch(self): receipt = MessageReceipt(sender_did=TestConfig.test_target_did) - with mock.patch.object(ConnRecord, "save", autospec=True), mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id, mock.patch.object( - self.manager, "store_did_document", mock.CoroutineMock() + with ( + mock.patch.object(ConnRecord, "save", autospec=True), + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + mock.patch.object(self.manager, "store_did_document", mock.CoroutineMock()), ): mock_conn_retrieve_by_req_id.return_value = mock.MagicMock( did=TestConfig.test_target_did, @@ -2139,11 +2281,14 @@ async def test_accept_complete_with_disclose(self): mock_complete = mock.MagicMock() receipt = MessageReceipt(sender_did=TestConfig.test_target_did) self.context.update_settings({"auto_disclose_features": True}) - with mock.patch.object( - ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_req_id, mock.patch.object( - V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() - ) as mock_proactive_disclose_features: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_request_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_req_id, + mock.patch.object( + V20DiscoveryMgr, "proactive_disclose_features", mock.CoroutineMock() + ) as mock_proactive_disclose_features, + ): mock_conn_retrieve_by_req_id.return_value.save = mock.CoroutineMock() mock_conn_retrieve_by_req_id.return_value.my_did = None mock_conn_retrieve_by_req_id.return_value.their_did = None diff --git a/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py b/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py index 20b0eace36..81be5fda3d 100644 --- a/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/didexchange/v1_0/tests/test_routes.py @@ -43,13 +43,13 @@ async def test_didx_accept_invitation(self): mock_conn_rec = mock.MagicMock(save=mock.CoroutineMock()) mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_class, mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_class, + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_class.retrieve_by_id.return_value = mock_conn_rec mock_didx_mgr.return_value.create_request = mock.CoroutineMock() @@ -70,9 +70,12 @@ async def test_didx_accept_invitation_not_found(self): async def test_didx_accept_invitation_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + ): mock_didx_mgr.return_value.create_request = mock.CoroutineMock( side_effect=test_module.DIDXManagerError() ) @@ -88,11 +91,10 @@ async def test_didx_create_request_implicit(self): "mediator_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", } - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_didx_mgr.return_value.create_request_implicit = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(return_value="mock serialization") @@ -111,9 +113,10 @@ async def test_didx_create_request_implicit_not_found_x(self): "auto_accept": "true", } - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.create_request_implicit = mock.CoroutineMock( side_effect=StorageNotFoundError("not found") ) @@ -130,9 +133,10 @@ async def test_didx_create_request_implicit_wallet_x(self): "auto_accept": "true", } - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.create_request_implicit = mock.CoroutineMock( side_effect=test_module.WalletError("wallet error") ) @@ -152,13 +156,11 @@ async def test_didx_receive_request_implicit(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.DIDXRequest, "deserialize", mock.MagicMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module.DIDXRequest, "deserialize", mock.MagicMock()), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_didx_mgr.return_value.receive_request = mock.CoroutineMock( return_value=mock_conn_rec ) @@ -174,11 +176,11 @@ async def test_didx_receive_request_implicit_not_found_x(self): self.request._thread.pthid = "did:sov:0000000000000000000000" self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module.DIDXRequest, "deserialize", mock.MagicMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module.DIDXRequest, "deserialize", mock.MagicMock()), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.receive_request = mock.CoroutineMock( side_effect=StorageNotFoundError("tricorder must be broken") ) @@ -195,11 +197,13 @@ async def test_didx_receive_request_implicit_bad_request_x(self): self.request._thread.pthid = "did:sov:0000000000000000000000" self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module.DIDXRequest, "deserialize", mock.MagicMock() - ) as mock_didx_req_deser, mock.patch.object( - test_module, "DIDXManager", autospec=True - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.DIDXRequest, "deserialize", mock.MagicMock() + ) as mock_didx_req_deser, + mock.patch.object(test_module, "DIDXManager", autospec=True), + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_req_deser.side_effect = test_module.BaseModelError("bad bits") with self.assertRaises(test_module.web.HTTPBadRequest) as context: await test_module.didx_receive_request_implicit(self.request) @@ -214,13 +218,13 @@ async def test_didx_accept_request(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve_by_id, mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve_by_id, + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve_by_id.return_value = mock_conn_rec mock_didx_mgr.return_value.create_response = mock.CoroutineMock() @@ -241,11 +245,13 @@ async def test_didx_accept_request_not_found(self): async def test_didx_accept_request_x(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.create_response = mock.CoroutineMock( side_effect=test_module.DIDXManagerError() ) @@ -257,11 +263,13 @@ async def test_didx_reject(self): self.request.match_info = {"conn_id": "dummy"} self.request.json = mock.CoroutineMock(return_value={"reason": "asdf"}) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.reject = mock.CoroutineMock() await test_module.didx_reject(self.request) @@ -282,11 +290,13 @@ async def test_didx_reject_x_bad_conn_state(self): self.request.match_info = {"conn_id": "dummy"} self.request.json = mock.CoroutineMock(return_value={"reason": "asdf"}) - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ), mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as mock_didx_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ), + mock.patch.object(test_module, "DIDXManager", autospec=True) as mock_didx_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_didx_mgr.return_value.reject = mock.CoroutineMock( side_effect=test_module.DIDXManagerError() ) diff --git a/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py b/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py index efb99110cb..9e428c958a 100644 --- a/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py +++ b/acapy_agent/protocols/discovery/v1_0/handlers/tests/test_query_handler.py @@ -69,11 +69,14 @@ async def test_receive_query_process_disclosed(self, request_context): request_context.connection_ready = True handler = QueryHandler() responder = MockResponder() - with mock.patch.object( - ProtocolRegistry, "protocols_matching_query", mock.MagicMock() - ), mock.patch.object( - ProtocolRegistry, "prepare_disclosed", mock.CoroutineMock() - ) as mock_prepare_disclosed: + with ( + mock.patch.object( + ProtocolRegistry, "protocols_matching_query", mock.MagicMock() + ), + mock.patch.object( + ProtocolRegistry, "prepare_disclosed", mock.CoroutineMock() + ) as mock_prepare_disclosed, + ): mock_prepare_disclosed.return_value = [ {"test": "test"}, { diff --git a/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py b/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py index 88ccfcecde..134b7a736b 100644 --- a/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/discovery/v1_0/tests/test_manager.py @@ -43,11 +43,14 @@ async def asyncSetUp(self): async def test_receive_disclosure(self): test_conn_id = "test123" self.disclose.assign_thread_id("test123") - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + ): mock_retrieve.return_value = TEST_DISCOVERY_EX_REC ex_rec = await self.manager.receive_disclose( disclose_msg=self.disclose, connection_id=test_conn_id @@ -62,19 +65,24 @@ async def test_receive_disclosure(self): async def test_receive_disclosure_retrieve_by_conn(self): test_conn_id = "test123" self.disclose.assign_thread_id("test123") - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = TEST_DISCOVERY_EX_REC @@ -91,15 +99,19 @@ async def test_receive_disclosure_retrieve_by_conn(self): async def test_receive_disclosure_retrieve_by_conn_not_found(self): test_conn_id = "test123" self.disclose.assign_thread_id("test123") - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -114,15 +126,19 @@ async def test_receive_disclosure_retrieve_by_conn_not_found(self): async def test_receive_disclosure_retrieve_new_ex_rec(self): test_conn_id = "test123" - with mock.patch.object( - V10DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -148,23 +164,27 @@ async def test_check_if_disclosure_received(self): async def test_create_and_send_query_with_connection(self): return_ex_rec = V10DiscoveryExchangeRecord(query_msg=Query(query="*")) - with mock.patch.object( - V10DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V10DiscoveryExchangeRecord, - "save", - mock.CoroutineMock(), - ), mock.patch.object( - V10DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() - ) as mock_disclosure_received, mock.patch.object( - self.responder, "send", mock.CoroutineMock() - ) as mock_send: + with ( + mock.patch.object( + V10DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V10DiscoveryExchangeRecord, + "save", + mock.CoroutineMock(), + ), + mock.patch.object( + V10DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() + ) as mock_disclosure_received, + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = V10DiscoveryExchangeRecord() mock_disclosure_received.return_value = return_ex_rec diff --git a/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py b/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py index d644c0bfce..3269bbafe2 100644 --- a/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/discovery/v1_0/tests/test_routes.py @@ -40,11 +40,12 @@ async def test_query_features(self): discovery_exchange_id="3fa85f64-5717-4562-b3fc-2c963f66afa6", query_msg=Query(query="*"), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V10DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V10DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -59,11 +60,12 @@ async def test_query_features_with_connection(self): query_msg=Query(query="*"), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V10DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V10DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -78,11 +80,12 @@ async def test_query_records(self): query_msg=Query(query="*"), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.return_value = test_rec await test_module.query_records(self.request) mock_response.assert_called_once_with({"results": [test_rec.serialize()]}) @@ -92,9 +95,12 @@ async def test_query_records_x(self): self.request.query = {"connection_id": "test"} - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) @@ -113,11 +119,12 @@ async def test_query_records_all(self): ), ] - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.return_value = test_recs await test_module.query_records(self.request) mock_response.assert_called_once_with( @@ -127,9 +134,12 @@ async def test_query_records_all(self): async def test_query_records_connection_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V10DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V10DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) diff --git a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py index 0405014557..11bf227dae 100644 --- a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py +++ b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_disclosures_handler.py @@ -94,14 +94,17 @@ async def test_disclosures_connection_id_no_thid(self, request_context): handler = DisclosuresHandler() mock_responder = MockResponder() - with mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=StorageNotFoundError), - ), mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(return_value=discovery_record), + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(return_value=discovery_record), + ), ): await handler.handle(request_context, mock_responder) assert not mock_responder.messages @@ -127,14 +130,17 @@ async def test_disclosures_no_conn_id_no_thid(self, request_context): handler = DisclosuresHandler() mock_responder = MockResponder() - with mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_id", - mock.CoroutineMock(side_effect=StorageNotFoundError), - ), mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(side_effect=StorageNotFoundError), + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_id", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), ): await handler.handle(request_context, mock_responder) assert not mock_responder.messages diff --git a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py index adf63001da..b988702070 100644 --- a/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py +++ b/acapy_agent/protocols/discovery/v2_0/handlers/tests/test_queries_handler.py @@ -134,11 +134,14 @@ async def test_receive_query_process_disclosed(self, request_context): request_context.connection_ready = True handler = QueriesHandler() responder = MockResponder() - with mock.patch.object( - V20DiscoveryMgr, "execute_protocol_query", mock.CoroutineMock() - ) as mock_exec_protocol_query, mock.patch.object( - V20DiscoveryMgr, "execute_goal_code_query", mock.CoroutineMock() - ) as mock_goal_code_protocol_query: + with ( + mock.patch.object( + V20DiscoveryMgr, "execute_protocol_query", mock.CoroutineMock() + ) as mock_exec_protocol_query, + mock.patch.object( + V20DiscoveryMgr, "execute_goal_code_query", mock.CoroutineMock() + ) as mock_goal_code_protocol_query, + ): mock_exec_protocol_query.return_value = [ {"test": "test"}, { diff --git a/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py b/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py index 3778d0784e..0473161c73 100644 --- a/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py +++ b/acapy_agent/protocols/discovery/v2_0/tests/test_manager.py @@ -52,11 +52,14 @@ async def asyncSetUp(self): async def test_receive_disclosure(self): test_conn_id = "test123" self.queries.assign_thread_id("test123") - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + ): mock_retrieve.return_value = TEST_DISCOVERY_EX_REC ex_rec = await self.manager.receive_disclose( disclose_msg=self.disclosures, connection_id=test_conn_id @@ -71,19 +74,24 @@ async def test_receive_disclosure(self): async def test_receive_disclosure_retrieve_by_conn(self): test_conn_id = "test123" self.queries.assign_thread_id("test123") - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = TEST_DISCOVERY_EX_REC @@ -100,15 +108,19 @@ async def test_receive_disclosure_retrieve_by_conn(self): async def test_receive_disclosure_retrieve_by_conn_not_found(self): test_conn_id = "test123" self.queries.assign_thread_id("test123") - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", autospec=True + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -123,15 +135,19 @@ async def test_receive_disclosure_retrieve_by_conn_not_found(self): async def test_receive_disclosure_retrieve_new_ex_rec(self): test_conn_id = "test123" - with mock.patch.object( - V20DiscoveryExchangeRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_by_id: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, "save", autospec=True + ) as save_ex, + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_by_id, + ): mock_retrieve_by_id.side_effect = StorageNotFoundError mock_exists_for_connection_id.return_value = False ex_rec = await self.manager.receive_disclose( @@ -144,25 +160,27 @@ async def test_receive_disclosure_retrieve_new_ex_rec(self): ) async def test_proactive_disclosure(self): - with mock.patch.object( - V20DiscoveryMgr, - "receive_query", - mock.CoroutineMock(), - ) as mock_receive_query, mock.patch.object( - self.responder, "send", mock.CoroutineMock() - ) as mock_send: + with ( + mock.patch.object( + V20DiscoveryMgr, + "receive_query", + mock.CoroutineMock(), + ) as mock_receive_query, + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): mock_receive_query.return_value = Disclosures() await self.manager.proactive_disclose_features("test123") mock_send.assert_called_once() async def test_proactive_disclosure_no_responder(self): self.profile.context.injector.clear_binding(BaseResponder) - with mock.patch.object( - V20DiscoveryMgr, - "receive_query", - mock.CoroutineMock(), - ) as mock_receive_query, mock.patch.object( - self.responder, "send", mock.CoroutineMock() + with ( + mock.patch.object( + V20DiscoveryMgr, + "receive_query", + mock.CoroutineMock(), + ) as mock_receive_query, + mock.patch.object(self.responder, "send", mock.CoroutineMock()), ): self._caplog.set_level(logging.WARNING) mock_receive_query.return_value = Disclosures() @@ -195,23 +213,27 @@ async def test_create_and_send_query_with_connection(self): ] ) ) - with mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "retrieve_by_connection_id", - mock.CoroutineMock(), - ) as mock_retrieve_by_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "save", - mock.CoroutineMock(), - ), mock.patch.object( - V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() - ) as mock_disclosure_received, mock.patch.object( - self.responder, "send", mock.CoroutineMock() - ) as mock_send: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "retrieve_by_connection_id", + mock.CoroutineMock(), + ) as mock_retrieve_by_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "save", + mock.CoroutineMock(), + ), + mock.patch.object( + V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() + ) as mock_disclosure_received, + mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, + ): mock_exists_for_connection_id.return_value = True mock_retrieve_by_connection_id.return_value = V20DiscoveryExchangeRecord() mock_disclosure_received.return_value = return_ex_rec @@ -223,17 +245,21 @@ async def test_create_and_send_query_with_connection(self): async def test_create_and_send_query_with_connection_no_responder(self): self.profile.context.injector.clear_binding(BaseResponder) - with mock.patch.object( - V20DiscoveryExchangeRecord, - "exists_for_connection_id", - mock.CoroutineMock(), - ) as mock_exists_for_connection_id, mock.patch.object( - V20DiscoveryExchangeRecord, - "save", - mock.CoroutineMock(), - ), mock.patch.object( - V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() - ) as mock_disclosure_received: + with ( + mock.patch.object( + V20DiscoveryExchangeRecord, + "exists_for_connection_id", + mock.CoroutineMock(), + ) as mock_exists_for_connection_id, + mock.patch.object( + V20DiscoveryExchangeRecord, + "save", + mock.CoroutineMock(), + ), + mock.patch.object( + V20DiscoveryMgr, "check_if_disclosure_received", mock.CoroutineMock() + ) as mock_disclosure_received, + ): self._caplog.set_level(logging.WARNING) mock_exists_for_connection_id.return_value = False mock_disclosure_received.side_effect = asyncio.TimeoutError diff --git a/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py b/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py index 464916b963..dc06abcb00 100644 --- a/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/discovery/v2_0/tests/test_routes.py @@ -46,11 +46,12 @@ async def test_query_features(self): ), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V20DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -74,11 +75,12 @@ async def test_query_features_with_connection(self): ), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20DiscoveryMgr, "create_and_send_query", autospec=True - ) as mock_create_query: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + V20DiscoveryMgr, "create_and_send_query", autospec=True + ) as mock_create_query, + ): mock_create_query.return_value = test_rec await test_module.query_features(self.request) mock_response.assert_called_once_with(test_rec.serialize()) @@ -98,11 +100,12 @@ async def test_query_records(self): ), ) - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.return_value = test_rec await test_module.query_records(self.request) mock_response.assert_called_once_with({"results": [test_rec.serialize()]}) @@ -112,9 +115,12 @@ async def test_query_records_x(self): self.request.query = {"connection_id": "test"} - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.retrieve_by_connection_id.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) @@ -143,11 +149,12 @@ async def test_query_records_all(self): ), ] - with mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.return_value = test_recs await test_module.query_records(self.request) mock_response.assert_called_once_with( @@ -157,9 +164,12 @@ async def test_query_records_all(self): async def test_query_records_connection_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object(test_module.web, "json_response"), mock.patch.object( - test_module, "V20DiscoveryExchangeRecord", autospec=True - ) as mock_ex_rec: + with ( + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, "V20DiscoveryExchangeRecord", autospec=True + ) as mock_ex_rec, + ): mock_ex_rec.query.side_effect = StorageError with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.query_records(self.request) diff --git a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py index 6519e9b27e..d333948eda 100644 --- a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_manager.py @@ -476,11 +476,10 @@ async def test_complete_transaction(self): ) ) - with mock.patch.object( - TransactionRecord, "save", autospec=True - ) as save_record, mock.patch.object( - ConnRecord, "retrieve_by_id" - ) as mock_conn_rec_retrieve: + with ( + mock.patch.object(TransactionRecord, "save", autospec=True) as save_record, + mock.patch.object(ConnRecord, "retrieve_by_id") as mock_conn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -534,11 +533,10 @@ async def test_complete_transaction_anoncreds( ) self.ledger.get_indy_storage = future - with mock.patch.object( - TransactionRecord, "save", autospec=True - ) as save_record, mock.patch.object( - ConnRecord, "retrieve_by_id" - ) as mock_conn_rec_retrieve: + with ( + mock.patch.object(TransactionRecord, "save", autospec=True) as save_record, + mock.patch.object(ConnRecord, "retrieve_by_id") as mock_conn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ diff --git a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py index 66bf109838..65dd81e8c7 100644 --- a/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/endorse_transaction/v1_0/tests/test_routes.py @@ -62,11 +62,12 @@ async def asyncSetUp(self): self.test_did = "sample-did" async def test_transactions_list(self): - with mock.patch.object( - TransactionRecord, "query", mock.CoroutineMock() - ) as mock_query, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + TransactionRecord, "query", mock.CoroutineMock() + ) as mock_query, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_query.return_value = [ mock.MagicMock(serialize=mock.MagicMock(return_value={"...": "..."})) ] @@ -75,9 +76,12 @@ async def test_transactions_list(self): mock_response.assert_called_once_with({"results": [{"...": "..."}]}) async def test_transactions_list_x(self): - with mock.patch.object( - TransactionRecord, "query", mock.CoroutineMock() - ) as mock_query, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + TransactionRecord, "query", mock.CoroutineMock() + ) as mock_query, + mock.patch.object(test_module.web, "json_response"), + ): mock_query.side_effect = test_module.StorageError() with self.assertRaises(test_module.web.HTTPBadRequest): @@ -86,11 +90,12 @@ async def test_transactions_list_x(self): async def test_transactions_retrieve(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) ) @@ -129,15 +134,18 @@ async def test_transaction_create_request(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -193,11 +201,14 @@ async def test_transaction_create_request_base_model_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -224,13 +235,17 @@ async def test_transaction_create_request_no_jobs_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -260,13 +275,17 @@ async def test_transaction_create_request_no_my_job_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -302,13 +321,17 @@ async def test_transaction_create_request_no_their_job_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( return_value=( @@ -344,11 +367,14 @@ async def test_transaction_create_request_my_wrong_job_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -375,13 +401,17 @@ async def test_transaction_create_request_mgr_create_request_x(self): "expires_time": "2021-03-29T05:22:19Z", } ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_request=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -423,15 +453,18 @@ async def test_endorse_transaction_response(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( return_value=( @@ -523,11 +556,14 @@ async def test_endorse_transaction_response_base_model_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -554,11 +590,14 @@ async def test_endorse_transaction_response_no_jobs_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -588,13 +627,17 @@ async def test_endorse_transaction_response_no_ledger_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( return_value=( @@ -639,11 +682,14 @@ async def test_endorse_transaction_response_wrong_my_job_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -682,13 +728,17 @@ async def test_endorse_transaction_response_ledger_x(self): side_effect=test_module.LedgerError() ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( return_value=( @@ -733,13 +783,18 @@ async def test_endorse_transaction_response_txn_mgr_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( create_endorse_response=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -779,15 +834,18 @@ async def test_refuse_transaction_response(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( create_refuse_response=mock.CoroutineMock( return_value=( @@ -859,11 +917,14 @@ async def test_refuse_transaction_response_conn_base_model_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -890,11 +951,14 @@ async def test_refuse_transaction_response_no_jobs_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -923,11 +987,14 @@ async def test_refuse_transaction_response_wrong_my_job_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -962,13 +1029,18 @@ async def test_refuse_transaction_response_txn_mgr_x(self): ), ) - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( create_refuse_response=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -993,15 +1065,18 @@ async def test_refuse_transaction_response_txn_mgr_x(self): async def test_cancel_transaction(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( cancel_transaction=mock.CoroutineMock( return_value=( @@ -1043,11 +1118,14 @@ async def test_cancel_transaction_not_found_x(self): async def test_cancel_transaction_conn_rec_base_model_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -1059,11 +1137,14 @@ async def test_cancel_transaction_conn_rec_base_model_x(self): async def test_cancel_transaction_no_jobs_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -1077,11 +1158,14 @@ async def test_cancel_transaction_no_jobs_x(self): async def test_cancel_transaction_wrong_my_job_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -1101,13 +1185,18 @@ async def test_cancel_transaction_wrong_my_job_x(self): async def test_cancel_transaction_txn_mgr_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( cancel_transaction=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -1132,15 +1221,18 @@ async def test_cancel_transaction_txn_mgr_x(self): async def test_transaction_resend(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( transaction_resend=mock.CoroutineMock( return_value=( @@ -1182,11 +1274,14 @@ async def test_transaction_resend_not_found_x(self): async def test_transaction_resend_conn_rec_base_model_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.side_effect = test_module.BaseModelError() mock_txn_rec_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value={"...": "..."}) @@ -1198,11 +1293,14 @@ async def test_transaction_resend_conn_rec_base_model_x(self): async def test_transaction_resend_no_jobs_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock(return_value=None) ) @@ -1216,11 +1314,14 @@ async def test_transaction_resend_no_jobs_x(self): async def test_transaction_resend_my_wrong_job_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -1241,13 +1342,18 @@ async def test_transaction_resend_my_wrong_job_x(self): async def test_transaction_resend_txn_mgr_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_txn_mgr.return_value = mock.MagicMock( transaction_resend=mock.CoroutineMock( side_effect=test_module.TransactionManagerError() @@ -1272,13 +1378,15 @@ async def test_transaction_resend_txn_mgr_x(self): async def test_set_endorser_role(self): self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value = mock.MagicMock( set_transaction_my_job=mock.CoroutineMock() ) @@ -1322,11 +1430,12 @@ async def test_set_endorser_role_base_model_x(self): async def test_set_endorser_info(self): self.request.match_info = {"conn_id": "dummy"} self.request.query = {"endorser_did": "did", "endorser_name": "name"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( return_value={ @@ -1354,11 +1463,12 @@ async def test_set_endorser_info(self): async def test_set_endorser_info_no_prior_value(self): self.request.match_info = {"conn_id": "dummy"} self.request.query = {"endorser_did": "did", "endorser_name": "name"} - with mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_rec_retrieve, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_rec_retrieve, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_conn_rec_retrieve.return_value = mock.MagicMock( metadata_get=mock.CoroutineMock( side_effect=[ @@ -1466,13 +1576,15 @@ async def test_set_endorser_info_my_wrong_job_x(self): async def test_transaction_write_schema_txn(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_txn_mgr.return_value.complete_transaction = mock.CoroutineMock() mock_txn_mgr.return_value.complete_transaction.return_value = ( @@ -1526,11 +1638,14 @@ async def test_transaction_write_wrong_state_x(self): async def test_transaction_write_schema_txn_complete_x(self): self.request.match_info = {"tran_id": "dummy"} - with mock.patch.object( - TransactionRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_txn_rec_retrieve, mock.patch.object( - test_module, "TransactionManager", mock.MagicMock() - ) as mock_txn_mgr: + with ( + mock.patch.object( + TransactionRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_txn_rec_retrieve, + mock.patch.object( + test_module, "TransactionManager", mock.MagicMock() + ) as mock_txn_mgr, + ): mock_txn_mgr.return_value = mock.MagicMock( complete_transaction=mock.CoroutineMock( side_effect=test_module.StorageError() diff --git a/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py b/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py index 656b3db249..c8a0e94d52 100644 --- a/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py +++ b/acapy_agent/protocols/introduction/v0_1/tests/test_routes.py @@ -70,11 +70,12 @@ async def test_introduction_start(self): mock_conn_rec = mock.MagicMock() mock_conn_rec.serialize = mock.MagicMock() - with mock.patch.object( - self.context, "inject_or", mock.MagicMock() - ) as mock_ctx_inject, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + self.context, "inject_or", mock.MagicMock() + ) as mock_ctx_inject, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_ctx_inject.return_value = mock.MagicMock( start_introduction=mock.CoroutineMock() ) diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py index 32aa553b2e..43eeb5e1ff 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_issue_handler.py @@ -117,11 +117,12 @@ async def test_called_auto_store_x(self): handler = test_module.CredentialIssueHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py index 4b3982431d..c6fe03eafc 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_offer_handler.py @@ -109,11 +109,12 @@ async def test_called_auto_request_x(self): handler = test_module.CredentialOfferHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py index 94b0ee83e3..905b7c2e46 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_proposal_handler.py @@ -86,11 +86,12 @@ async def test_called_auto_offer_x(self): handler = test_module.CredentialProposalHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py index 7050d754e6..740a3f759c 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py +++ b/acapy_agent/protocols/issue_credential/v1_0/handlers/tests/test_credential_request_handler.py @@ -128,10 +128,11 @@ async def test_called_auto_issue_x(self): }, ) - with mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - cred_ex_rec, "save_error_state", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(cred_ex_rec, "save_error_state", mock.CoroutineMock()), ): mock_cred_mgr.return_value.receive_request = mock.CoroutineMock( return_value=cred_ex_rec @@ -146,11 +147,12 @@ async def test_called_auto_issue_x(self): handler = test_module.CredentialRequestHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ), mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(responder, "send_reply", mock.CoroutineMock()), + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py b/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py index dabca65888..661504d4c2 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py +++ b/acapy_agent/protocols/issue_credential/v1_0/models/tests/test_credential_exchange.py @@ -77,11 +77,12 @@ async def test_save_error_state(self): record.state = V10CredentialExchange.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="test") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py b/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py index a8bed3b72b..af7a358fec 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/issue_credential/v1_0/tests/test_manager.py @@ -402,12 +402,12 @@ async def test_create_bound_offer(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "get_cached_key", autospec=True - ) as get_cached_key, mock.patch.object( - V10CredentialExchange, "set_cached_key", autospec=True + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, "get_cached_key", autospec=True + ) as get_cached_key, + mock.patch.object(V10CredentialExchange, "set_cached_key", autospec=True), ): get_cached_key.return_value = None issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -473,12 +473,12 @@ async def test_create_bound_offer_no_cred_def(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, "get_cached_key", autospec=True - ) as get_cached_key, mock.patch.object( - V10CredentialExchange, "set_cached_key", autospec=True + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, "get_cached_key", autospec=True + ) as get_cached_key, + mock.patch.object(V10CredentialExchange, "set_cached_key", autospec=True), ): get_cached_key.return_value = None issuer = mock.MagicMock() @@ -526,12 +526,13 @@ async def test_receive_offer_proposed(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(return_value=stored_exchange), + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(return_value=stored_exchange), + ), ): exchange = await self.manager.receive_offer(offer, connection_id) @@ -565,12 +566,13 @@ async def test_receive_free_offer(self): self.profile.context.connection_record = mock.MagicMock() self.profile.context.connection_record.connection_id = connection_id - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(side_effect=StorageNotFoundError), + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(side_effect=StorageNotFoundError), + ), ): exchange = await self.manager.receive_offer(offer, connection_id) @@ -752,13 +754,16 @@ async def test_receive_request(self): requests_attach=[CredentialRequest.wrap_indy_cred_req(INDY_CRED_REQ)] ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(return_value=stored_exchange), - ) as retrieve_ex: + with ( + mock.patch.object( + V10CredentialExchange, "save", autospec=True + ) as save_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(return_value=stored_exchange), + ) as retrieve_ex, + ): exchange = await self.manager.receive_request(request, mock_conn, None) retrieve_ex.assert_called() @@ -787,13 +792,14 @@ async def test_receive_request_no_connection_cred_request(self): ) mock_oob = mock.MagicMock() - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as mock_save, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as mock_retrieve: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as mock_save, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as mock_retrieve, + ): mock_retrieve.return_value = stored_exchange cx_rec = await self.manager.receive_request(request, mock_conn, mock_oob) @@ -822,13 +828,14 @@ async def test_receive_request_no_cred_ex_with_offer_found(self): connection_id="test_conn_id", ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as mock_retrieve: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as mock_retrieve, + ): mock_retrieve.side_effect = (StorageNotFoundError(),) with self.assertRaises(StorageNotFoundError): await self.manager.receive_request(request, mock_conn, None) @@ -870,11 +877,10 @@ async def test_issue_credential_revocable(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex: + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + ): revoc.return_value.get_or_create_active_registry = mock.CoroutineMock( return_value=( mock.MagicMock( # active_rev_reg_rec @@ -959,12 +965,13 @@ async def test_issue_credential_non_revocable(self): self.ledger.__aenter__ = mock.CoroutineMock(return_value=self.ledger) self.profile.context.injector.clear_binding(BaseLedger) self.profile.context.injector.bind_instance(BaseLedger, self.ledger) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), ): (ret_exchange, ret_cred_issue) = await self.manager.issue_credential( stored_exchange, comment=comment, retries=0 @@ -1022,11 +1029,10 @@ async def test_issue_credential_fills_rr(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex: + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + ): revoc.return_value = mock.MagicMock( get_or_create_active_registry=( mock.CoroutineMock( @@ -1216,13 +1222,14 @@ async def test_receive_credential(self): credentials_attach=[CredentialIssue.wrap_indy_credential(INDY_CRED)] ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(return_value=stored_exchange), - ) as retrieve_ex: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(return_value=stored_exchange), + ) as retrieve_ex, + ): exchange = await self.manager.receive_credential(issue, connection_id) assert retrieve_ex.call_args.args[1] == connection_id @@ -1283,12 +1290,12 @@ async def test_store_credential(self): return_value=("test_ledger_id", self.ledger) ) self.profile.context.injector.bind_instance(IndyLedgerRequestsExecutor, executor) - with mock.patch.object( - test_module, "RevocationRegistry", autospec=True - ) as mock_rev_reg, mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True + with ( + mock.patch.object( + test_module, "RevocationRegistry", autospec=True + ) as mock_rev_reg, + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object(V10CredentialExchange, "delete_record", autospec=True), ): mock_rev_reg.from_definition = mock.MagicMock( return_value=mock.MagicMock( @@ -1389,10 +1396,9 @@ async def test_store_credential_no_preview(self): return_value=("test_ledger_id", self.ledger) ) self.profile.context.injector.bind_instance(IndyLedgerRequestsExecutor, executor) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object(V10CredentialExchange, "delete_record", autospec=True), ): ret_exchange = await self.manager.store_credential(stored_exchange) @@ -1480,15 +1486,18 @@ async def test_send_credential_ack(self): async with self.profile.session() as session: await stored_exchange.save(session) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ), mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True - ) as mock_delete_ex, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exception, mock.patch.object( - test_module.LOGGER, "warning", mock.MagicMock() - ) as mock_log_warning: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True), + mock.patch.object( + V10CredentialExchange, "delete_record", autospec=True + ) as mock_delete_ex, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exception, + mock.patch.object( + test_module.LOGGER, "warning", mock.MagicMock() + ) as mock_log_warning, + ): mock_delete_ex.side_effect = test_module.StorageError() (exch, ack) = await self.manager.send_credential_ack(stored_exchange) assert ack._thread @@ -1516,15 +1525,17 @@ async def test_receive_credential_ack(self): ack = CredentialAck() - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, "delete_record", autospec=True - ) as delete_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as retrieve_ex: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, "delete_record", autospec=True + ) as delete_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as retrieve_ex, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_credential_ack(ack, connection_id) @@ -1557,13 +1568,14 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V10CredentialExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10CredentialExchange, - "retrieve_by_connection_and_thread", - mock.CoroutineMock(), - ) as retrieve_ex: + with ( + mock.patch.object(V10CredentialExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_connection_and_thread", + mock.CoroutineMock(), + ) as retrieve_ex, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_problem_report( diff --git a/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py b/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py index a5fe618496..dddac2e214 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/issue_credential/v1_0/tests/test_routes.py @@ -120,13 +120,16 @@ async def test_credential_exchange_retrieve_x(self): async def test_credential_exchange_create(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -151,13 +154,16 @@ async def test_credential_exchange_create(self): async def test_credential_exchange_create_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), + mock.patch.object(test_module.web, "json_response"), + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -184,13 +190,16 @@ async def test_credential_exchange_create_no_proposal(self): async def test_credential_exchange_send(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -229,11 +238,12 @@ async def test_credential_exchange_send_no_conn_record(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -255,11 +265,12 @@ async def test_credential_exchange_send_not_ready(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -274,12 +285,14 @@ async def test_credential_exchange_send_not_ready(self): async def test_credential_exchange_send_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -313,13 +326,13 @@ async def test_credential_exchange_send_proposal(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex_record = mock.MagicMock() mock_credential_manager.return_value.create_proposal.return_value = ( mock_cred_ex_record @@ -336,12 +349,14 @@ async def test_credential_exchange_send_proposal(self): async def test_credential_exchange_send_proposal_no_conn_record(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( @@ -373,12 +388,14 @@ async def test_credential_exchange_send_proposal_deser_x(self): async def test_credential_exchange_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.CredentialPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module.CredentialPreview, "deserialize", autospec=True + ), ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() @@ -399,11 +416,12 @@ async def test_credential_exchange_send_proposal_x(self): return_value={"connection_id": conn_id, "credential_proposal": preview_spec} ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -428,13 +446,13 @@ async def test_credential_exchange_create_free_offer(self): self.context.update_settings({"debug.auto_respond_credential_offer": True}) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_cred_ex_record = mock.MagicMock() mock_credential_manager.return_value.create_offer.return_value = ( @@ -498,11 +516,12 @@ async def test_credential_exchange_create_free_offer_deser_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_credential_manager.return_value.create_offer.side_effect = ( test_module.BaseModelError() @@ -522,11 +541,12 @@ async def test_credential_exchange_create_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock( side_effect=test_module.BaseModelError(), @@ -555,13 +575,13 @@ async def test_credential_exchange_send_free_offer(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_credential_manager.return_value.create_offer = mock.CoroutineMock() mock_cred_ex_record = mock.MagicMock() @@ -606,11 +626,12 @@ async def test_credential_exchange_send_free_offer_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -629,11 +650,12 @@ async def test_credential_exchange_send_free_offer_not_ready(self): self.request.json = mock.CoroutineMock() self.request.json.return_value["auto_issue"] = True - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -658,11 +680,13 @@ async def test_credential_exchange_send_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -684,15 +708,16 @@ async def test_credential_exchange_send_bound_offer(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_PROPOSAL_RECEIVED @@ -732,13 +757,15 @@ async def test_credential_exchange_send_bound_offer_no_conn_record(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock( @@ -785,13 +812,15 @@ async def test_credential_exchange_send_bound_offer_not_ready(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -816,15 +845,16 @@ async def test_credential_exchange_send_request(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_OFFER_RECEIVED @@ -847,17 +877,19 @@ async def test_credential_exchange_send_request_no_conn(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "OobRecord", autospec=True - ) as mock_oob_rec, mock.patch.object( - test_module, "default_did_from_verkey", autospec=True - ) as mock_default_did_from_verkey, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "OobRecord", autospec=True) as mock_oob_rec, + mock.patch.object( + test_module, "default_did_from_verkey", autospec=True + ) as mock_default_did_from_verkey, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_oob_rec.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock.MagicMock(our_recipient_key="our-recipient_key") ) @@ -905,13 +937,15 @@ async def test_credential_exchange_send_request_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -938,13 +972,15 @@ async def test_credential_exchange_send_request_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -969,15 +1005,16 @@ async def test_credential_exchange_issue(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_REQUEST_RECEIVED @@ -1020,13 +1057,15 @@ async def test_credential_exchange_issue_no_conn_record(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + ): mock_cred_ex_rec.state = mock_cred_ex_cls.STATE_REQUEST_RECEIVED mock_cred_ex_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_cred_ex_rec @@ -1050,13 +1089,15 @@ async def test_credential_exchange_issue_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_REQUEST_RECEIVED @@ -1084,13 +1125,15 @@ async def test_credential_exchange_issue_rev_reg_full(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + ): mock_cred_ex_cls.state = mock_cred_ex_cls.STATE_REQUEST_RECEIVED mock_cred_ex_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_cred_ex_rec @@ -1116,13 +1159,15 @@ async def test_credential_exchange_issue_deser_x(self): serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + ): mock_cred_ex_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_cred_ex_rec ) @@ -1141,15 +1186,16 @@ async def test_credential_exchange_store(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_CREDENTIAL_RECEIVED @@ -1177,15 +1223,16 @@ async def test_credential_exchange_store_bad_cred_id_json(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value.state = ( mock_cred_ex.STATE_CREDENTIAL_RECEIVED @@ -1226,13 +1273,15 @@ async def test_credential_exchange_store_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock( @@ -1262,13 +1311,13 @@ async def test_credential_exchange_store_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "CredentialManager", autospec=True - ), mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object(test_module, "CredentialManager", autospec=True), + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.connection_id = "conn-123" mock_cred_ex.thread_id = "conn-123" mock_cred_ex.retrieve_by_id = mock.CoroutineMock() @@ -1287,13 +1336,16 @@ async def test_credential_exchange_store_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "CredentialManager", autospec=True - ) as mock_credential_manager, mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "CredentialManager", autospec=True + ) as mock_credential_manager, + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_ex_record = mock.MagicMock( state=mock_cred_ex_cls.STATE_CREDENTIAL_RECEIVED, serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -1316,11 +1368,12 @@ async def test_credential_exchange_store_x(self): async def test_credential_exchange_remove(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock() mock_cred_ex.retrieve_by_id.return_value = mock_cred_ex @@ -1366,15 +1419,17 @@ async def test_credential_exchange_problem_report(self): self.request.match_info = {"cred_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "CredentialManager", autospec=True - ), mock.patch.object(test_module, "ConnRecord", autospec=True), mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "CredentialManager", autospec=True), + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -1410,13 +1465,13 @@ async def test_credential_exchange_problem_report_x(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "CredentialManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V10CredentialExchange", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "CredentialManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V10CredentialExchange", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( save_error_state=mock.CoroutineMock( diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py index fed47beaf3..f795929e8b 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/anoncreds/tests/test_handler.py @@ -1146,15 +1146,19 @@ async def test_store_credential(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module, "RevocationRegistry", autospec=True - ) as mock_rev_reg, mock.patch.object( - test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module, "RevocationRegistry", autospec=True + ) as mock_rev_reg, + mock.patch.object( + test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + ): mock_rev_reg.from_definition = mock.MagicMock( return_value=mock.MagicMock( get_or_fetch_local_tails_path=mock.CoroutineMock() @@ -1251,11 +1255,14 @@ async def test_store_credential_holder_store_indy_error(self): side_effect=test_module.AnonCredsHolderError("Problem", {"message": "Nope"}) ) - with mock.patch.object( - test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record, mock.patch.object( - test_module.RevocationRegistry, "from_definition", mock.MagicMock() - ) as mock_rev_reg: + with ( + mock.patch.object( + test_module.AnonCredsCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + mock.patch.object( + test_module.RevocationRegistry, "from_definition", mock.MagicMock() + ) as mock_rev_reg, + ): mock_get_detail_record.return_value = mock.MagicMock( cred_request_metadata=cred_req_meta, save=mock.CoroutineMock(), diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py index 91c80e2b7a..78bd346d02 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/indy/tests/test_handler.py @@ -1132,15 +1132,19 @@ async def test_store_credential(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - test_module, "RevocationRegistry", autospec=True - ) as mock_rev_reg, mock.patch.object( - test_module.IndyCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object( + test_module, "RevocationRegistry", autospec=True + ) as mock_rev_reg, + mock.patch.object( + test_module.IndyCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + ): mock_rev_reg.from_definition = mock.MagicMock( return_value=mock.MagicMock( get_or_fetch_local_tails_path=mock.CoroutineMock() @@ -1236,11 +1240,14 @@ async def test_store_credential_holder_store_indy_error(self): side_effect=test_module.IndyHolderError("Problem", {"message": "Nope"}) ) - with mock.patch.object( - test_module.IndyCredFormatHandler, "get_detail_record", autospec=True - ) as mock_get_detail_record, mock.patch.object( - test_module.RevocationRegistry, "from_definition", mock.MagicMock() - ) as mock_rev_reg: + with ( + mock.patch.object( + test_module.IndyCredFormatHandler, "get_detail_record", autospec=True + ) as mock_get_detail_record, + mock.patch.object( + test_module.RevocationRegistry, "from_definition", mock.MagicMock() + ) as mock_rev_reg, + ): mock_get_detail_record.return_value = mock.MagicMock( cred_request_metadata=cred_req_meta, save=mock.CoroutineMock(), diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py index 2b2e948adb..33a92abbc9 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/ld_proof/tests/test_handler.py @@ -255,12 +255,13 @@ async def test_receive_proposal(self): await self.handler.receive_proposal(cred_ex_record, cred_proposal_message) async def test_create_offer(self): - with mock.patch.object( - VcLdpManager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ) as mock_can_issue, patch.object( - test_module, "get_properties_without_context", return_value=[] + with ( + mock.patch.object( + VcLdpManager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ) as mock_can_issue, + patch.object(test_module, "get_properties_without_context", return_value=[]), ): (cred_format, attachment) = await self.handler.create_offer( self.cred_proposal @@ -295,11 +296,14 @@ async def test_create_offer_adds_bbs_context(self): ], ) - with mock.patch.object( - VcLdpManager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ), patch.object(test_module, "get_properties_without_context", return_value=[]): + with ( + mock.patch.object( + VcLdpManager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ), + patch.object(test_module, "get_properties_without_context", return_value=[]), + ): (cred_format, attachment) = await self.handler.create_offer(cred_proposal) # assert BBS url added to context @@ -320,11 +324,14 @@ async def test_create_offer_adds_ed25519_2020_context(self): ], ) - with mock.patch.object( - VcLdpManager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ), patch.object(test_module, "get_properties_without_context", return_value=[]): + with ( + mock.patch.object( + VcLdpManager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ), + patch.object(test_module, "get_properties_without_context", return_value=[]), + ): (cred_format, attachment) = await self.handler.create_offer(cred_proposal) # assert BBS url added to context @@ -342,15 +349,19 @@ async def test_create_offer_x_no_proposal(self): async def test_create_offer_x_wrong_attributes(self): missing_properties = ["foo"] - with mock.patch.object( - self.manager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ), patch.object( - test_module, - "get_properties_without_context", - return_value=missing_properties, - ), self.assertRaises(LinkedDataProofException) as context: + with ( + mock.patch.object( + self.manager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ), + patch.object( + test_module, + "get_properties_without_context", + return_value=missing_properties, + ), + self.assertRaises(LinkedDataProofException) as context, + ): await self.handler.create_offer(self.cred_proposal) assert ( @@ -885,17 +896,24 @@ async def test_store_credential_x_not_verified(self): cred_id = "cred_id" self.holder.store_credential = mock.CoroutineMock() - with mock.patch.object( - self.manager, - "_get_suite", - mock.CoroutineMock(), - ), mock.patch.object( - self.manager, - "verify_credential", - mock.CoroutineMock(return_value=DocumentVerificationResult(verified=False)), - ), mock.patch.object( - self.manager, - "_get_proof_purpose", - ), self.assertRaises(V20CredFormatError) as context: + with ( + mock.patch.object( + self.manager, + "_get_suite", + mock.CoroutineMock(), + ), + mock.patch.object( + self.manager, + "verify_credential", + mock.CoroutineMock( + return_value=DocumentVerificationResult(verified=False) + ), + ), + mock.patch.object( + self.manager, + "_get_proof_purpose", + ), + self.assertRaises(V20CredFormatError) as context, + ): await self.handler.store_credential(cred_ex_record, cred_id) assert "Received invalid credential: " in str(context.exception) diff --git a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py index b87034e70c..ccd1a854e2 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_offer_handler.py @@ -109,11 +109,14 @@ async def test_called_auto_request_x_indy(self): handler = test_module.V20CredOfferHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() @@ -145,11 +148,14 @@ async def test_called_auto_request_x_anoncreds(self): handler = test_module.V20CredOfferHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py index 8ece39bf7b..a901018d08 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_proposal_handler.py @@ -86,11 +86,14 @@ async def test_called_auto_offer_x_indy(self): handler = test_module.V20CredProposalHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() @@ -115,11 +118,14 @@ async def test_called_auto_offer_x_anoncreds(self): handler = test_module.V20CredProposalHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py index 3fc7571b62..f2d9763e0f 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/handlers/tests/test_cred_request_handler.py @@ -102,10 +102,11 @@ async def test_called_auto_issue_x_indy(self): ) request_context.injector.bind_instance(OobMessageProcessor, mock_oob_processor) - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - cred_ex_rec, "save_error_state", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(cred_ex_rec, "save_error_state", mock.CoroutineMock()), ): mock_cred_mgr.return_value.receive_request = mock.CoroutineMock( return_value=cred_ex_rec @@ -120,11 +121,14 @@ async def test_called_auto_issue_x_indy(self): handler = test_module.V20CredRequestHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() @@ -142,10 +146,11 @@ async def test_called_auto_issue_x_anoncreds(self): ) request_context.injector.bind_instance(OobMessageProcessor, mock_oob_processor) - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - cred_ex_rec, "save_error_state", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(cred_ex_rec, "save_error_state", mock.CoroutineMock()), ): mock_cred_mgr.return_value.receive_request = mock.CoroutineMock( return_value=cred_ex_rec @@ -160,11 +165,14 @@ async def test_called_auto_issue_x_anoncreds(self): handler = test_module.V20CredRequestHandler() responder = MockResponder() - with mock.patch.object( - responder, "send_reply", mock.CoroutineMock() - ) as mock_send_reply, mock.patch.object( - handler._logger, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object( + responder, "send_reply", mock.CoroutineMock() + ) as mock_send_reply, + mock.patch.object( + handler._logger, "exception", mock.MagicMock() + ) as mock_log_exc, + ): await handler.handle(request_context, responder) mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py b/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py index a3ef8a756d..b7fdaa2e7b 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py +++ b/acapy_agent/protocols/issue_credential/v2_0/models/tests/test_cred_ex_record.py @@ -125,11 +125,12 @@ async def test_save_error_state(self): record.state = V20CredExRecord.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="test") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py b/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py index 65062ad5ea..015033925e 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py +++ b/acapy_agent/protocols/issue_credential/v2_0/tests/test_manager.py @@ -145,11 +145,10 @@ async def test_create_proposal(self): ) ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_proposal = mock.CoroutineMock( return_value=( V20CredFormat( @@ -186,11 +185,10 @@ async def test_create_proposal_no_preview(self): connection_id = "test_conn_id" comment = "comment" - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_proposal = mock.CoroutineMock( return_value=( V20CredFormat( @@ -236,11 +234,10 @@ async def test_receive_proposal(self): ) ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_proposal = mock.CoroutineMock() cred_proposal = V20CredProposal( @@ -308,11 +305,10 @@ async def test_create_free_offer(self): cred_proposal=cred_proposal, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_offer = mock.CoroutineMock( return_value=( V20CredFormat( @@ -384,11 +380,10 @@ async def test_create_bound_offer(self): cred_proposal=cred_proposal, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_offer = mock.CoroutineMock( return_value=( V20CredFormat( @@ -492,15 +487,15 @@ async def test_receive_offer_proposed(self): thread_id=thread_id, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, - "retrieve_by_conn_and_thread", - mock.CoroutineMock(return_value=stored_cx_rec), - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, + "retrieve_by_conn_and_thread", + mock.CoroutineMock(return_value=stored_cx_rec), + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_offer = mock.CoroutineMock() cx_rec = await self.manager.receive_offer(cred_offer, connection_id) @@ -549,13 +544,13 @@ async def test_receive_free_offer(self): self.context.conn_record = mock.MagicMock() self.context.conn_record.connection_id = connection_id - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_offer = mock.CoroutineMock() mock_retrieve.side_effect = (StorageNotFoundError(),) cx_rec = await self.manager.receive_offer(cred_offer, connection_id) @@ -602,11 +597,10 @@ async def test_create_bound_request(self): self.cache = InMemoryCache() self.context.injector.bind_instance(BaseCache, self.cache) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_request = mock.CoroutineMock( return_value=( V20CredFormat( @@ -689,11 +683,10 @@ async def test_create_free_request(self): self.cache = InMemoryCache() self.context.injector.bind_instance(BaseCache, self.cache) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.create_request = mock.CoroutineMock( return_value=( V20CredFormat( @@ -754,13 +747,13 @@ async def test_receive_request(self): requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_retrieve.side_effect = (StorageNotFoundError(),) mock_handler.return_value.receive_request = mock.CoroutineMock() @@ -799,13 +792,13 @@ async def test_receive_request_no_connection_cred_request(self): mock_conn = mock.MagicMock(connection_id="test_conn_id") mock_oob = mock.MagicMock() - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_retrieve.return_value = stored_cx_rec mock_handler.return_value.receive_request = mock.CoroutineMock() @@ -834,11 +827,13 @@ async def test_receive_request_no_cred_ex_with_offer_found(self): requests_attach=[AttachDecorator.data_base64(INDY_CRED_REQ, ident="0")], ) - with mock.patch.object(V20CredExRecord, "save", autospec=True), mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True), + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_retrieve.side_effect = (StorageNotFoundError(),) mock_handler.return_value.receive_request = mock.CoroutineMock() @@ -926,11 +921,10 @@ async def test_issue_credential_indy(self): ) self.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.issue_credential = mock.CoroutineMock( return_value=( V20CredFormat( @@ -1033,11 +1027,10 @@ async def test_issue_credential_anoncreds(self): ) self.context.injector.bind_instance(AnonCredsIssuer, issuer) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.issue_credential = mock.CoroutineMock( return_value=( V20CredFormat( @@ -1139,15 +1132,15 @@ async def test_receive_cred(self): credentials_attach=[AttachDecorator.data_base64(INDY_CRED, ident="0")], ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, - "retrieve_by_conn_and_thread", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, + "retrieve_by_conn_and_thread", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.receive_credential = mock.CoroutineMock() mock_retrieve.return_value = stored_cx_rec ret_cx_rec = await self.manager.receive_credential( @@ -1282,13 +1275,13 @@ async def test_store_credential(self): thread_id=thread_id, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - test_module.V20CredManager, "delete_cred_ex_record", autospec=True - ) as mock_delete, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + test_module.V20CredManager, "delete_cred_ex_record", autospec=True + ) as mock_delete, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_handler.return_value.store_credential = mock.CoroutineMock() ret_cx_rec = await self.manager.store_credential( @@ -1329,15 +1322,18 @@ async def test_send_cred_ack(self): auto_remove=True, ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save_ex, mock.patch.object( - V20CredExRecord, "delete_record", autospec=True - ) as mock_delete_ex, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exception, mock.patch.object( - test_module.LOGGER, "warning", mock.MagicMock() - ) as mock_log_warning: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save_ex, + mock.patch.object( + V20CredExRecord, "delete_record", autospec=True + ) as mock_delete_ex, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exception, + mock.patch.object( + test_module.LOGGER, "warning", mock.MagicMock() + ) as mock_log_warning, + ): mock_delete_ex.side_effect = test_module.StorageError() (_, ack) = await self.manager.send_cred_ack(stored_exchange) assert ack._thread @@ -1361,15 +1357,18 @@ async def test_receive_cred_ack(self): ack = V20CredAck() - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as mock_save, mock.patch.object( - V20CredExRecord, "delete_record", autospec=True - ) as mock_delete, mock.patch.object( - V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.V20CredManager, "delete_cred_ex_record", autospec=True - ) as mock_delete: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as mock_save, + mock.patch.object( + V20CredExRecord, "delete_record", autospec=True + ) as mock_delete, + mock.patch.object( + V20CredExRecord, "retrieve_by_conn_and_thread", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object( + test_module.V20CredManager, "delete_cred_ex_record", autospec=True + ) as mock_delete, + ): mock_retrieve.return_value = stored_cx_rec ret_cx_rec = await self.manager.receive_credential_ack( ack, @@ -1386,13 +1385,15 @@ async def test_delete_cred_ex_record(self): stored_cx_rec = mock.MagicMock(delete_record=mock.CoroutineMock()) stored_indy = mock.MagicMock(delete_record=mock.CoroutineMock()) - with mock.patch.object( - V20CredExRecord, "delete_record", autospec=True - ), mock.patch.object( - V20CredExRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module, "V20CredFormat", mock.MagicMock() - ) as mock_cred_format: + with ( + mock.patch.object(V20CredExRecord, "delete_record", autospec=True), + mock.patch.object( + V20CredExRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object( + test_module, "V20CredFormat", mock.MagicMock() + ) as mock_cred_format, + ): mock_retrieve.return_value = stored_cx_rec mock_cred_format.Format = [ mock.MagicMock( @@ -1428,13 +1429,14 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V20CredExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20CredExRecord, - "retrieve_by_conn_and_thread", - mock.CoroutineMock(), - ) as retrieve_ex: + with ( + mock.patch.object(V20CredExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20CredExRecord, + "retrieve_by_conn_and_thread", + mock.CoroutineMock(), + ) as retrieve_ex, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_problem_report( diff --git a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py index 1359057136..9e3663d5ed 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py @@ -135,11 +135,12 @@ async def test_credential_exchange_list_x(self): async def test_credential_exchange_retrieve(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -173,11 +174,12 @@ async def test_credential_exchange_retrieve(self): async def test_credential_exchange_retrieve_indy_ld_proof(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -231,11 +233,12 @@ async def test_credential_exchange_retrieve_not_found(self): async def test_credential_exchange_retrieve_x(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -254,13 +257,14 @@ async def test_credential_exchange_retrieve_x(self): async def test_credential_exchange_create(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -283,13 +287,14 @@ async def test_credential_exchange_create(self): async def test_credential_exchange_create_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -323,13 +328,14 @@ async def test_credential_exchange_create_no_filter(self): async def test_credential_exchange_send(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True - ), mock.patch.object(test_module.web, "json_response") as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -353,17 +359,19 @@ async def test_credential_exchange_send_request_no_conn_no_holder_did(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "OobRecord", autospec=True - ) as mock_oob_rec, mock.patch.object( - test_module, "default_did_from_verkey", autospec=True - ) as mock_default_did_from_verkey, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "OobRecord", autospec=True) as mock_oob_rec, + mock.patch.object( + test_module, "default_did_from_verkey", autospec=True + ) as mock_default_did_from_verkey, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_oob_rec.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock.MagicMock(our_recipient_key="our-recipient_key") ) @@ -403,11 +411,12 @@ async def test_credential_exchange_send_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -433,11 +442,12 @@ async def test_credential_exchange_send_not_ready(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): mock_conn_rec.retrieve_by_id.return_value.is_ready = False mock_cred_mgr.return_value.create_offer.return_value = ( @@ -451,12 +461,12 @@ async def test_credential_exchange_send_not_ready(self): async def test_credential_exchange_send_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), ): mock_cred_ex_record = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -493,13 +503,13 @@ async def test_credential_exchange_send_proposal(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cx_rec = mock.MagicMock() mock_cred_mgr.return_value.create_proposal.return_value = mock_cx_rec @@ -525,12 +535,12 @@ async def test_credential_exchange_send_proposal_no_filter(self): async def test_credential_exchange_send_proposal_no_conn_record(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( @@ -554,11 +564,12 @@ async def test_credential_exchange_send_proposal_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): mock_cx_rec = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -571,12 +582,12 @@ async def test_credential_exchange_send_proposal_x(self): async def test_credential_exchange_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.V20CredPreview, "deserialize", autospec=True + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.V20CredPreview, "deserialize", autospec=True), ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() @@ -599,13 +610,13 @@ async def test_credential_exchange_create_free_offer(self): ) self.context.update_settings({"debug.auto_respond_credential_offer": True}) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -642,11 +653,12 @@ async def test_credential_exchange_create_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): mock_cx_rec = mock.MagicMock( serialize=mock.MagicMock( side_effect=test_module.BaseModelError(), @@ -675,13 +687,13 @@ async def test_credential_exchange_send_free_offer(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() mock_cred_mgr.return_value.create_offer.return_value = ( @@ -713,13 +725,13 @@ async def test_credential_exchange_send_free_offer_vcdi(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): # Mock the creation of a credential offer, especially for handling VC-DI mock_cred_mgr.return_value.create_offer = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() @@ -759,11 +771,12 @@ async def test_credential_exchange_send_free_offer_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -789,11 +802,12 @@ async def test_credential_exchange_send_free_offer_not_ready(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -818,11 +832,13 @@ async def test_credential_exchange_send_free_offer_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_cx_rec = mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), save_error_state=mock.CoroutineMock(), @@ -843,15 +859,16 @@ async def test_credential_exchange_send_bound_offer(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_PROPOSAL_RECEIVED @@ -874,13 +891,16 @@ async def test_credential_exchange_send_bound_offer_linked_data_error(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_PROPOSAL_RECEIVED @@ -916,13 +936,15 @@ async def test_credential_exchange_send_bound_offer_no_conn_record(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock( @@ -969,13 +991,15 @@ async def test_credential_exchange_send_bound_offer_not_ready(self): self.request.json = mock.CoroutineMock(return_value={}) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -1000,15 +1024,16 @@ async def test_credential_exchange_send_request(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_OFFER_RECEIVED @@ -1044,13 +1069,15 @@ async def test_credential_exchange_send_request_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -1077,13 +1104,15 @@ async def test_credential_exchange_send_request_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -1111,13 +1140,13 @@ async def test_credential_exchange_send_free_request(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value.create_request = mock.CoroutineMock() mock_cx_rec = mock.MagicMock() @@ -1145,11 +1174,12 @@ async def test_credential_exchange_send_free_request_no_conn_record(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate storage not found (bad connection id) mock_conn_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() @@ -1171,11 +1201,12 @@ async def test_credential_exchange_send_free_request_not_ready(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + ): # Emulate connection not ready mock_conn_rec.retrieve_by_id = mock.CoroutineMock() mock_conn_rec.retrieve_by_id.return_value.is_ready = False @@ -1196,11 +1227,13 @@ async def test_credential_exchange_send_free_request_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_cred_mgr.return_value.create_request = mock.CoroutineMock( side_effect=[ test_module.LedgerError(), @@ -1217,17 +1250,17 @@ async def test_credential_exchange_issue(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_REQUEST_RECEIVED @@ -1266,17 +1299,17 @@ async def test_credential_exchange_issue_vcdi(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_REQUEST_RECEIVED @@ -1335,13 +1368,15 @@ async def test_credential_exchange_issue_no_conn_record(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec.state = mock_cx_rec_cls.STATE_REQUEST_RECEIVED mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) @@ -1363,13 +1398,15 @@ async def test_credential_exchange_issue_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.retrieve_by_id = mock.CoroutineMock() mock_cx_rec.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_REQUEST_RECEIVED @@ -1397,13 +1434,15 @@ async def test_credential_exchange_issue_rev_reg_full_indy(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec.state = mock_cx_rec_cls.STATE_REQUEST_RECEIVED mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) @@ -1427,13 +1466,15 @@ async def test_credential_exchange_issue_rev_reg_full_anoncreds(self): serialize=mock.MagicMock(), save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec.state = mock_cx_rec_cls.STATE_REQUEST_RECEIVED mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) @@ -1459,13 +1500,15 @@ async def test_credential_exchange_issue_deser_x(self): mock_conn_rec = mock.MagicMock(ConnRecord, autospec=True) mock_conn_rec.retrieve_by_id = mock.CoroutineMock(return_value=ConnRecord()) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock(return_value=mock_cx_rec) mock_cred_mgr.return_value = mock.MagicMock( issue_credential=mock.CoroutineMock( @@ -1491,17 +1534,17 @@ async def test_credential_exchange_store(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - V20CredFormat.Format, "handler" - ) as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_CREDENTIAL_RECEIVED @@ -1543,19 +1586,22 @@ async def test_credential_exchange_store_bad_cred_id_json(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response, mock.patch.object( - LDProofCredFormatHandler, "get_detail_record", autospec=True - ) as mock_ld_proof_get_detail_record, mock.patch.object( - IndyCredFormatHandler, "get_detail_record", autospec=True - ) as mock_indy_get_detail_record: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + mock.patch.object( + LDProofCredFormatHandler, "get_detail_record", autospec=True + ) as mock_ld_proof_get_detail_record, + mock.patch.object( + IndyCredFormatHandler, "get_detail_record", autospec=True + ) as mock_indy_get_detail_record, + ): mock_cx_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_cx_rec_cls.retrieve_by_id.return_value.state = ( test_module.V20CredExRecord.STATE_CREDENTIAL_RECEIVED @@ -1613,13 +1659,15 @@ async def test_credential_exchange_store_no_conn_record(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock( @@ -1647,13 +1695,13 @@ async def test_credential_exchange_store_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec, + ): mock_cx_rec.connection_id = "conn-123" mock_cx_rec.thread_id = "conn-123" mock_cx_rec.retrieve_by_id = mock.CoroutineMock() @@ -1672,15 +1720,17 @@ async def test_credential_exchange_store_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cx_rec_cls, mock.patch.object( - test_module.web, "json_response" - ), mock.patch.object(V20CredFormat.Format, "handler") as mock_handler: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cx_rec_cls, + mock.patch.object(test_module.web, "json_response"), + mock.patch.object(V20CredFormat.Format, "handler") as mock_handler, + ): mock_cx_rec = mock.MagicMock( state=mock_cx_rec_cls.STATE_CREDENTIAL_RECEIVED, serialize=mock.MagicMock(side_effect=test_module.BaseModelError()), @@ -1716,11 +1766,12 @@ async def test_credential_exchange_store_x(self): async def test_credential_exchange_remove(self): self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ) as mock_cred_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20CredManager", autospec=True + ) as mock_cred_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_mgr.return_value = mock.MagicMock( delete_cred_ex_record=mock.CoroutineMock() ) @@ -1765,15 +1816,16 @@ async def test_credential_exchange_problem_report(self): self.request.match_info = {"cred_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex, mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -1793,11 +1845,12 @@ async def test_credential_exchange_problem_report_bad_cred_ex_id(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() ) @@ -1811,13 +1864,13 @@ async def test_credential_exchange_problem_report_x(self): ) self.request.match_info = {"cred_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20CredManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V20CredExRecord", autospec=True - ) as mock_cred_ex: + with ( + mock.patch.object(test_module, "V20CredManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V20CredExRecord", autospec=True + ) as mock_cred_ex, + ): mock_cred_ex.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( save_error_state=mock.CoroutineMock( diff --git a/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py b/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py index 9d1ae4b624..1e5b41ba7e 100644 --- a/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/out_of_band/v1_0/tests/test_manager.py @@ -399,11 +399,14 @@ async def test_create_invitation_multitenant_local(self): } ) - with mock.patch.object( - AskarWallet, "create_signing_key", autospec=True - ) as mock_wallet_create_signing_key, mock.patch.object( - self.multitenant_mgr, "get_default_mediator" - ) as mock_get_default_mediator: + with ( + mock.patch.object( + AskarWallet, "create_signing_key", autospec=True + ) as mock_wallet_create_signing_key, + mock.patch.object( + self.multitenant_mgr, "get_default_mediator" + ) as mock_get_default_mediator, + ): mock_wallet_create_signing_key.return_value = KeyInfo( TestConfig.test_verkey, None, ED25519 ) @@ -455,11 +458,12 @@ async def test_create_invitation_mediation_overwrites_routing_and_endpoint(self) endpoint=self.test_mediator_endpoint, ) await mediation_record.save(session) - with mock.patch.object( - MediationManager, - "get_default_mediator_id", - ) as mock_get_default_mediator, mock.patch.object( - mock_conn_rec, "metadata_set", mock.CoroutineMock() + with ( + mock.patch.object( + MediationManager, + "get_default_mediator_id", + ) as mock_get_default_mediator, + mock.patch.object(mock_conn_rec, "metadata_set", mock.CoroutineMock()), ): invite = await self.manager.create_invitation( my_endpoint=TestConfig.test_endpoint, @@ -496,13 +500,16 @@ async def test_create_invitation_no_handshake_no_attachments_x(self): async def test_create_invitation_attachment_v1_0_cred_offer(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - V10CredentialExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -530,13 +537,16 @@ async def test_create_invitation_attachment_v1_0_cred_offer(self): async def test_create_invitation_attachment_v1_0_cred_offer_no_handshake(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - V10CredentialExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + V10CredentialExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -564,17 +574,21 @@ async def test_create_invitation_attachment_v1_0_cred_offer_no_handshake(self): } async def test_create_invitation_attachment_v2_0_cred_offer(self): - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - test_module.V10CredentialExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid_v1, mock.patch.object( - test_module.V20CredExRecord, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_cxid_v2: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + test_module.V10CredentialExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid_v1, + mock.patch.object( + test_module.V20CredExRecord, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_cxid_v2, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -602,13 +616,16 @@ async def test_create_invitation_attachment_v2_0_cred_offer(self): async def test_create_invitation_attachment_present_proof_v1_0(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - test_module.V10PresentationExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_pxid: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + test_module.V10PresentationExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_pxid, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -637,17 +654,21 @@ async def test_create_invitation_attachment_present_proof_v1_0(self): async def test_create_invitation_attachment_present_proof_v2_0(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - AskarWallet, "get_public_did", autospec=True - ) as mock_wallet_get_public_did, mock.patch.object( - test_module.V10PresentationExchange, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_pxid_1, mock.patch.object( - test_module.V20PresExRecord, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_pxid_2: + with ( + mock.patch.object( + AskarWallet, "get_public_did", autospec=True + ) as mock_wallet_get_public_did, + mock.patch.object( + test_module.V10PresentationExchange, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_pxid_1, + mock.patch.object( + test_module.V20PresExRecord, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_pxid_2, + ): mock_wallet_get_public_did.return_value = DIDInfo( TestConfig.test_did, TestConfig.test_verkey, @@ -904,14 +925,17 @@ async def test_wait_for_conn_rec_active_retrieve_by_id(self): async def test_create_handshake_reuse_msg(self): self.profile.context.update_settings({"public_invites": True}) - with mock.patch.object( - OutOfBandManager, - "fetch_connection_targets", - autospec=True, - ) as oob_mgr_fetch_conn, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=self.test_conn_rec), + with ( + mock.patch.object( + OutOfBandManager, + "fetch_connection_targets", + autospec=True, + ) as oob_mgr_fetch_conn, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=self.test_conn_rec), + ), ): oob_mgr_fetch_conn.return_value = ConnectionTarget( did=TestConfig.test_did, @@ -974,17 +998,19 @@ async def test_receive_reuse_message_existing_found(self): self.test_conn_rec.invitation_msg_id = "test_123" self.test_conn_rec.state = ConnRecord.State.COMPLETED.rfc160 - with mock.patch.object( - OutOfBandManager, - "fetch_connection_targets", - autospec=True, - ) as oob_mgr_fetch_conn, mock.patch.object( - OobRecord, - "retrieve_by_tag_filter", - autospec=True, - ) as mock_retrieve_oob, mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify: + with ( + mock.patch.object( + OutOfBandManager, + "fetch_connection_targets", + autospec=True, + ) as oob_mgr_fetch_conn, + mock.patch.object( + OobRecord, + "retrieve_by_tag_filter", + autospec=True, + ) as mock_retrieve_oob, + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + ): mock_retrieve_oob.return_value = mock.MagicMock( emit_event=mock.CoroutineMock(), delete_record=mock.CoroutineMock(), @@ -1031,17 +1057,19 @@ async def test_receive_reuse_message_existing_found_multi_use(self): self.test_conn_rec.invitation_msg_id = "test_123" self.test_conn_rec.state = ConnRecord.State.COMPLETED.rfc160 - with mock.patch.object( - OutOfBandManager, - "fetch_connection_targets", - autospec=True, - ) as oob_mgr_fetch_conn, mock.patch.object( - OobRecord, - "retrieve_by_tag_filter", - autospec=True, - ) as mock_retrieve_oob, mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify: + with ( + mock.patch.object( + OutOfBandManager, + "fetch_connection_targets", + autospec=True, + ) as oob_mgr_fetch_conn, + mock.patch.object( + OobRecord, + "retrieve_by_tag_filter", + autospec=True, + ) as mock_retrieve_oob, + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + ): mock_retrieve_oob.return_value = mock.MagicMock( emit_event=mock.CoroutineMock(), delete_record=mock.CoroutineMock(), @@ -1085,11 +1113,12 @@ async def test_receive_reuse_accepted(self): reuse_msg_accepted = HandshakeReuseAccept() reuse_msg_accepted.assign_thread_id(thid="the-thread-id", pthid="the-pthid") - with mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify, mock.patch.object( - OobRecord, "retrieve_by_tag_filter", autospec=True - ) as mock_retrieve_oob: + with ( + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + mock.patch.object( + OobRecord, "retrieve_by_tag_filter", autospec=True + ) as mock_retrieve_oob, + ): mock_retrieve_oob.return_value = mock.MagicMock( emit_event=mock.CoroutineMock(), delete_record=mock.CoroutineMock(), @@ -1122,11 +1151,12 @@ async def test_receive_reuse_accepted_x(self): reuse_msg_accepted = HandshakeReuseAccept() reuse_msg_accepted.assign_thread_id(thid="the-thread-id", pthid="the-pthid") - with mock.patch.object( - self.profile, "notify", autospec=True - ) as mock_notify, mock.patch.object( - OobRecord, "retrieve_by_tag_filter", autospec=True - ) as mock_retrieve_oob: + with ( + mock.patch.object(self.profile, "notify", autospec=True) as mock_notify, + mock.patch.object( + OobRecord, "retrieve_by_tag_filter", autospec=True + ) as mock_retrieve_oob, + ): mock_retrieve_oob.side_effect = (StorageNotFoundError,) with self.assertRaises(test_module.OutOfBandManagerError) as err: @@ -1219,11 +1249,14 @@ async def test_receive_invitation_with_valid_mediation(self): endpoint=self.test_mediator_endpoint, ) await mediation_record.save(session) - with mock.patch.object( - DIDXManager, "receive_invitation", mock.CoroutineMock() - ) as mock_didx_recv_invi, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_conn_by_id: + with ( + mock.patch.object( + DIDXManager, "receive_invitation", mock.CoroutineMock() + ) as mock_didx_recv_invi, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_conn_by_id, + ): invite = await self.manager.create_invitation( my_endpoint=TestConfig.test_endpoint, my_label="test123", @@ -1249,15 +1282,18 @@ async def test_receive_invitation_with_valid_mediation(self): async def test_receive_invitation_with_invalid_mediation(self): mock_conn = mock.MagicMock(connection_id="dummy-connection") - with mock.patch.object( - DIDXManager, - "receive_invitation", - mock.CoroutineMock(), - ) as mock_didx_recv_invi, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(), - ) as mock_retrieve_conn_by_id: + with ( + mock.patch.object( + DIDXManager, + "receive_invitation", + mock.CoroutineMock(), + ) as mock_didx_recv_invi, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(), + ) as mock_retrieve_conn_by_id, + ): invite = await self.manager.create_invitation( my_endpoint=TestConfig.test_endpoint, my_label="test123", @@ -1287,11 +1323,12 @@ async def test_receive_invitation_didx_services_with_service_block(self): mock_conn = mock.MagicMock(connection_id="dummy-connection") - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as didx_mgr_cls, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve_conn_by_id: + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as didx_mgr_cls, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve_conn_by_id, + ): didx_mgr_cls.return_value = mock.MagicMock( receive_invitation=mock.CoroutineMock(return_value=mock_conn) ) @@ -1316,11 +1353,14 @@ async def test_receive_invitation_connection_protocol(self): mock_conn = mock.MagicMock(connection_id="dummy-connection") - with mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as conn_mgr_cls, mock.patch.object( - ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_conn_retrieve_by_id: + with ( + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as conn_mgr_cls, + mock.patch.object( + ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_conn_retrieve_by_id, + ): conn_mgr_cls.return_value = mock.MagicMock( receive_invitation=mock.CoroutineMock(return_value=mock_conn) ) @@ -1405,17 +1445,20 @@ async def test_existing_conn_record_public_did(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(), - ) as oob_mgr_find_existing_conn, mock.patch.object( - OobRecord, "save", mock.CoroutineMock() - ) as oob_record_save, mock.patch.object( - OobRecord, "retrieve_by_id", mock.CoroutineMock() - ) as oob_record_retrieve_by_id, mock.patch.object( - OutOfBandManager, "fetch_connection_targets", autospec=True - ) as oob_mgr_fetch_conn: + with ( + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(), + ) as oob_mgr_find_existing_conn, + mock.patch.object(OobRecord, "save", mock.CoroutineMock()) as oob_record_save, + mock.patch.object( + OobRecord, "retrieve_by_id", mock.CoroutineMock() + ) as oob_record_retrieve_by_id, + mock.patch.object( + OutOfBandManager, "fetch_connection_targets", autospec=True + ) as oob_mgr_fetch_conn, + ): oob_mgr_find_existing_conn.return_value = test_exist_conn oob_mgr_fetch_conn.return_value = [] oob_invitation = InvitationMessage( @@ -1450,18 +1493,22 @@ async def test_receive_invitation_handshake_reuse(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - test_module.OutOfBandManager, - "_handle_handshake_reuse", - mock.CoroutineMock(), - ) as handle_handshake_reuse, mock.patch.object( - test_module.OutOfBandManager, - "_perform_handshake", - mock.CoroutineMock(), - ) as perform_handshake, mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(return_value=test_exist_conn), + with ( + mock.patch.object( + test_module.OutOfBandManager, + "_handle_handshake_reuse", + mock.CoroutineMock(), + ) as handle_handshake_reuse, + mock.patch.object( + test_module.OutOfBandManager, + "_perform_handshake", + mock.CoroutineMock(), + ) as perform_handshake, + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(return_value=test_exist_conn), + ), ): oob_invitation = InvitationMessage( handshake_protocols=[ @@ -1498,22 +1545,27 @@ async def test_receive_invitation_handshake_reuse_failed(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - test_module.OutOfBandManager, - "_handle_handshake_reuse", - mock.CoroutineMock(), - ) as handle_handshake_reuse, mock.patch.object( - test_module.OutOfBandManager, - "_perform_handshake", - mock.CoroutineMock(), - ) as perform_handshake, mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(return_value=test_exist_conn), - ), mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=test_exist_conn), + with ( + mock.patch.object( + test_module.OutOfBandManager, + "_handle_handshake_reuse", + mock.CoroutineMock(), + ) as handle_handshake_reuse, + mock.patch.object( + test_module.OutOfBandManager, + "_perform_handshake", + mock.CoroutineMock(), + ) as perform_handshake, + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(return_value=test_exist_conn), + ), + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=test_exist_conn), + ), ): oob_invitation = InvitationMessage( handshake_protocols=[ @@ -1562,12 +1614,13 @@ async def test_receive_invitation_services_with_service_did(self): mock_conn = mock.MagicMock(connection_id="dummy") - with mock.patch.object( - test_module, "DIDXManager", autospec=True - ) as didx_mgr_cls, mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_conn), + with ( + mock.patch.object(test_module, "DIDXManager", autospec=True) as didx_mgr_cls, + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_conn), + ), ): didx_mgr_cls.return_value = mock.MagicMock( receive_invitation=mock.CoroutineMock(return_value=mock_conn) @@ -1598,15 +1651,18 @@ async def test_request_attach_oob_message_processor_connectionless(self): endpoint=self.test_endpoint, recipient_keys=[self.test_verkey] ) - with mock.patch.object( - AskarWallet, - "create_signing_key", - mock.CoroutineMock(), - ) as mock_create_signing_key, mock.patch.object( - OutOfBandManager, - "_service_decorator_from_service", - mock.CoroutineMock(), - ) as mock_service_decorator_from_service: + with ( + mock.patch.object( + AskarWallet, + "create_signing_key", + mock.CoroutineMock(), + ) as mock_create_signing_key, + mock.patch.object( + OutOfBandManager, + "_service_decorator_from_service", + mock.CoroutineMock(), + ) as mock_service_decorator_from_service, + ): mock_create_signing_key.return_value = KeyInfo( verkey="H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", metadata={}, @@ -1696,13 +1752,16 @@ async def test_request_attach_wait_for_conn_rec_active(self): their_role=ConnRecord.Role.REQUESTER, ) - with mock.patch.object( - OutOfBandManager, "_wait_for_conn_rec_active" - ) as mock_wait_for_conn_rec_active, mock.patch.object( - ConnRecord, - "find_existing_connection", - mock.CoroutineMock(), - ) as oob_mgr_find_existing_conn: + with ( + mock.patch.object( + OutOfBandManager, "_wait_for_conn_rec_active" + ) as mock_wait_for_conn_rec_active, + mock.patch.object( + ConnRecord, + "find_existing_connection", + mock.CoroutineMock(), + ) as oob_mgr_find_existing_conn, + ): oob_mgr_find_existing_conn.return_value = test_exist_conn mock_wait_for_conn_rec_active.return_value = None oob_invitation = InvitationMessage( @@ -1837,11 +1896,14 @@ async def test_delete_stale_connection_by_invitation(self): updated_at=datetime_to_str(older_datetime), ) ] - with mock.patch.object( - ConnRecord, "query", mock.CoroutineMock() - ) as mock_connrecord_query, mock.patch.object( - ConnRecord, "delete_record", mock.CoroutineMock() - ) as mock_connrecord_delete: + with ( + mock.patch.object( + ConnRecord, "query", mock.CoroutineMock() + ) as mock_connrecord_query, + mock.patch.object( + ConnRecord, "delete_record", mock.CoroutineMock() + ) as mock_connrecord_delete, + ): mock_connrecord_query.return_value = records await self.manager.delete_stale_connection_by_invitation("test123") mock_connrecord_delete.assert_called_once() @@ -1868,15 +1930,20 @@ async def test_delete_conn_and_oob_record_invitation(self): invitation_msg_id="test123", ) ] - with mock.patch.object( - ConnRecord, "query", mock.CoroutineMock() - ) as mock_connrecord_query, mock.patch.object( - ConnRecord, "delete_record", mock.CoroutineMock() - ) as mock_connrecord_delete, mock.patch.object( - OobRecord, "query", mock.CoroutineMock() - ) as mock_oobrecord_query, mock.patch.object( - OobRecord, "delete_record", mock.CoroutineMock() - ) as mock_oobrecord_delete: + with ( + mock.patch.object( + ConnRecord, "query", mock.CoroutineMock() + ) as mock_connrecord_query, + mock.patch.object( + ConnRecord, "delete_record", mock.CoroutineMock() + ) as mock_connrecord_delete, + mock.patch.object( + OobRecord, "query", mock.CoroutineMock() + ) as mock_oobrecord_query, + mock.patch.object( + OobRecord, "delete_record", mock.CoroutineMock() + ) as mock_oobrecord_delete, + ): mock_connrecord_query.return_value = conn_records mock_oobrecord_query.return_value = oob_records await self.manager.delete_conn_and_oob_record_invitation("test123") diff --git a/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py b/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py index a42378c811..6e25915185 100644 --- a/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/out_of_band/v1_0/tests/test_routes.py @@ -40,11 +40,14 @@ async def test_invitation_create(self): } self.request.json = mock.CoroutineMock(return_value=body) - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.create_invitation = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(return_value={"abc": "123"}) @@ -75,11 +78,14 @@ async def test_invitation_create(self): async def test_invitation_remove(self): self.request.match_info = {"invi_msg_id": "dummy"} - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.delete_conn_and_oob_record_invitation = ( mock.CoroutineMock(return_value=None) ) @@ -100,11 +106,14 @@ async def test_invitation_create_with_accept(self): } self.request.json = mock.CoroutineMock(return_value=body) - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.create_invitation = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(return_value={"abc": "123"}) @@ -142,11 +151,14 @@ async def test_invitation_create_x(self): } ) - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.create_invitation = mock.CoroutineMock( side_effect=test_module.OutOfBandManagerError() ) @@ -159,13 +171,15 @@ async def test_invitation_receive(self): self.request.json = mock.CoroutineMock() expected_connection_record = ConnRecord(connection_id="some-id") - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.InvitationMessage, "deserialize", mock.Mock() - ), mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object(test_module.InvitationMessage, "deserialize", mock.Mock()), + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_oob_mgr.return_value.receive_invitation = mock.CoroutineMock( return_value=expected_connection_record ) @@ -183,11 +197,13 @@ async def test_invitation_receive_forbidden_x(self): async def test_invitation_receive_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "OutOfBandManager", autospec=True - ) as mock_oob_mgr, mock.patch.object( - test_module.InvitationMessage, "deserialize", mock.Mock() - ), mock.patch.object(test_module.web, "json_response", mock.Mock()): + with ( + mock.patch.object( + test_module, "OutOfBandManager", autospec=True + ) as mock_oob_mgr, + mock.patch.object(test_module.InvitationMessage, "deserialize", mock.Mock()), + mock.patch.object(test_module.web, "json_response", mock.Mock()), + ): mock_oob_mgr.return_value.receive_invitation = mock.CoroutineMock( side_effect=test_module.StorageError("cannot write") ) diff --git a/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py b/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py index 654c62f432..3af1efe80e 100644 --- a/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py +++ b/acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py @@ -2177,27 +2177,33 @@ async def test_create_vp_no_issuer(self): cred_tags={"some": "tag"}, ), ] - with mock.patch.object( - DIFPresExchHandler, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info, mock.patch.object( - DIFPresExchHandler, - "make_requirement", - mock.CoroutineMock(), - ) as mock_make_req, mock.patch.object( - DIFPresExchHandler, - "apply_requirements", - mock.CoroutineMock(), - ) as mock_apply_req, mock.patch.object( - DIFPresExchHandler, - "merge", - mock.CoroutineMock(), - ) as mock_merge, mock.patch.object( - test_module, - "create_presentation", - mock.CoroutineMock(), - ) as mock_create_vp: + with ( + mock.patch.object( + DIFPresExchHandler, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + mock.patch.object( + DIFPresExchHandler, + "make_requirement", + mock.CoroutineMock(), + ) as mock_make_req, + mock.patch.object( + DIFPresExchHandler, + "apply_requirements", + mock.CoroutineMock(), + ) as mock_apply_req, + mock.patch.object( + DIFPresExchHandler, + "merge", + mock.CoroutineMock(), + ) as mock_merge, + mock.patch.object( + test_module, + "create_presentation", + mock.CoroutineMock(), + ) as mock_create_vp, + ): mock_make_req.return_value = mock.MagicMock() mock_apply_req.return_value = mock.MagicMock() mock_merge.return_value = (VC_RECORDS, {}) @@ -2229,31 +2235,38 @@ async def test_create_vp_with_bbs_suite(self): self.profile, proof_type=BbsBlsSignature2020.signature_type ) cred_list, pd_list = await self.setup_tuple(self.profile) - with mock.patch.object( - DIFPresExchHandler, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info, mock.patch.object( - DIFPresExchHandler, - "make_requirement", - mock.CoroutineMock(), - ) as mock_make_req, mock.patch.object( - DIFPresExchHandler, - "apply_requirements", - mock.CoroutineMock(), - ) as mock_apply_req, mock.patch.object( - DIFPresExchHandler, - "merge", - mock.CoroutineMock(), - ) as mock_merge, mock.patch.object( - test_module, - "create_presentation", - mock.CoroutineMock(), - ) as mock_create_vp, mock.patch.object( - test_module, - "sign_presentation", - mock.CoroutineMock(), - ) as mock_sign_vp: + with ( + mock.patch.object( + DIFPresExchHandler, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + mock.patch.object( + DIFPresExchHandler, + "make_requirement", + mock.CoroutineMock(), + ) as mock_make_req, + mock.patch.object( + DIFPresExchHandler, + "apply_requirements", + mock.CoroutineMock(), + ) as mock_apply_req, + mock.patch.object( + DIFPresExchHandler, + "merge", + mock.CoroutineMock(), + ) as mock_merge, + mock.patch.object( + test_module, + "create_presentation", + mock.CoroutineMock(), + ) as mock_create_vp, + mock.patch.object( + test_module, + "sign_presentation", + mock.CoroutineMock(), + ) as mock_sign_vp, + ): mock_make_req.return_value = mock.MagicMock() mock_apply_req.return_value = mock.MagicMock() mock_merge.return_value = (cred_list, {}) @@ -2286,31 +2299,38 @@ async def test_create_vp_no_issuer_with_bbs_suite(self): self.profile, proof_type=BbsBlsSignature2020.signature_type ) cred_list, pd_list = await self.setup_tuple(self.profile) - with mock.patch.object( - DIFPresExchHandler, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info, mock.patch.object( - DIFPresExchHandler, - "make_requirement", - mock.CoroutineMock(), - ) as mock_make_req, mock.patch.object( - DIFPresExchHandler, - "apply_requirements", - mock.CoroutineMock(), - ) as mock_apply_req, mock.patch.object( - DIFPresExchHandler, - "merge", - mock.CoroutineMock(), - ) as mock_merge, mock.patch.object( - test_module, - "create_presentation", - mock.CoroutineMock(), - ) as mock_create_vp, mock.patch.object( - DIFPresExchHandler, - "get_sign_key_credential_subject_id", - mock.CoroutineMock(), - ) as mock_sign_key_cred_subject: + with ( + mock.patch.object( + DIFPresExchHandler, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + mock.patch.object( + DIFPresExchHandler, + "make_requirement", + mock.CoroutineMock(), + ) as mock_make_req, + mock.patch.object( + DIFPresExchHandler, + "apply_requirements", + mock.CoroutineMock(), + ) as mock_apply_req, + mock.patch.object( + DIFPresExchHandler, + "merge", + mock.CoroutineMock(), + ) as mock_merge, + mock.patch.object( + test_module, + "create_presentation", + mock.CoroutineMock(), + ) as mock_create_vp, + mock.patch.object( + DIFPresExchHandler, + "get_sign_key_credential_subject_id", + mock.CoroutineMock(), + ) as mock_sign_key_cred_subject, + ): mock_make_req.return_value = mock.MagicMock() mock_apply_req.return_value = mock.MagicMock() mock_merge.return_value = (cred_list, {}) diff --git a/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py b/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py index e43c2e80b0..25ccd85984 100644 --- a/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py +++ b/acapy_agent/protocols/present_proof/v1_0/handlers/tests/test_presentation_request_handler.py @@ -97,11 +97,14 @@ async def test_called(self): auto_present=True, ) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance ) @@ -149,11 +152,14 @@ async def test_called_not_found(self): auto_present=True, ) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( side_effect=StorageNotFoundError ) @@ -222,11 +228,14 @@ async def test_called_auto_present(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -302,11 +311,14 @@ async def test_called_auto_present_x(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = mock_px_rec mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -368,11 +380,14 @@ async def test_called_auto_present_no_preview(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -435,11 +450,14 @@ async def test_called_auto_present_pred_no_match(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -498,11 +516,14 @@ async def test_called_auto_present_pred_single_match(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -570,11 +591,14 @@ async def test_called_auto_present_pred_multi_match(self): ) self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -694,11 +718,14 @@ async def test_called_auto_present_multi_cred_match_reft(self): self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -798,11 +825,14 @@ async def test_called_auto_present_bait_and_switch(self): mock_holder.get_credentials_for_presentation_request_by_referent = by_reft self.request_context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "PresentationManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V10PresentationExchange", autospec=True - ) as mock_pres_ex_cls: + with ( + mock.patch.object( + test_module, "PresentationManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V10PresentationExchange", autospec=True + ) as mock_pres_ex_cls, + ): mock_pres_ex_cls.return_value = px_rec_instance mock_pres_ex_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance diff --git a/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py b/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py index 6868be17f3..4556877338 100644 --- a/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py +++ b/acapy_agent/protocols/present_proof/v1_0/models/tests/test_record.py @@ -129,11 +129,12 @@ async def test_save_error_state(self): record.state = V10PresentationExchange.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="testing") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py b/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py index 7674f7e1f7..574acb5139 100644 --- a/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/present_proof/v1_0/tests/test_manager.py @@ -340,9 +340,10 @@ async def test_record_eq(self): async def test_create_exchange_for_proposal(self): proposal = PresentationProposal() - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object(PresentationProposal, "serialize", autospec=True): + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object(PresentationProposal, "serialize", autospec=True), + ): exchange = await self.manager.create_exchange_for_proposal( CONN_ID, proposal, @@ -441,13 +442,15 @@ async def test_create_presentation(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -484,13 +487,15 @@ async def test_create_presentation_proof_req_non_revoc_interval_none(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -545,13 +550,15 @@ async def test_create_presentation_self_asserted(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -616,13 +623,15 @@ async def test_create_presentation_no_revocation(self): self.holder.create_presentation = mock.CoroutineMock(return_value="{}") self.profile.context.injector.bind_instance(IndyHolder, self.holder) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module.LOGGER, "info", mock.MagicMock() - ) as mock_log_info: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module.LOGGER, "info", mock.MagicMock() + ) as mock_log_info, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -690,13 +699,15 @@ async def test_create_presentation_bad_revoc_state(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -776,13 +787,15 @@ async def test_create_presentation_multi_matching_proposal_creds_names(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - test_module, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + test_module, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -921,13 +934,14 @@ async def test_receive_presentation(self): }, ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - V10PresentationExchange, - "retrieve_by_tag_filter", - mock.CoroutineMock(return_value=exchange_dummy), - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + V10PresentationExchange, + "retrieve_by_tag_filter", + mock.CoroutineMock(return_value=exchange_dummy), + ) as retrieve_ex, + ): retrieve_ex.side_effect = [exchange_dummy] exchange_out = await self.manager.receive_presentation( PRES, connection_record, None @@ -1024,11 +1038,12 @@ async def test_receive_presentation_oob(self): }, ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [exchange_dummy] exchange_out = await self.manager.receive_presentation(PRES, None, None) assert exchange_out.state == ( @@ -1125,11 +1140,12 @@ async def test_receive_presentation_bait_and_switch(self): }, ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ), mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True), + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy with self.assertRaises(PresentationManagerError): await self.manager.receive_presentation(PRES, connection_record, None) @@ -1137,11 +1153,12 @@ async def test_receive_presentation_bait_and_switch(self): async def test_receive_presentation_connectionless(self): exchange_dummy = V10PresentationExchange() - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy exchange_out = await self.manager.receive_presentation(PRES, None, None) save_ex.assert_called_once() @@ -1221,11 +1238,12 @@ async def test_receive_presentation_ack_a(self): exchange_dummy = V10PresentationExchange() message = mock.MagicMock() - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy exchange_out = await self.manager.receive_presentation_ack( message, connection_record @@ -1242,11 +1260,12 @@ async def test_receive_presentation_ack_b(self): exchange_dummy = V10PresentationExchange() message = mock.MagicMock(_verification_result="true") - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = exchange_dummy exchange_out = await self.manager.receive_presentation_ack( message, connection_record @@ -1275,17 +1294,19 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V10PresentationExchange, "save", autospec=True - ) as save_ex, mock.patch.object( - V10PresentationExchange, - "retrieve_by_tag_filter", - mock.CoroutineMock(), - ) as retrieve_ex, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session: + with ( + mock.patch.object(V10PresentationExchange, "save", autospec=True) as save_ex, + mock.patch.object( + V10PresentationExchange, + "retrieve_by_tag_filter", + mock.CoroutineMock(), + ) as retrieve_ex, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + ): retrieve_ex.return_value = stored_exchange ret_exchange = await self.manager.receive_problem_report( diff --git a/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py b/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py index 5c55474765..28c7930443 100644 --- a/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/tests/test_routes.py @@ -300,16 +300,20 @@ async def test_presentation_exchange_retrieve_x(self): async def test_presentation_exchange_send_proposal(self): self.request.json = mock.CoroutineMock() - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ), mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ) as mock_preview: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ), + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ) as mock_preview, + ): # Since we are mocking import importlib.reload(test_module) @@ -347,18 +351,22 @@ async def test_presentation_exchange_send_proposal_no_conn_record(self): async def test_presentation_exchange_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "messages.presentation_proposal.PresentationProposal" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "messages.presentation_proposal.PresentationProposal" + ), + autospec=True, ), - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -372,15 +380,19 @@ async def test_presentation_exchange_send_proposal_not_ready(self): async def test_presentation_exchange_send_proposal_x(self): self.request.json = mock.CoroutineMock() - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ), mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ), + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), ): # Since we are mocking import importlib.reload(test_module) @@ -402,26 +414,31 @@ async def test_presentation_exchange_create_request(self): return_value={"comment": "dummy", "proof_request": {}} ) - with mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ) as mock_attach_decorator, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ) as mock_attach_decorator, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -451,26 +468,31 @@ async def test_presentation_exchange_create_request_x(self): return_value={"comment": "dummy", "proof_request": {}} ) - with mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ), + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -496,30 +518,36 @@ async def test_presentation_exchange_send_free_request(self): } ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ) as mock_attach_decorator, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ) as mock_attach_decorator, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -592,28 +620,32 @@ async def test_presentation_exchange_send_free_request_x(self): } ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ) as mock_attach_decorator, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ) as mock_attach_decorator, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, ), - autospec=True, ): # Since we are mocking import importlib.reload(test_module) @@ -655,27 +687,33 @@ async def test_presentation_exchange_send_bound_request(self): ), ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ) as mock_presentation_request, mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange", - autospec=True, - ) as mock_presentation_exchange: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object( + test_module, "PresentationRequest", autospec=True + ) as mock_presentation_request, + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange", + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -712,29 +750,33 @@ async def test_presentation_exchange_send_bound_request_not_found(self): self.request.json = mock.CoroutineMock(return_value={"trace": False}) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -756,29 +798,33 @@ async def test_presentation_exchange_send_bound_request_not_ready(self): self.request.json = mock.CoroutineMock(return_value={"trace": False}) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -839,29 +885,33 @@ async def test_presentation_exchange_send_bound_request_x(self): self.request.json = mock.CoroutineMock(return_value={"trace": False}) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -921,21 +971,24 @@ async def test_presentation_exchange_send_presentation(self): ), ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" - ), - autospec=True, - ) as mock_presentation_exchange: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -987,29 +1040,33 @@ async def test_presentation_exchange_send_presentation_not_found(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1031,29 +1088,33 @@ async def test_presentation_exchange_send_presentation_not_ready(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, + ), + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1105,29 +1166,33 @@ async def test_presentation_exchange_send_presentation_x(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch.object( - test_module, "IndyPresPreview", autospec=True - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch.object(test_module, "IndyPresPreview", autospec=True), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1158,30 +1223,36 @@ async def test_presentation_exchange_send_presentation_x(self): async def test_presentation_exchange_verify_presentation(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - "acapy_agent.indy.util.generate_pr_nonce", - autospec=True, - ), mock.patch( - "acapy_agent.indy.models.pres_preview.IndyPresPreview", - autospec=True, - ), mock.patch.object( - test_module, "PresentationRequest", autospec=True - ), mock.patch( - "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + "acapy_agent.indy.util.generate_pr_nonce", + autospec=True, ), - autospec=True, - ) as mock_presentation_exchange: + mock.patch( + "acapy_agent.indy.models.pres_preview.IndyPresPreview", + autospec=True, + ), + mock.patch.object(test_module, "PresentationRequest", autospec=True), + mock.patch( + "acapy_agent.messaging.decorators.attach_decorator.AttachDecorator", + autospec=True, + ), + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1262,19 +1333,23 @@ async def test_presentation_exchange_verify_presentation_x(self): ), ) - with mock.patch( - "acapy_agent.connections.models.conn_record.ConnRecord", - autospec=True, - ) as mock_connection_record, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ) as mock_presentation_manager, mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" - ), - autospec=True, - ) as mock_presentation_exchange: + with ( + mock.patch( + "acapy_agent.connections.models.conn_record.ConnRecord", + autospec=True, + ) as mock_connection_record, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, + ) as mock_presentation_manager, + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_presentation_exchange, + ): # Since we are mocking import importlib.reload(test_module) @@ -1314,20 +1389,23 @@ async def test_presentation_exchange_problem_report(self): self.request.match_info = {"pres_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_pres_ex, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_pres_ex, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): # Since we are mocking import importlib.reload(test_module) @@ -1347,16 +1425,19 @@ async def test_presentation_exchange_problem_report_bad_pres_ex_id(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_pres_ex: + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_pres_ex, + ): # Since we are mocking import importlib.reload(test_module) @@ -1371,18 +1452,21 @@ async def test_presentation_exchange_problem_report_x(self): self.request.json = mock.CoroutineMock() self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch( - ( - "acapy_agent.protocols.present_proof.v1_0." - "models.presentation_exchange.V10PresentationExchange" + with ( + mock.patch( + ( + "acapy_agent.protocols.present_proof.v1_0." + "models.presentation_exchange.V10PresentationExchange" + ), + autospec=True, + ) as mock_pres_ex, + mock.patch( + "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", + autospec=True, ), - autospec=True, - ) as mock_pres_ex, mock.patch( - "acapy_agent.protocols.present_proof.v1_0.manager.PresentationManager", - autospec=True, - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object(test_module.web, "json_response"): + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object(test_module.web, "json_response"), + ): # Since we are mocking import importlib.reload(test_module) mock_pres_ex.retrieve_by_id = mock.CoroutineMock( diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py index 820fe2771e..2d0f73d59d 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py @@ -727,17 +727,20 @@ async def test_create_pres_prover_proof_spec_with_record_ids(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - DIFPresExchHandler, - "create_vp", - mock.CoroutineMock(), - ) as mock_create_vp, mock.patch.object( - VCHolder, - "search_credentials", - mock.CoroutineMock( - return_value=mock.MagicMock( - fetch=mock.CoroutineMock(return_value=cred_list) - ) + with ( + mock.patch.object( + DIFPresExchHandler, + "create_vp", + mock.CoroutineMock(), + ) as mock_create_vp, + mock.patch.object( + VCHolder, + "search_credentials", + mock.CoroutineMock( + return_value=mock.MagicMock( + fetch=mock.CoroutineMock(return_value=cred_list) + ) + ), ), ): mock_create_vp.return_value = DIF_PRES @@ -2211,11 +2214,12 @@ async def test_verify_received_pres_fail_schema_filter(self): auto_present=True, error_msg="error", ) - with mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ) as mock_log_err, mock.patch.object( - jsonld, "expand", mock.MagicMock() - ) as mock_jsonld_expand: + with ( + mock.patch.object( + test_module.LOGGER, "error", mock.MagicMock() + ) as mock_log_err, + mock.patch.object(jsonld, "expand", mock.MagicMock()) as mock_jsonld_expand, + ): mock_jsonld_expand.return_value = EXPANDED_CRED_FHIR_TYPE_2 await self.handler.receive_pres(message=dif_pres, pres_ex_record=record) mock_log_err.assert_called_once() diff --git a/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py b/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py index 0168fa6a36..bbce190491 100644 --- a/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/handlers/tests/test_pres_request_handler.py @@ -220,11 +220,14 @@ async def test_called(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance ) @@ -261,11 +264,14 @@ async def test_called_not_found(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( side_effect=StorageNotFoundError ) @@ -304,11 +310,14 @@ async def test_called_auto_present_x_indy(self): save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -347,11 +356,14 @@ async def test_called_auto_present_x_anoncreds(self): save_error_state=mock.CoroutineMock(), ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -389,11 +401,14 @@ async def test_called_auto_present_indy(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -463,11 +478,14 @@ async def test_called_auto_present_anoncreds(self): auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -526,11 +544,14 @@ async def test_called_auto_present_dif(self): pres_proposal=pres_proposal, auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -585,11 +606,14 @@ async def test_called_auto_present_no_preview_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -644,11 +668,14 @@ async def test_called_auto_present_no_preview_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -704,11 +731,14 @@ async def test_called_auto_present_pred_no_match_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -760,11 +790,14 @@ async def test_called_auto_present_pred_no_match_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = mock_px_rec mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=mock_px_rec @@ -810,11 +843,14 @@ async def test_called_auto_present_pred_single_match_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -864,11 +900,14 @@ async def test_called_auto_present_pred_single_match_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -923,11 +962,14 @@ async def test_called_auto_present_pred_multi_match_indy(self): ) self.request_context.injector.bind_instance(IndyHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -982,11 +1024,14 @@ async def test_called_auto_present_pred_multi_match_anoncreds(self): ) self.request_context.injector.bind_instance(AnonCredsHolder, self.mock_holder) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -1084,11 +1129,14 @@ async def test_called_auto_present_multi_cred_match_reft_indy(self): pres_proposal=pres_proposal.serialize(), auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance @@ -1186,11 +1234,14 @@ async def test_called_auto_present_multi_cred_match_reft_anoncreds(self): pres_proposal=pres_proposal.serialize(), auto_present=True, ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + ): mock_pres_ex_rec_cls.return_value = px_rec_instance mock_pres_ex_rec_cls.retrieve_by_tag_filter = mock.CoroutineMock( return_value=px_rec_instance diff --git a/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py b/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py index ee0255e9a6..eafd51d68c 100644 --- a/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py +++ b/acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py @@ -124,11 +124,12 @@ async def test_save_error_state(self): record.state = V20PresExRecord.STATE_PROPOSAL_RECEIVED await record.save(session) - with mock.patch.object( - record, "save", mock.CoroutineMock() - ) as mock_save, mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ) as mock_log_exc: + with ( + mock.patch.object(record, "save", mock.CoroutineMock()) as mock_save, + mock.patch.object( + test_module.LOGGER, "exception", mock.MagicMock() + ) as mock_log_exc, + ): mock_save.side_effect = test_module.StorageError() await record.save_error_state(session, reason="testing") mock_log_exc.assert_called_once() diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py index 94a6ee2966..ccc823dabf 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager.py @@ -512,9 +512,10 @@ async def test_create_exchange_for_proposal(self): ] ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object(V20PresProposal, "serialize", autospec=True): + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object(V20PresProposal, "serialize", autospec=True), + ): px_rec = await self.manager.create_exchange_for_proposal( CONN_ID, proposal, @@ -704,11 +705,14 @@ async def test_receive_pres_catch_diferror(self): pres_request=pres_req.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object( - DIFPresFormatHandler, "receive_pres", autospec=True - ) as mock_receive_pres, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object( + DIFPresFormatHandler, "receive_pres", autospec=True + ) as mock_receive_pres, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): mock_receive_pres.return_value = False retrieve_ex.side_effect = [px_rec] with self.assertRaises(V20PresManagerError) as context: @@ -776,13 +780,15 @@ async def test_create_pres_indy(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -830,15 +836,18 @@ async def test_create_pres_indy_and_dif(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator_indy, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - DIFPresFormatHandler, "create_pres", autospec=True - ) as mock_create_pres: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator_indy, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object( + DIFPresFormatHandler, "create_pres", autospec=True + ) as mock_create_pres, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator_indy.data_base64 = mock.MagicMock( @@ -891,17 +900,20 @@ async def test_create_pres_proof_req_non_revoc_interval_none(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -943,13 +955,15 @@ async def test_create_pres_self_asserted(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -1021,13 +1035,15 @@ async def test_create_pres_no_revocation(self): self.holder.create_presentation = mock.CoroutineMock(return_value="{}") self.profile.context.injector.bind_instance(IndyHolder, self.holder) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module.LOGGER, "info", mock.MagicMock() - ) as mock_log_info: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module.LOGGER, "info", mock.MagicMock() + ) as mock_log_info, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -1116,12 +1132,15 @@ async def test_create_pres_bad_revoc_state(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - test_indy_util_module.LOGGER, "error", mock.MagicMock() + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object(test_indy_util_module.LOGGER, "error", mock.MagicMock()), ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) @@ -1203,13 +1222,15 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -1287,9 +1308,12 @@ async def test_no_matching_creds_indy_handler(self): get_creds = mock.CoroutineMock(return_value=()) self.holder.get_credentials_for_presentation_request_by_referent = get_creds - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -1352,11 +1376,12 @@ async def test_receive_pres(self): assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME assert by_format.get("pres_request").get("indy") == INDY_PROOF_REQ_NAME - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1421,11 +1446,12 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self): assert by_format.get("pres_proposal").get("indy") == INDY_PROOF_REQ_NAME assert by_format.get("pres_request").get("indy") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1497,11 +1523,12 @@ async def test_receive_pres_indy_no_predicate_restrictions(self): assert by_format.get("pres_request").get("indy") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1569,11 +1596,12 @@ async def test_receive_pres_indy_no_attr_restrictions(self): assert by_format.get("pres_request").get("indy") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1630,9 +1658,12 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1678,9 +1709,12 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1733,9 +1767,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1785,9 +1822,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1838,9 +1878,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1890,9 +1933,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1942,9 +1988,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1994,9 +2043,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -2036,11 +2088,14 @@ async def test_verify_pres(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() @@ -2096,32 +2151,40 @@ async def test_verify_pres_indy_and_dif(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch( - "acapy_agent.vc.vc_ld.verify.verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=False) + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), ), - ), mock.patch.object( - IndyVerifier, - "verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=True) + mock.patch( + "acapy_agent.vc.vc_ld.verify.verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=False) + ), + ), + mock.patch.object( + IndyVerifier, + "verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=True) + ), ), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) @@ -2167,11 +2230,12 @@ async def test_receive_pres_ack_a(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock() - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2184,11 +2248,12 @@ async def test_receive_pres_ack_b(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock(_verification_result="true") - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2213,17 +2278,19 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, - "retrieve_by_tag_filter", - mock.CoroutineMock(), - ) as retrieve_ex, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, + "retrieve_by_tag_filter", + mock.CoroutineMock(), + ) as retrieve_ex, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + ): retrieve_ex.return_value = stored_exchange await self.manager.receive_problem_report(problem, connection_id) diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py index 78d93e01a7..9f88377968 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_manager_anoncreds.py @@ -518,9 +518,10 @@ async def test_create_exchange_for_proposal(self): ] ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object(V20PresProposal, "serialize", autospec=True): + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object(V20PresProposal, "serialize", autospec=True), + ): px_rec = await self.manager.create_exchange_for_proposal( CONN_ID, proposal, @@ -712,11 +713,14 @@ async def test_receive_pres_catch_diferror(self): pres_request=pres_req.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object( - DIFPresFormatHandler, "receive_pres", autospec=True - ) as mock_receive_pres, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object( + DIFPresFormatHandler, "receive_pres", autospec=True + ) as mock_receive_pres, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): mock_receive_pres.return_value = False retrieve_ex.side_effect = [px_rec] with self.assertRaises(V20PresManagerError) as context: @@ -787,13 +791,15 @@ async def test_create_pres_indy(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -842,15 +848,18 @@ async def test_create_pres_indy_and_dif(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator_indy, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - DIFPresFormatHandler, "create_pres", autospec=True - ) as mock_create_pres: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator_indy, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object( + DIFPresFormatHandler, "create_pres", autospec=True + ) as mock_create_pres, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator_indy.data_base64 = mock.MagicMock( @@ -904,17 +913,20 @@ async def test_create_pres_proof_req_non_revoc_interval_none(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -957,13 +969,15 @@ async def test_create_pres_self_asserted(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -1036,13 +1050,15 @@ async def test_create_pres_no_revocation(self): self.holder.create_presentation = mock.AsyncMock(return_value="{}") self.profile.context.injector.bind_instance(AnonCredsHolder, self.holder) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module.LOGGER, "info", mock.MagicMock() - ) as mock_log_info: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module.LOGGER, "info", mock.MagicMock() + ) as mock_log_info, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -1132,12 +1148,15 @@ async def test_create_pres_bad_revoc_state(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr, mock.patch.object( - test_indy_util_module.LOGGER, "error", mock.MagicMock() + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + mock.patch.object(test_indy_util_module.LOGGER, "error", mock.MagicMock()), ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) @@ -1220,13 +1239,15 @@ async def test_create_pres_multi_matching_proposal_creds_names(self): return_value="/tmp/sample/tails/path" ) ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator, mock.patch.object( - test_indy_util_module, "RevocationRegistry", autospec=True - ) as mock_rr: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + mock.patch.object( + test_indy_util_module, "RevocationRegistry", autospec=True + ) as mock_rr, + ): mock_rr.from_definition = mock.MagicMock(return_value=more_magic_rr) mock_attach_decorator.data_base64 = mock.MagicMock( @@ -1304,9 +1325,12 @@ async def test_no_matching_creds_indy_handler(self): get_creds = mock.CoroutineMock(return_value=()) self.holder.get_credentials_for_presentation_request_by_referent = get_creds - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - test_indy_handler, "AttachDecorator", autospec=True - ) as mock_attach_decorator: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + test_indy_handler, "AttachDecorator", autospec=True + ) as mock_attach_decorator, + ): mock_attach_decorator.data_base64 = mock.MagicMock( return_value=mock_attach_decorator ) @@ -1375,11 +1399,12 @@ async def test_receive_pres(self): assert by_format.get("pres_proposal").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME assert by_format.get("pres_request").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1448,11 +1473,12 @@ async def test_receive_pres_receive_pred_value_mismatch_punt_to_indy(self): assert by_format.get("pres_proposal").get("anoncreds") == ANONCREDS_PROOF_REQ_NAME assert by_format.get("pres_request").get("anoncreds") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1528,11 +1554,12 @@ async def test_receive_pres_indy_no_predicate_restrictions(self): assert by_format.get("pres_request").get("anoncreds") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1602,11 +1629,12 @@ async def test_receive_pres_indy_no_attr_restrictions(self): assert by_format.get("pres_request").get("anoncreds") == indy_proof_req - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.side_effect = [px_rec_dummy] px_rec_out = await self.manager.receive_pres(pres, connection_record, None) assert retrieve_ex.call_args.args[1] == {"thread_id": "thread-id"} @@ -1667,9 +1695,12 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1723,9 +1754,12 @@ async def test_receive_pres_bait_and_switch_attr_name(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1782,9 +1816,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1840,9 +1877,12 @@ async def test_receive_pres_bait_and_switch_attr_names(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1897,9 +1937,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -1957,9 +2000,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -2017,9 +2063,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -2077,9 +2126,12 @@ async def test_receive_pres_bait_and_switch_pred(self): pres_request=pres_request.serialize(), pres=pres_x.serialize(), ) - with mock.patch.object(V20PresExRecord, "save", autospec=True), mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True), + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy with self.assertRaises(V20PresFormatHandlerError) as context: await self.manager.receive_pres(pres_x, connection_record, None) @@ -2124,11 +2176,14 @@ async def test_verify_pres(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() @@ -2187,32 +2242,40 @@ async def test_verify_pres_indy_and_dif(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), - ), mock.patch( - "acapy_agent.vc.vc_ld.verify.verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=False) + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=("test_ledger_id", self.ledger)), ), - ), mock.patch.object( - AnonCredsVerifier, - "verify_presentation", - mock.CoroutineMock( - return_value=PresentationVerificationResult(verified=True) + mock.patch( + "acapy_agent.vc.vc_ld.verify.verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=False) + ), ), - ), mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex: + mock.patch.object( + AnonCredsVerifier, + "verify_presentation", + mock.CoroutineMock( + return_value=PresentationVerificationResult(verified=True) + ), + ), + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + ): px_rec_out = await self.manager.verify_pres(px_rec_in) save_ex.assert_called_once() assert px_rec_out.state == (V20PresExRecord.STATE_DONE) @@ -2258,11 +2321,12 @@ async def test_receive_pres_ack_a(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock() - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2275,11 +2339,12 @@ async def test_receive_pres_ack_b(self): px_rec_dummy = V20PresExRecord() message = mock.MagicMock(_verification_result="true") - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, "retrieve_by_tag_filter", autospec=True - ) as retrieve_ex: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, "retrieve_by_tag_filter", autospec=True + ) as retrieve_ex, + ): retrieve_ex.return_value = px_rec_dummy px_rec_out = await self.manager.receive_pres_ack(message, conn_record) save_ex.assert_called_once() @@ -2304,17 +2369,19 @@ async def test_receive_problem_report(self): } ) - with mock.patch.object( - V20PresExRecord, "save", autospec=True - ) as save_ex, mock.patch.object( - V20PresExRecord, - "retrieve_by_tag_filter", - mock.CoroutineMock(), - ) as retrieve_ex, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session: + with ( + mock.patch.object(V20PresExRecord, "save", autospec=True) as save_ex, + mock.patch.object( + V20PresExRecord, + "retrieve_by_tag_filter", + mock.CoroutineMock(), + ) as retrieve_ex, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + ): retrieve_ex.return_value = stored_exchange await self.manager.receive_problem_report(problem, connection_id) diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py index b1fb15ef7f..7d120b0052 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes.py @@ -256,11 +256,14 @@ async def test_present_proof_list(self): mock_pres_ex_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.query = mock.CoroutineMock( return_value=[mock_pres_ex_rec_inst] ) @@ -339,11 +342,14 @@ async def test_present_proof_credentials_list_single_referent(self): ) self.profile.context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -365,11 +371,14 @@ async def test_present_proof_credentials_list_multiple_referents(self): ) self.profile.context.injector.bind_instance(IndyHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -429,11 +438,14 @@ async def test_present_proof_credentials_list_dif(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -506,11 +518,14 @@ async def test_present_proof_credentials_list_dif_one_of_filter(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -579,11 +594,14 @@ async def test_present_proof_credentials_dif_no_tag_query(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -652,11 +670,14 @@ async def test_present_proof_credentials_single_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -725,11 +746,14 @@ async def test_present_proof_credentials_double_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -791,10 +815,11 @@ async def test_present_proof_credentials_single_ldp_vp_error(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -851,10 +876,11 @@ async def test_present_proof_credentials_double_ldp_vp_error(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -908,10 +934,11 @@ async def test_present_proof_credentials_list_limit_disclosure_no_bbs(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -968,10 +995,11 @@ async def test_present_proof_credentials_no_ldp_vp(self): mock_vc_holder.search_credentials = mock.MagicMock() self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -1034,11 +1062,14 @@ async def test_present_proof_credentials_list_schema_uri(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_vc_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) mock_response.assert_called_once_with( @@ -1097,10 +1128,11 @@ async def test_present_proof_credentials_list_dif_error(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): with self.assertRaises(test_module.web.HTTPBadRequest): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record @@ -1109,11 +1141,14 @@ async def test_present_proof_credentials_list_dif_error(self): async def test_present_proof_retrieve(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock( @@ -1165,15 +1200,16 @@ async def test_present_proof_send_proposal(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=True) ) @@ -1199,10 +1235,11 @@ async def test_present_proof_send_proposal_no_conn_record(self): async def test_present_proof_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresProposal", autospec=True + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object(test_module, "V20PresProposal", autospec=True), ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=False) @@ -1214,11 +1251,12 @@ async def test_present_proof_send_proposal_not_ready(self): async def test_present_proof_send_proposal_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + ): mock_pres_mgr.return_value.create_exchange_for_proposal = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.StorageError()), @@ -1240,13 +1278,15 @@ async def test_present_proof_create_request(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) @@ -1268,11 +1308,13 @@ async def test_present_proof_create_request_x(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module.web, "json_response", mock.MagicMock()): + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), + ): mock_pres_mgr_inst = mock.MagicMock( create_exchange_for_request=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1295,17 +1337,19 @@ async def test_present_proof_send_free_request(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock({"thread_id": "sample-thread-id"}) @@ -1359,13 +1403,16 @@ async def test_present_proof_send_free_request_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module, "V20PresExRecord", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + ): mock_conn_rec_inst = mock.MagicMock() mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_conn_rec_inst @@ -1401,15 +1448,20 @@ async def test_present_proof_send_bound_request(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1454,11 +1506,14 @@ async def test_present_proof_send_bound_request_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1492,11 +1547,14 @@ async def test_present_proof_send_bound_request_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1580,13 +1638,17 @@ async def test_present_proof_send_bound_request_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1634,15 +1696,18 @@ async def test_present_proof_send_presentation(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1685,15 +1750,18 @@ async def test_present_proof_send_presentation_dif(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1758,15 +1826,18 @@ async def test_present_proof_send_presentation_dif_error(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=px_rec_instance ) @@ -1831,11 +1902,14 @@ async def test_present_proof_send_presentation_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1873,11 +1947,14 @@ async def test_present_proof_send_presentation_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1945,13 +2022,18 @@ async def test_present_proof_send_presentation_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1985,15 +2067,20 @@ async def test_present_proof_send_presentation_x(self): async def test_present_proof_verify_presentation(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PRESENTATION_RECEIVED, @@ -2050,14 +2137,17 @@ async def test_present_proof_verify_presentation_bad_state(self): async def test_present_proof_verify_presentation_x(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", @@ -2095,15 +2185,16 @@ async def test_present_proof_problem_report(self): self.request.match_info = {"pres_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -2136,13 +2227,13 @@ async def test_present_proof_problem_report_x(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageError() ) @@ -2153,11 +2244,14 @@ async def test_present_proof_problem_report_x(self): async def test_present_proof_remove(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( state=test_module.V20PresExRecord.STATE_DONE, diff --git a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py index faa4f0f278..4a29ff2b08 100644 --- a/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py +++ b/acapy_agent/protocols/present_proof/v2_0/tests/test_routes_anoncreds.py @@ -258,11 +258,14 @@ async def test_present_proof_list(self): mock_pres_ex_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.query = mock.CoroutineMock( return_value=[mock_pres_ex_rec_inst] ) @@ -349,11 +352,14 @@ async def test_present_proof_credentials_list_single_referent(self): ), ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -379,11 +385,14 @@ async def test_present_proof_credentials_list_multiple_referents(self): ), ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.return_value = mock.MagicMock( retrieve_by_id=mock.CoroutineMock() ) @@ -445,11 +454,14 @@ async def test_present_proof_credentials_list_dif(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -523,11 +535,14 @@ async def test_present_proof_credentials_list_dif_one_of_filter(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -598,11 +613,14 @@ async def test_present_proof_credentials_dif_no_tag_query(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -673,11 +691,14 @@ async def test_present_proof_credentials_single_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -748,11 +769,14 @@ async def test_present_proof_credentials_double_ldp_vp_claim_format(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) @@ -818,10 +842,11 @@ async def test_present_proof_credentials_single_ldp_vp_error(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -882,10 +907,11 @@ async def test_present_proof_credentials_double_ldp_vp_error(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -943,10 +969,11 @@ async def test_present_proof_credentials_list_limit_disclosure_no_bbs(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -1007,10 +1034,11 @@ async def test_present_proof_credentials_no_ldp_vp(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record with self.assertRaises(test_module.web.HTTPBadRequest): @@ -1075,11 +1103,14 @@ async def test_present_proof_credentials_list_schema_uri(self): ) self.profile.context.injector.bind_instance(VCHolder, mock_holder) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record await test_module.present_proof_credentials_list(self.request) mock_response.assert_called_once_with( @@ -1139,10 +1170,11 @@ async def test_present_proof_credentials_list_dif_error(self): error_msg=None, ) - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): with self.assertRaises(test_module.web.HTTPBadRequest): mock_pres_ex_rec_cls.retrieve_by_id.return_value = record @@ -1151,11 +1183,14 @@ async def test_present_proof_credentials_list_dif_error(self): async def test_present_proof_retrieve(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_pres_ex_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_pres_ex_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_pres_ex_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock( @@ -1207,15 +1242,16 @@ async def test_present_proof_send_proposal(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True) as mock_conn_rec, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=True) ) @@ -1241,10 +1277,11 @@ async def test_present_proof_send_proposal_no_conn_record(self): async def test_present_proof_send_proposal_not_ready(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresProposal", autospec=True + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object(test_module, "V20PresProposal", autospec=True), ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(is_ready=False) @@ -1256,11 +1293,12 @@ async def test_present_proof_send_proposal_not_ready(self): async def test_present_proof_send_proposal_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ), mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr: + with ( + mock.patch.object(test_module, "ConnRecord", autospec=True), + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr, + ): mock_pres_mgr.return_value.create_exchange_for_proposal = mock.CoroutineMock( return_value=mock.MagicMock( serialize=mock.MagicMock(side_effect=test_module.StorageError()), @@ -1282,13 +1320,15 @@ async def test_present_proof_create_request(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock(return_value={"thread_id": "sample-thread-id"}) ) @@ -1310,11 +1350,13 @@ async def test_present_proof_create_request_x(self): } ) - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module.web, "json_response", mock.MagicMock()): + with ( + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), + ): mock_pres_mgr_inst = mock.MagicMock( create_exchange_for_request=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1337,17 +1379,19 @@ async def test_present_proof_send_free_request(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ), mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock() mock_px_rec_inst = mock.MagicMock( serialize=mock.MagicMock({"thread_id": "sample-thread-id"}) @@ -1401,13 +1445,16 @@ async def test_present_proof_send_free_request_x(self): } ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresRequest", autospec=True - ), mock.patch.object(test_module, "V20PresExRecord", autospec=True): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object(test_module, "V20PresRequest", autospec=True), + mock.patch.object(test_module, "V20PresExRecord", autospec=True), + ): mock_conn_rec_inst = mock.MagicMock() mock_conn_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=mock_conn_rec_inst @@ -1443,15 +1490,20 @@ async def test_present_proof_send_bound_request(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1496,11 +1548,14 @@ async def test_present_proof_send_bound_request_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1534,11 +1589,14 @@ async def test_present_proof_send_bound_request_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1622,13 +1680,17 @@ async def test_present_proof_send_bound_request_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PROPOSAL_RECEIVED, @@ -1676,15 +1738,18 @@ async def test_present_proof_send_presentation(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1727,15 +1792,18 @@ async def test_present_proof_send_presentation_dif(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1800,15 +1868,18 @@ async def test_present_proof_send_presentation_dif_error(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec_cls.retrieve_by_id = mock.CoroutineMock( return_value=px_rec_instance ) @@ -1873,11 +1944,14 @@ async def test_present_proof_send_presentation_not_found(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1914,11 +1988,14 @@ async def test_present_proof_send_presentation_not_ready(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -1986,13 +2063,18 @@ async def test_present_proof_send_presentation_x(self): ), ) - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response"), + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_REQUEST_RECEIVED, @@ -2026,15 +2108,20 @@ async def test_present_proof_send_presentation_x(self): async def test_present_proof_verify_presentation(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", state=test_module.V20PresExRecord.STATE_PRESENTATION_RECEIVED, @@ -2091,14 +2178,17 @@ async def test_present_proof_verify_presentation_bad_state(self): async def test_present_proof_verify_presentation_x(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "ConnRecord", autospec=True - ) as mock_conn_rec_cls, mock.patch.object( - test_module, "V20PresManager", autospec=True - ) as mock_pres_mgr_cls, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec_cls, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module, "ConnRecord", autospec=True + ) as mock_conn_rec_cls, + mock.patch.object( + test_module, "V20PresManager", autospec=True + ) as mock_pres_mgr_cls, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec_cls, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_px_rec_inst = mock.MagicMock( connection_id="dummy", @@ -2136,15 +2226,16 @@ async def test_present_proof_problem_report(self): self.request.match_info = {"pres_ex_id": "dummy"} magic_report = mock.MagicMock() - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ) as mock_problem_report, mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object( + test_module, "problem_report_for_record", mock.MagicMock() + ) as mock_problem_report, + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock(save_error_state=mock.CoroutineMock()) ) @@ -2177,13 +2268,13 @@ async def test_present_proof_problem_report_x(self): ) self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresManager", autospec=True - ), mock.patch.object( - test_module, "problem_report_for_record", mock.MagicMock() - ), mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec: + with ( + mock.patch.object(test_module, "V20PresManager", autospec=True), + mock.patch.object(test_module, "problem_report_for_record", mock.MagicMock()), + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( side_effect=test_module.StorageError() ) @@ -2194,11 +2285,14 @@ async def test_present_proof_problem_report_x(self): async def test_present_proof_remove(self): self.request.match_info = {"pres_ex_id": "dummy"} - with mock.patch.object( - test_module, "V20PresExRecord", autospec=True - ) as mock_px_rec, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as mock_response: + with ( + mock.patch.object( + test_module, "V20PresExRecord", autospec=True + ) as mock_px_rec, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as mock_response, + ): mock_px_rec.retrieve_by_id = mock.CoroutineMock( return_value=mock.MagicMock( state=test_module.V20PresExRecord.STATE_DONE, diff --git a/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py b/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py index 4e3b19f933..73c642c489 100644 --- a/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py +++ b/acapy_agent/protocols/routing/v1_0/handlers/tests/test_forward_handler.py @@ -28,13 +28,15 @@ async def test_handle(self): handler = test_module.ForwardHandler() responder = MockResponder() - with mock.patch.object( - test_module, "RoutingManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, "ConnectionManager", autospec=True - ) as mock_connection_mgr, mock.patch.object( - self.context.profile, "notify", autospec=True - ) as mock_notify: + with ( + mock.patch.object(test_module, "RoutingManager", autospec=True) as mock_mgr, + mock.patch.object( + test_module, "ConnectionManager", autospec=True + ) as mock_connection_mgr, + mock.patch.object( + self.context.profile, "notify", autospec=True + ) as mock_notify, + ): mock_mgr.return_value.get_recipient = mock.CoroutineMock( return_value=RouteRecord(connection_id="dummy") ) diff --git a/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py b/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py index cf05eae733..6012046e75 100644 --- a/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/trustping/v1_0/tests/test_routes.py @@ -31,13 +31,15 @@ async def test_connections_send_ping(self): self.request.json = mock.CoroutineMock(return_value={"comment": "some comment"}) self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module, "Ping", mock.MagicMock() - ) as mock_ping, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() - ) as json_response: + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module, "Ping", mock.MagicMock()) as mock_ping, + mock.patch.object( + test_module.web, "json_response", mock.MagicMock() + ) as json_response, + ): mock_ping.return_value = mock.MagicMock(_thread_id="dummy") mock_retrieve.return_value = mock.MagicMock(is_ready=True) result = await test_module.connections_send_ping(self.request) @@ -48,10 +50,11 @@ async def test_connections_send_ping_no_conn(self): self.request.json = mock.CoroutineMock(return_value={"comment": "some comment"}) self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_retrieve.side_effect = test_module.StorageNotFoundError() with self.assertRaises(test_module.web.HTTPNotFound): @@ -61,10 +64,11 @@ async def test_connections_send_ping_not_ready(self): self.request.json = mock.CoroutineMock(return_value={"comment": "some comment"}) self.request.match_info = {"conn_id": "dummy"} - with mock.patch.object( - test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.MagicMock() + with ( + mock.patch.object( + test_module.ConnRecord, "retrieve_by_id", mock.CoroutineMock() + ) as mock_retrieve, + mock.patch.object(test_module.web, "json_response", mock.MagicMock()), ): mock_retrieve.return_value = mock.MagicMock(is_ready=False) with self.assertRaises(test_module.web.HTTPBadRequest): diff --git a/acapy_agent/resolver/default/tests/test_legacy_peer.py b/acapy_agent/resolver/default/tests/test_legacy_peer.py index fb7cb8f264..46f18caf8a 100644 --- a/acapy_agent/resolver/default/tests/test_legacy_peer.py +++ b/acapy_agent/resolver/default/tests/test_legacy_peer.py @@ -79,11 +79,10 @@ async def test_supports_x_unknown_did( @pytest.mark.asyncio async def test_resolve(self, resolver: LegacyPeerDIDResolver, profile: Profile): """Test resolve.""" - with mock.patch.object( - test_module, "BaseConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "LegacyDocCorrections" - ) as mock_corrections: + with ( + mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr, + mock.patch.object(test_module, "LegacyDocCorrections") as mock_corrections, + ): doc = object() mock_corrections.apply = mock.MagicMock(return_value=doc) mock_mgr.return_value = mock.MagicMock( @@ -102,11 +101,11 @@ async def test_resolve_x_not_found( This should be impossible in practice but still. """ - with mock.patch.object( - test_module, "BaseConnectionManager" - ) as mock_mgr, mock.patch.object( - test_module, "LegacyDocCorrections" - ) as mock_corrections, pytest.raises(test_module.DIDNotFound): + with ( + mock.patch.object(test_module, "BaseConnectionManager") as mock_mgr, + mock.patch.object(test_module, "LegacyDocCorrections") as mock_corrections, + pytest.raises(test_module.DIDNotFound), + ): doc = object mock_corrections.apply = mock.MagicMock(return_value=doc) mock_mgr.return_value = mock.MagicMock( diff --git a/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py b/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py index 8038414429..12488dd350 100644 --- a/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py +++ b/acapy_agent/revocation/models/tests/test_issuer_rev_reg_record.py @@ -178,28 +178,32 @@ async def test_fix_ledger_entry(self, mock_handle): settings={"tails_server_base_url": "http://1.2.3.4:8088"}, ) _test_profile.context.injector.bind_instance(BaseLedger, self.ledger) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "query_by_ids", - mock.CoroutineMock( - return_value=[ - test_module.IssuerCredRevRecord( - record_id=test_module.UUID4_EXAMPLE, - state=test_module.IssuerCredRevRecord.STATE_REVOKED, - cred_ex_id=test_module.UUID4_EXAMPLE, - rev_reg_id=REV_REG_ID, - cred_rev_id="1", - ) - ] + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "query_by_ids", + mock.CoroutineMock( + return_value=[ + test_module.IssuerCredRevRecord( + record_id=test_module.UUID4_EXAMPLE, + state=test_module.IssuerCredRevRecord.STATE_REVOKED, + cred_ex_id=test_module.UUID4_EXAMPLE, + rev_reg_id=REV_REG_ID, + cred_rev_id="1", + ) + ] + ), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_revoc_reg_id", + mock.CoroutineMock(return_value=rec), + ), + mock.patch.object( + test_module, + "generate_ledger_rrrecovery_txn", + mock.CoroutineMock(return_value=rev_reg_delta), ), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_revoc_reg_id", - mock.CoroutineMock(return_value=rec), - ), mock.patch.object( - test_module, - "generate_ledger_rrrecovery_txn", - mock.CoroutineMock(return_value=rev_reg_delta), ): assert ( _test_rev_reg_delta, diff --git a/acapy_agent/revocation/models/tests/test_revocation_registry.py b/acapy_agent/revocation/models/tests/test_revocation_registry.py index 6416d38767..d438a42aa3 100644 --- a/acapy_agent/revocation/models/tests/test_revocation_registry.py +++ b/acapy_agent/revocation/models/tests/test_revocation_registry.py @@ -128,13 +128,11 @@ async def test_retrieve_tails(self): rmtree(TAILS_DIR, ignore_errors=True) more_magic = mock.MagicMock() - with mock.patch.object( - test_module, "Session", autospec=True - ) as mock_session, mock.patch.object( - base58, "b58encode", mock.MagicMock() - ) as mock_b58enc, mock.patch.object( - Path, "is_file", autospec=True - ) as mock_is_file: + with ( + mock.patch.object(test_module, "Session", autospec=True) as mock_session, + mock.patch.object(base58, "b58encode", mock.MagicMock()) as mock_b58enc, + mock.patch.object(Path, "is_file", autospec=True) as mock_is_file, + ): mock_session.return_value.__enter__ = mock.MagicMock(return_value=more_magic) more_magic.get = mock.MagicMock( return_value=mock.MagicMock( diff --git a/acapy_agent/revocation/tests/test_indy.py b/acapy_agent/revocation/tests/test_indy.py index 26a44e35a2..224369b372 100644 --- a/acapy_agent/revocation/tests/test_indy.py +++ b/acapy_agent/revocation/tests/test_indy.py @@ -226,13 +226,16 @@ async def test_get_ledger_registry(self): BaseMultitenantManager, mock.MagicMock(MultitenantManager, autospec=True), ) - with mock.patch.object( - IndyLedgerRequestsExecutor, - "get_ledger_for_identifier", - mock.CoroutineMock(return_value=(None, self.ledger)), - ), mock.patch.object( - RevocationRegistry, "from_definition", mock.MagicMock() - ) as mock_from_def: + with ( + mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + mock.CoroutineMock(return_value=(None, self.ledger)), + ), + mock.patch.object( + RevocationRegistry, "from_definition", mock.MagicMock() + ) as mock_from_def, + ): result = await self.revoc.get_ledger_registry("dummy2") assert result == mock_from_def.return_value assert "dummy2" in IndyRevocation.REV_REG_CACHE diff --git a/acapy_agent/revocation/tests/test_manager.py b/acapy_agent/revocation/tests/test_manager.py index 7e4d85baf5..3105141cb8 100644 --- a/acapy_agent/revocation/tests/test_manager.py +++ b/acapy_agent/revocation/tests/test_manager.py @@ -59,16 +59,18 @@ async def test_revoke_credential_publish(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -120,16 +122,18 @@ async def test_revoke_credential_notify(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -200,20 +204,23 @@ async def test_revoke_credential_publish_endorser(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), - ), mock.patch.object( - test_module.ConnRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=conn_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), + mock.patch.object( + test_module.ConnRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=conn_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -270,21 +277,24 @@ async def test_revoke_credential_publish_endorser_x(self): ) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), - ), mock.patch.object( - ConnRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError("no such rec") + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), + mock.patch.object( + ConnRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=test_module.StorageNotFoundError("no such rec") + ), ), ): mock_retrieve.return_value = mock.MagicMock( @@ -350,12 +360,13 @@ async def test_revoke_credential_pend(self): issuer = mock.MagicMock(IndyIssuer, autospec=True) self.profile.context.injector.bind_instance(IndyIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): revoc.return_value.get_issuer_rev_reg_record = mock.CoroutineMock( return_value=mock_issuer_rev_reg_record @@ -420,15 +431,18 @@ async def test_publish_pending_revocations_endorser(self): ) conn_id = conn_record.connection_id assert conn_id is not None - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -482,15 +496,18 @@ async def test_publish_pending_revocations_endorser_x(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -531,14 +548,17 @@ async def test_publish_pending_revocations_basic(self): send_entry=mock.CoroutineMock(), clear_pending=mock.CoroutineMock(), ) - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) issuer.merge_revocation_registry_deltas = mock.CoroutineMock( @@ -588,15 +608,18 @@ async def test_publish_pending_revocations_1_rev_reg_all(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) @@ -648,15 +671,18 @@ async def test_publish_pending_revocations_1_rev_reg_some(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(IndyIssuer, autospec=True) diff --git a/acapy_agent/revocation/tests/test_routes.py b/acapy_agent/revocation/tests/test_routes.py index f79a5590f9..97f33c5cc8 100644 --- a/acapy_agent/revocation/tests/test_routes.py +++ b/acapy_agent/revocation/tests/test_routes.py @@ -117,11 +117,12 @@ async def test_revoke(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -137,14 +138,17 @@ async def test_revoke_endorser_no_conn_id_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="dummy-conn-id"), - ), mock.patch.object(test_module.web, "json_response"), mock.patch.object( - TransactionManager, "create_record", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="dummy-conn-id"), + ), + mock.patch.object(test_module.web, "json_response"), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} @@ -163,15 +167,18 @@ async def test_revoke_endorser_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ), mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="test_conn_id"), - ), mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="test_conn_id"), + ), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} ) @@ -187,14 +194,17 @@ async def test_revoke_endorser_no_conn_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value=None), - ), mock.patch.object(test_module.web, "json_response"), mock.patch.object( - TransactionManager, "create_record", mock.CoroutineMock() + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value=None), + ), + mock.patch.object(test_module.web, "json_response"), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} @@ -213,15 +223,18 @@ async def test_revoke_endorser(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ), mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="test_conn_id"), - ), mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="test_conn_id"), + ), + mock.patch.object(TransactionManager, "create_record", mock.CoroutineMock()), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( return_value={"result": "..."} ) @@ -237,12 +250,15 @@ async def test_revoke_endorser_x(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value=None), + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value=None), + ), ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() with self.assertRaises(test_module.web.HTTPBadRequest): @@ -256,11 +272,12 @@ async def test_revoke_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -276,9 +293,12 @@ async def test_revoke_not_found(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() ) @@ -289,11 +309,12 @@ async def test_revoke_not_found(self): async def test_publish_revocations(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = mock.CoroutineMock( return_value=({}, pub_pending.return_value) @@ -318,20 +339,25 @@ async def test_publish_revocations_x(self): async def test_publish_revocations_endorser(self): self.author_request.json = mock.CoroutineMock(return_value={}) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value="dummy-conn-id"), - ), mock.patch.object( - TransactionManager, - "create_record", - mock.CoroutineMock(return_value=TransactionRecord()), - ), mock.patch.object( - TransactionManager, - "create_request", - mock.CoroutineMock(), + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value="dummy-conn-id"), + ), + mock.patch.object( + TransactionManager, + "create_record", + mock.CoroutineMock(return_value=TransactionRecord()), + ), + mock.patch.object( + TransactionManager, + "create_request", + mock.CoroutineMock(), + ), ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = mock.CoroutineMock( @@ -385,13 +411,17 @@ async def test_publish_revocations_endorser_exceptions(self): async def test_publish_revocations_endorser_x(self): self.author_request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module, - "get_endorser_connection_id", - mock.CoroutineMock(return_value=None), - ), mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object( + test_module, + "get_endorser_connection_id", + mock.CoroutineMock(return_value=None), + ), + mock.patch.object(test_module.web, "json_response"), + ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = mock.CoroutineMock( return_value=( @@ -410,11 +440,12 @@ async def test_publish_revocations_endorser_x(self): async def test_clear_pending_revocations(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): clear_pending = mock.CoroutineMock() mock_mgr.return_value.clear_pending_revocations = clear_pending @@ -427,9 +458,12 @@ async def test_clear_pending_revocations(self): async def test_clear_pending_revocations_x(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + ): clear_pending = mock.CoroutineMock(side_effect=test_module.StorageError()) mock_mgr.return_value.clear_pending_revocations = clear_pending @@ -445,11 +479,15 @@ async def test_create_rev_reg(self): } ) - with mock.patch.object(AskarStorage, "find_all_records"), mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object(AskarStorage, "find_all_records"), + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( init_issuer_registry=mock.CoroutineMock( return_value=mock.MagicMock( @@ -472,11 +510,14 @@ async def test_create_rev_reg_no_such_cred_def(self): } ) - with mock.patch.object( - BaseStorage, "find_all_records", autospec=True - ) as mock_find, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + BaseStorage, "find_all_records", autospec=True + ) as mock_find, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_find.return_value = False with self.assertRaises(HTTPNotFound): @@ -492,13 +533,17 @@ async def test_create_rev_reg_no_revo_support(self): } ) - with mock.patch.object( - AskarStorage, "find_all_records", autospec=True - ) as mock_find, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + AskarStorage, "find_all_records", autospec=True + ) as mock_find, + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_find.return_value = True mock_indy_revoc.return_value = mock.MagicMock( init_issuer_registry=mock.CoroutineMock( @@ -520,11 +565,14 @@ async def test_rev_regs_created(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module.IssuerRevRegRecord, "query", mock.CoroutineMock() - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, "query", mock.CoroutineMock() + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_query.return_value = [mock.MagicMock(revoc_reg_id="dummy")] result = await test_module.rev_regs_created(self.request) @@ -537,11 +585,14 @@ async def test_get_rev_reg(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -560,11 +611,14 @@ async def test_get_rev_reg_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -581,17 +635,21 @@ async def test_get_rev_reg_issued(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_revoc_reg_id", - mock.CoroutineMock(), - ), mock.patch.object( - test_module.IssuerCredRevRecord, - "query_by_ids", - mock.CoroutineMock(), - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_revoc_reg_id", + mock.CoroutineMock(), + ), + mock.patch.object( + test_module.IssuerCredRevRecord, + "query_by_ids", + mock.CoroutineMock(), + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_query.return_value = [{"...": "..."}, {"...": "..."}] result = await test_module.get_rev_reg_issued_count(self.request) @@ -625,13 +683,16 @@ async def test_get_cred_rev_record(self): "cred_rev_id": CRED_REV_ID, } - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_ids", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_ids", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -645,13 +706,16 @@ async def test_get_cred_rev_record_by_cred_ex_id(self): self.request.query = {"cred_ex_id": CRED_EX_ID} - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -687,11 +751,14 @@ async def test_get_active_rev_reg(self): CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" self.request.match_info = {"cred_def_id": CRED_DEF_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_active_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -708,11 +775,14 @@ async def test_get_active_rev_reg_not_found(self): CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" self.request.match_info = {"cred_def_id": CRED_DEF_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_active_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -729,11 +799,14 @@ async def test_get_tails_file(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock(tails_local_path="dummy") @@ -750,11 +823,14 @@ async def test_get_tails_file_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -771,11 +847,14 @@ async def test_upload_tails_file_basic(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_upload = mock.CoroutineMock() mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( @@ -841,11 +920,14 @@ async def test_send_rev_reg_def(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -866,11 +948,14 @@ async def test_send_rev_reg_def_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -909,11 +994,14 @@ async def test_send_rev_reg_entry(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -933,11 +1021,14 @@ async def test_send_rev_reg_entry_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -979,11 +1070,14 @@ async def test_update_rev_reg(self): return_value={"tails_public_uri": f"http://sample.ca:8181/tails/{REV_REG_ID}"} ) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1007,11 +1101,14 @@ async def test_update_rev_reg_not_found(self): return_value={"tails_public_uri": f"http://sample.ca:8181/tails/{REV_REG_ID}"} ) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") @@ -1061,11 +1158,14 @@ async def test_set_rev_reg_state(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( return_value=mock.MagicMock( @@ -1094,11 +1194,14 @@ async def test_set_rev_reg_state_not_found(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "IndyRevocation", autospec=True + ) as mock_indy_revoc, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_json_response, + ): mock_indy_revoc.return_value = mock.MagicMock( get_issuer_rev_reg_record=mock.CoroutineMock( side_effect=test_module.StorageNotFoundError(error_code="dummy") diff --git a/acapy_agent/revocation_anoncreds/tests/test_manager.py b/acapy_agent/revocation_anoncreds/tests/test_manager.py index 9c62d37d9d..eeacc02929 100644 --- a/acapy_agent/revocation_anoncreds/tests/test_manager.py +++ b/acapy_agent/revocation_anoncreds/tests/test_manager.py @@ -61,16 +61,18 @@ async def test_revoke_credential_publish(self): ) self.profile.context.injector.bind_instance(AnonCredsIssuer, issuer) - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): mock_retrieve.return_value = mock.MagicMock( rev_reg_id="dummy-rr-id", cred_rev_id=CRED_REV_ID @@ -139,20 +141,23 @@ async def test_revoke_credential_pend(self): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) self.profile.context.injector.bind_instance(AnonCredsIssuer, issuer) - with mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as revoc, mock.patch.object( - self.profile, - "session", - mock.MagicMock(return_value=self.profile.session()), - ) as session, mock.patch.object( - self.profile, - "transaction", - mock.MagicMock(return_value=session.return_value), - ) as session, mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object(test_module, "IndyRevocation", autospec=True) as revoc, + mock.patch.object( + self.profile, + "session", + mock.MagicMock(return_value=self.profile.session()), + ) as session, + mock.patch.object( + self.profile, + "transaction", + mock.MagicMock(return_value=session.return_value), + ) as session, + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): revoc.return_value.get_issuer_rev_reg_record = mock.CoroutineMock( return_value=mock_issuer_rev_reg_record @@ -189,14 +194,17 @@ async def test_publish_pending_revocations_basic(self): send_entry=mock.CoroutineMock(), clear_pending=mock.CoroutineMock(), ) - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=[mock_issuer_rev_reg_record]), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_record), + ), ): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) issuer.merge_revocation_registry_deltas = mock.AsyncMock(side_effect=deltas) @@ -245,15 +253,18 @@ async def test_publish_pending_revocations_1_rev_reg_all(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) @@ -304,15 +315,18 @@ async def test_publish_pending_revocations_1_rev_reg_some(self): clear_pending=mock.CoroutineMock(), ), ] - with mock.patch.object( - test_module.IssuerRevRegRecord, - "query_by_pending", - mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), - ), mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_id", - mock.CoroutineMock( - side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + with ( + mock.patch.object( + test_module.IssuerRevRegRecord, + "query_by_pending", + mock.CoroutineMock(return_value=mock_issuer_rev_reg_records), + ), + mock.patch.object( + test_module.IssuerRevRegRecord, + "retrieve_by_id", + mock.CoroutineMock( + side_effect=lambda _, id, **args: mock_issuer_rev_reg_records[id] + ), ), ): issuer = mock.MagicMock(AnonCredsIssuer, autospec=True) diff --git a/acapy_agent/revocation_anoncreds/tests/test_routes.py b/acapy_agent/revocation_anoncreds/tests/test_routes.py index 4fef93761e..6f0ea1577b 100644 --- a/acapy_agent/revocation_anoncreds/tests/test_routes.py +++ b/acapy_agent/revocation_anoncreds/tests/test_routes.py @@ -85,11 +85,12 @@ async def test_revoke(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -104,11 +105,12 @@ async def test_revoke_by_cred_ex_id(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock() await test_module.revoke(self.request) @@ -124,9 +126,12 @@ async def test_revoke_not_found(self): } ) - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object(test_module.web, "json_response"): + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response"), + ): mock_mgr.return_value.revoke_credential = mock.CoroutineMock( side_effect=test_module.StorageNotFoundError() ) @@ -137,11 +142,12 @@ async def test_revoke_not_found(self): async def test_publish_revocations(self): self.request.json = mock.CoroutineMock() - with mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, mock.patch.object( - test_module.web, "json_response" - ) as mock_response: + with ( + mock.patch.object( + test_module, "RevocationManager", autospec=True + ) as mock_mgr, + mock.patch.object(test_module.web, "json_response") as mock_response, + ): pub_pending = mock.CoroutineMock() mock_mgr.return_value.publish_pending_revocations = pub_pending @@ -168,13 +174,16 @@ async def test_rev_regs_created(self): "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, } - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definitions", - mock.AsyncMock(), - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definitions", + mock.AsyncMock(), + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_query.return_value = ["dummy"] result = await test_module.get_rev_regs(self.request) @@ -188,13 +197,15 @@ async def test_get_rev_reg(self): RECORD_ID = "4ba81d6e-f341-4e37-83d4-6b1d3e25a7bd" self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "AnonCredsRevocation", autospec=True - ) as mock_anon_creds_revoc, mock.patch.object( - test_module, "uuid4", mock.Mock() - ) as mock_uuid, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, + mock.patch.object(test_module, "uuid4", mock.Mock()) as mock_uuid, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_uuid.return_value = RECORD_ID mock_anon_creds_revoc.return_value = mock.MagicMock( get_created_revocation_registry_definition=mock.AsyncMock( @@ -250,11 +261,14 @@ async def test_get_rev_reg_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module, "AnonCredsRevocation", autospec=True - ) as mock_anon_creds_revoc, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_anon_creds_revoc.return_value = mock.MagicMock( get_created_revocation_registry_definition=mock.AsyncMock( return_value=None @@ -271,17 +285,21 @@ async def test_get_rev_reg_issued(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - autospec=True, - ) as mock_rev_reg_def, mock.patch.object( - test_module.IssuerCredRevRecord, - "query_by_ids", - mock.CoroutineMock(), - ) as mock_query, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + autospec=True, + ) as mock_rev_reg_def, + mock.patch.object( + test_module.IssuerCredRevRecord, + "query_by_ids", + mock.CoroutineMock(), + ) as mock_query, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_rev_reg_def.return_value = {} mock_query.return_value = [{}, {}] result = await test_module.get_rev_reg_issued_count(self.request) @@ -316,13 +334,16 @@ async def test_get_cred_rev_record(self): "cred_rev_id": CRED_REV_ID, } - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_ids", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_ids", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -336,13 +357,16 @@ async def test_get_cred_rev_record_by_cred_ex_id(self): self.request.query = {"cred_ex_id": CRED_EX_ID} - with mock.patch.object( - test_module.IssuerCredRevRecord, - "retrieve_by_cred_ex_id", - mock.CoroutineMock(), - ) as mock_retrieve, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.IssuerCredRevRecord, + "retrieve_by_cred_ex_id", + mock.CoroutineMock(), + ) as mock_retrieve, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_retrieve.return_value = mock.MagicMock( serialize=mock.MagicMock(return_value="dummy") ) @@ -379,13 +403,16 @@ async def test_get_tails_file(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - mock.AsyncMock(), - ) as mock_get_rev_reg, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + mock.AsyncMock(), + ) as mock_get_rev_reg, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_get_rev_reg.return_value = RevRegDef( issuer_id="issuer_id", type="CL_ACCUM", @@ -409,13 +436,16 @@ async def test_get_tails_file_not_found(self): ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - mock.AsyncMock(), - ) as mock_get_rev_reg, mock.patch.object( - test_module.web, "FileResponse", mock.Mock() - ) as mock_file_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + mock.AsyncMock(), + ) as mock_get_rev_reg, + mock.patch.object( + test_module.web, "FileResponse", mock.Mock() + ) as mock_file_response, + ): mock_get_rev_reg.return_value = None with self.assertRaises(HTTPNotFound): @@ -433,13 +463,15 @@ async def test_set_rev_reg_state(self): "state": test_module.RevRegDefState.STATE_FINISHED, } - with mock.patch.object( - test_module, "AnonCredsRevocation", autospec=True - ) as mock_anon_creds_revoc, mock.patch.object( - test_module, "uuid4", mock.Mock() - ) as mock_uuid, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, + mock.patch.object(test_module, "uuid4", mock.Mock()) as mock_uuid, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_uuid.return_value = RECORD_ID mock_anon_creds_revoc.return_value = mock.MagicMock( set_rev_reg_state=mock.AsyncMock(return_value={}), @@ -500,13 +532,16 @@ async def test_set_rev_reg_state_not_found(self): "state": test_module.RevRegDefState.STATE_FINISHED, } - with mock.patch.object( - test_module.AnonCredsRevocation, - "get_created_revocation_registry_definition", - mock.AsyncMock(), - ) as mock_rev_reg_def, mock.patch.object( - test_module.web, "json_response", mock.Mock() - ) as mock_json_response: + with ( + mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + mock.AsyncMock(), + ) as mock_rev_reg_def, + mock.patch.object( + test_module.web, "json_response", mock.Mock() + ) as mock_json_response, + ): mock_rev_reg_def.return_value = None with self.assertRaises(HTTPNotFound): diff --git a/acapy_agent/settings/tests/test_routes.py b/acapy_agent/settings/tests/test_routes.py index 7327093c78..707aa6760a 100644 --- a/acapy_agent/settings/tests/test_routes.py +++ b/acapy_agent/settings/tests/test_routes.py @@ -190,11 +190,12 @@ async def test_update_profile_settings(mock_response, profile): ), __getitem__=lambda _, k: request_dict[k], ) - with mock.patch.object( - multi_tenant_manager, "update_wallet" - ) as update_wallet, mock.patch.object( - multi_tenant_manager, "get_wallet_and_profile" - ) as get_wallet_and_profile: + with ( + mock.patch.object(multi_tenant_manager, "update_wallet") as update_wallet, + mock.patch.object( + multi_tenant_manager, "get_wallet_and_profile" + ) as get_wallet_and_profile, + ): get_wallet_and_profile.return_value = ( mock.MagicMock( settings={ diff --git a/acapy_agent/storage/tests/test_askar_storage.py b/acapy_agent/storage/tests/test_askar_storage.py index b36925ea7f..c959c6e3fa 100644 --- a/acapy_agent/storage/tests/test_askar_storage.py +++ b/acapy_agent/storage/tests/test_askar_storage.py @@ -46,17 +46,23 @@ class TestAskarStorage: @pytest.mark.skip @pytest.mark.asyncio async def test_record(self): - with mock.patch.object( - indy.wallet, "create_wallet", mock.CoroutineMock() - ) as mock_create, mock.patch.object( - indy.wallet, "open_wallet", mock.CoroutineMock() - ) as mock_open, mock.patch.object( - indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() - ) as mock_master, mock.patch.object( - indy.wallet, "close_wallet", mock.CoroutineMock() - ) as mock_close, mock.patch.object( - indy.wallet, "delete_wallet", mock.CoroutineMock() - ) as mock_delete: + with ( + mock.patch.object( + indy.wallet, "create_wallet", mock.CoroutineMock() + ) as mock_create, + mock.patch.object( + indy.wallet, "open_wallet", mock.CoroutineMock() + ) as mock_open, + mock.patch.object( + indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() + ) as mock_master, + mock.patch.object( + indy.wallet, "close_wallet", mock.CoroutineMock() + ) as mock_close, + mock.patch.object( + indy.wallet, "delete_wallet", mock.CoroutineMock() + ) as mock_delete, + ): fake_wallet = AskarWallet( { "auto_create": True, @@ -154,19 +160,23 @@ async def test_record(self): with pytest.raises(test_module.StorageError): await storage.get_record("connection", "dummy-id") - with mock.patch.object( - test_module.non_secrets, - "update_wallet_record_value", - mock.CoroutineMock(), - ) as mock_update_value, mock.patch.object( - test_module.non_secrets, - "update_wallet_record_tags", - mock.CoroutineMock(), - ) as mock_update_tags, mock.patch.object( - test_module.non_secrets, - "delete_wallet_record", - mock.CoroutineMock(), - ) as mock_delete: + with ( + mock.patch.object( + test_module.non_secrets, + "update_wallet_record_value", + mock.CoroutineMock(), + ) as mock_update_value, + mock.patch.object( + test_module.non_secrets, + "update_wallet_record_tags", + mock.CoroutineMock(), + ) as mock_update_tags, + mock.patch.object( + test_module.non_secrets, + "delete_wallet_record", + mock.CoroutineMock(), + ) as mock_delete, + ): mock_update_value.side_effect = test_module.IndyError( test_module.ErrorCode.CommonInvalidStructure ) @@ -209,17 +219,23 @@ async def test_record(self): @pytest.mark.skip @pytest.mark.asyncio async def test_storage_search_x(self): - with mock.patch.object( - indy.wallet, "create_wallet", mock.CoroutineMock() - ) as mock_create, mock.patch.object( - indy.wallet, "open_wallet", mock.CoroutineMock() - ) as mock_open, mock.patch.object( - indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() - ) as mock_master, mock.patch.object( - indy.wallet, "close_wallet", mock.CoroutineMock() - ) as mock_close, mock.patch.object( - indy.wallet, "delete_wallet", mock.CoroutineMock() - ) as mock_delete: + with ( + mock.patch.object( + indy.wallet, "create_wallet", mock.CoroutineMock() + ) as mock_create, + mock.patch.object( + indy.wallet, "open_wallet", mock.CoroutineMock() + ) as mock_open, + mock.patch.object( + indy.anoncreds, "prover_create_master_secret", mock.CoroutineMock() + ) as mock_master, + mock.patch.object( + indy.wallet, "close_wallet", mock.CoroutineMock() + ) as mock_close, + mock.patch.object( + indy.wallet, "delete_wallet", mock.CoroutineMock() + ) as mock_delete, + ): fake_wallet = AskarWallet( { "auto_create": True, @@ -246,26 +262,33 @@ async def test_storage_search_x(self): with pytest.raises(StorageSearchError): await search.fetch(10) - with mock.patch.object( - indy.non_secrets, "open_wallet_search", mock.CoroutineMock() - ) as mock_indy_open_search, mock.patch.object( - indy.non_secrets, "close_wallet_search", mock.CoroutineMock() - ) as mock_indy_close_search: + with ( + mock.patch.object( + indy.non_secrets, "open_wallet_search", mock.CoroutineMock() + ) as mock_indy_open_search, + mock.patch.object( + indy.non_secrets, "close_wallet_search", mock.CoroutineMock() + ) as mock_indy_close_search, + ): mock_indy_open_search.side_effect = test_module.IndyError("no open") search = storage.search_records("connection") with pytest.raises(StorageSearchError): await search.open() await search.close() - with mock.patch.object( - indy.non_secrets, "open_wallet_search", mock.CoroutineMock() - ) as mock_indy_open_search, mock.patch.object( - indy.non_secrets, - "fetch_wallet_search_next_records", - mock.CoroutineMock(), - ) as mock_indy_fetch, mock.patch.object( - indy.non_secrets, "close_wallet_search", mock.CoroutineMock() - ) as mock_indy_close_search: + with ( + mock.patch.object( + indy.non_secrets, "open_wallet_search", mock.CoroutineMock() + ) as mock_indy_open_search, + mock.patch.object( + indy.non_secrets, + "fetch_wallet_search_next_records", + mock.CoroutineMock(), + ) as mock_indy_fetch, + mock.patch.object( + indy.non_secrets, "close_wallet_search", mock.CoroutineMock() + ) as mock_indy_close_search, + ): mock_indy_fetch.side_effect = test_module.IndyError("no fetch") search = storage.search_records("connection") await search.open() @@ -273,11 +296,14 @@ async def test_storage_search_x(self): await search.fetch(10) await search.close() - with mock.patch.object( - indy.non_secrets, "open_wallet_search", mock.CoroutineMock() - ) as mock_indy_open_search, mock.patch.object( - indy.non_secrets, "close_wallet_search", mock.CoroutineMock() - ) as mock_indy_close_search: + with ( + mock.patch.object( + indy.non_secrets, "open_wallet_search", mock.CoroutineMock() + ) as mock_indy_open_search, + mock.patch.object( + indy.non_secrets, "close_wallet_search", mock.CoroutineMock() + ) as mock_indy_close_search, + ): mock_indy_close_search.side_effect = test_module.IndyError("no close") search = storage.search_records("connection") await search.open() diff --git a/acapy_agent/tests/test_main.py b/acapy_agent/tests/test_main.py index ea2d7b0573..c403d0469d 100644 --- a/acapy_agent/tests/test_main.py +++ b/acapy_agent/tests/test_main.py @@ -5,11 +5,11 @@ class TestMain(TestCase): def test_main(self): - with mock.patch.object(test_module, "__name__", "__main__"), mock.patch.object( - test_module, "init_debug", mock.MagicMock() - ) as mock_debug, mock.patch.object( - test_module, "run", mock.MagicMock() - ) as mock_run: + with ( + mock.patch.object(test_module, "__name__", "__main__"), + mock.patch.object(test_module, "init_debug", mock.MagicMock()) as mock_debug, + mock.patch.object(test_module, "run", mock.MagicMock()) as mock_run, + ): args = ["aca-py"] test_module.main(args) mock_debug.assert_called_once_with(args) diff --git a/acapy_agent/transport/inbound/tests/test_session.py b/acapy_agent/transport/inbound/tests/test_session.py index 985fbc7f3a..421adcc3c8 100644 --- a/acapy_agent/transport/inbound/tests/test_session.py +++ b/acapy_agent/transport/inbound/tests/test_session.py @@ -134,11 +134,10 @@ async def test_receive(self): ) test_msg = mock.MagicMock() - with mock.patch.object( - sess, "parse_inbound", mock.CoroutineMock() - ) as encode, mock.patch.object( - sess, "receive_inbound", mock.MagicMock() - ) as receive: + with ( + mock.patch.object(sess, "parse_inbound", mock.CoroutineMock()) as encode, + mock.patch.object(sess, "receive_inbound", mock.MagicMock()) as receive, + ): result = await sess.receive(test_msg) encode.assert_awaited_once_with(test_msg) receive.assert_called_once_with(encode.return_value) @@ -165,11 +164,10 @@ async def test_receive_no_wallet_found(self): ) test_msg = mock.MagicMock() - with mock.patch.object( - sess, "parse_inbound", mock.CoroutineMock() - ) as encode, mock.patch.object( - sess, "receive_inbound", mock.MagicMock() - ) as receive: + with ( + mock.patch.object(sess, "parse_inbound", mock.CoroutineMock()) as encode, + mock.patch.object(sess, "receive_inbound", mock.MagicMock()) as receive, + ): result = await sess.receive(test_msg) encode.assert_awaited_once_with(test_msg) receive.assert_called_once_with(encode.return_value) diff --git a/acapy_agent/transport/outbound/tests/test_manager.py b/acapy_agent/transport/outbound/tests/test_manager.py index abdd0252a2..18ad129a8f 100644 --- a/acapy_agent/transport/outbound/tests/test_manager.py +++ b/acapy_agent/transport/outbound/tests/test_manager.py @@ -224,11 +224,13 @@ async def test_process_loop_new(self): message=mock.MagicMock(enc_payload=b"encr"), ) ] - with mock.patch.object( - mgr, "deliver_queued_message", mock.MagicMock() - ), mock.patch.object( - mgr.outbound_event, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object(test_module, "trace_event", mock.MagicMock()): + with ( + mock.patch.object(mgr, "deliver_queued_message", mock.MagicMock()), + mock.patch.object( + mgr.outbound_event, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(test_module, "trace_event", mock.MagicMock()), + ): mock_wait.side_effect = KeyError() # cover state=NEW logic and bail with self.assertRaises(KeyError): @@ -245,11 +247,13 @@ async def test_process_loop_new_deliver(self): message=mock.MagicMock(enc_payload=b"encr"), ) ] - with mock.patch.object( - mgr, "deliver_queued_message", mock.MagicMock() - ), mock.patch.object( - mgr.outbound_event, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object(test_module, "trace_event", mock.MagicMock()): + with ( + mock.patch.object(mgr, "deliver_queued_message", mock.MagicMock()), + mock.patch.object( + mgr.outbound_event, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(test_module, "trace_event", mock.MagicMock()), + ): mock_wait.side_effect = KeyError() # cover state=DELIVER logic and bail with self.assertRaises(KeyError): @@ -278,14 +282,13 @@ async def test_finished_deliver_x_log_debug(self): mock_handle_not_delivered = mock.MagicMock() mgr = OutboundTransportManager(self.profile, mock_handle_not_delivered) mgr.outbound_buffer.append(mock_queued) - with mock.patch.object( - test_module.LOGGER, "exception", mock.MagicMock() - ), mock.patch.object( - test_module.LOGGER, "error", mock.MagicMock() - ), mock.patch.object( - test_module.LOGGER, "isEnabledFor", mock.MagicMock() - ) as mock_logger_enabled, mock.patch.object( - mgr, "process_queued", mock.MagicMock() + with ( + mock.patch.object(test_module.LOGGER, "exception", mock.MagicMock()), + mock.patch.object(test_module.LOGGER, "error", mock.MagicMock()), + mock.patch.object( + test_module.LOGGER, "isEnabledFor", mock.MagicMock() + ) as mock_logger_enabled, + mock.patch.object(mgr, "process_queued", mock.MagicMock()), ): mock_logger_enabled.return_value = True # cover debug logging mgr.finished_deliver(mock_queued, mock_completed_x) diff --git a/acapy_agent/transport/queue/tests/test_basic_queue.py b/acapy_agent/transport/queue/tests/test_basic_queue.py index 6d54899f69..992ba3a7be 100644 --- a/acapy_agent/transport/queue/tests/test_basic_queue.py +++ b/acapy_agent/transport/queue/tests/test_basic_queue.py @@ -37,13 +37,16 @@ async def test_dequeue_x(self): test_value = "test value" await queue.enqueue(test_value) - with mock.patch.object( - test_module.asyncio, "get_event_loop", mock.MagicMock() - ) as mock_get_event_loop, mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - queue, "stop_event" - ) as mock_stop_event, mock.patch.object(queue, "queue"): + with ( + mock.patch.object( + test_module.asyncio, "get_event_loop", mock.MagicMock() + ) as mock_get_event_loop, + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(queue, "stop_event") as mock_stop_event, + mock.patch.object(queue, "queue"), + ): mock_stop_event.is_set.return_value = False mock_wait.return_value = ( mock.MagicMock(), @@ -68,13 +71,16 @@ async def test_dequeue_none(self): test_value = "test value" await queue.enqueue(test_value) - with mock.patch.object( - test_module.asyncio, "get_event_loop", mock.MagicMock() - ) as mock_get_event_loop, mock.patch.object( - test_module.asyncio, "wait", mock.CoroutineMock() - ) as mock_wait, mock.patch.object( - queue, "stop_event" - ) as mock_stop_event, mock.patch.object(queue, "queue"): + with ( + mock.patch.object( + test_module.asyncio, "get_event_loop", mock.MagicMock() + ) as mock_get_event_loop, + mock.patch.object( + test_module.asyncio, "wait", mock.CoroutineMock() + ) as mock_wait, + mock.patch.object(queue, "stop_event") as mock_stop_event, + mock.patch.object(queue, "queue"), + ): mock_stop_event.is_set.return_value = False mock_wait.return_value = ( mock.MagicMock(), diff --git a/acapy_agent/utils/tests/test_classloader.py b/acapy_agent/utils/tests/test_classloader.py index 5a9c8be5e5..daead84132 100644 --- a/acapy_agent/utils/tests/test_classloader.py +++ b/acapy_agent/utils/tests/test_classloader.py @@ -42,9 +42,12 @@ def test_import_missing(self): assert ClassLoader.load_module("acapy_agent", "not.a-module") is None def test_import_error(self): - with mock.patch.object( - test_module, "import_module", autospec=True - ) as import_module, mock.patch.object(test_module.sys, "modules", {}): + with ( + mock.patch.object( + test_module, "import_module", autospec=True + ) as import_module, + mock.patch.object(test_module.sys, "modules", {}), + ): import_module.side_effect = ModuleNotFoundError with self.assertRaises(ModuleLoadError): ClassLoader.load_module("acapy_agent.config") diff --git a/acapy_agent/utils/tests/test_task_queue.py b/acapy_agent/utils/tests/test_task_queue.py index 26815e87cc..b079bf53bb 100644 --- a/acapy_agent/utils/tests/test_task_queue.py +++ b/acapy_agent/utils/tests/test_task_queue.py @@ -106,11 +106,10 @@ def done(complete: CompletedTask): async def noop(): return - with mock.patch.object( - queue, "drain", mock.MagicMock() - ) as mock_drain, mock.patch.object( - queue, "wait_for", mock.CoroutineMock() - ) as mock_wait_for: + with ( + mock.patch.object(queue, "drain", mock.MagicMock()) as mock_drain, + mock.patch.object(queue, "wait_for", mock.CoroutineMock()) as mock_wait_for, + ): mock_drain.side_effect = [queue.loop.create_task(noop()), None] await queue.complete(cleanup=True) diff --git a/acapy_agent/vc/vc_ld/tests/test_manager.py b/acapy_agent/vc/vc_ld/tests/test_manager.py index 7b5dd4c81b..bc6a5b3d4b 100644 --- a/acapy_agent/vc/vc_ld/tests/test_manager.py +++ b/acapy_agent/vc/vc_ld/tests/test_manager.py @@ -158,15 +158,18 @@ async def test_get_did_info_for_did_sov(self): assert did_info == did async def test_get_suite_for_document(self): - with mock.patch.object( - self.manager, - "assert_can_issue_with_id_and_proof_type", - mock.CoroutineMock(), - ) as mock_can_issue, mock.patch.object( - self.manager, - "_did_info_for_did", - mock.CoroutineMock(), - ) as mock_did_info: + with ( + mock.patch.object( + self.manager, + "assert_can_issue_with_id_and_proof_type", + mock.CoroutineMock(), + ) as mock_can_issue, + mock.patch.object( + self.manager, + "_did_info_for_did", + mock.CoroutineMock(), + ) as mock_did_info, + ): suite = await self.manager._get_suite_for_document(self.vc, self.options) assert suite.signature_type == self.options.proof_type diff --git a/acapy_agent/wallet/tests/test_anoncreds_upgrade.py b/acapy_agent/wallet/tests/test_anoncreds_upgrade.py index 37f6ab94d1..9e6c0f04ad 100644 --- a/acapy_agent/wallet/tests/test_anoncreds_upgrade.py +++ b/acapy_agent/wallet/tests/test_anoncreds_upgrade.py @@ -329,17 +329,19 @@ async def test_failed_upgrade(self): ) ) - with mock.patch.object( - anoncreds_upgrade, "upgrade_and_delete_schema_records" - ), mock.patch.object( - anoncreds_upgrade, "upgrade_and_delete_cred_def_records" - ), mock.patch.object( - AskarProfileSession, "rollback" - ) as mock_rollback, mock.patch.object( - AskarProfileSession, - "commit", - # Don't wait for sleep in retry to speed up test - ) as mock_commit, mock.patch.object(asyncio, "sleep"): + with ( + mock.patch.object(anoncreds_upgrade, "upgrade_and_delete_schema_records"), + mock.patch.object( + anoncreds_upgrade, "upgrade_and_delete_cred_def_records" + ), + mock.patch.object(AskarProfileSession, "rollback") as mock_rollback, + mock.patch.object( + AskarProfileSession, + "commit", + # Don't wait for sleep in retry to speed up test + ) as mock_commit, + mock.patch.object(asyncio, "sleep"), + ): """ Only tests schemas and cred_defs failing to upgrade because the other objects are hard to mock. These tests should be enough to cover them as the logic is the same. diff --git a/acapy_agent/wallet/tests/test_crypto.py b/acapy_agent/wallet/tests/test_crypto.py index 0596f30821..429a551179 100644 --- a/acapy_agent/wallet/tests/test_crypto.py +++ b/acapy_agent/wallet/tests/test_crypto.py @@ -39,11 +39,14 @@ def test_seeds_keys(self): assert test_module.sign_pk_from_sk(secret_key) in secret_key def test_decode_pack_message_x(self): - with mock.patch.object( - test_module, "decode_pack_message_outer", mock.MagicMock() - ) as mock_decode_outer, mock.patch.object( - test_module, "extract_payload_key", mock.MagicMock() - ) as mock_extract: + with ( + mock.patch.object( + test_module, "decode_pack_message_outer", mock.MagicMock() + ) as mock_decode_outer, + mock.patch.object( + test_module, "extract_payload_key", mock.MagicMock() + ) as mock_extract, + ): mock_decode_outer.return_value = (b"wrapper", {"my": b"recip"}, True) with pytest.raises(ValueError) as excinfo: From 27edc6ed48133c93eb28af2dd3832fd1de17ba59 Mon Sep 17 00:00:00 2001 From: Mourits de Beer <31511766+ff137@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:20:12 +0200 Subject: [PATCH 074/152] :art: Replace deprecated ABC decorators (#3357) Signed-off-by: ff137 Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com> --- acapy_agent/messaging/base_message.py | 17 +++++++++++------ .../issue_credential/v2_0/formats/handler.py | 5 +++-- .../present_proof/v2_0/formats/handler.py | 5 +++-- acapy_agent/vc/ld_proofs/crypto/key_pair.py | 8 +++++--- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/acapy_agent/messaging/base_message.py b/acapy_agent/messaging/base_message.py index 91df02cb1f..766aa47898 100644 --- a/acapy_agent/messaging/base_message.py +++ b/acapy_agent/messaging/base_message.py @@ -1,6 +1,6 @@ """Base message.""" -from abc import ABC, abstractclassmethod, abstractmethod, abstractproperty +from abc import ABC, abstractmethod from enum import Enum, auto from typing import TYPE_CHECKING, Optional, Type @@ -23,15 +23,18 @@ class BaseMessage(ABC): the context of the plugin. """ - @abstractproperty + @property + @abstractmethod def _type(self) -> str: """Return message type.""" - @abstractproperty + @property + @abstractmethod def _id(self) -> str: """Return message id.""" - @abstractproperty + @property + @abstractmethod def _thread_id(self) -> Optional[str]: """Return message thread id.""" @@ -39,10 +42,12 @@ def _thread_id(self) -> Optional[str]: def serialize(self, msg_format: DIDCommVersion = DIDCommVersion.v1) -> dict: """Return serialized message in format specified.""" - @abstractclassmethod + @classmethod + @abstractmethod def deserialize(cls, value: dict, msg_format: DIDCommVersion = DIDCommVersion.v1): """Return message object deserialized from value in format specified.""" - @abstractproperty + @property + @abstractmethod def Handler(self) -> Type["BaseHandler"]: """Return reference to handler class.""" diff --git a/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py b/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py index cc5cc15f7e..a001b11d86 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/formats/handler.py @@ -1,7 +1,7 @@ """V2.0 issue-credential base credential format handler.""" import logging -from abc import ABC, abstractclassmethod, abstractmethod +from abc import ABC, abstractmethod from typing import Mapping, Optional, Tuple from .....core.error import BaseError @@ -60,7 +60,8 @@ def get_format_identifier(self, message_type: str) -> str: def get_format_data(self, message_type: str, data: dict) -> CredFormatAttachment: """Get credential format and attachment objects for use in cred ex messages.""" - @abstractclassmethod + @classmethod + @abstractmethod def validate_fields(cls, message_type: str, attachment_data: dict) -> None: """Validate attachment data for specific message type and format.""" diff --git a/acapy_agent/protocols/present_proof/v2_0/formats/handler.py b/acapy_agent/protocols/present_proof/v2_0/formats/handler.py index 7e4e421cb6..2a36cc3757 100644 --- a/acapy_agent/protocols/present_proof/v2_0/formats/handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/formats/handler.py @@ -1,7 +1,7 @@ """present-proof-v2 format handler - supports ANONCREDS, DIF and INDY.""" import logging -from abc import ABC, abstractclassmethod, abstractmethod +from abc import ABC, abstractmethod from typing import Optional, Tuple from .....core.error import BaseError @@ -56,7 +56,8 @@ def get_format_identifier(self, message_type: str) -> str: def get_format_data(self, message_type: str, data: dict) -> PresFormatAttachment: """Get presentation format and attach objects for use in pres_ex messages.""" - @abstractclassmethod + @classmethod + @abstractmethod def validate_fields(cls, message_type: str, attachment_data: dict) -> None: """Validate attachment data for specific message type and format.""" diff --git a/acapy_agent/vc/ld_proofs/crypto/key_pair.py b/acapy_agent/vc/ld_proofs/crypto/key_pair.py index 0409bc3769..c11e249eea 100644 --- a/acapy_agent/vc/ld_proofs/crypto/key_pair.py +++ b/acapy_agent/vc/ld_proofs/crypto/key_pair.py @@ -1,6 +1,6 @@ """Base key pair class.""" -from abc import ABC, abstractmethod, abstractproperty +from abc import ABC, abstractmethod from typing import List, Optional, Union @@ -15,7 +15,8 @@ async def sign(self, message: Union[List[bytes], bytes]) -> bytes: async def verify(self, message: Union[List[bytes], bytes], signature: bytes) -> bool: """Verify message(s) against signature using key pair.""" - @abstractproperty + @property + @abstractmethod def has_public_key(self) -> bool: """Whether key pair has a public key. @@ -23,7 +24,8 @@ def has_public_key(self) -> bool: in the verification process. """ - @abstractproperty + @property + @abstractmethod def public_key(self) -> Optional[bytes]: """Getter for the public key bytes. From a7e0a698541ab689e285c958a3189f5d96ea1824 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 27 Nov 2024 23:36:35 +0200 Subject: [PATCH 075/152] :art: Reduce log verbosity Signed-off-by: ff137 --- acapy_agent/utils/classloader.py | 37 +------------------------------- 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index ca40073cc2..15eb8c6779 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -50,46 +50,34 @@ def load_module( ) if package: - LOGGER.debug("Preloading parent package: %s", package) # preload parent package if not cls.load_module(package): - LOGGER.debug("Failed to preload parent package: %s", package) return None # must treat as a relative import if not mod_path.startswith("."): mod_path = f".{mod_path}" - LOGGER.debug("Adjusted mod_path for relative import: %s", mod_path) full_path = resolve_name(mod_path, package) - LOGGER.debug("Resolved full module path: %s", full_path) if full_path in sys.modules: - LOGGER.debug("Module %s is already loaded", full_path) return sys.modules[full_path] if "." in mod_path: parent_mod_path, mod_name = mod_path.rsplit(".", 1) - LOGGER.debug( - "Parent module path: %s, Module name: %s", parent_mod_path, mod_name - ) if parent_mod_path and parent_mod_path[-1] != ".": parent_mod = cls.load_module(parent_mod_path, package) if not parent_mod: - LOGGER.debug("Failed to load parent module: %s", parent_mod_path) return None package = parent_mod.__name__ mod_path = f".{mod_name}" - LOGGER.debug("Adjusted mod_path after loading parent: %s", mod_path) # Load the module spec first - LOGGER.debug("Finding spec for module: %s with package: %s", mod_path, package) spec = find_spec(mod_path, package) if not spec: - LOGGER.debug("Module spec not found for: %s", mod_path) return None try: - LOGGER.debug("Importing module: %s with package: %s", mod_path, package) + LOGGER.debug("Importing package: %s, module: %s", package, mod_path) return import_module(mod_path, package) except ModuleNotFoundError as e: LOGGER.warning("Module %s not found during import", full_path) @@ -128,11 +116,6 @@ def load_class( if "." in class_name: # import module and find class mod_path, class_name = class_name.rsplit(".", 1) - LOGGER.debug( - "Extracted module path: %s, class name: %s from full class path", - mod_path, - class_name, - ) elif default_module: mod_path = default_module LOGGER.debug("No module in class name, using default_module: %s", mod_path) @@ -187,13 +170,6 @@ def load_subclass_of( """ - LOGGER.debug( - "Attempting to load subclass of %s from module %s with package %s", - base_class.__name__, - mod_path, - package, - ) - mod = cls.load_module(mod_path, package) if not mod: LOGGER.warning( @@ -205,21 +181,11 @@ def load_subclass_of( # Find the first declared class that inherits from the base_class try: - LOGGER.debug( - "Inspecting classes in module %s for subclasses of %s", - mod_path, - base_class.__name__, - ) imported_class = next( obj for name, obj in inspect.getmembers(mod, inspect.isclass) if issubclass(obj, base_class) and obj is not base_class ) - LOGGER.debug( - "Found subclass %s of base class %s", - imported_class.__name__, - base_class.__name__, - ) except StopIteration: LOGGER.debug( "No subclass of %s found in module %s", @@ -244,7 +210,6 @@ def scan_subpackages(cls, package: str) -> Sequence[str]: try: package_path = resources.files(package) - LOGGER.debug("Found package path: %s", package_path) except FileNotFoundError: LOGGER.warning("Package %s not found during subpackage scan", package) raise ModuleLoadError(f"Undefined package {package}") From 35e64452832d34ce0b10efc74ee56cae5a319054 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 27 Nov 2024 23:39:10 +0200 Subject: [PATCH 076/152] :sparkles: Add `lru_cache` to load_class and set maxsize Signed-off-by: ff137 --- acapy_agent/utils/classloader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 15eb8c6779..de6588eee0 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -26,7 +26,7 @@ class ClassLoader: """Class used to load classes from modules dynamically.""" @classmethod - @lru_cache + @lru_cache(maxsize=1024) def load_module( cls, mod_path: str, package: Optional[str] = None ) -> Optional[ModuleType]: @@ -84,6 +84,7 @@ def load_module( raise ModuleLoadError(f"Unable to import module {full_path}: {str(e)}") from e @classmethod + @lru_cache(maxsize=1024) def load_class( cls, class_name: str, From 7ae9138354c65d5e90bcde6947945d0a57015235 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 28 Nov 2024 12:53:25 +0200 Subject: [PATCH 077/152] :zap: Add class caching to DeferLoad Resolves #3360 Signed-off-by: ff137 --- acapy_agent/utils/classloader.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 29fd81bc4d..09d4799aea 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -181,18 +181,21 @@ def scan_subpackages(cls, package: str) -> Sequence[str]: class DeferLoad: """Helper to defer loading of a class definition.""" + _class_cache = {} # Shared cache for resolved classes + def __init__(self, cls_path: str): """Initialize the `DeferLoad` instance with a qualified class path.""" self._cls_path = cls_path - self._inst = None def __call__(self, *args, **kwargs): """Magic method to call the `DeferLoad` as a function.""" - return (self.resolved)(*args, **kwargs) + return self.resolved(*args, **kwargs) @property def resolved(self): """Accessor for the resolved class instance.""" - if not self._inst: - self._inst = ClassLoader.load_class(self._cls_path) - return self._inst + if self._cls_path not in DeferLoad._class_cache: + DeferLoad._class_cache[self._cls_path] = ClassLoader.load_class( + self._cls_path + ) + return DeferLoad._class_cache[self._cls_path] From 31782d451d6e0ef1dd7c05aadfb63fe329068113 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 10:55:34 +0200 Subject: [PATCH 078/152] :rewind: Revert addition of lru caching Signed-off-by: ff137 --- acapy_agent/utils/classloader.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index de6588eee0..e99cbecb1b 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -3,7 +3,6 @@ import inspect import logging import sys -from functools import lru_cache from importlib import import_module, resources from importlib.util import find_spec, resolve_name from types import ModuleType @@ -26,7 +25,6 @@ class ClassLoader: """Class used to load classes from modules dynamically.""" @classmethod - @lru_cache(maxsize=1024) def load_module( cls, mod_path: str, package: Optional[str] = None ) -> Optional[ModuleType]: @@ -84,7 +82,6 @@ def load_module( raise ModuleLoadError(f"Unable to import module {full_path}: {str(e)}") from e @classmethod - @lru_cache(maxsize=1024) def load_class( cls, class_name: str, From 15d46311afd6c2ce21b287a42df756c6180dad48 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 10:59:27 +0200 Subject: [PATCH 079/152] :art: Update logs / reduce verbosity Signed-off-by: ff137 --- acapy_agent/core/plugin_registry.py | 44 +++-------------------------- acapy_agent/utils/classloader.py | 15 +--------- 2 files changed, 5 insertions(+), 54 deletions(-) diff --git a/acapy_agent/core/plugin_registry.py b/acapy_agent/core/plugin_registry.py index 4b6b31d99e..55bf1d08a1 100644 --- a/acapy_agent/core/plugin_registry.py +++ b/acapy_agent/core/plugin_registry.py @@ -133,7 +133,7 @@ def register_plugin(self, module_name: str) -> Optional[ModuleType]: LOGGER.debug("Registered plugin: %s", module_name) return mod - LOGGER.debug("Failed to register plugin: %s", module_name) + LOGGER.warning("Failed to register plugin: %s", module_name) return None def _is_already_registered(self, module_name: str) -> bool: @@ -163,7 +163,6 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: """Validate the plugin based on various criteria.""" # Check if the plugin has a 'setup' method if hasattr(mod, "setup"): - LOGGER.debug("Plugin %s has a 'setup' method.", module_name) return True # Check for 'routes' or 'message_types' modules @@ -172,7 +171,6 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: routes = ClassLoader.load_module("routes", module_name) message_types = ClassLoader.load_module("message_types", module_name) if routes or message_types: - LOGGER.debug("Plugin %s has 'routes' or 'message_types'.", module_name) return True # Check for 'definition' module with 'versions' attribute @@ -194,7 +192,6 @@ def _is_valid_plugin(self, mod: ModuleType, module_name: str) -> bool: # Validate the 'versions' attribute try: self.validate_version(definition.versions, module_name) - LOGGER.debug("Plugin %s has valid versions.", module_name) return True except ProtocolDefinitionValidationError as e: LOGGER.error( @@ -217,14 +214,15 @@ def register_package(self, package_name: str) -> Sequence[ModuleType]: for module_name in module_names: # Skip any module whose last segment is 'tests' if module_name.split(".")[-1] == "tests": - LOGGER.debug("Skipping test module: %s", module_name) continue plugin = self.register_plugin(module_name) if plugin: registered_plugins.append(plugin) else: - LOGGER.debug("Failed to register %s under %s", module_name, package_name) + LOGGER.warning( + "Failed to register %s under %s", module_name, package_name + ) return registered_plugins @@ -233,14 +231,9 @@ async def init_context(self, context: InjectionContext) -> None: LOGGER.debug("Initializing plugin context for %d plugins", len(self._plugins)) for plugin in self._plugins.values(): - plugin_name = plugin.__name__ if hasattr(plugin, "setup"): - LOGGER.debug("Running setup for plugin: %s", plugin_name) await plugin.setup(context) else: - LOGGER.debug( - "Loading protocols for plugin without setup: %s", plugin_name - ) await self.load_protocols(context, plugin) # register event handlers for each protocol, if provided @@ -256,56 +249,45 @@ async def load_protocol_version( protocol_registry = context.inject(ProtocolRegistry) goal_code_registry = context.inject(GoalCodeRegistry) - module_name = mod.__name__ - LOGGER.debug("Loading protocol version for module: %s", module_name) - if hasattr(mod, "MESSAGE_TYPES"): - LOGGER.debug("Registering message types for: %s", module_name) protocol_registry.register_message_types( mod.MESSAGE_TYPES, version_definition=version_definition ) if hasattr(mod, "CONTROLLERS"): - LOGGER.debug("Registering controllers for: %s", module_name) protocol_registry.register_controllers(mod.CONTROLLERS) goal_code_registry.register_controllers(mod.CONTROLLERS) async def load_protocols(self, context: InjectionContext, plugin: ModuleType) -> None: """For modules that don't implement setup, register protocols manually.""" plugin_name = plugin.__name__ - LOGGER.debug("Loading protocols for plugin: %s", plugin_name) # If this module contains message_types, then assume that # this is a valid module of the old style (not versioned) try: message_types_path = f"{plugin_name}.message_types" - LOGGER.debug("Attempting to load message types from: %s", message_types_path) mod = ClassLoader.load_module(message_types_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin module message types: %s", e) return if mod: - LOGGER.debug("Found non-versioned message types for: %s", plugin_name) await self.load_protocol_version(context, mod) else: # Otherwise, try check for definition.py for versioned protocol packages try: definition_path = f"{plugin_name}.definition" - LOGGER.debug("Attempting to load definition from: %s", definition_path) definition = ClassLoader.load_module(definition_path) except ModuleLoadError as e: LOGGER.error("Error loading plugin definition module: %s", e) return if definition: - LOGGER.debug("Loading versioned protocols for: %s", plugin_name) for protocol_version in definition.versions: version_path = ( f"{plugin_name}.{protocol_version['path']}.message_types" ) try: - LOGGER.debug("Loading message types from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error( @@ -326,16 +308,13 @@ async def register_admin_routes(self, app) -> None: for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.debug("Processing routes for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. - LOGGER.debug("Loading versioned routes for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.debug("Loading routes from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error( @@ -344,20 +323,17 @@ async def register_admin_routes(self, app) -> None: continue if mod and hasattr(mod, "register"): - LOGGER.debug("Registering routes for: %s", plugin_name) await mod.register(app) else: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.debug("Loading non-versioned routes from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading admin routes from %s: %s", routes_path, e) continue if mod and hasattr(mod, "register"): - LOGGER.debug("Registering routes for: %s", plugin_name) await mod.register(app) def register_protocol_events(self, context: InjectionContext) -> None: @@ -371,36 +347,30 @@ def register_protocol_events(self, context: InjectionContext) -> None: for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.debug("Processing events for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Load plugin routes that are in a versioned package. - LOGGER.debug("Loading versioned events for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.debug("Loading events from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error("Error loading events from %s: %s", version_path, e) continue if mod and hasattr(mod, "register_events"): - LOGGER.debug("Registering events from: %s", version_path) mod.register_events(event_bus) else: # Load plugin routes that aren't in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.debug("Loading non-versioned events from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading events from %s: %s", routes_path, e) continue if mod and hasattr(mod, "register_events"): - LOGGER.debug("Registering events from: %s", version_path) mod.register_events(event_bus) def post_process_routes(self, app) -> None: @@ -409,36 +379,30 @@ def post_process_routes(self, app) -> None: for plugin in self._plugins.values(): plugin_name = plugin.__name__ - LOGGER.debug("Post-processing routes for plugin: %s", plugin_name) mod = None definition = ClassLoader.load_module("definition", plugin_name) if definition: # Set binary file responses for routes that are in a versioned package. - LOGGER.debug("Processing versioned routes for: %s", plugin_name) for plugin_version in definition.versions: version_path = f"{plugin_name}.{plugin_version['path']}.routes" try: - LOGGER.debug("Loading routes from: %s", version_path) mod = ClassLoader.load_module(version_path) except ModuleLoadError as e: LOGGER.error("Error loading routes from %s: %s", version_path, e) continue if mod and hasattr(mod, "post_process_routes"): - LOGGER.debug("Post-processing routes for %s", plugin_name) mod.post_process_routes(app) else: # Set binary file responses for routes not in a versioned package. routes_path = f"{plugin_name}.routes" try: - LOGGER.debug("Loading non-versioned routes from: %s", routes_path) mod = ClassLoader.load_module(routes_path) except ModuleLoadError as e: LOGGER.error("Error loading routes from %s: %s", routes_path, e) continue if mod and hasattr(mod, "post_process_routes"): - LOGGER.debug("Post-processing routes for %s", plugin_name) mod.post_process_routes(app) def __repr__(self) -> str: diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index e99cbecb1b..678d135f2a 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -41,11 +41,6 @@ def load_module( ModuleLoadError: If there was an error loading the module """ - LOGGER.debug( - "Attempting to load module: %s%s", - mod_path, - f" with package: {package}" if package else "", - ) if package: # preload parent package @@ -75,7 +70,6 @@ def load_module( return None try: - LOGGER.debug("Importing package: %s, module: %s", package, mod_path) return import_module(mod_path, package) except ModuleNotFoundError as e: LOGGER.warning("Module %s not found during import", full_path) @@ -104,13 +98,6 @@ def load_class( """ - LOGGER.debug( - "Attempting to load class: %s%s%s", - class_name, - f", with default_module: {default_module}" if default_module else "", - f", with package: {package}" if package else "", - ) - if "." in class_name: # import module and find class mod_path, class_name = class_name.rsplit(".", 1) @@ -223,7 +210,7 @@ def scan_subpackages(cls, package: str) -> Sequence[str]: if (item / "__init__.py").exists(): subpackage = f"{package}.{joiner}{item.name}" found.append(subpackage) - LOGGER.debug("Total sub-packages found under %s: %s", package, found) + LOGGER.debug("%d sub-packages found under %s: %s", len(found), package, found) return found From 0e41c89717d314143b8444bdadeea089a1f58063 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 10:31:55 +0200 Subject: [PATCH 080/152] Revert "Don't pass rekey to sub_wallet_profile" This reverts commit e59d2753895303e2b62dae68b425a108b85521b6. --- acapy_agent/multitenant/single_wallet_askar_manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/acapy_agent/multitenant/single_wallet_askar_manager.py b/acapy_agent/multitenant/single_wallet_askar_manager.py index 4e39683247..157bd287e0 100644 --- a/acapy_agent/multitenant/single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/single_wallet_askar_manager.py @@ -74,7 +74,6 @@ async def get_wallet_profile( sub_wallet_settings = { "wallet.recreate": False, "wallet.seed": None, - "wallet.key": "", "wallet.rekey": None, "wallet.id": None, "wallet.name": multitenant_wallet_name, From 3e1029ff1237cb01164f0c03f348e5b220e86056 Mon Sep 17 00:00:00 2001 From: Ricky Ng-Adam Date: Wed, 28 Aug 2024 10:22:37 -0400 Subject: [PATCH 081/152] Fixes #3202: new suppress banner and replace print by logging statements Signed-off-by: Ricky Ng-Adam --- .../anoncreds/default/did_indy/registry.py | 2 +- .../anoncreds/default/did_web/registry.py | 5 ++- .../anoncreds/default/legacy_indy/registry.py | 2 +- acapy_agent/config/argparse.py | 8 +++++ acapy_agent/core/conductor.py | 35 ++++++++++--------- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/acapy_agent/anoncreds/default/did_indy/registry.py b/acapy_agent/anoncreds/default/did_indy/registry.py index dcaafe4c06..388dfe5022 100644 --- a/acapy_agent/anoncreds/default/did_indy/registry.py +++ b/acapy_agent/anoncreds/default/did_indy/registry.py @@ -41,7 +41,7 @@ def supported_identifiers_regex(self) -> Pattern: async def setup(self, context: InjectionContext): """Setup.""" - print("Successfully registered DIDIndyRegistry") + LOGGER.info("Successfully registered DIDIndyRegistry") async def get_schema(self, profile: Profile, schema_id: str) -> GetSchemaResult: """Get a schema from the registry.""" diff --git a/acapy_agent/anoncreds/default/did_web/registry.py b/acapy_agent/anoncreds/default/did_web/registry.py index f97ba88fb8..9afa2ebb80 100644 --- a/acapy_agent/anoncreds/default/did_web/registry.py +++ b/acapy_agent/anoncreds/default/did_web/registry.py @@ -1,5 +1,6 @@ """DID Web Registry.""" +import logging import re from typing import Optional, Pattern, Sequence @@ -17,6 +18,8 @@ ) from ...models.schema import AnonCredsSchema, GetSchemaResult, SchemaResult +LOGGER = logging.getLogger(__name__) + class DIDWebRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar): """DIDWebRegistry.""" @@ -40,7 +43,7 @@ def supported_identifiers_regex(self) -> Pattern: async def setup(self, context: InjectionContext): """Setup.""" - print("Successfully registered DIDWebRegistry") + LOGGER.info("Successfully registered DIDWebRegistry") async def get_schema(self, profile, schema_id: str) -> GetSchemaResult: """Get a schema from the registry.""" diff --git a/acapy_agent/anoncreds/default/legacy_indy/registry.py b/acapy_agent/anoncreds/default/legacy_indy/registry.py index aff1040616..2f91937580 100644 --- a/acapy_agent/anoncreds/default/legacy_indy/registry.py +++ b/acapy_agent/anoncreds/default/legacy_indy/registry.py @@ -144,7 +144,7 @@ def supported_identifiers_regex(self) -> Pattern: async def setup(self, context: InjectionContext): """Setup.""" - print("Successfully registered LegacyIndyRegistry") + LOGGER.info("Successfully registered LegacyIndyRegistry") @staticmethod def make_schema_id(schema: AnonCredsSchema) -> str: diff --git a/acapy_agent/config/argparse.py b/acapy_agent/config/argparse.py index ec0d3d95e1..0d231f2307 100644 --- a/acapy_agent/config/argparse.py +++ b/acapy_agent/config/argparse.py @@ -1028,6 +1028,13 @@ def add_arguments(self, parser: ArgumentParser): "('debug', 'info', 'warning', 'error', 'critical')" ), ) + parser.add_argument( + "--no-banner", + action="store_true", + env_var="ACAPY_NO_BANNER", + default=False, + help=("Suppress banner in logs"), + ) def get_settings(self, args: Namespace) -> dict: """Extract logging settings.""" @@ -1038,6 +1045,7 @@ def get_settings(self, args: Namespace) -> dict: settings["log.file"] = args.log_file if args.log_level: settings["log.level"] = args.log_level + settings["log.banner"] = not args.no_banner return settings diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 9935b6f745..8ae2d3bbd3 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -318,24 +318,25 @@ async def start(self) -> None: # Get agent label default_label = context.settings.get("default_label") - if context.settings.get("transport.disabled"): - LoggingConfigurator.print_banner( - default_label, - None, - None, - self.setup_public_did and self.setup_public_did.did, - self.admin_server, - ) - else: - LoggingConfigurator.print_banner( - default_label, - self.inbound_transport_manager.registered_transports, - self.outbound_transport_manager.registered_transports, - self.setup_public_did and self.setup_public_did.did, - self.admin_server, - ) + if context.settings.get("log.banner", True): + if context.settings.get("transport.disabled"): + LoggingConfigurator.print_banner( + default_label, + None, + None, + self.setup_public_did and self.setup_public_did.did, + self.admin_server, + ) + else: + LoggingConfigurator.print_banner( + default_label, + self.inbound_transport_manager.registered_transports, + self.outbound_transport_manager.registered_transports, + self.setup_public_did and self.setup_public_did.did, + self.admin_server, + ) - LoggingConfigurator.print_notices(context.settings) + LoggingConfigurator.print_notices(context.settings) # record ACA-Py version in Wallet, if needed from_version_storage = None From 7e76226b9984a61d5a257507ef9bdad40a5d2c61 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 6 Nov 2024 11:38:43 +0200 Subject: [PATCH 082/152] :art: Print agent label and version even if banner suppressed Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 8ae2d3bbd3..76dac524e4 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -317,6 +317,7 @@ async def start(self) -> None: # Get agent label default_label = context.settings.get("default_label") + public_did = self.setup_public_did and self.setup_public_did.did if context.settings.get("log.banner", True): if context.settings.get("transport.disabled"): @@ -324,7 +325,7 @@ async def start(self) -> None: default_label, None, None, - self.setup_public_did and self.setup_public_did.did, + public_did, self.admin_server, ) else: @@ -332,11 +333,20 @@ async def start(self) -> None: default_label, self.inbound_transport_manager.registered_transports, self.outbound_transport_manager.registered_transports, - self.setup_public_did and self.setup_public_did.did, + public_did, self.admin_server, ) LoggingConfigurator.print_notices(context.settings) + else: + LOGGER.info(default_label) + LOGGER.info("ver: %s", __version__) + + if public_did: + LOGGER.info("Public DID Information") + LOGGER.info("DID: %s", public_did) + + LOGGER.debug("Note: the rest of the startup banner is suppressed") # record ACA-Py version in Wallet, if needed from_version_storage = None From c4b7fc6931a5ba2523ea62ae27ceb40ba1ce9306 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 11:06:35 +0200 Subject: [PATCH 083/152] :white_check_mark: Fix pagination assertions Signed-off-by: ff137 --- .../messaging/models/tests/test_base_record.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/acapy_agent/messaging/models/tests/test_base_record.py b/acapy_agent/messaging/models/tests/test_base_record.py index ab262ff3ee..36bf7fa7db 100644 --- a/acapy_agent/messaging/models/tests/test_base_record.py +++ b/acapy_agent/messaging/models/tests/test_base_record.py @@ -165,6 +165,8 @@ async def test_query(self): mock_storage.find_all_records.assert_awaited_once_with( type_filter=BaseRecordImpl.RECORD_TYPE, tag_query=tag_filter, + order_by=None, + descending=False, ) assert result and isinstance(result[0], BaseRecordImpl) assert result[0]._id == record_id @@ -216,6 +218,8 @@ async def test_query_post_filter(self): mock_storage.find_all_records.assert_awaited_once_with( type_filter=ARecordImpl.RECORD_TYPE, tag_query=tag_filter, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -339,6 +343,8 @@ async def test_query_with_limit(self): tag_query=tag_filter, limit=10, offset=0, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -369,6 +375,8 @@ async def test_query_with_offset(self): tag_query=tag_filter, limit=DEFAULT_PAGE_SIZE, offset=10, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -399,6 +407,8 @@ async def test_query_with_limit_and_offset(self): tag_query=tag_filter, limit=10, offset=5, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -433,7 +443,10 @@ async def test_query_with_limit_and_offset_and_post_filter(self): post_filter_positive={"a": "one"}, ) mock_storage.find_all_records.assert_awaited_once_with( - type_filter=ARecordImpl.RECORD_TYPE, tag_query=tag_filter + type_filter=ARecordImpl.RECORD_TYPE, + tag_query=tag_filter, + order_by=None, + descending=False, ) assert len(result) == 10 assert result and isinstance(result[0], ARecordImpl) From fb142d88414eefa051b2cdaf40b4adc3ec262354 Mon Sep 17 00:00:00 2001 From: Mourits de Beer <31511766+ff137@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:32:15 +0200 Subject: [PATCH 084/152] =?UTF-8?q?=F0=9F=91=B7=20Upload=20Python=20Packag?= =?UTF-8?q?e=20to=20TestPyPI=20(#4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :construction_worker: Upload Python Package to TestPyPI Signed-off-by: ff137 * :construction_worker: Update project name and version for testpypi Signed-off-by: ff137 * :art: Signed-off-by: ff137 --------- Signed-off-by: ff137 --- .github/workflows/pythonpublish.yml | 21 +++++++++++---------- acapy_agent/version.py | 2 +- pyproject.toml | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index c74ef590df..74fb6a26eb 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -1,29 +1,30 @@ -name: Upload Python Package +name: Upload Python Package to TestPyPI on: release: types: [created] + workflow_dispatch: # Allows manual triggering of the workflow for testing jobs: deploy: runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/p/acapy-agent - permissions: - id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.x" - - name: Install build and publish dependencies + - name: Install build dependencies run: | python -m pip install --upgrade pip pip install setuptools wheel twine poetry - - name: Build and publish + - name: Build package distributions run: | poetry build - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + - name: Publish to TestPyPI + env: + TWINE_USERNAME: ${{ secrets.TEST_PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.TEST_PYPI_PASSWORD }} + run: | + twine upload --repository-url https://test.pypi.org/legacy/ --skip-existing dist/* diff --git a/acapy_agent/version.py b/acapy_agent/version.py index f0b415185b..4e0fac50bf 100644 --- a/acapy_agent/version.py +++ b/acapy_agent/version.py @@ -2,5 +2,5 @@ from importlib import metadata -__version__ = metadata.version("acapy-agent") +__version__ = metadata.version("acapy-agent-didx") RECORD_TYPE_ACAPY_VERSION = "acapy_version" diff --git a/pyproject.toml b/pyproject.toml index de8a3531bc..482afd20f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] -name = "acapy_agent" -version = "1.1.0" +name = "acapy_agent_didx" +version = "1.1.1-20241114" description = "(ACA-Py) A Cloud Agent Python is a foundation for building decentralized identity applications and services running in non-mobile environments. " authors = [] license = "Apache-2.0" From 4ea7b63bd478f86414150f1c9dc6c09267ff1a3f Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 14 Nov 2024 13:56:05 +0200 Subject: [PATCH 085/152] Version 1.1.1-20241115 Signed-off-by: ff137 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 482afd20f2..38780e5cae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "acapy_agent_didx" -version = "1.1.1-20241114" +version = "1.1.1-20241115" description = "(ACA-Py) A Cloud Agent Python is a foundation for building decentralized identity applications and services running in non-mobile environments. " authors = [] license = "Apache-2.0" From eab7271fe8562fe0463ded8e2cd87cd51c41831a Mon Sep 17 00:00:00 2001 From: Mourits de Beer <31511766+ff137@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:52:43 +0200 Subject: [PATCH 086/152] =?UTF-8?q?=F0=9F=8E=A8=20Deprecate=20count/start?= =?UTF-8?q?=20query=20params=20and=20implement=20limit/offset=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * art: Modify count/start query params to be Integers, not Strings Signed-off-by: ff137 * memo: Update openapi spec Signed-off-by: ff137 * rewind: Revert start/count field to remain String type; mark as deprecated Signed-off-by: ff137 * sparkles: Implement limit/offset alongside deprecated count/start Signed-off-by: ff137 * art: Standardise naming convention from count/start to limit/offset Signed-off-by: ff137 * rewind: Revert start/count field to remain String type; mark as deprecated Signed-off-by: ff137 * sparkles: Implement limit/offset alongside deprecated count/start Signed-off-by: ff137 * art: Remove unused query string schema from `w3c_creds_list` Signed-off-by: ff137 * art: Rename args Signed-off-by: ff137 * memo: Update openapi specs Signed-off-by: ff137 * white_check_mark: Signed-off-by: ff137 --------- Signed-off-by: ff137 --- acapy_agent/anoncreds/holder.py | 23 ++-- acapy_agent/anoncreds/tests/test_holder.py | 10 +- acapy_agent/holder/routes.py | 53 ++++++-- acapy_agent/indy/credx/holder.py | 23 ++-- .../indy/credx/tests/test_cred_issuance.py | 16 +-- acapy_agent/indy/models/xform.py | 8 +- .../protocols/present_proof/v1_0/routes.py | 48 +++++-- .../protocols/present_proof/v2_0/routes.py | 60 ++++++--- open-api/openapi.json | 117 +++++++++++------- open-api/swagger.json | 107 +++++++++------- 10 files changed, 294 insertions(+), 171 deletions(-) diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index f8dd4445f7..6da4456c72 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -379,12 +379,12 @@ async def store_credential_w3c( return credential_id - async def get_credentials(self, start: int, count: int, wql: dict): + async def get_credentials(self, *, offset: int, limit: int, wql: dict): """Get credentials stored in the wallet. Args: - start: Starting index - count: Number of records to return + offset: Starting index + limit: Number of records to return wql: wql query dict """ @@ -395,8 +395,8 @@ async def get_credentials(self, start: int, count: int, wql: dict): rows = self.profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=wql, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self.profile.settings.get("wallet.askar_profile"), ) async for row in rows: @@ -413,8 +413,9 @@ async def get_credentials_for_presentation_request_by_referent( self, presentation_request: dict, referents: Sequence[str], - start: int, - count: int, + *, + offset: int, + limit: int, extra_query: Optional[dict] = None, ): """Get credentials stored in the wallet. @@ -422,8 +423,8 @@ async def get_credentials_for_presentation_request_by_referent( Args: presentation_request: Valid presentation request from issuer referents: Presentation request referents to use to search for creds - start: Starting index - count: Maximum number of records to return + offset: Starting index + limit: Maximum number of records to return extra_query: wql query dict """ @@ -466,8 +467,8 @@ async def get_credentials_for_presentation_request_by_referent( rows = self.profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=tag_filter, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self.profile.settings.get("wallet.askar_profile"), ) async for row in rows: diff --git a/acapy_agent/anoncreds/tests/test_holder.py b/acapy_agent/anoncreds/tests/test_holder.py index 34d23ef75f..c894b21e3f 100644 --- a/acapy_agent/anoncreds/tests/test_holder.py +++ b/acapy_agent/anoncreds/tests/test_holder.py @@ -397,7 +397,7 @@ async def test_store_credential_failed_trx(self, *_): async def test_get_credentials(self, _): async with self.profile.session() as session: await session.handle.insert(CATEGORY_CREDENTIAL, json.dumps(MOCK_CRED)) - result = await self.holder.get_credentials(0, 10, {}) + result = await self.holder.get_credentials(offset=0, limit=10, wql={}) assert isinstance(result, list) assert len(result) == 1 @@ -410,9 +410,9 @@ async def test_get_credentials_errors(self): ) with self.assertRaises(AnonCredsHolderError): - await self.holder.get_credentials(0, 10, {}) + await self.holder.get_credentials(offset=0, limit=10, wql={}) with self.assertRaises(AnonCredsHolderError): - await self.holder.get_credentials(0, 10, {}) + await self.holder.get_credentials(offset=0, limit=10, wql={}) async def test_get_credentials_for_presentation_request_by_referent(self): self.profile.store.scan = mock.Mock( @@ -432,13 +432,13 @@ async def test_get_credentials_for_presentation_request_by_referent(self): "restrictions": [{"schema_name": "MYCO Biomarker"}], } await self.holder.get_credentials_for_presentation_request_by_referent( - mock_pres_req, None, start=0, count=10 + mock_pres_req, None, offset=0, limit=10 ) # non-existent referent with self.assertRaises(AnonCredsHolderError): await self.holder.get_credentials_for_presentation_request_by_referent( - mock_pres_req, "not-found-ref", start=0, count=10 + mock_pres_req, "not-found-ref", offset=0, limit=10 ) @mock.patch.object(Credential, "load", return_value=MockCredential()) diff --git a/acapy_agent/holder/routes.py b/acapy_agent/holder/routes.py index 37c1d5e1e7..cda58ccc75 100644 --- a/acapy_agent/holder/routes.py +++ b/acapy_agent/holder/routes.py @@ -33,6 +33,7 @@ NUM_STR_WHOLE_VALIDATE, UUID4_EXAMPLE, ) +from ..storage.base import DEFAULT_PAGE_SIZE, MAXIMUM_PAGE_SIZE from ..storage.error import StorageError, StorageNotFoundError from ..storage.vc_holder.base import VCHolder from ..storage.vc_holder.vc_record import VCRecordSchema @@ -66,17 +67,41 @@ class CredentialsListQueryStringSchema(OpenAPISchema): start = fields.Str( required=False, + load_default=0, validate=NUM_STR_WHOLE_VALIDATE, - metadata={"description": "Start index", "example": NUM_STR_WHOLE_EXAMPLE}, + metadata={ + "description": "Start index (DEPRECATED - use offset instead)", + "example": NUM_STR_WHOLE_EXAMPLE, + "deprecated": True, + }, ) count = fields.Str( required=False, + load_default=10, validate=NUM_STR_NATURAL_VALIDATE, metadata={ - "description": "Maximum number to retrieve", + "description": "Maximum number to retrieve (DEPRECATED - use limit instead)", "example": NUM_STR_NATURAL_EXAMPLE, + "deprecated": True, + }, + ) + limit = fields.Int( + required=False, + validate=lambda x: x > 0 and x <= MAXIMUM_PAGE_SIZE, + metadata={"description": "Number of results to return", "example": 50}, + error_messages={ + "validator_failed": ( + "Value must be greater than 0 and " + f"less than or equal to {MAXIMUM_PAGE_SIZE}" + ) }, ) + offset = fields.Int( + required=False, + validate=lambda x: x >= 0, + metadata={"description": "Offset for pagination", "example": 0}, + error_messages={"validator_failed": "Value must be 0 or greater"}, + ) wql = fields.Str( required=False, validate=INDY_WQL_VALIDATE, @@ -379,25 +404,32 @@ async def credentials_list(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - start = request.query.get("start") - count = request.query.get("count") + + # Handle both old style start/count and new limit/offset + # TODO: Remove start/count and swap to PaginatedQuerySchema and get_limit_offset + if "limit" in request.query or "offset" in request.query: + # New style - use limit/offset + limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) + offset = int(request.query.get("offset", 0)) + else: + # Old style - use start/count + limit = int(request.query.get("count", "10")) + offset = int(request.query.get("start", "0")) # url encoded json wql encoded_wql = request.query.get("wql") or "{}" wql = json.loads(encoded_wql) - # defaults - start = int(start) if isinstance(start, str) else 0 - count = int(count) if isinstance(count, str) else 10 - if context.settings.get(wallet_type_config) == "askar-anoncreds": holder = AnonCredsHolder(context.profile) - credentials = await holder.get_credentials(start, count, wql) + credentials = await holder.get_credentials(limit=limit, offset=offset, wql=wql) else: async with context.profile.session() as session: holder = session.inject(IndyHolder) try: - credentials = await holder.get_credentials(start, count, wql) + credentials = await holder.get_credentials( + limit=limit, offset=offset, wql=wql + ) except IndyHolderError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err @@ -476,7 +508,6 @@ async def w3c_cred_remove(request: web.BaseRequest): summary="Fetch W3C credentials from wallet", ) @request_schema(W3CCredentialsListRequestSchema()) -@querystring_schema(CredentialsListQueryStringSchema()) @response_schema(VCRecordListSchema(), 200, description="") @tenant_authentication async def w3c_creds_list(request: web.BaseRequest): diff --git a/acapy_agent/indy/credx/holder.py b/acapy_agent/indy/credx/holder.py index 27ba7837e2..089f1620d1 100644 --- a/acapy_agent/indy/credx/holder.py +++ b/acapy_agent/indy/credx/holder.py @@ -236,12 +236,12 @@ async def store_credential( return credential_id - async def get_credentials(self, start: int, count: int, wql: dict): + async def get_credentials(self, *, offset: int, limit: int, wql: dict): """Get credentials stored in the wallet. Args: - start: Starting index - count: Number of records to return + offset: Starting index + limit: Number of records to return wql: wql query dict """ @@ -252,8 +252,8 @@ async def get_credentials(self, start: int, count: int, wql: dict): rows = self._profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=wql, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self._profile.settings.get("wallet.askar_profile"), ) async for row in rows: @@ -270,8 +270,9 @@ async def get_credentials_for_presentation_request_by_referent( self, presentation_request: dict, referents: Sequence[str], - start: int, - count: int, + *, + offset: int, + limit: int, extra_query: Optional[dict] = None, ): """Get credentials stored in the wallet. @@ -279,8 +280,8 @@ async def get_credentials_for_presentation_request_by_referent( Args: presentation_request: Valid presentation request from issuer referents: Presentation request referents to use to search for creds - start: Starting index - count: Maximum number of records to return + offset: Starting index + limit: Maximum number of records to return extra_query: wql query dict """ @@ -323,8 +324,8 @@ async def get_credentials_for_presentation_request_by_referent( rows = self._profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=tag_filter, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self._profile.settings.get("wallet.askar_profile"), ) async for row in rows: diff --git a/acapy_agent/indy/credx/tests/test_cred_issuance.py b/acapy_agent/indy/credx/tests/test_cred_issuance.py index 9b8c222dc2..f0154b0a7b 100644 --- a/acapy_agent/indy/credx/tests/test_cred_issuance.py +++ b/acapy_agent/indy/credx/tests/test_cred_issuance.py @@ -132,7 +132,7 @@ async def test_issue_store_non_rev(self): assert not await self.holder.get_mime_type(cred_id, "name") - creds = await self.holder.get_credentials(None, None, None) + creds = await self.holder.get_credentials(offset=None, limit=None, wql=None) assert len(creds) == 1 assert creds[0] == stored_cred @@ -142,9 +142,9 @@ async def test_issue_store_non_rev(self): await self.holder.get_credentials_for_presentation_request_by_referent( PRES_REQ_NON_REV, None, - 0, - 10, - {}, + offset=0, + limit=10, + extra_query={}, ) ) assert pres_creds == [ @@ -247,7 +247,7 @@ async def test_issue_store_rev(self): assert found stored_cred = json.loads(found) - creds = await self.holder.get_credentials(None, None, None) + creds = await self.holder.get_credentials(offset=None, limit=None, wql=None) assert len(creds) == 1 assert creds[0] == stored_cred @@ -257,9 +257,9 @@ async def test_issue_store_rev(self): await self.holder.get_credentials_for_presentation_request_by_referent( PRES_REQ_REV, None, - 0, - 10, - {}, + offset=0, + limit=10, + extra_query={}, ) ) assert pres_creds == [ diff --git a/acapy_agent/indy/models/xform.py b/acapy_agent/indy/models/xform.py index 6e80794889..c8082ce576 100644 --- a/acapy_agent/indy/models/xform.py +++ b/acapy_agent/indy/models/xform.py @@ -34,8 +34,8 @@ async def indy_proof_req_preview2indy_requested_creds( credentials = await holder.get_credentials_for_presentation_request_by_referent( presentation_request=indy_proof_req, referents=(referent,), - start=0, - count=100, + offset=0, + limit=100, ) if not credentials: raise ValueError( @@ -87,8 +87,8 @@ async def indy_proof_req_preview2indy_requested_creds( credentials = await holder.get_credentials_for_presentation_request_by_referent( presentation_request=indy_proof_req, referents=(referent,), - start=0, - count=100, + offset=0, + limit=100, ) if not credentials: raise ValueError( diff --git a/acapy_agent/protocols/present_proof/v1_0/routes.py b/acapy_agent/protocols/present_proof/v1_0/routes.py index 97459a687e..7fb2eee48b 100644 --- a/acapy_agent/protocols/present_proof/v1_0/routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/routes.py @@ -36,6 +36,7 @@ UUID4_EXAMPLE, UUID4_VALIDATE, ) +from ....storage.base import DEFAULT_PAGE_SIZE, MAXIMUM_PAGE_SIZE from ....storage.error import StorageError, StorageNotFoundError from ....utils.tracing import AdminAPIMessageTracingSchema, get_timer, trace_event from ....wallet.error import WalletNotFoundError @@ -237,21 +238,42 @@ class CredentialsFetchQueryStringSchema(OpenAPISchema): ) start = fields.Str( required=False, + load_default="0", validate=NUM_STR_WHOLE_VALIDATE, metadata={ - "description": "Start index", + "description": "Start index (DEPRECATED - use offset instead)", "strict": True, "example": NUM_STR_WHOLE_EXAMPLE, + "deprecated": True, }, ) count = fields.Str( required=False, + load_default="10", validate=NUM_STR_NATURAL_VALIDATE, metadata={ - "description": "Maximum number to retrieve", + "description": "Maximum number to retrieve (DEPRECATED - use limit instead)", "example": NUM_STR_NATURAL_EXAMPLE, + "deprecated": True, }, ) + limit = fields.Int( + required=False, + validate=lambda x: x > 0 and x <= MAXIMUM_PAGE_SIZE, + metadata={"description": "Number of results to return", "example": 50}, + error_messages={ + "validator_failed": ( + "Value must be greater than 0 and " + f"less than or equal to {MAXIMUM_PAGE_SIZE}" + ) + }, + ) + offset = fields.Int( + required=False, + validate=lambda x: x >= 0, + metadata={"description": "Offset for pagination", "example": 0}, + error_messages={"validator_failed": "Value must be 0 or greater"}, + ) extra_query = fields.Str( required=False, validate=INDY_EXTRA_WQL_VALIDATE, @@ -413,25 +435,29 @@ async def presentation_exchange_credentials_list(request: web.BaseRequest): except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - start = request.query.get("start") - count = request.query.get("count") + # Handle both old style start/count and new limit/offset + # TODO: Remove start/count and swap to PaginatedQuerySchema and get_limit_offset + if "limit" in request.query or "offset" in request.query: + # New style - use limit/offset + limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) + offset = int(request.query.get("offset", 0)) + else: + # Old style - use start/count + limit = int(request.query.get("count", "10")) + offset = int(request.query.get("start", "0")) # url encoded json extra_query encoded_extra_query = request.query.get("extra_query") or "{}" extra_query = json.loads(encoded_extra_query) - # defaults - start = int(start) if isinstance(start, str) else 0 - count = int(count) if isinstance(count, str) else 10 - holder = profile.inject(IndyHolder) try: credentials = await holder.get_credentials_for_presentation_request_by_referent( pres_ex_record._presentation_request.ser, presentation_referents, - start, - count, - extra_query, + offset=offset, + limit=limit, + extra_query=extra_query, ) except IndyHolderError as err: if pres_ex_record: diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index b53188f118..0472d24e48 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -38,7 +38,7 @@ UUID4_EXAMPLE, UUID4_VALIDATE, ) -from ....storage.base import BaseStorage +from ....storage.base import DEFAULT_PAGE_SIZE, MAXIMUM_PAGE_SIZE, BaseStorage from ....storage.error import StorageError, StorageNotFoundError from ....storage.vc_holder.base import VCHolder from ....storage.vc_holder.vc_record import VCRecord @@ -55,12 +55,7 @@ from . import problem_report_for_record, report_problem from .formats.handler import V20PresFormatHandlerError from .manager import V20PresManager -from .message_types import ( - ATTACHMENT_FORMAT, - PRES_20_PROPOSAL, - PRES_20_REQUEST, - SPEC_URI, -) +from .message_types import ATTACHMENT_FORMAT, PRES_20_PROPOSAL, PRES_20_REQUEST, SPEC_URI from .messages.pres_format import V20PresFormat from .messages.pres_problem_report import ProblemReportReason from .messages.pres_proposal import V20PresProposal @@ -366,21 +361,42 @@ class V20CredentialsFetchQueryStringSchema(OpenAPISchema): ) start = fields.Str( required=False, + load_default="0", validate=NUM_STR_WHOLE_VALIDATE, metadata={ - "description": "Start index", + "description": "Start index (DEPRECATED - use offset instead)", "strict": True, "example": NUM_STR_WHOLE_EXAMPLE, + "deprecated": True, }, ) count = fields.Str( required=False, + load_default="10", validate=NUM_STR_NATURAL_VALIDATE, metadata={ - "description": "Maximum number to retrieve", + "description": "Maximum number to retrieve (DEPRECATED - use limit instead)", "example": NUM_STR_NATURAL_EXAMPLE, + "deprecated": True, + }, + ) + limit = fields.Int( + required=False, + validate=lambda x: x > 0 and x <= MAXIMUM_PAGE_SIZE, + metadata={"description": "Number of results to return", "example": 50}, + error_messages={ + "validator_failed": ( + "Value must be greater than 0 and " + f"less than or equal to {MAXIMUM_PAGE_SIZE}" + ) }, ) + offset = fields.Int( + required=False, + validate=lambda x: x >= 0, + metadata={"description": "Offset for pagination", "example": 0}, + error_messages={"validator_failed": "Value must be 0 or greater"}, + ) extra_query = fields.Str( required=False, validate=INDY_EXTRA_WQL_VALIDATE, @@ -563,17 +579,21 @@ async def present_proof_credentials_list(request: web.BaseRequest): except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - start = request.query.get("start") - count = request.query.get("count") + # Handle both old style start/count and new limit/offset + # TODO: Remove start/count and swap to PaginatedQuerySchema and get_limit_offset + if "limit" in request.query or "offset" in request.query: + # New style - use limit/offset + limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) + offset = int(request.query.get("offset", 0)) + else: + # Old style - use start/count + limit = int(request.query.get("count", "10")) + offset = int(request.query.get("start", "0")) # url encoded json extra_query encoded_extra_query = request.query.get("extra_query") or "{}" extra_query = json.loads(encoded_extra_query) - # defaults - start = int(start) if isinstance(start, str) else 0 - count = int(count) if isinstance(count, str) else 10 - wallet_type = profile.settings.get_value("wallet.type") if wallet_type == "askar-anoncreds": holder = AnonCredsHolder(profile) @@ -595,9 +615,9 @@ async def present_proof_credentials_list(request: web.BaseRequest): await holder.get_credentials_for_presentation_request_by_referent( pres_request, pres_referents, - start, - count, - extra_query, + offset=offset, + limit=limit, + extra_query=extra_query, ) ) @@ -756,7 +776,7 @@ async def present_proof_credentials_list(request: web.BaseRequest): search = dif_holder.search_credentials( proof_types=proof_type, pd_uri_list=uri_group ) - cred_group = await search.fetch(count) + cred_group = await search.fetch(limit) ( cred_group_vcrecord_list, cred_group_vcrecord_ids_set, @@ -770,7 +790,7 @@ async def present_proof_credentials_list(request: web.BaseRequest): proof_types=proof_type, pd_uri_list=uri_list, ) - records = await search.fetch(count) + records = await search.fetch(limit) # Avoiding addition of duplicate records vcrecord_list, vcrecord_ids_set = await process_vcrecords_return_list( records, record_ids diff --git a/open-api/openapi.json b/open-api/openapi.json index 444c97fbbe..398b1d02ef 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -2054,18 +2054,34 @@ "/credentials" : { "get" : { "parameters" : [ { - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "in" : "query", "name" : "count", "schema" : { + "default" : "10", "pattern" : "^[1-9][0-9]*$", "type" : "string" } }, { - "description" : "Start index", + "description" : "Number of results to return", + "in" : "query", + "name" : "limit", + "schema" : { + "type" : "integer" + } + }, { + "description" : "Offset for pagination", + "in" : "query", + "name" : "offset", + "schema" : { + "type" : "integer" + } + }, { + "description" : "Start index (DEPRECATED - use offset instead)", "in" : "query", "name" : "start", "schema" : { + "default" : "0", "pattern" : "^[0-9]*$", "type" : "string" } @@ -2096,31 +2112,6 @@ }, "/credentials/w3c" : { "post" : { - "parameters" : [ { - "description" : "Maximum number to retrieve", - "in" : "query", - "name" : "count", - "schema" : { - "pattern" : "^[1-9][0-9]*$", - "type" : "string" - } - }, { - "description" : "Start index", - "in" : "query", - "name" : "start", - "schema" : { - "pattern" : "^[0-9]*$", - "type" : "string" - } - }, { - "description" : "(JSON) WQL query", - "in" : "query", - "name" : "wql", - "schema" : { - "pattern" : "^{.*}$", - "type" : "string" - } - } ], "requestBody" : { "content" : { "*/*" : { @@ -4923,10 +4914,11 @@ "type" : "string" } }, { - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "in" : "query", "name" : "count", "schema" : { + "default" : "10", "pattern" : "^[1-9][0-9]*$", "type" : "string" } @@ -4938,6 +4930,20 @@ "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$", "type" : "string" } + }, { + "description" : "Number of results to return", + "in" : "query", + "name" : "limit", + "schema" : { + "type" : "integer" + } + }, { + "description" : "Offset for pagination", + "in" : "query", + "name" : "offset", + "schema" : { + "type" : "integer" + } }, { "description" : "Proof request referents of interest, comma-separated", "in" : "query", @@ -4946,10 +4952,11 @@ "type" : "string" } }, { - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "in" : "query", "name" : "start", "schema" : { + "default" : "0", "pattern" : "^[0-9]*$", "type" : "string" } @@ -5341,10 +5348,11 @@ "type" : "string" } }, { - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "in" : "query", "name" : "count", "schema" : { + "default" : "10", "pattern" : "^[1-9][0-9]*$", "type" : "string" } @@ -5356,6 +5364,20 @@ "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$", "type" : "string" } + }, { + "description" : "Number of results to return", + "in" : "query", + "name" : "limit", + "schema" : { + "type" : "integer" + } + }, { + "description" : "Offset for pagination", + "in" : "query", + "name" : "offset", + "schema" : { + "type" : "integer" + } }, { "description" : "Proof request referents of interest, comma-separated", "in" : "query", @@ -5364,10 +5386,11 @@ "type" : "string" } }, { - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "in" : "query", "name" : "start", "schema" : { + "default" : "0", "pattern" : "^[0-9]*$", "type" : "string" } @@ -8376,12 +8399,12 @@ "type" : "string" }, "kid" : { - "description" : "Optional kid to bind to the keypair, such as a verificationMethod.", + "description" : "Optional kid to bind to the keypair, such as a verificationMethod.", "example" : "did:web:example.com#key-01", "type" : "string" }, "seed" : { - "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode.", + "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode.", "example" : "00000000000000000000000000000000", "type" : "string" } @@ -8450,7 +8473,7 @@ }, "wallet_type" : { "description" : "Type of the wallet to create. Must be same as base wallet.", - "enum" : [ "askar", "askar-anoncreds", "in_memory" ], + "enum" : [ "askar", "askar-anoncreds" ], "example" : "askar", "type" : "string" }, @@ -9322,7 +9345,7 @@ "type" : "string" }, "mediation_id" : { - "description" : "Medation ID to use for endpoint information.", + "description" : "Mediation ID to use for endpoint information.", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", "type" : "string" @@ -9553,47 +9576,47 @@ "additionalProperties" : true, "properties" : { "challenge" : { - "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks.", + "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks.", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", "type" : "string" }, "created" : { - "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string", + "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string", "example" : "2010-01-01T19:23:24Z", "type" : "string" }, "cryptosuite" : { - "description" : "An identifier for the cryptographic suite that can be used to verify the proof.", + "description" : "An identifier for the cryptographic suite that can be used to verify the proof.", "example" : "eddsa-jcs-2022", "type" : "string" }, "domain" : { - "description" : "It conveys one or more security domains in which the proof is meant to be used.", + "description" : "It conveys one or more security domains in which the proof is meant to be used.", "example" : "example.com", "type" : "string" }, "expires" : { - "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string", + "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string", "example" : "2010-01-01T19:23:24Z", "type" : "string" }, "id" : { - "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN", + "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", "type" : "string" }, "nonce" : { - "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures.", + "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures.", "example" : "CF69iO3nfvqRsRBNElE8b4wO39SyJHPM7Gg1nExltW5vSfQA1lvDCR/zXX1To0/4NLo==", "type" : "string" }, "previousProof" : { - "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed.", + "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed.", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", "type" : "string" }, "proofPurpose" : { - "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended.", + "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended.", "example" : "assertionMethod", "type" : "string" }, @@ -9603,12 +9626,12 @@ "type" : "string" }, "type" : { - "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL].", + "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL].", "example" : "DataIntegrityProof", "type" : "string" }, "verificationMethod" : { - "description" : "A verification method is the means and information needed to verify the proof. ", + "description" : "A verification method is the means and information needed to verify the proof.", "example" : "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL", "pattern" : "\\w+:(\\/?\\/?)[^\\s]+", "type" : "string" @@ -14085,7 +14108,7 @@ "UpdateKeyRequest" : { "properties" : { "kid" : { - "description" : "New kid to bind to the key pair, such as a verificationMethod.", + "description" : "New kid to bind to the key pair, such as a verificationMethod.", "example" : "did:web:example.com#key-02", "type" : "string" }, diff --git a/open-api/swagger.json b/open-api/swagger.json index 3267ac846e..b3f325664f 100644 --- a/open-api/swagger.json +++ b/open-api/swagger.json @@ -1718,16 +1718,30 @@ "parameters" : [ { "name" : "count", "in" : "query", - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "required" : false, "type" : "string", + "default" : "10", "pattern" : "^[1-9][0-9]*$" + }, { + "name" : "limit", + "in" : "query", + "description" : "Number of results to return", + "required" : false, + "type" : "integer" + }, { + "name" : "offset", + "in" : "query", + "description" : "Offset for pagination", + "required" : false, + "type" : "integer" }, { "name" : "start", "in" : "query", - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "required" : false, "type" : "string", + "default" : "0", "pattern" : "^[0-9]*$" }, { "name" : "wql", @@ -1759,27 +1773,6 @@ "schema" : { "$ref" : "#/definitions/W3CCredentialsListRequest" } - }, { - "name" : "count", - "in" : "query", - "description" : "Maximum number to retrieve", - "required" : false, - "type" : "string", - "pattern" : "^[1-9][0-9]*$" - }, { - "name" : "start", - "in" : "query", - "description" : "Start index", - "required" : false, - "type" : "string", - "pattern" : "^[0-9]*$" - }, { - "name" : "wql", - "in" : "query", - "description" : "(JSON) WQL query", - "required" : false, - "type" : "string", - "pattern" : "^{.*}$" } ], "responses" : { "200" : { @@ -4050,9 +4043,10 @@ }, { "name" : "count", "in" : "query", - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "required" : false, "type" : "string", + "default" : "10", "pattern" : "^[1-9][0-9]*$" }, { "name" : "extra_query", @@ -4061,6 +4055,18 @@ "required" : false, "type" : "string", "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$" + }, { + "name" : "limit", + "in" : "query", + "description" : "Number of results to return", + "required" : false, + "type" : "integer" + }, { + "name" : "offset", + "in" : "query", + "description" : "Offset for pagination", + "required" : false, + "type" : "integer" }, { "name" : "referent", "in" : "query", @@ -4070,9 +4076,10 @@ }, { "name" : "start", "in" : "query", - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "required" : false, "type" : "string", + "default" : "0", "pattern" : "^[0-9]*$" } ], "responses" : { @@ -4389,9 +4396,10 @@ }, { "name" : "count", "in" : "query", - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "required" : false, "type" : "string", + "default" : "10", "pattern" : "^[1-9][0-9]*$" }, { "name" : "extra_query", @@ -4400,6 +4408,18 @@ "required" : false, "type" : "string", "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$" + }, { + "name" : "limit", + "in" : "query", + "description" : "Number of results to return", + "required" : false, + "type" : "integer" + }, { + "name" : "offset", + "in" : "query", + "description" : "Offset for pagination", + "required" : false, + "type" : "integer" }, { "name" : "referent", "in" : "query", @@ -4409,9 +4429,10 @@ }, { "name" : "start", "in" : "query", - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "required" : false, "type" : "string", + "default" : "0", "pattern" : "^[0-9]*$" } ], "deprecated" : true, @@ -7007,12 +7028,12 @@ "kid" : { "type" : "string", "example" : "did:web:example.com#key-01", - "description" : "Optional kid to bind to the keypair, such as a verificationMethod." + "description" : "Optional kid to bind to the keypair, such as a verificationMethod." }, "seed" : { "type" : "string", "example" : "00000000000000000000000000000000", - "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode." + "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode." } } }, @@ -7081,7 +7102,7 @@ "type" : "string", "example" : "askar", "description" : "Type of the wallet to create. Must be same as base wallet.", - "enum" : [ "askar", "askar-anoncreds", "in_memory" ] + "enum" : [ "askar", "askar-anoncreds" ] }, "wallet_webhook_urls" : { "type" : "array", @@ -7909,7 +7930,7 @@ "mediation_id" : { "type" : "string", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "description" : "Medation ID to use for endpoint information.", + "description" : "Mediation ID to use for endpoint information.", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } } @@ -8135,47 +8156,47 @@ "challenge" : { "type" : "string", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks." + "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks." }, "created" : { "type" : "string", "example" : "2010-01-01T19:23:24Z", - "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string" + "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string" }, "cryptosuite" : { "type" : "string", "example" : "eddsa-jcs-2022", - "description" : "An identifier for the cryptographic suite that can be used to verify the proof." + "description" : "An identifier for the cryptographic suite that can be used to verify the proof." }, "domain" : { "type" : "string", "example" : "example.com", - "description" : "It conveys one or more security domains in which the proof is meant to be used." + "description" : "It conveys one or more security domains in which the proof is meant to be used." }, "expires" : { "type" : "string", "example" : "2010-01-01T19:23:24Z", - "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string" + "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string" }, "id" : { "type" : "string", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", - "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN" + "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN" }, "nonce" : { "type" : "string", "example" : "CF69iO3nfvqRsRBNElE8b4wO39SyJHPM7Gg1nExltW5vSfQA1lvDCR/zXX1To0/4NLo==", - "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures." + "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures." }, "previousProof" : { "type" : "string", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", - "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed." + "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed." }, "proofPurpose" : { "type" : "string", "example" : "assertionMethod", - "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended." + "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended." }, "proofValue" : { "type" : "string", @@ -8185,12 +8206,12 @@ "type" : { "type" : "string", "example" : "DataIntegrityProof", - "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL]." + "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL]." }, "verificationMethod" : { "type" : "string", "example" : "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL", - "description" : "A verification method is the means and information needed to verify the proof. ", + "description" : "A verification method is the means and information needed to verify the proof.", "pattern" : "\\w+:(\\/?\\/?)[^\\s]+" } }, @@ -12479,7 +12500,7 @@ "kid" : { "type" : "string", "example" : "did:web:example.com#key-02", - "description" : "New kid to bind to the key pair, such as a verificationMethod." + "description" : "New kid to bind to the key pair, such as a verificationMethod." }, "multikey" : { "type" : "string", From 88e614e8c4af827fd29aab28680c0d412613b4ee Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 16 Aug 2024 23:19:13 +0300 Subject: [PATCH 087/152] sparkles: add `order_by` and `descending` options to query / scan and fetch_all methods Signed-off-by: ff137 --- acapy_agent/messaging/models/base_record.py | 8 ++++++++ acapy_agent/multitenant/admin/routes.py | 9 +++++++-- .../protocols/connections/v1_0/routes.py | 9 +++++++-- .../protocols/issue_credential/v1_0/routes.py | 9 +++++++-- .../protocols/issue_credential/v2_0/routes.py | 9 +++++++-- .../protocols/present_proof/v1_0/routes.py | 9 +++++++-- .../protocols/present_proof/v2_0/routes.py | 9 +++++++-- acapy_agent/storage/askar.py | 17 ++++++++++++++++- acapy_agent/storage/base.py | 11 +++++++++++ 9 files changed, 77 insertions(+), 13 deletions(-) diff --git a/acapy_agent/messaging/models/base_record.py b/acapy_agent/messaging/models/base_record.py index e613c6e6d9..f32a8e0c4e 100644 --- a/acapy_agent/messaging/models/base_record.py +++ b/acapy_agent/messaging/models/base_record.py @@ -293,6 +293,8 @@ async def query( *, limit: Optional[int] = None, offset: Optional[int] = None, + order_by: Optional[str] = None, + descending: bool = False, post_filter_positive: Optional[dict] = None, post_filter_negative: Optional[dict] = None, alt: bool = False, @@ -304,6 +306,8 @@ async def query( tag_filter: An optional dictionary of tag filter clauses limit: The maximum number of records to retrieve offset: The offset to start retrieving records from + order_by: An optional field by which to order the records. + descending: Whether to order the records in descending order. post_filter_positive: Additional value filters to apply matching positively post_filter_negative: Additional value filters to apply matching negatively alt: set to match any (positive=True) value or miss all (positive=False) @@ -327,11 +331,15 @@ async def query( tag_query=tag_query, limit=limit, offset=offset, + order_by=order_by, + descending=descending, ) else: rows = await storage.find_all_records( type_filter=cls.RECORD_TYPE, tag_query=tag_query, + order_by=order_by, + descending=descending, ) num_results_post_filter = 0 # used if applying pagination post-filter diff --git a/acapy_agent/multitenant/admin/routes.py b/acapy_agent/multitenant/admin/routes.py index 8ebea184a7..a569902ad4 100644 --- a/acapy_agent/multitenant/admin/routes.py +++ b/acapy_agent/multitenant/admin/routes.py @@ -16,7 +16,10 @@ from ...core.profile import ProfileManagerProvider from ...messaging.models.base import BaseModelError from ...messaging.models.openapi import OpenAPISchema -from ...messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset +from ...messaging.models.paginated_query import ( + PaginatedQuerySchema, + get_paginated_query_params, +) from ...messaging.valid import UUID4_EXAMPLE, JSONWebToken from ...multitenant.base import BaseMultitenantManager from ...storage.error import StorageError, StorageNotFoundError @@ -383,7 +386,7 @@ async def wallets_list(request: web.BaseRequest): if wallet_name: query["wallet_name"] = wallet_name - limit, offset = get_limit_offset(request) + limit, offset, order_by, descending = get_paginated_query_params(request) try: async with profile.session() as session: @@ -392,6 +395,8 @@ async def wallets_list(request: web.BaseRequest): tag_filter=query, limit=limit, offset=offset, + order_by=order_by, + descending=descending, ) results = [format_wallet_record(record) for record in records] results.sort(key=lambda w: w["created_at"]) diff --git a/acapy_agent/protocols/connections/v1_0/routes.py b/acapy_agent/protocols/connections/v1_0/routes.py index 63344e5749..78cfbb590e 100644 --- a/acapy_agent/protocols/connections/v1_0/routes.py +++ b/acapy_agent/protocols/connections/v1_0/routes.py @@ -19,7 +19,10 @@ from ....connections.models.conn_record import ConnRecord, ConnRecordSchema from ....messaging.models.base import BaseModelError from ....messaging.models.openapi import OpenAPISchema -from ....messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset +from ....messaging.models.paginated_query import ( + PaginatedQuerySchema, + get_paginated_query_params, +) from ....messaging.valid import ( ENDPOINT_EXAMPLE, ENDPOINT_VALIDATE, @@ -469,7 +472,7 @@ async def connections_list(request: web.BaseRequest): if request.query.get("connection_protocol"): post_filter["connection_protocol"] = request.query["connection_protocol"] - limit, offset = get_limit_offset(request) + limit, offset, order_by, descending = get_paginated_query_params(request) profile = context.profile try: @@ -479,6 +482,8 @@ async def connections_list(request: web.BaseRequest): tag_filter, limit=limit, offset=offset, + order_by=order_by, + descending=descending, post_filter_positive=post_filter, alt=True, ) diff --git a/acapy_agent/protocols/issue_credential/v1_0/routes.py b/acapy_agent/protocols/issue_credential/v1_0/routes.py index 1b5581a51b..95bb4eeedc 100644 --- a/acapy_agent/protocols/issue_credential/v1_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v1_0/routes.py @@ -23,7 +23,10 @@ from ....messaging.credential_definitions.util import CRED_DEF_TAGS from ....messaging.models.base import BaseModelError from ....messaging.models.openapi import OpenAPISchema -from ....messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset +from ....messaging.models.paginated_query import ( + PaginatedQuerySchema, + get_paginated_query_params, +) from ....messaging.valid import ( INDY_CRED_DEF_ID_EXAMPLE, INDY_CRED_DEF_ID_VALIDATE, @@ -411,7 +414,7 @@ async def credential_exchange_list(request: web.BaseRequest): if request.query.get(k, "") != "" } - limit, offset = get_limit_offset(request) + limit, offset, order_by, descending = get_paginated_query_params(request) try: async with context.profile.session() as session: @@ -420,6 +423,8 @@ async def credential_exchange_list(request: web.BaseRequest): tag_filter=tag_filter, limit=limit, offset=offset, + order_by=order_by, + descending=descending, post_filter_positive=post_filter, ) results = [record.serialize() for record in records] diff --git a/acapy_agent/protocols/issue_credential/v2_0/routes.py b/acapy_agent/protocols/issue_credential/v2_0/routes.py index 9128f7aeac..1c06a4e572 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/routes.py @@ -26,7 +26,10 @@ from ....messaging.decorators.attach_decorator import AttachDecorator from ....messaging.models.base import BaseModelError from ....messaging.models.openapi import OpenAPISchema -from ....messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset +from ....messaging.models.paginated_query import ( + PaginatedQuerySchema, + get_paginated_query_params, +) from ....messaging.valid import ( ANONCREDS_DID_EXAMPLE, ANONCREDS_SCHEMA_ID_EXAMPLE, @@ -611,7 +614,7 @@ async def credential_exchange_list(request: web.BaseRequest): if request.query.get(k, "") != "" } - limit, offset = get_limit_offset(request) + limit, offset, order_by, descending = get_paginated_query_params(request) try: async with profile.session() as session: @@ -620,6 +623,8 @@ async def credential_exchange_list(request: web.BaseRequest): tag_filter=tag_filter, limit=limit, offset=offset, + order_by=order_by, + descending=descending, post_filter_positive=post_filter, ) diff --git a/acapy_agent/protocols/present_proof/v1_0/routes.py b/acapy_agent/protocols/present_proof/v1_0/routes.py index 97459a687e..ef9cad6a2d 100644 --- a/acapy_agent/protocols/present_proof/v1_0/routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/routes.py @@ -25,7 +25,10 @@ from ....messaging.decorators.attach_decorator import AttachDecorator from ....messaging.models.base import BaseModelError from ....messaging.models.openapi import OpenAPISchema -from ....messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset +from ....messaging.models.paginated_query import ( + PaginatedQuerySchema, + get_paginated_query_params, +) from ....messaging.valid import ( INDY_EXTRA_WQL_EXAMPLE, INDY_EXTRA_WQL_VALIDATE, @@ -309,7 +312,7 @@ async def presentation_exchange_list(request: web.BaseRequest): if request.query.get(k, "") != "" } - limit, offset = get_limit_offset(request) + limit, offset, order_by, descending = get_paginated_query_params(request) try: async with context.profile.session() as session: @@ -318,6 +321,8 @@ async def presentation_exchange_list(request: web.BaseRequest): tag_filter=tag_filter, limit=limit, offset=offset, + order_by=order_by, + descending=descending, post_filter_positive=post_filter, ) results = [record.serialize() for record in records] diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index b53188f118..a9af5de0f3 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -27,7 +27,10 @@ from ....messaging.decorators.attach_decorator import AttachDecorator from ....messaging.models.base import BaseModelError from ....messaging.models.openapi import OpenAPISchema -from ....messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset +from ....messaging.models.paginated_query import ( + PaginatedQuerySchema, + get_paginated_query_params, +) from ....messaging.valid import ( INDY_EXTRA_WQL_EXAMPLE, INDY_EXTRA_WQL_VALIDATE, @@ -467,7 +470,7 @@ async def present_proof_list(request: web.BaseRequest): if request.query.get(k, "") != "" } - limit, offset = get_limit_offset(request) + limit, offset, order_by, descending = get_paginated_query_params(request) try: async with profile.session() as session: @@ -476,6 +479,8 @@ async def present_proof_list(request: web.BaseRequest): tag_filter=tag_filter, limit=limit, offset=offset, + order_by=order_by, + descending=descending, post_filter_positive=post_filter, ) results = [record.serialize() for record in records] diff --git a/acapy_agent/storage/askar.py b/acapy_agent/storage/askar.py index a3480c2ef6..607c6b927f 100644 --- a/acapy_agent/storage/askar.py +++ b/acapy_agent/storage/askar.py @@ -174,6 +174,8 @@ async def find_paginated_records( tag_query: Optional[Mapping] = None, limit: int = DEFAULT_PAGE_SIZE, offset: int = 0, + order_by: Optional[str] = None, + descending: bool = False, ) -> Sequence[StorageRecord]: """Retrieve a page of records matching a particular type filter and tag query. @@ -182,6 +184,11 @@ async def find_paginated_records( tag_query: An optional dictionary of tag filter clauses limit: The maximum number of records to retrieve offset: The offset to start retrieving records from + order_by: An optional field by which to order the records. + descending: Whether to order the records in descending order. + + Returns: + A sequence of StorageRecord matching the filter and query parameters. """ results = [] @@ -190,6 +197,8 @@ async def find_paginated_records( tag_filter=tag_query, limit=limit, offset=offset, + order_by=order_by, + descending=descending, profile=self._session.profile.settings.get("wallet.askar_profile"), ): results += ( @@ -206,13 +215,19 @@ async def find_all_records( self, type_filter: str, tag_query: Optional[Mapping] = None, + order_by: Optional[str] = None, + descending: bool = False, options: Optional[Mapping] = None, ): """Retrieve all records matching a particular type filter and tag query.""" for_update = bool(options and options.get("forUpdate")) results = [] for row in await self._session.handle.fetch_all( - type_filter, tag_query, for_update=for_update + category=type_filter, + tag_filter=tag_query, + order_by=order_by, + descending=descending, + for_update=for_update, ): results.append( StorageRecord( diff --git a/acapy_agent/storage/base.py b/acapy_agent/storage/base.py index d1cbc8086e..e065c32b88 100644 --- a/acapy_agent/storage/base.py +++ b/acapy_agent/storage/base.py @@ -99,6 +99,8 @@ async def find_paginated_records( tag_query: Optional[Mapping] = None, limit: int = DEFAULT_PAGE_SIZE, offset: int = 0, + order_by: Optional[str] = None, + descending: bool = False, ) -> Sequence[StorageRecord]: """Retrieve a page of records matching a particular type filter and tag query. @@ -107,6 +109,11 @@ async def find_paginated_records( tag_query: An optional dictionary of tag filter clauses limit: The maximum number of records to retrieve offset: The offset to start retrieving records from + order_by: An optional field by which to order the records. + descending: Whether to order the records in descending order. + + Returns: + A sequence of StorageRecord matching the filter and query parameters. """ @abstractmethod @@ -114,6 +121,8 @@ async def find_all_records( self, type_filter: str, tag_query: Optional[Mapping] = None, + order_by: Optional[str] = None, + descending: bool = False, options: Optional[Mapping] = None, ) -> Sequence[StorageRecord]: """Retrieve all records matching a particular type filter and tag query. @@ -121,6 +130,8 @@ async def find_all_records( Args: type_filter: The type of records to filter by. tag_query: An optional dictionary of tag filter clauses. + order_by: An optional field by which to order the records. + descending: Whether to order the records in descending order. options: Additional options for the query. """ From 5d6dd467fc45fbcc8c062087d761d186fd1fd29d Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 16 Aug 2024 23:20:45 +0300 Subject: [PATCH 088/152] sparkles: add `order_by` and `descending` options to PaginatedQuerySchema Signed-off-by: ff137 --- acapy_agent/messaging/models/paginated_query.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/acapy_agent/messaging/models/paginated_query.py b/acapy_agent/messaging/models/paginated_query.py index c6e6e99795..1e72e0a0cc 100644 --- a/acapy_agent/messaging/models/paginated_query.py +++ b/acapy_agent/messaging/models/paginated_query.py @@ -4,6 +4,7 @@ from aiohttp.web import BaseRequest from marshmallow import fields +from marshmallow.validate import OneOf from ...messaging.models.openapi import OpenAPISchema from ...storage.base import DEFAULT_PAGE_SIZE, MAXIMUM_PAGE_SIZE @@ -31,6 +32,20 @@ class PaginatedQuerySchema(OpenAPISchema): metadata={"description": "Offset for pagination", "example": 0}, error_messages={"validator_failed": "Value must be 0 or greater"}, ) + order_by = fields.Str( + required=False, + load_default=None, + dump_only=True, # Hide from schema by making it dump-only + load_only=True, # Ensure it can still be loaded/validated + validate=OneOf(["id"]), # Example of possible fields + metadata={"description": "Order results in descending order if true"}, + error_messages={"validator_failed": "Ordering only support for column `id`"}, + ) + descending = fields.Bool( + required=False, + load_default=False, + metadata={"description": "Order results in descending order if true"}, + ) def get_limit_offset(request: BaseRequest) -> Tuple[int, int]: From c62b7f53440e2d7c86287a1260eb59bc96dcd426 Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 16 Aug 2024 23:21:28 +0300 Subject: [PATCH 089/152] sparkles: modify `get_limit_offset` to `get_paginated_query_params` Signed-off-by: ff137 --- acapy_agent/messaging/models/paginated_query.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/acapy_agent/messaging/models/paginated_query.py b/acapy_agent/messaging/models/paginated_query.py index 1e72e0a0cc..2cb430d087 100644 --- a/acapy_agent/messaging/models/paginated_query.py +++ b/acapy_agent/messaging/models/paginated_query.py @@ -48,16 +48,22 @@ class PaginatedQuerySchema(OpenAPISchema): ) -def get_limit_offset(request: BaseRequest) -> Tuple[int, int]: - """Read the limit and offset query parameters from a request as ints, with defaults. +def get_paginated_query_params(request: BaseRequest) -> Tuple[int, int, str, bool]: + """Read the limit, offset, order_by, and descending query parameters from a request. Args: - request: aiohttp request object + request: aiohttp request object. Returns: - A tuple of the limit and offset values + A tuple containing: + - limit (int): The number of results to return, defaulting to DEFAULT_PAGE_SIZE. + - offset (int): The offset for pagination, defaulting to 0. + - order_by (str): The field by which to order results, defaulting to "id". + - descending (bool): Whether to order results in descending order, defaulting to False. """ limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) offset = int(request.query.get("offset", 0)) - return limit, offset + order_by = request.query.get("order_by", "id") + descending = bool(request.query.get("descending", False)) + return limit, offset, order_by, descending From 424a54d5667c25880cd4ac807bb0c585ec01bab3 Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 16 Aug 2024 23:24:37 +0300 Subject: [PATCH 090/152] construction: test in-progress aries-askar PR: https://github.com/hyperledger/aries-askar/pull/291 Signed-off-by: ff137 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index de8a3531bc..3b9d330e0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ did-tdw = "^0.2.1" # askar -aries-askar = { version = "~0.3.2", optional = true } +aries-askar= { git = "https://github.com/ff137/aries-askar.git", branch = "test/order-by-scan", subdirectory = "wrappers/python", optional = true } indy-credx = { version = "~1.1.1", optional = true } indy-vdr = { version = "~0.4.0", optional = true } anoncreds = { version = "0.2.0", optional = true } From 6cce359204fe6118656072bc66465745bfde0f37 Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 16 Aug 2024 23:37:25 +0300 Subject: [PATCH 091/152] arrow_up: Update lock file Signed-off-by: ff137 --- poetry.lock | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2ec25c70e1..8486be3579 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "aiofiles" @@ -221,20 +221,23 @@ tests = ["apispec[marshmallow,yaml]", "openapi-spec-validator (==0.7.1)", "pytes yaml = ["PyYAML (>=3.10)"] [[package]] -name = "aries-askar" +name = "aries_askar" version = "0.3.2" description = "" optional = false python-versions = ">=3.6.3" -files = [ - {file = "aries_askar-0.3.2-py3-none-macosx_10_9_universal2.whl", hash = "sha256:02ddbe1773ce72c57edafff5777a1337d4a678da7484596712949170fb3ca1dc"}, - {file = "aries_askar-0.3.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:176eebcf833bb9974a162fd931c8d67669e4f0145b351ce9cb1289fd2d5a345c"}, - {file = "aries_askar-0.3.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:63f9ab97db4778ced830a6d1135e1f8bd1ca564de27218bd114f1cffbd31b04c"}, - {file = "aries_askar-0.3.2-py3-none-win_amd64.whl", hash = "sha256:6b4253377d5ed167ed94790e49c58584b68f897d2541ac4bb18fd37e9264164b"}, -] +files = [] +develop = false [package.dependencies] -cached-property = ">=1.5.2,<1.6.0" +cached_property = ">=1.5.2,<1.6.0" + +[package.source] +type = "git" +url = "https://github.com/ff137/aries-askar.git" +reference = "test/order-by-scan" +resolved_reference = "15564e50542313abff570b45711ba71587c4d855" +subdirectory = "wrappers/python" [[package]] name = "async-timeout" From 2102f4137265dfb52d954d6150dbe58992e91387 Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 16 Aug 2024 23:37:38 +0300 Subject: [PATCH 092/152] art: fix ruff warning Signed-off-by: ff137 --- acapy_agent/messaging/models/paginated_query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acapy_agent/messaging/models/paginated_query.py b/acapy_agent/messaging/models/paginated_query.py index 2cb430d087..34a4d940c6 100644 --- a/acapy_agent/messaging/models/paginated_query.py +++ b/acapy_agent/messaging/models/paginated_query.py @@ -59,7 +59,7 @@ def get_paginated_query_params(request: BaseRequest) -> Tuple[int, int, str, boo - limit (int): The number of results to return, defaulting to DEFAULT_PAGE_SIZE. - offset (int): The offset for pagination, defaulting to 0. - order_by (str): The field by which to order results, defaulting to "id". - - descending (bool): Whether to order results in descending order, defaulting to False. + - descending (bool): Order results in descending order; defaults to False. """ limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) From 362cff75daa844b83092354af5d50de43b3751ef Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 16 Aug 2024 23:37:53 +0300 Subject: [PATCH 093/152] white_check_mark: fix assertions Signed-off-by: ff137 --- .../messaging/models/tests/test_base_record.py | 15 ++++++++++++++- .../connections/v1_0/tests/test_routes.py | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/acapy_agent/messaging/models/tests/test_base_record.py b/acapy_agent/messaging/models/tests/test_base_record.py index ab262ff3ee..672705dfd7 100644 --- a/acapy_agent/messaging/models/tests/test_base_record.py +++ b/acapy_agent/messaging/models/tests/test_base_record.py @@ -164,6 +164,8 @@ async def test_query(self): result = await BaseRecordImpl.query(session, tag_filter) mock_storage.find_all_records.assert_awaited_once_with( type_filter=BaseRecordImpl.RECORD_TYPE, + order_by=None, + descending=False, tag_query=tag_filter, ) assert result and isinstance(result[0], BaseRecordImpl) @@ -216,6 +218,8 @@ async def test_query_post_filter(self): mock_storage.find_all_records.assert_awaited_once_with( type_filter=ARecordImpl.RECORD_TYPE, tag_query=tag_filter, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -339,6 +343,8 @@ async def test_query_with_limit(self): tag_query=tag_filter, limit=10, offset=0, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -369,6 +375,8 @@ async def test_query_with_offset(self): tag_query=tag_filter, limit=DEFAULT_PAGE_SIZE, offset=10, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -399,6 +407,8 @@ async def test_query_with_limit_and_offset(self): tag_query=tag_filter, limit=10, offset=5, + order_by=None, + descending=False, ) assert result and isinstance(result[0], ARecordImpl) assert result[0]._id == record_id @@ -433,7 +443,10 @@ async def test_query_with_limit_and_offset_and_post_filter(self): post_filter_positive={"a": "one"}, ) mock_storage.find_all_records.assert_awaited_once_with( - type_filter=ARecordImpl.RECORD_TYPE, tag_query=tag_filter + type_filter=ARecordImpl.RECORD_TYPE, + tag_query=tag_filter, + order_by=None, + descending=False, ) assert len(result) == 10 assert result and isinstance(result[0], ARecordImpl) diff --git a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py index 917c795c5f..88a2517338 100644 --- a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py @@ -101,6 +101,8 @@ async def test_connections_list(self): }, limit=100, offset=0, + order_by="id", + descending=False, post_filter_positive={ "their_role": list(ConnRecord.Role.REQUESTER.value), "connection_protocol": "connections/1.0", From 2a1e5ae0a8cae036674376c3417fb142ce7e98cc Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 20 Aug 2024 16:45:57 +0300 Subject: [PATCH 094/152] construction: test aries-askar with TestPyPI package Signed-off-by: ff137 --- docker/Dockerfile | 8 +++++--- poetry.lock | 10 ++++------ pyproject.toml | 9 +++++++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index ab9dc1861a..acf36cc46e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -16,8 +16,8 @@ ARG acapy_name="aries-cloudagent" ARG acapy_version ARG acapy_reqs=[askar,didcommv2] -ENV HOME="/home/$user" \ - APP_ROOT="$HOME" \ +ENV HOME="/home/$user" +ENV APP_ROOT="$HOME" \ LC_ALL=C.UTF-8 \ LANG=C.UTF-8 \ PIP_NO_CACHE_DIR=off \ @@ -96,7 +96,9 @@ USER $user COPY --from=build /src/dist/acapy_agent*.whl . RUN acapy_agent_package=$(find ./ -name "acapy_agent*.whl" | head -n 1) && \ echo "Installing ${acapy_agent_package} ..." && \ - pip install --no-cache-dir --find-links=. ${acapy_agent_package}${acapy_reqs} && \ + pip install --no-cache-dir --find-links=. \ + --extra-index-url https://test.pypi.org/simple/ \ + ${acapy_agent_package}${acapy_reqs} && \ rm acapy_agent*.whl && \ chmod +rx $(python -m site --user-site) $HOME/.local diff --git a/poetry.lock b/poetry.lock index 8486be3579..b8e6c36975 100644 --- a/poetry.lock +++ b/poetry.lock @@ -233,11 +233,9 @@ develop = false cached_property = ">=1.5.2,<1.6.0" [package.source] -type = "git" -url = "https://github.com/ff137/aries-askar.git" -reference = "test/order-by-scan" -resolved_reference = "15564e50542313abff570b45711ba71587c4d855" -subdirectory = "wrappers/python" +type = "legacy" +url = "https://test.pypi.org/simple" +reference = "testpypi" [[package]] name = "async-timeout" @@ -3088,7 +3086,7 @@ multidict = ">=4.0" propcache = ">=0.2.0" [extras] -askar = ["anoncreds", "aries-askar", "indy-credx", "indy-vdr"] +askar = ["anoncreds", "aries-askar-ff137", "indy-credx", "indy-vdr"] bbs = ["ursa-bbs-signatures"] didcommv2 = ["didcomm-messaging"] diff --git a/pyproject.toml b/pyproject.toml index 3b9d330e0a..d7514833e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ did-tdw = "^0.2.1" # askar -aries-askar= { git = "https://github.com/ff137/aries-askar.git", branch = "test/order-by-scan", subdirectory = "wrappers/python", optional = true } +aries-askar-ff137 = {version = "^0.3.3b0", source = "testpypi", optional = true} indy-credx = { version = "~1.1.1", optional = true } indy-vdr = { version = "~0.4.0", optional = true } anoncreds = { version = "0.2.0", optional = true } @@ -87,13 +87,18 @@ pytest-xdist = "^3.6.1" debugpy = "^1.8.9" [tool.poetry.extras] -askar = ["aries-askar", "indy-credx", "indy-vdr", "anoncreds"] +askar = ["aries-askar-ff137", "indy-credx", "indy-vdr", "anoncreds"] bbs = ["ursa-bbs-signatures"] didcommv2 = ["didcomm-messaging"] [tool.poetry.scripts] aca-py = "acapy_agent.__main__:script_main" +[[tool.poetry.source]] +name = "testpypi" +url = "https://test.pypi.org/simple/" +priority = "supplemental" + [tool.ruff] lint.select = ["B006", "C", "D", "E", "F"] From 42fd632cfc40238ad96ccb1ea03eb631fdd26244 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 21 Aug 2024 20:33:09 +0300 Subject: [PATCH 095/152] construction: test latest askar testpypi package Signed-off-by: ff137 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d7514833e7..93801941b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ did-tdw = "^0.2.1" # askar -aries-askar-ff137 = {version = "^0.3.3b0", source = "testpypi", optional = true} +aries-askar-ff137 = {version = "^0.3.3b1", source = "testpypi", optional = true} indy-credx = { version = "~1.1.1", optional = true } indy-vdr = { version = "~0.4.0", optional = true } anoncreds = { version = "0.2.0", optional = true } From 6c11a514afd873ffc4df3a89bcdcefc09df4a291 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 22 Aug 2024 12:37:51 +0300 Subject: [PATCH 096/152] art: Update order_by description and default value. Include in schema Signed-off-by: ff137 --- acapy_agent/messaging/models/paginated_query.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/acapy_agent/messaging/models/paginated_query.py b/acapy_agent/messaging/models/paginated_query.py index 34a4d940c6..b938af772d 100644 --- a/acapy_agent/messaging/models/paginated_query.py +++ b/acapy_agent/messaging/models/paginated_query.py @@ -34,12 +34,14 @@ class PaginatedQuerySchema(OpenAPISchema): ) order_by = fields.Str( required=False, - load_default=None, - dump_only=True, # Hide from schema by making it dump-only - load_only=True, # Ensure it can still be loaded/validated - validate=OneOf(["id"]), # Example of possible fields - metadata={"description": "Order results in descending order if true"}, - error_messages={"validator_failed": "Ordering only support for column `id`"}, + load_default="id", + validate=OneOf(["id"]), # only one possible column supported in askar + metadata={ + "description": ( + 'The column to order results by. Only "id" is currently supported.' + ) + }, + error_messages={"validator_failed": '`order_by` only supports column "id"'}, ) descending = fields.Bool( required=False, From db8a376d0922be05ad423a9fb5730c3cd528c6fd Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 30 Aug 2024 14:05:06 +0300 Subject: [PATCH 097/152] bug: fix deserialisation of descending: bool parameter Signed-off-by: ff137 --- acapy_agent/messaging/models/paginated_query.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/acapy_agent/messaging/models/paginated_query.py b/acapy_agent/messaging/models/paginated_query.py index b938af772d..670c3cda2b 100644 --- a/acapy_agent/messaging/models/paginated_query.py +++ b/acapy_agent/messaging/models/paginated_query.py @@ -46,7 +46,10 @@ class PaginatedQuerySchema(OpenAPISchema): descending = fields.Bool( required=False, load_default=False, + truthy={"true", "1", "yes"}, + falsy={"false", "0", "no"}, metadata={"description": "Order results in descending order if true"}, + error_messages={"invalid": "Not a valid boolean."}, ) @@ -67,5 +70,9 @@ def get_paginated_query_params(request: BaseRequest) -> Tuple[int, int, str, boo limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) offset = int(request.query.get("offset", 0)) order_by = request.query.get("order_by", "id") - descending = bool(request.query.get("descending", False)) + + # Convert the 'descending' parameter to a boolean + descending_str = request.query.get("descending", "False").lower() + descending = descending_str in {"true", "1", "yes"} + return limit, offset, order_by, descending From e1256df7a9ab5da5397512fbb5453c7563d20fde Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 30 Aug 2024 14:05:27 +0300 Subject: [PATCH 098/152] rewind: revert to testing 0.3.3b0 askar test package Signed-off-by: ff137 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 93801941b5..fcf652ca7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ did-tdw = "^0.2.1" # askar -aries-askar-ff137 = {version = "^0.3.3b1", source = "testpypi", optional = true} +aries-askar-ff137 = {version = "==0.3.3b0", source = "testpypi", optional = true} indy-credx = { version = "~1.1.1", optional = true } indy-vdr = { version = "~0.4.0", optional = true } anoncreds = { version = "0.2.0", optional = true } From 3691e907e6410e19261cf71ff550c13c4a9d90d8 Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 30 Aug 2024 17:48:41 +0300 Subject: [PATCH 099/152] fire: remove unnecessary record sorts (now that askar sorts by id == sorting by created_at) Signed-off-by: ff137 --- acapy_agent/multitenant/admin/routes.py | 1 - acapy_agent/protocols/connections/v1_0/routes.py | 15 --------------- 2 files changed, 16 deletions(-) diff --git a/acapy_agent/multitenant/admin/routes.py b/acapy_agent/multitenant/admin/routes.py index a569902ad4..470e4e059b 100644 --- a/acapy_agent/multitenant/admin/routes.py +++ b/acapy_agent/multitenant/admin/routes.py @@ -399,7 +399,6 @@ async def wallets_list(request: web.BaseRequest): descending=descending, ) results = [format_wallet_record(record) for record in records] - results.sort(key=lambda w: w["created_at"]) except (StorageError, BaseModelError) as err: raise web.HTTPBadRequest(reason=err.roll_up) from err diff --git a/acapy_agent/protocols/connections/v1_0/routes.py b/acapy_agent/protocols/connections/v1_0/routes.py index 78cfbb590e..0e415ceabc 100644 --- a/acapy_agent/protocols/connections/v1_0/routes.py +++ b/acapy_agent/protocols/connections/v1_0/routes.py @@ -414,20 +414,6 @@ class EndpointsResultSchema(OpenAPISchema): ) -def connection_sort_key(conn): - """Get the sorting key for a particular connection.""" - - conn_rec_state = ConnRecord.State.get(conn["state"]) - if conn_rec_state is ConnRecord.State.ABANDONED: - pfx = "2" - elif conn_rec_state is ConnRecord.State.INVITATION: - pfx = "1" - else: - pfx = "0" - - return pfx + conn["created_at"] - - @docs( tags=["connection"], summary="Query agent-to-agent connections", @@ -488,7 +474,6 @@ async def connections_list(request: web.BaseRequest): alt=True, ) results = [record.serialize() for record in records] - results.sort(key=connection_sort_key) except (StorageError, BaseModelError) as err: raise web.HTTPBadRequest(reason=err.roll_up) from err From 99d25edf0d630bcdbe802ea509bef0285f7bc9ab Mon Sep 17 00:00:00 2001 From: ff137 Date: Fri, 30 Aug 2024 17:53:12 +0300 Subject: [PATCH 100/152] white_check_mark: fix test assertions -- wallet_list and connections_list no longer does additional sorting Signed-off-by: ff137 --- acapy_agent/multitenant/admin/tests/test_routes.py | 2 +- acapy_agent/protocols/connections/v1_0/tests/test_routes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/acapy_agent/multitenant/admin/tests/test_routes.py b/acapy_agent/multitenant/admin/tests/test_routes.py index 4ec0ba142a..6f24c863de 100644 --- a/acapy_agent/multitenant/admin/tests/test_routes.py +++ b/acapy_agent/multitenant/admin/tests/test_routes.py @@ -87,7 +87,7 @@ async def test_wallets_list(self): ), ] mock_wallet_record.query = mock.CoroutineMock() - mock_wallet_record.query.return_value = [wallets[2], wallets[0], wallets[1]] + mock_wallet_record.query.return_value = wallets await test_module.wallets_list(self.request) mock_response.assert_called_once_with( diff --git a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py index 88a2517338..002ad67263 100644 --- a/acapy_agent/protocols/connections/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/connections/v1_0/tests/test_routes.py @@ -87,7 +87,7 @@ async def test_connections_list(self): ) ), ] - mock_conn_rec.query.return_value = [conns[2], conns[0], conns[1]] # jumbled + mock_conn_rec.query.return_value = conns with mock.patch.object(test_module.web, "json_response") as mock_response: await test_module.connections_list(self.request) From 0f5eb330f5f70f2319244ec6095c6e4e46989607 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 22 Oct 2024 16:40:29 +0300 Subject: [PATCH 101/152] arrow_up: Update lock file Signed-off-by: ff137 --- poetry.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index b8e6c36975..20f4bb9311 100644 --- a/poetry.lock +++ b/poetry.lock @@ -230,7 +230,7 @@ files = [] develop = false [package.dependencies] -cached_property = ">=1.5.2,<1.6.0" +cached-property = ">=1.5.2,<1.6.0" [package.source] type = "legacy" From 833ff2536e20aa51c759e2730dee2474c5bb5423 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 29 Aug 2024 12:15:10 +0300 Subject: [PATCH 102/152] art: Modify count/start query params to be Integers, not Strings Signed-off-by: ff137 --- acapy_agent/holder/routes.py | 31 ++++++++++--------- .../protocols/present_proof/v1_0/routes.py | 31 +++++++++---------- .../protocols/present_proof/v2_0/routes.py | 31 +++++++++---------- 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/acapy_agent/holder/routes.py b/acapy_agent/holder/routes.py index 37c1d5e1e7..2d8001656c 100644 --- a/acapy_agent/holder/routes.py +++ b/acapy_agent/holder/routes.py @@ -27,11 +27,13 @@ ENDPOINT_VALIDATE, INDY_WQL_EXAMPLE, INDY_WQL_VALIDATE, - NUM_STR_NATURAL_EXAMPLE, - NUM_STR_NATURAL_VALIDATE, + NATURAL_NUM_EXAMPLE, + NATURAL_NUM_VALIDATE, NUM_STR_WHOLE_EXAMPLE, NUM_STR_WHOLE_VALIDATE, UUID4_EXAMPLE, + WHOLE_NUM_EXAMPLE, + WHOLE_NUM_VALIDATE, ) from ..storage.error import StorageError, StorageNotFoundError from ..storage.vc_holder.base import VCHolder @@ -64,17 +66,22 @@ class CredInfoListSchema(OpenAPISchema): class CredentialsListQueryStringSchema(OpenAPISchema): """Parameters and validators for query string in credentials list query.""" - start = fields.Str( + start = fields.Int( required=False, - validate=NUM_STR_WHOLE_VALIDATE, - metadata={"description": "Start index", "example": NUM_STR_WHOLE_EXAMPLE}, + load_default=0, + validate=WHOLE_NUM_VALIDATE, + metadata={ + "description": "Start index", + "example": WHOLE_NUM_EXAMPLE, + }, ) - count = fields.Str( + count = fields.Int( required=False, - validate=NUM_STR_NATURAL_VALIDATE, + load_default=10, + validate=NATURAL_NUM_VALIDATE, metadata={ "description": "Maximum number to retrieve", - "example": NUM_STR_NATURAL_EXAMPLE, + "example": NATURAL_NUM_EXAMPLE, }, ) wql = fields.Str( @@ -379,17 +386,13 @@ async def credentials_list(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - start = request.query.get("start") - count = request.query.get("count") + start = int(request.query.get("start", 0)) + count = int(request.query.get("count", 10)) # url encoded json wql encoded_wql = request.query.get("wql") or "{}" wql = json.loads(encoded_wql) - # defaults - start = int(start) if isinstance(start, str) else 0 - count = int(count) if isinstance(count, str) else 10 - if context.settings.get(wallet_type_config) == "askar-anoncreds": holder = AnonCredsHolder(context.profile) credentials = await holder.get_credentials(start, count, wql) diff --git a/acapy_agent/protocols/present_proof/v1_0/routes.py b/acapy_agent/protocols/present_proof/v1_0/routes.py index 97459a687e..cee88c5e9c 100644 --- a/acapy_agent/protocols/present_proof/v1_0/routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/routes.py @@ -29,12 +29,12 @@ from ....messaging.valid import ( INDY_EXTRA_WQL_EXAMPLE, INDY_EXTRA_WQL_VALIDATE, - NUM_STR_NATURAL_EXAMPLE, - NUM_STR_NATURAL_VALIDATE, - NUM_STR_WHOLE_EXAMPLE, - NUM_STR_WHOLE_VALIDATE, + NATURAL_NUM_EXAMPLE, + NATURAL_NUM_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, + WHOLE_NUM_EXAMPLE, + WHOLE_NUM_VALIDATE, ) from ....storage.error import StorageError, StorageNotFoundError from ....utils.tracing import AdminAPIMessageTracingSchema, get_timer, trace_event @@ -235,21 +235,22 @@ class CredentialsFetchQueryStringSchema(OpenAPISchema): "example": "1_name_uuid,2_score_uuid", }, ) - start = fields.Str( + start = fields.Int( required=False, - validate=NUM_STR_WHOLE_VALIDATE, + load_default=0, + validate=WHOLE_NUM_VALIDATE, metadata={ "description": "Start index", - "strict": True, - "example": NUM_STR_WHOLE_EXAMPLE, + "example": WHOLE_NUM_EXAMPLE, }, ) - count = fields.Str( + count = fields.Int( required=False, - validate=NUM_STR_NATURAL_VALIDATE, + load_default=10, + validate=NATURAL_NUM_VALIDATE, metadata={ "description": "Maximum number to retrieve", - "example": NUM_STR_NATURAL_EXAMPLE, + "example": NATURAL_NUM_EXAMPLE, }, ) extra_query = fields.Str( @@ -413,17 +414,13 @@ async def presentation_exchange_credentials_list(request: web.BaseRequest): except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - start = request.query.get("start") - count = request.query.get("count") + start = int(request.query.get("start", 0)) + count = int(request.query.get("count", 10)) # url encoded json extra_query encoded_extra_query = request.query.get("extra_query") or "{}" extra_query = json.loads(encoded_extra_query) - # defaults - start = int(start) if isinstance(start, str) else 0 - count = int(count) if isinstance(count, str) else 10 - holder = profile.inject(IndyHolder) try: credentials = await holder.get_credentials_for_presentation_request_by_referent( diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index b53188f118..9f8f67d6c2 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -31,12 +31,12 @@ from ....messaging.valid import ( INDY_EXTRA_WQL_EXAMPLE, INDY_EXTRA_WQL_VALIDATE, - NUM_STR_NATURAL_EXAMPLE, - NUM_STR_NATURAL_VALIDATE, - NUM_STR_WHOLE_EXAMPLE, - NUM_STR_WHOLE_VALIDATE, + NATURAL_NUM_EXAMPLE, + NATURAL_NUM_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, + WHOLE_NUM_EXAMPLE, + WHOLE_NUM_VALIDATE, ) from ....storage.base import BaseStorage from ....storage.error import StorageError, StorageNotFoundError @@ -364,21 +364,22 @@ class V20CredentialsFetchQueryStringSchema(OpenAPISchema): "example": "1_name_uuid,2_score_uuid", }, ) - start = fields.Str( + start = fields.Int( required=False, - validate=NUM_STR_WHOLE_VALIDATE, + load_default=0, + validate=WHOLE_NUM_VALIDATE, metadata={ "description": "Start index", - "strict": True, - "example": NUM_STR_WHOLE_EXAMPLE, + "example": WHOLE_NUM_EXAMPLE, }, ) - count = fields.Str( + count = fields.Int( required=False, - validate=NUM_STR_NATURAL_VALIDATE, + load_default=10, + validate=NATURAL_NUM_VALIDATE, metadata={ "description": "Maximum number to retrieve", - "example": NUM_STR_NATURAL_EXAMPLE, + "example": NATURAL_NUM_EXAMPLE, }, ) extra_query = fields.Str( @@ -563,17 +564,13 @@ async def present_proof_credentials_list(request: web.BaseRequest): except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - start = request.query.get("start") - count = request.query.get("count") + start = int(request.query.get("start", 0)) + count = int(request.query.get("count", 10)) # url encoded json extra_query encoded_extra_query = request.query.get("extra_query") or "{}" extra_query = json.loads(encoded_extra_query) - # defaults - start = int(start) if isinstance(start, str) else 0 - count = int(count) if isinstance(count, str) else 10 - wallet_type = profile.settings.get_value("wallet.type") if wallet_type == "askar-anoncreds": holder = AnonCredsHolder(profile) From f9531b53ed9ac1fe3c27292de1dee60b95d7c0cc Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 29 Aug 2024 12:18:04 +0300 Subject: [PATCH 103/152] memo: Update openapi spec Signed-off-by: ff137 --- open-api/openapi.json | 40 ++++++++++++++++++++++++---------------- open-api/swagger.json | 40 ++++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/open-api/openapi.json b/open-api/openapi.json index 444c97fbbe..ead3da68b1 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -2058,16 +2058,18 @@ "in" : "query", "name" : "count", "schema" : { - "pattern" : "^[1-9][0-9]*$", - "type" : "string" + "default" : 10, + "minimum" : 1, + "type" : "integer" } }, { "description" : "Start index", "in" : "query", "name" : "start", "schema" : { - "pattern" : "^[0-9]*$", - "type" : "string" + "default" : 0, + "minimum" : 0, + "type" : "integer" } }, { "description" : "(JSON) WQL query", @@ -2101,16 +2103,18 @@ "in" : "query", "name" : "count", "schema" : { - "pattern" : "^[1-9][0-9]*$", - "type" : "string" + "default" : 10, + "minimum" : 1, + "type" : "integer" } }, { "description" : "Start index", "in" : "query", "name" : "start", "schema" : { - "pattern" : "^[0-9]*$", - "type" : "string" + "default" : 0, + "minimum" : 0, + "type" : "integer" } }, { "description" : "(JSON) WQL query", @@ -4927,8 +4931,9 @@ "in" : "query", "name" : "count", "schema" : { - "pattern" : "^[1-9][0-9]*$", - "type" : "string" + "default" : 10, + "minimum" : 1, + "type" : "integer" } }, { "description" : "(JSON) object mapping referents to extra WQL queries", @@ -4950,8 +4955,9 @@ "in" : "query", "name" : "start", "schema" : { - "pattern" : "^[0-9]*$", - "type" : "string" + "default" : 0, + "minimum" : 0, + "type" : "integer" } } ], "responses" : { @@ -5345,8 +5351,9 @@ "in" : "query", "name" : "count", "schema" : { - "pattern" : "^[1-9][0-9]*$", - "type" : "string" + "default" : 10, + "minimum" : 1, + "type" : "integer" } }, { "description" : "(JSON) object mapping referents to extra WQL queries", @@ -5368,8 +5375,9 @@ "in" : "query", "name" : "start", "schema" : { - "pattern" : "^[0-9]*$", - "type" : "string" + "default" : 0, + "minimum" : 0, + "type" : "integer" } } ], "responses" : { diff --git a/open-api/swagger.json b/open-api/swagger.json index 3267ac846e..1bbb89732a 100644 --- a/open-api/swagger.json +++ b/open-api/swagger.json @@ -1720,15 +1720,17 @@ "in" : "query", "description" : "Maximum number to retrieve", "required" : false, - "type" : "string", - "pattern" : "^[1-9][0-9]*$" + "type" : "integer", + "default" : 10, + "minimum" : 1 }, { "name" : "start", "in" : "query", "description" : "Start index", "required" : false, - "type" : "string", - "pattern" : "^[0-9]*$" + "type" : "integer", + "default" : 0, + "minimum" : 0 }, { "name" : "wql", "in" : "query", @@ -1764,15 +1766,17 @@ "in" : "query", "description" : "Maximum number to retrieve", "required" : false, - "type" : "string", - "pattern" : "^[1-9][0-9]*$" + "type" : "integer", + "default" : 10, + "minimum" : 1 }, { "name" : "start", "in" : "query", "description" : "Start index", "required" : false, - "type" : "string", - "pattern" : "^[0-9]*$" + "type" : "integer", + "default" : 0, + "minimum" : 0 }, { "name" : "wql", "in" : "query", @@ -4052,8 +4056,9 @@ "in" : "query", "description" : "Maximum number to retrieve", "required" : false, - "type" : "string", - "pattern" : "^[1-9][0-9]*$" + "type" : "integer", + "default" : 10, + "minimum" : 1 }, { "name" : "extra_query", "in" : "query", @@ -4072,8 +4077,9 @@ "in" : "query", "description" : "Start index", "required" : false, - "type" : "string", - "pattern" : "^[0-9]*$" + "type" : "integer", + "default" : 0, + "minimum" : 0 } ], "responses" : { "200" : { @@ -4391,8 +4397,9 @@ "in" : "query", "description" : "Maximum number to retrieve", "required" : false, - "type" : "string", - "pattern" : "^[1-9][0-9]*$" + "type" : "integer", + "default" : 10, + "minimum" : 1 }, { "name" : "extra_query", "in" : "query", @@ -4411,8 +4418,9 @@ "in" : "query", "description" : "Start index", "required" : false, - "type" : "string", - "pattern" : "^[0-9]*$" + "type" : "integer", + "default" : 0, + "minimum" : 0 } ], "deprecated" : true, "responses" : { From df97243e46b3b0bd680945e8ba54fe556285474c Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 15:18:23 +0200 Subject: [PATCH 104/152] rewind: Revert start/count field to remain String type; mark as deprecated Signed-off-by: ff137 --- acapy_agent/holder/routes.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/acapy_agent/holder/routes.py b/acapy_agent/holder/routes.py index 2d8001656c..e8e52c3ae2 100644 --- a/acapy_agent/holder/routes.py +++ b/acapy_agent/holder/routes.py @@ -27,13 +27,11 @@ ENDPOINT_VALIDATE, INDY_WQL_EXAMPLE, INDY_WQL_VALIDATE, - NATURAL_NUM_EXAMPLE, - NATURAL_NUM_VALIDATE, + NUM_STR_NATURAL_EXAMPLE, + NUM_STR_NATURAL_VALIDATE, NUM_STR_WHOLE_EXAMPLE, NUM_STR_WHOLE_VALIDATE, UUID4_EXAMPLE, - WHOLE_NUM_EXAMPLE, - WHOLE_NUM_VALIDATE, ) from ..storage.error import StorageError, StorageNotFoundError from ..storage.vc_holder.base import VCHolder @@ -66,22 +64,24 @@ class CredInfoListSchema(OpenAPISchema): class CredentialsListQueryStringSchema(OpenAPISchema): """Parameters and validators for query string in credentials list query.""" - start = fields.Int( + start = fields.Str( required=False, load_default=0, - validate=WHOLE_NUM_VALIDATE, + validate=NUM_STR_WHOLE_VALIDATE, metadata={ - "description": "Start index", - "example": WHOLE_NUM_EXAMPLE, + "description": "Start index (DEPRECATED - use offset instead)", + "example": NUM_STR_WHOLE_EXAMPLE, + "deprecated": True, }, ) - count = fields.Int( + count = fields.Str( required=False, load_default=10, - validate=NATURAL_NUM_VALIDATE, + validate=NUM_STR_NATURAL_VALIDATE, metadata={ - "description": "Maximum number to retrieve", - "example": NATURAL_NUM_EXAMPLE, + "description": "Maximum number to retrieve (DEPRECATED - use limit instead)", + "example": NUM_STR_NATURAL_EXAMPLE, + "deprecated": True, }, ) wql = fields.Str( From f748fb13635dd37a61afe75a90ce70a8b0a06609 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 15:18:59 +0200 Subject: [PATCH 105/152] sparkles: Implement limit/offset alongside deprecated count/start Signed-off-by: ff137 --- acapy_agent/holder/routes.py | 37 ++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/acapy_agent/holder/routes.py b/acapy_agent/holder/routes.py index e8e52c3ae2..493c44b1c1 100644 --- a/acapy_agent/holder/routes.py +++ b/acapy_agent/holder/routes.py @@ -33,6 +33,7 @@ NUM_STR_WHOLE_VALIDATE, UUID4_EXAMPLE, ) +from ..storage.base import DEFAULT_PAGE_SIZE, MAXIMUM_PAGE_SIZE from ..storage.error import StorageError, StorageNotFoundError from ..storage.vc_holder.base import VCHolder from ..storage.vc_holder.vc_record import VCRecordSchema @@ -84,6 +85,23 @@ class CredentialsListQueryStringSchema(OpenAPISchema): "deprecated": True, }, ) + limit = fields.Int( + required=False, + validate=lambda x: x > 0 and x <= MAXIMUM_PAGE_SIZE, + metadata={"description": "Number of results to return", "example": 50}, + error_messages={ + "validator_failed": ( + "Value must be greater than 0 and " + f"less than or equal to {MAXIMUM_PAGE_SIZE}" + ) + }, + ) + offset = fields.Int( + required=False, + validate=lambda x: x >= 0, + metadata={"description": "Offset for pagination", "example": 0}, + error_messages={"validator_failed": "Value must be 0 or greater"}, + ) wql = fields.Str( required=False, validate=INDY_WQL_VALIDATE, @@ -386,8 +404,17 @@ async def credentials_list(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] - start = int(request.query.get("start", 0)) - count = int(request.query.get("count", 10)) + + # Handle both old style start/count and new limit/offset + # TODO: Remove start/count and swap to PaginatedQuerySchema and get_limit_offset + if "limit" in request.query or "offset" in request.query: + # New style - use limit/offset + limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) + offset = int(request.query.get("offset", 0)) + else: + # Old style - use start/count + limit = int(request.query.get("count", "10")) + offset = int(request.query.get("start", "0")) # url encoded json wql encoded_wql = request.query.get("wql") or "{}" @@ -395,12 +422,14 @@ async def credentials_list(request: web.BaseRequest): if context.settings.get(wallet_type_config) == "askar-anoncreds": holder = AnonCredsHolder(context.profile) - credentials = await holder.get_credentials(start, count, wql) + credentials = await holder.get_credentials(limit=limit, offset=offset, wql=wql) else: async with context.profile.session() as session: holder = session.inject(IndyHolder) try: - credentials = await holder.get_credentials(start, count, wql) + credentials = await holder.get_credentials( + limit=limit, offset=offset, wql=wql + ) except IndyHolderError as err: raise web.HTTPBadRequest(reason=err.roll_up) from err From 86ed4a1cbfbd5c47106dd29d9fb1ac72a593d6a6 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 15:26:44 +0200 Subject: [PATCH 106/152] art: Standardise naming convention from count/start to limit/offset Signed-off-by: ff137 --- acapy_agent/anoncreds/holder.py | 23 ++++++++++--------- acapy_agent/anoncreds/tests/test_holder.py | 10 ++++---- acapy_agent/indy/credx/holder.py | 23 ++++++++++--------- .../indy/credx/tests/test_cred_issuance.py | 12 +++++----- .../protocols/present_proof/v2_0/routes.py | 6 ++--- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/acapy_agent/anoncreds/holder.py b/acapy_agent/anoncreds/holder.py index f8dd4445f7..6da4456c72 100644 --- a/acapy_agent/anoncreds/holder.py +++ b/acapy_agent/anoncreds/holder.py @@ -379,12 +379,12 @@ async def store_credential_w3c( return credential_id - async def get_credentials(self, start: int, count: int, wql: dict): + async def get_credentials(self, *, offset: int, limit: int, wql: dict): """Get credentials stored in the wallet. Args: - start: Starting index - count: Number of records to return + offset: Starting index + limit: Number of records to return wql: wql query dict """ @@ -395,8 +395,8 @@ async def get_credentials(self, start: int, count: int, wql: dict): rows = self.profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=wql, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self.profile.settings.get("wallet.askar_profile"), ) async for row in rows: @@ -413,8 +413,9 @@ async def get_credentials_for_presentation_request_by_referent( self, presentation_request: dict, referents: Sequence[str], - start: int, - count: int, + *, + offset: int, + limit: int, extra_query: Optional[dict] = None, ): """Get credentials stored in the wallet. @@ -422,8 +423,8 @@ async def get_credentials_for_presentation_request_by_referent( Args: presentation_request: Valid presentation request from issuer referents: Presentation request referents to use to search for creds - start: Starting index - count: Maximum number of records to return + offset: Starting index + limit: Maximum number of records to return extra_query: wql query dict """ @@ -466,8 +467,8 @@ async def get_credentials_for_presentation_request_by_referent( rows = self.profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=tag_filter, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self.profile.settings.get("wallet.askar_profile"), ) async for row in rows: diff --git a/acapy_agent/anoncreds/tests/test_holder.py b/acapy_agent/anoncreds/tests/test_holder.py index 34d23ef75f..c894b21e3f 100644 --- a/acapy_agent/anoncreds/tests/test_holder.py +++ b/acapy_agent/anoncreds/tests/test_holder.py @@ -397,7 +397,7 @@ async def test_store_credential_failed_trx(self, *_): async def test_get_credentials(self, _): async with self.profile.session() as session: await session.handle.insert(CATEGORY_CREDENTIAL, json.dumps(MOCK_CRED)) - result = await self.holder.get_credentials(0, 10, {}) + result = await self.holder.get_credentials(offset=0, limit=10, wql={}) assert isinstance(result, list) assert len(result) == 1 @@ -410,9 +410,9 @@ async def test_get_credentials_errors(self): ) with self.assertRaises(AnonCredsHolderError): - await self.holder.get_credentials(0, 10, {}) + await self.holder.get_credentials(offset=0, limit=10, wql={}) with self.assertRaises(AnonCredsHolderError): - await self.holder.get_credentials(0, 10, {}) + await self.holder.get_credentials(offset=0, limit=10, wql={}) async def test_get_credentials_for_presentation_request_by_referent(self): self.profile.store.scan = mock.Mock( @@ -432,13 +432,13 @@ async def test_get_credentials_for_presentation_request_by_referent(self): "restrictions": [{"schema_name": "MYCO Biomarker"}], } await self.holder.get_credentials_for_presentation_request_by_referent( - mock_pres_req, None, start=0, count=10 + mock_pres_req, None, offset=0, limit=10 ) # non-existent referent with self.assertRaises(AnonCredsHolderError): await self.holder.get_credentials_for_presentation_request_by_referent( - mock_pres_req, "not-found-ref", start=0, count=10 + mock_pres_req, "not-found-ref", offset=0, limit=10 ) @mock.patch.object(Credential, "load", return_value=MockCredential()) diff --git a/acapy_agent/indy/credx/holder.py b/acapy_agent/indy/credx/holder.py index 27ba7837e2..089f1620d1 100644 --- a/acapy_agent/indy/credx/holder.py +++ b/acapy_agent/indy/credx/holder.py @@ -236,12 +236,12 @@ async def store_credential( return credential_id - async def get_credentials(self, start: int, count: int, wql: dict): + async def get_credentials(self, *, offset: int, limit: int, wql: dict): """Get credentials stored in the wallet. Args: - start: Starting index - count: Number of records to return + offset: Starting index + limit: Number of records to return wql: wql query dict """ @@ -252,8 +252,8 @@ async def get_credentials(self, start: int, count: int, wql: dict): rows = self._profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=wql, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self._profile.settings.get("wallet.askar_profile"), ) async for row in rows: @@ -270,8 +270,9 @@ async def get_credentials_for_presentation_request_by_referent( self, presentation_request: dict, referents: Sequence[str], - start: int, - count: int, + *, + offset: int, + limit: int, extra_query: Optional[dict] = None, ): """Get credentials stored in the wallet. @@ -279,8 +280,8 @@ async def get_credentials_for_presentation_request_by_referent( Args: presentation_request: Valid presentation request from issuer referents: Presentation request referents to use to search for creds - start: Starting index - count: Maximum number of records to return + offset: Starting index + limit: Maximum number of records to return extra_query: wql query dict """ @@ -323,8 +324,8 @@ async def get_credentials_for_presentation_request_by_referent( rows = self._profile.store.scan( category=CATEGORY_CREDENTIAL, tag_filter=tag_filter, - offset=start, - limit=count, + offset=offset, + limit=limit, profile=self._profile.settings.get("wallet.askar_profile"), ) async for row in rows: diff --git a/acapy_agent/indy/credx/tests/test_cred_issuance.py b/acapy_agent/indy/credx/tests/test_cred_issuance.py index 9b8c222dc2..b1ce0c7058 100644 --- a/acapy_agent/indy/credx/tests/test_cred_issuance.py +++ b/acapy_agent/indy/credx/tests/test_cred_issuance.py @@ -142,9 +142,9 @@ async def test_issue_store_non_rev(self): await self.holder.get_credentials_for_presentation_request_by_referent( PRES_REQ_NON_REV, None, - 0, - 10, - {}, + offset=0, + limit=10, + extra_query={}, ) ) assert pres_creds == [ @@ -257,9 +257,9 @@ async def test_issue_store_rev(self): await self.holder.get_credentials_for_presentation_request_by_referent( PRES_REQ_REV, None, - 0, - 10, - {}, + offset=0, + limit=10, + extra_query={}, ) ) assert pres_creds == [ diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index 9f8f67d6c2..4229e5c603 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -592,9 +592,9 @@ async def present_proof_credentials_list(request: web.BaseRequest): await holder.get_credentials_for_presentation_request_by_referent( pres_request, pres_referents, - start, - count, - extra_query, + offset=start, + limit=count, + extra_query=extra_query, ) ) From bf16c9ed4af37dddffde363928df721f7cb46b49 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 15:34:39 +0200 Subject: [PATCH 107/152] rewind: Revert start/count field to remain String type; mark as deprecated Signed-off-by: ff137 --- .../protocols/present_proof/v1_0/routes.py | 31 ++++++++------- .../protocols/present_proof/v2_0/routes.py | 38 +++++++++---------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/acapy_agent/protocols/present_proof/v1_0/routes.py b/acapy_agent/protocols/present_proof/v1_0/routes.py index cee88c5e9c..5783a5df6d 100644 --- a/acapy_agent/protocols/present_proof/v1_0/routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/routes.py @@ -29,12 +29,12 @@ from ....messaging.valid import ( INDY_EXTRA_WQL_EXAMPLE, INDY_EXTRA_WQL_VALIDATE, - NATURAL_NUM_EXAMPLE, - NATURAL_NUM_VALIDATE, + NUM_STR_NATURAL_EXAMPLE, + NUM_STR_NATURAL_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, - WHOLE_NUM_EXAMPLE, - WHOLE_NUM_VALIDATE, ) from ....storage.error import StorageError, StorageNotFoundError from ....utils.tracing import AdminAPIMessageTracingSchema, get_timer, trace_event @@ -235,22 +235,25 @@ class CredentialsFetchQueryStringSchema(OpenAPISchema): "example": "1_name_uuid,2_score_uuid", }, ) - start = fields.Int( + start = fields.Str( required=False, - load_default=0, - validate=WHOLE_NUM_VALIDATE, + load_default="0", + validate=NUM_STR_WHOLE_VALIDATE, metadata={ - "description": "Start index", - "example": WHOLE_NUM_EXAMPLE, + "description": "Start index (DEPRECATED - use offset instead)", + "strict": True, + "example": NUM_STR_WHOLE_EXAMPLE, + "deprecated": True, }, ) - count = fields.Int( + count = fields.Str( required=False, - load_default=10, - validate=NATURAL_NUM_VALIDATE, + load_default="10", + validate=NUM_STR_NATURAL_VALIDATE, metadata={ - "description": "Maximum number to retrieve", - "example": NATURAL_NUM_EXAMPLE, + "description": "Maximum number to retrieve (DEPRECATED - use limit instead)", + "example": NUM_STR_NATURAL_EXAMPLE, + "deprecated": True, }, ) extra_query = fields.Str( diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index 4229e5c603..eb622b9fb4 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -31,12 +31,12 @@ from ....messaging.valid import ( INDY_EXTRA_WQL_EXAMPLE, INDY_EXTRA_WQL_VALIDATE, - NATURAL_NUM_EXAMPLE, - NATURAL_NUM_VALIDATE, + NUM_STR_NATURAL_EXAMPLE, + NUM_STR_NATURAL_VALIDATE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, UUID4_EXAMPLE, UUID4_VALIDATE, - WHOLE_NUM_EXAMPLE, - WHOLE_NUM_VALIDATE, ) from ....storage.base import BaseStorage from ....storage.error import StorageError, StorageNotFoundError @@ -55,12 +55,7 @@ from . import problem_report_for_record, report_problem from .formats.handler import V20PresFormatHandlerError from .manager import V20PresManager -from .message_types import ( - ATTACHMENT_FORMAT, - PRES_20_PROPOSAL, - PRES_20_REQUEST, - SPEC_URI, -) +from .message_types import ATTACHMENT_FORMAT, PRES_20_PROPOSAL, PRES_20_REQUEST, SPEC_URI from .messages.pres_format import V20PresFormat from .messages.pres_problem_report import ProblemReportReason from .messages.pres_proposal import V20PresProposal @@ -364,22 +359,25 @@ class V20CredentialsFetchQueryStringSchema(OpenAPISchema): "example": "1_name_uuid,2_score_uuid", }, ) - start = fields.Int( + start = fields.Str( required=False, - load_default=0, - validate=WHOLE_NUM_VALIDATE, + load_default="0", + validate=NUM_STR_WHOLE_VALIDATE, metadata={ - "description": "Start index", - "example": WHOLE_NUM_EXAMPLE, + "description": "Start index (DEPRECATED - use offset instead)", + "strict": True, + "example": NUM_STR_WHOLE_EXAMPLE, + "deprecated": True, }, ) - count = fields.Int( + count = fields.Str( required=False, - load_default=10, - validate=NATURAL_NUM_VALIDATE, + load_default="10", + validate=NUM_STR_NATURAL_VALIDATE, metadata={ - "description": "Maximum number to retrieve", - "example": NATURAL_NUM_EXAMPLE, + "description": "Maximum number to retrieve (DEPRECATED - use limit instead)", + "example": NUM_STR_NATURAL_EXAMPLE, + "deprecated": True, }, ) extra_query = fields.Str( From f2276e4d177d5fb76386dca13a71a3e98b528d09 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 15:39:18 +0200 Subject: [PATCH 108/152] sparkles: Implement limit/offset alongside deprecated count/start Signed-off-by: ff137 --- .../protocols/present_proof/v1_0/routes.py | 36 ++++++++++++++--- .../protocols/present_proof/v2_0/routes.py | 39 +++++++++++++++---- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/acapy_agent/protocols/present_proof/v1_0/routes.py b/acapy_agent/protocols/present_proof/v1_0/routes.py index 5783a5df6d..7fb2eee48b 100644 --- a/acapy_agent/protocols/present_proof/v1_0/routes.py +++ b/acapy_agent/protocols/present_proof/v1_0/routes.py @@ -36,6 +36,7 @@ UUID4_EXAMPLE, UUID4_VALIDATE, ) +from ....storage.base import DEFAULT_PAGE_SIZE, MAXIMUM_PAGE_SIZE from ....storage.error import StorageError, StorageNotFoundError from ....utils.tracing import AdminAPIMessageTracingSchema, get_timer, trace_event from ....wallet.error import WalletNotFoundError @@ -256,6 +257,23 @@ class CredentialsFetchQueryStringSchema(OpenAPISchema): "deprecated": True, }, ) + limit = fields.Int( + required=False, + validate=lambda x: x > 0 and x <= MAXIMUM_PAGE_SIZE, + metadata={"description": "Number of results to return", "example": 50}, + error_messages={ + "validator_failed": ( + "Value must be greater than 0 and " + f"less than or equal to {MAXIMUM_PAGE_SIZE}" + ) + }, + ) + offset = fields.Int( + required=False, + validate=lambda x: x >= 0, + metadata={"description": "Offset for pagination", "example": 0}, + error_messages={"validator_failed": "Value must be 0 or greater"}, + ) extra_query = fields.Str( required=False, validate=INDY_EXTRA_WQL_VALIDATE, @@ -417,8 +435,16 @@ async def presentation_exchange_credentials_list(request: web.BaseRequest): except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - start = int(request.query.get("start", 0)) - count = int(request.query.get("count", 10)) + # Handle both old style start/count and new limit/offset + # TODO: Remove start/count and swap to PaginatedQuerySchema and get_limit_offset + if "limit" in request.query or "offset" in request.query: + # New style - use limit/offset + limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) + offset = int(request.query.get("offset", 0)) + else: + # Old style - use start/count + limit = int(request.query.get("count", "10")) + offset = int(request.query.get("start", "0")) # url encoded json extra_query encoded_extra_query = request.query.get("extra_query") or "{}" @@ -429,9 +455,9 @@ async def presentation_exchange_credentials_list(request: web.BaseRequest): credentials = await holder.get_credentials_for_presentation_request_by_referent( pres_ex_record._presentation_request.ser, presentation_referents, - start, - count, - extra_query, + offset=offset, + limit=limit, + extra_query=extra_query, ) except IndyHolderError as err: if pres_ex_record: diff --git a/acapy_agent/protocols/present_proof/v2_0/routes.py b/acapy_agent/protocols/present_proof/v2_0/routes.py index eb622b9fb4..0472d24e48 100644 --- a/acapy_agent/protocols/present_proof/v2_0/routes.py +++ b/acapy_agent/protocols/present_proof/v2_0/routes.py @@ -38,7 +38,7 @@ UUID4_EXAMPLE, UUID4_VALIDATE, ) -from ....storage.base import BaseStorage +from ....storage.base import DEFAULT_PAGE_SIZE, MAXIMUM_PAGE_SIZE, BaseStorage from ....storage.error import StorageError, StorageNotFoundError from ....storage.vc_holder.base import VCHolder from ....storage.vc_holder.vc_record import VCRecord @@ -380,6 +380,23 @@ class V20CredentialsFetchQueryStringSchema(OpenAPISchema): "deprecated": True, }, ) + limit = fields.Int( + required=False, + validate=lambda x: x > 0 and x <= MAXIMUM_PAGE_SIZE, + metadata={"description": "Number of results to return", "example": 50}, + error_messages={ + "validator_failed": ( + "Value must be greater than 0 and " + f"less than or equal to {MAXIMUM_PAGE_SIZE}" + ) + }, + ) + offset = fields.Int( + required=False, + validate=lambda x: x >= 0, + metadata={"description": "Offset for pagination", "example": 0}, + error_messages={"validator_failed": "Value must be 0 or greater"}, + ) extra_query = fields.Str( required=False, validate=INDY_EXTRA_WQL_VALIDATE, @@ -562,8 +579,16 @@ async def present_proof_credentials_list(request: web.BaseRequest): except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - start = int(request.query.get("start", 0)) - count = int(request.query.get("count", 10)) + # Handle both old style start/count and new limit/offset + # TODO: Remove start/count and swap to PaginatedQuerySchema and get_limit_offset + if "limit" in request.query or "offset" in request.query: + # New style - use limit/offset + limit = int(request.query.get("limit", DEFAULT_PAGE_SIZE)) + offset = int(request.query.get("offset", 0)) + else: + # Old style - use start/count + limit = int(request.query.get("count", "10")) + offset = int(request.query.get("start", "0")) # url encoded json extra_query encoded_extra_query = request.query.get("extra_query") or "{}" @@ -590,8 +615,8 @@ async def present_proof_credentials_list(request: web.BaseRequest): await holder.get_credentials_for_presentation_request_by_referent( pres_request, pres_referents, - offset=start, - limit=count, + offset=offset, + limit=limit, extra_query=extra_query, ) ) @@ -751,7 +776,7 @@ async def present_proof_credentials_list(request: web.BaseRequest): search = dif_holder.search_credentials( proof_types=proof_type, pd_uri_list=uri_group ) - cred_group = await search.fetch(count) + cred_group = await search.fetch(limit) ( cred_group_vcrecord_list, cred_group_vcrecord_ids_set, @@ -765,7 +790,7 @@ async def present_proof_credentials_list(request: web.BaseRequest): proof_types=proof_type, pd_uri_list=uri_list, ) - records = await search.fetch(count) + records = await search.fetch(limit) # Avoiding addition of duplicate records vcrecord_list, vcrecord_ids_set = await process_vcrecords_return_list( records, record_ids From 36f78936d00baa4f00b421bdc79cc9ddbabe225c Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 15:41:45 +0200 Subject: [PATCH 109/152] art: Remove unused query string schema from `w3c_creds_list` Signed-off-by: ff137 --- acapy_agent/holder/routes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/acapy_agent/holder/routes.py b/acapy_agent/holder/routes.py index 493c44b1c1..cda58ccc75 100644 --- a/acapy_agent/holder/routes.py +++ b/acapy_agent/holder/routes.py @@ -508,7 +508,6 @@ async def w3c_cred_remove(request: web.BaseRequest): summary="Fetch W3C credentials from wallet", ) @request_schema(W3CCredentialsListRequestSchema()) -@querystring_schema(CredentialsListQueryStringSchema()) @response_schema(VCRecordListSchema(), 200, description="") @tenant_authentication async def w3c_creds_list(request: web.BaseRequest): From 50337703d8c72a33033d4fe33f083dfc43690521 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 15:43:49 +0200 Subject: [PATCH 110/152] art: Rename args Signed-off-by: ff137 --- acapy_agent/indy/models/xform.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acapy_agent/indy/models/xform.py b/acapy_agent/indy/models/xform.py index 6e80794889..c8082ce576 100644 --- a/acapy_agent/indy/models/xform.py +++ b/acapy_agent/indy/models/xform.py @@ -34,8 +34,8 @@ async def indy_proof_req_preview2indy_requested_creds( credentials = await holder.get_credentials_for_presentation_request_by_referent( presentation_request=indy_proof_req, referents=(referent,), - start=0, - count=100, + offset=0, + limit=100, ) if not credentials: raise ValueError( @@ -87,8 +87,8 @@ async def indy_proof_req_preview2indy_requested_creds( credentials = await holder.get_credentials_for_presentation_request_by_referent( presentation_request=indy_proof_req, referents=(referent,), - start=0, - count=100, + offset=0, + limit=100, ) if not credentials: raise ValueError( From d50dd42a2e1c76399dfa7b2c04034e29f0d48845 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 19:55:55 +0200 Subject: [PATCH 111/152] memo: Update openapi specs Signed-off-by: ff137 --- open-api/openapi.json | 147 +++++++++++++++++++++++------------------- open-api/swagger.json | 139 +++++++++++++++++++++------------------ 2 files changed, 157 insertions(+), 129 deletions(-) diff --git a/open-api/openapi.json b/open-api/openapi.json index ead3da68b1..398b1d02ef 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -2054,23 +2054,37 @@ "/credentials" : { "get" : { "parameters" : [ { - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "in" : "query", "name" : "count", "schema" : { - "default" : 10, - "minimum" : 1, + "default" : "10", + "pattern" : "^[1-9][0-9]*$", + "type" : "string" + } + }, { + "description" : "Number of results to return", + "in" : "query", + "name" : "limit", + "schema" : { "type" : "integer" } }, { - "description" : "Start index", + "description" : "Offset for pagination", "in" : "query", - "name" : "start", + "name" : "offset", "schema" : { - "default" : 0, - "minimum" : 0, "type" : "integer" } + }, { + "description" : "Start index (DEPRECATED - use offset instead)", + "in" : "query", + "name" : "start", + "schema" : { + "default" : "0", + "pattern" : "^[0-9]*$", + "type" : "string" + } }, { "description" : "(JSON) WQL query", "in" : "query", @@ -2098,33 +2112,6 @@ }, "/credentials/w3c" : { "post" : { - "parameters" : [ { - "description" : "Maximum number to retrieve", - "in" : "query", - "name" : "count", - "schema" : { - "default" : 10, - "minimum" : 1, - "type" : "integer" - } - }, { - "description" : "Start index", - "in" : "query", - "name" : "start", - "schema" : { - "default" : 0, - "minimum" : 0, - "type" : "integer" - } - }, { - "description" : "(JSON) WQL query", - "in" : "query", - "name" : "wql", - "schema" : { - "pattern" : "^{.*}$", - "type" : "string" - } - } ], "requestBody" : { "content" : { "*/*" : { @@ -4927,13 +4914,13 @@ "type" : "string" } }, { - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "in" : "query", "name" : "count", "schema" : { - "default" : 10, - "minimum" : 1, - "type" : "integer" + "default" : "10", + "pattern" : "^[1-9][0-9]*$", + "type" : "string" } }, { "description" : "(JSON) object mapping referents to extra WQL queries", @@ -4943,6 +4930,20 @@ "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$", "type" : "string" } + }, { + "description" : "Number of results to return", + "in" : "query", + "name" : "limit", + "schema" : { + "type" : "integer" + } + }, { + "description" : "Offset for pagination", + "in" : "query", + "name" : "offset", + "schema" : { + "type" : "integer" + } }, { "description" : "Proof request referents of interest, comma-separated", "in" : "query", @@ -4951,13 +4952,13 @@ "type" : "string" } }, { - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "in" : "query", "name" : "start", "schema" : { - "default" : 0, - "minimum" : 0, - "type" : "integer" + "default" : "0", + "pattern" : "^[0-9]*$", + "type" : "string" } } ], "responses" : { @@ -5347,13 +5348,13 @@ "type" : "string" } }, { - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "in" : "query", "name" : "count", "schema" : { - "default" : 10, - "minimum" : 1, - "type" : "integer" + "default" : "10", + "pattern" : "^[1-9][0-9]*$", + "type" : "string" } }, { "description" : "(JSON) object mapping referents to extra WQL queries", @@ -5363,6 +5364,20 @@ "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$", "type" : "string" } + }, { + "description" : "Number of results to return", + "in" : "query", + "name" : "limit", + "schema" : { + "type" : "integer" + } + }, { + "description" : "Offset for pagination", + "in" : "query", + "name" : "offset", + "schema" : { + "type" : "integer" + } }, { "description" : "Proof request referents of interest, comma-separated", "in" : "query", @@ -5371,13 +5386,13 @@ "type" : "string" } }, { - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "in" : "query", "name" : "start", "schema" : { - "default" : 0, - "minimum" : 0, - "type" : "integer" + "default" : "0", + "pattern" : "^[0-9]*$", + "type" : "string" } } ], "responses" : { @@ -8384,12 +8399,12 @@ "type" : "string" }, "kid" : { - "description" : "Optional kid to bind to the keypair, such as a verificationMethod.", + "description" : "Optional kid to bind to the keypair, such as a verificationMethod.", "example" : "did:web:example.com#key-01", "type" : "string" }, "seed" : { - "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode.", + "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode.", "example" : "00000000000000000000000000000000", "type" : "string" } @@ -8458,7 +8473,7 @@ }, "wallet_type" : { "description" : "Type of the wallet to create. Must be same as base wallet.", - "enum" : [ "askar", "askar-anoncreds", "in_memory" ], + "enum" : [ "askar", "askar-anoncreds" ], "example" : "askar", "type" : "string" }, @@ -9330,7 +9345,7 @@ "type" : "string" }, "mediation_id" : { - "description" : "Medation ID to use for endpoint information.", + "description" : "Mediation ID to use for endpoint information.", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", "type" : "string" @@ -9561,47 +9576,47 @@ "additionalProperties" : true, "properties" : { "challenge" : { - "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks.", + "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks.", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", "type" : "string" }, "created" : { - "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string", + "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string", "example" : "2010-01-01T19:23:24Z", "type" : "string" }, "cryptosuite" : { - "description" : "An identifier for the cryptographic suite that can be used to verify the proof.", + "description" : "An identifier for the cryptographic suite that can be used to verify the proof.", "example" : "eddsa-jcs-2022", "type" : "string" }, "domain" : { - "description" : "It conveys one or more security domains in which the proof is meant to be used.", + "description" : "It conveys one or more security domains in which the proof is meant to be used.", "example" : "example.com", "type" : "string" }, "expires" : { - "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string", + "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string", "example" : "2010-01-01T19:23:24Z", "type" : "string" }, "id" : { - "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN", + "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", "type" : "string" }, "nonce" : { - "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures.", + "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures.", "example" : "CF69iO3nfvqRsRBNElE8b4wO39SyJHPM7Gg1nExltW5vSfQA1lvDCR/zXX1To0/4NLo==", "type" : "string" }, "previousProof" : { - "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed.", + "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed.", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", "type" : "string" }, "proofPurpose" : { - "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended.", + "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended.", "example" : "assertionMethod", "type" : "string" }, @@ -9611,12 +9626,12 @@ "type" : "string" }, "type" : { - "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL].", + "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL].", "example" : "DataIntegrityProof", "type" : "string" }, "verificationMethod" : { - "description" : "A verification method is the means and information needed to verify the proof. ", + "description" : "A verification method is the means and information needed to verify the proof.", "example" : "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL", "pattern" : "\\w+:(\\/?\\/?)[^\\s]+", "type" : "string" @@ -14093,7 +14108,7 @@ "UpdateKeyRequest" : { "properties" : { "kid" : { - "description" : "New kid to bind to the key pair, such as a verificationMethod.", + "description" : "New kid to bind to the key pair, such as a verificationMethod.", "example" : "did:web:example.com#key-02", "type" : "string" }, diff --git a/open-api/swagger.json b/open-api/swagger.json index 1bbb89732a..b3f325664f 100644 --- a/open-api/swagger.json +++ b/open-api/swagger.json @@ -1718,19 +1718,31 @@ "parameters" : [ { "name" : "count", "in" : "query", - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "required" : false, - "type" : "integer", - "default" : 10, - "minimum" : 1 + "type" : "string", + "default" : "10", + "pattern" : "^[1-9][0-9]*$" + }, { + "name" : "limit", + "in" : "query", + "description" : "Number of results to return", + "required" : false, + "type" : "integer" + }, { + "name" : "offset", + "in" : "query", + "description" : "Offset for pagination", + "required" : false, + "type" : "integer" }, { "name" : "start", "in" : "query", - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "required" : false, - "type" : "integer", - "default" : 0, - "minimum" : 0 + "type" : "string", + "default" : "0", + "pattern" : "^[0-9]*$" }, { "name" : "wql", "in" : "query", @@ -1761,29 +1773,6 @@ "schema" : { "$ref" : "#/definitions/W3CCredentialsListRequest" } - }, { - "name" : "count", - "in" : "query", - "description" : "Maximum number to retrieve", - "required" : false, - "type" : "integer", - "default" : 10, - "minimum" : 1 - }, { - "name" : "start", - "in" : "query", - "description" : "Start index", - "required" : false, - "type" : "integer", - "default" : 0, - "minimum" : 0 - }, { - "name" : "wql", - "in" : "query", - "description" : "(JSON) WQL query", - "required" : false, - "type" : "string", - "pattern" : "^{.*}$" } ], "responses" : { "200" : { @@ -4054,11 +4043,11 @@ }, { "name" : "count", "in" : "query", - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "required" : false, - "type" : "integer", - "default" : 10, - "minimum" : 1 + "type" : "string", + "default" : "10", + "pattern" : "^[1-9][0-9]*$" }, { "name" : "extra_query", "in" : "query", @@ -4066,6 +4055,18 @@ "required" : false, "type" : "string", "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$" + }, { + "name" : "limit", + "in" : "query", + "description" : "Number of results to return", + "required" : false, + "type" : "integer" + }, { + "name" : "offset", + "in" : "query", + "description" : "Offset for pagination", + "required" : false, + "type" : "integer" }, { "name" : "referent", "in" : "query", @@ -4075,11 +4076,11 @@ }, { "name" : "start", "in" : "query", - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "required" : false, - "type" : "integer", - "default" : 0, - "minimum" : 0 + "type" : "string", + "default" : "0", + "pattern" : "^[0-9]*$" } ], "responses" : { "200" : { @@ -4395,11 +4396,11 @@ }, { "name" : "count", "in" : "query", - "description" : "Maximum number to retrieve", + "description" : "Maximum number to retrieve (DEPRECATED - use limit instead)", "required" : false, - "type" : "integer", - "default" : 10, - "minimum" : 1 + "type" : "string", + "default" : "10", + "pattern" : "^[1-9][0-9]*$" }, { "name" : "extra_query", "in" : "query", @@ -4407,6 +4408,18 @@ "required" : false, "type" : "string", "pattern" : "^{\\s*\".*?\"\\s*:\\s*{.*?}\\s*(,\\s*\".*?\"\\s*:\\s*{.*?}\\s*)*\\s*}$" + }, { + "name" : "limit", + "in" : "query", + "description" : "Number of results to return", + "required" : false, + "type" : "integer" + }, { + "name" : "offset", + "in" : "query", + "description" : "Offset for pagination", + "required" : false, + "type" : "integer" }, { "name" : "referent", "in" : "query", @@ -4416,11 +4429,11 @@ }, { "name" : "start", "in" : "query", - "description" : "Start index", + "description" : "Start index (DEPRECATED - use offset instead)", "required" : false, - "type" : "integer", - "default" : 0, - "minimum" : 0 + "type" : "string", + "default" : "0", + "pattern" : "^[0-9]*$" } ], "deprecated" : true, "responses" : { @@ -7015,12 +7028,12 @@ "kid" : { "type" : "string", "example" : "did:web:example.com#key-01", - "description" : "Optional kid to bind to the keypair, such as a verificationMethod." + "description" : "Optional kid to bind to the keypair, such as a verificationMethod." }, "seed" : { "type" : "string", "example" : "00000000000000000000000000000000", - "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode." + "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode." } } }, @@ -7089,7 +7102,7 @@ "type" : "string", "example" : "askar", "description" : "Type of the wallet to create. Must be same as base wallet.", - "enum" : [ "askar", "askar-anoncreds", "in_memory" ] + "enum" : [ "askar", "askar-anoncreds" ] }, "wallet_webhook_urls" : { "type" : "array", @@ -7917,7 +7930,7 @@ "mediation_id" : { "type" : "string", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "description" : "Medation ID to use for endpoint information.", + "description" : "Mediation ID to use for endpoint information.", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } } @@ -8143,47 +8156,47 @@ "challenge" : { "type" : "string", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks." + "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks." }, "created" : { "type" : "string", "example" : "2010-01-01T19:23:24Z", - "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string" + "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string" }, "cryptosuite" : { "type" : "string", "example" : "eddsa-jcs-2022", - "description" : "An identifier for the cryptographic suite that can be used to verify the proof." + "description" : "An identifier for the cryptographic suite that can be used to verify the proof." }, "domain" : { "type" : "string", "example" : "example.com", - "description" : "It conveys one or more security domains in which the proof is meant to be used." + "description" : "It conveys one or more security domains in which the proof is meant to be used." }, "expires" : { "type" : "string", "example" : "2010-01-01T19:23:24Z", - "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string" + "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string" }, "id" : { "type" : "string", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", - "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN" + "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN" }, "nonce" : { "type" : "string", "example" : "CF69iO3nfvqRsRBNElE8b4wO39SyJHPM7Gg1nExltW5vSfQA1lvDCR/zXX1To0/4NLo==", - "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures." + "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures." }, "previousProof" : { "type" : "string", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", - "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed." + "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed." }, "proofPurpose" : { "type" : "string", "example" : "assertionMethod", - "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended." + "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended." }, "proofValue" : { "type" : "string", @@ -8193,12 +8206,12 @@ "type" : { "type" : "string", "example" : "DataIntegrityProof", - "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL]." + "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL]." }, "verificationMethod" : { "type" : "string", "example" : "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL", - "description" : "A verification method is the means and information needed to verify the proof. ", + "description" : "A verification method is the means and information needed to verify the proof.", "pattern" : "\\w+:(\\/?\\/?)[^\\s]+" } }, @@ -12487,7 +12500,7 @@ "kid" : { "type" : "string", "example" : "did:web:example.com#key-02", - "description" : "New kid to bind to the key pair, such as a verificationMethod." + "description" : "New kid to bind to the key pair, such as a verificationMethod." }, "multikey" : { "type" : "string", From 908f35a33319092c8b8be2d6e300bcde15bfff63 Mon Sep 17 00:00:00 2001 From: ff137 Date: Tue, 12 Nov 2024 22:10:08 +0200 Subject: [PATCH 112/152] white_check_mark: Signed-off-by: ff137 --- acapy_agent/indy/credx/tests/test_cred_issuance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acapy_agent/indy/credx/tests/test_cred_issuance.py b/acapy_agent/indy/credx/tests/test_cred_issuance.py index b1ce0c7058..f0154b0a7b 100644 --- a/acapy_agent/indy/credx/tests/test_cred_issuance.py +++ b/acapy_agent/indy/credx/tests/test_cred_issuance.py @@ -132,7 +132,7 @@ async def test_issue_store_non_rev(self): assert not await self.holder.get_mime_type(cred_id, "name") - creds = await self.holder.get_credentials(None, None, None) + creds = await self.holder.get_credentials(offset=None, limit=None, wql=None) assert len(creds) == 1 assert creds[0] == stored_cred @@ -247,7 +247,7 @@ async def test_issue_store_rev(self): assert found stored_cred = json.loads(found) - creds = await self.holder.get_credentials(None, None, None) + creds = await self.holder.get_credentials(offset=None, limit=None, wql=None) assert len(creds) == 1 assert creds[0] == stored_cred From d615112bde5d24f3cd4a60243086ffaebce63eb3 Mon Sep 17 00:00:00 2001 From: ff137 Date: Sat, 30 Nov 2024 10:41:34 +0200 Subject: [PATCH 113/152] art: Update start/count keywords to offset/limit Signed-off-by: ff137 --- acapy_agent/anoncreds/models/utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acapy_agent/anoncreds/models/utils.py b/acapy_agent/anoncreds/models/utils.py index 51f140844f..ac5797190c 100644 --- a/acapy_agent/anoncreds/models/utils.py +++ b/acapy_agent/anoncreds/models/utils.py @@ -39,8 +39,8 @@ async def get_requested_creds_from_proof_request_preview( credentials = await holder.get_credentials_for_presentation_request_by_referent( presentation_request=proof_request, referents=(referent,), - start=0, - count=100, + offset=0, + limit=100, ) if not credentials: raise ValueError(_get_value_error_msg(proof_request, referent)) @@ -61,8 +61,8 @@ async def get_requested_creds_from_proof_request_preview( credentials = await holder.get_credentials_for_presentation_request_by_referent( presentation_request=proof_request, referents=(referent,), - start=0, - count=100, + offset=0, + limit=100, ) if not credentials: raise ValueError(_get_value_error_msg(proof_request, referent)) From 98f285d4022f7cb9a69671c8aece9c73d6494d77 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 11:42:32 +0200 Subject: [PATCH 114/152] :bug: Fix IndyVdrLedgerPool RuntimeWarning Resolves #3328 Signed-off-by: ff137 --- acapy_agent/ledger/indy_vdr.py | 286 +++++++++++++++++++++++++++++---- 1 file changed, 257 insertions(+), 29 deletions(-) diff --git a/acapy_agent/ledger/indy_vdr.py b/acapy_agent/ledger/indy_vdr.py index d26734ec6f..e966f04c50 100644 --- a/acapy_agent/ledger/indy_vdr.py +++ b/acapy_agent/ledger/indy_vdr.py @@ -11,7 +11,7 @@ from io import StringIO from pathlib import Path from time import time -from typing import List, Optional, Tuple, Union +from typing import Dict, List, Optional, Tuple, Union from indy_vdr import Pool, Request, VdrError, ledger, open_pool @@ -40,36 +40,48 @@ def _normalize_txns(txns: str) -> str: """Normalize a set of genesis transactions.""" + LOGGER.debug("Normalizing genesis transactions") lines = StringIO() for line in txns.splitlines(): line = line.strip() if line: lines.write(line) lines.write("\n") + LOGGER.debug("Finished normalizing genesis transactions") return lines.getvalue() def _write_safe(path: Path, content: str): """Atomically write to a file path.""" + LOGGER.debug("Writing content safely to path: %s", path) dir_path = path.parent with tempfile.NamedTemporaryFile(dir=dir_path, delete=False) as tmp: + LOGGER.debug("Created temporary file: %s", tmp.name) tmp.write(content.encode("utf-8")) tmp_name = tmp.name + LOGGER.debug("Renaming temporary file to target path") os.rename(tmp_name, path) + LOGGER.debug("Successfully wrote content to: %s", path) def _hash_txns(txns: str) -> str: """Obtain a hash of a set of genesis transactions.""" - return hashlib.sha256(txns.encode("utf-8")).hexdigest()[-16:] + LOGGER.debug("Calculating hash of genesis transactions") + hash_value = hashlib.sha256(txns.encode("utf-8")).hexdigest()[-16:] + LOGGER.debug("Generated transaction hash: %s", hash_value) + return hash_value class IndyVdrLedgerPool: - """Indy-VDR ledger pool manager.""" + """Indy-VDR ledger pool manager with singleton behavior based on configuration.""" + + _instances: Dict[tuple, "IndyVdrLedgerPool"] = {} + _lock = asyncio.Lock() def __init__( self, - name: str, *, + name: str, keepalive: int = 0, cache: Optional[BaseCache] = None, cache_duration: int = 600, @@ -77,69 +89,232 @@ def __init__( read_only: bool = False, socks_proxy: Optional[str] = None, ): - """Initialize an IndyLedger instance. + """Private constructor. Use 'create_instance' to instantiate.""" + LOGGER.debug( + "Initializing IndyVdrLedgerPool with name: %s, keepalive: %s, " + "cache_duration: %s, read_only: %s", + name, + keepalive, + cache_duration, + read_only, + ) - Args: - name: The pool ledger configuration name - keepalive: How many seconds to keep the ledger open - cache: The cache instance to use - cache_duration: The TTL for ledger cache entries - genesis_transactions: The ledger genesis transaction as a string - read_only: Prevent any ledger write operations - socks_proxy: Specifies socks proxy for ZMQ to connect to ledger pool - """ - self.ref_count = 0 - self.ref_lock = asyncio.Lock() + # Instance attributes + self.name = name self.keepalive = keepalive - self.close_task: asyncio.Future = None self.cache = cache - self.cache_duration: int = cache_duration + self.cache_duration = cache_duration + self.genesis_transactions = genesis_transactions + self.read_only = read_only + self.socks_proxy = socks_proxy + + self.ref_count = 0 + self.ref_lock = asyncio.Lock() + self.close_task: Optional[asyncio.Task] = None self.handle: Optional[Pool] = None - self.name = name self.cfg_path_cache: Optional[Path] = None self.genesis_hash_cache: Optional[str] = None self.genesis_txns_cache = genesis_transactions self.init_config = bool(genesis_transactions) self.taa_cache: Optional[str] = None - self.read_only: bool = read_only - self.socks_proxy: str = socks_proxy + + LOGGER.debug("Pool %s initialization staged", name) + + @classmethod + async def get_or_create( + cls, + *, + name: str, + keepalive: int = 0, + cache: Optional[BaseCache] = None, + cache_duration: int = 600, + genesis_transactions: Optional[str] = None, + read_only: bool = False, + socks_proxy: Optional[str] = None, + ) -> "IndyVdrLedgerPool": + """Asynchronously get or create the singleton instance based on configuration. + + Args: + name: The pool ledger configuration name. + keepalive: How many seconds to keep the ledger open. + cache: The cache instance to use. + cache_duration: The TTL for ledger cache entries. + genesis_transactions: The ledger genesis transaction as a string. + read_only: Prevent any ledger write operations. + socks_proxy: Specifies socks proxy for ZMQ to connect to ledger pool. + + Returns: + An initialized instance of IndyVdrLedgerPool. + """ + LOGGER.debug( + "Creating or retrieving IndyVdrLedgerPool instance with params: name=%s, " + "keepalive=%s, cache_duration=%s, read_only=%s, socks_proxy=%s", + name, + keepalive, + cache_duration, + read_only, + socks_proxy, + ) + + config_key = ( + name, + keepalive, + cache_duration, + genesis_transactions, + read_only, + socks_proxy, + ) + LOGGER.debug("Generated config key: %s", config_key) + + async with cls._lock: + if config_key not in cls._instances: + LOGGER.debug( + "No existing instance found for config key, creating new instance" + ) + instance = cls( + name=name, + keepalive=keepalive, + cache=cache, + cache_duration=cache_duration, + genesis_transactions=genesis_transactions, + read_only=read_only, + socks_proxy=socks_proxy, + ) + try: + LOGGER.debug("Initializing new IndyVdrLedgerPool instance") + await instance.initialize() + except Exception as e: + LOGGER.exception( + "Initialization failed for IndyVdrLedgerPool with config: %s", + config_key, + exc_info=e, + ) + raise + cls._instances[config_key] = instance + LOGGER.debug( + "Successfully created and stored new IndyVdrLedgerPool instance: %s", + config_key, + ) + else: + LOGGER.debug( + "Found existing IndyVdrLedgerPool instance for config: %s", config_key + ) + instance = cls._instances[config_key] + + async with instance.ref_lock: + instance.ref_count += 1 + LOGGER.debug( + "Incremented reference count to %s for instance %s", + instance.ref_count, + config_key, + ) + + LOGGER.debug( + "Returning IndyVdrLedgerPool instance with ref_count: %s", + instance.ref_count, + ) + return instance + + async def initialize(self): + """Initialize the ledger pool.""" + LOGGER.debug("Beginning pool initialization") + if self.init_config: + LOGGER.debug("Creating pool config with genesis transactions") + await self.create_pool_config(self.genesis_txns_cache, recreate=True) + self.init_config = False + LOGGER.debug("Opening pool connection") + await self.open() + LOGGER.debug("Pool initialization complete") + + @classmethod + async def release_instance(cls, instance: "IndyVdrLedgerPool"): + """Release a reference to the instance and possibly remove it from the registry. + + Args: + instance: The IndyVdrLedgerPool instance to release. + """ + LOGGER.debug("Beginning instance release process for pool: %s", instance.name) + config_key = ( + instance.name, + instance.keepalive, + instance.cache_duration, + instance.genesis_transactions, + instance.read_only, + instance.socks_proxy, + ) + LOGGER.debug("Generated config key for release: %s", config_key) + + async with cls._lock: + async with instance.ref_lock: + instance.ref_count -= 1 + LOGGER.debug( + "Decremented reference count to %s for instance %s", + instance.ref_count, + config_key, + ) + if instance.ref_count <= 0: + LOGGER.debug( + "Reference count is zero or negative, cleaning up instance" + ) + await instance.close() + del cls._instances[config_key] + LOGGER.debug( + "Successfully removed IndyVdrLedgerPool instance: %s", config_key + ) + else: + LOGGER.debug( + "Instance still has active references: %s", instance.ref_count + ) @property def cfg_path(self) -> Path: """Get the path to the configuration file, ensuring it's created.""" if not self.cfg_path_cache: + LOGGER.debug("Creating configuration path cache") self.cfg_path_cache = storage_path("vdr", create=True) + LOGGER.debug("Configuration path set to: %s", self.cfg_path_cache) return self.cfg_path_cache @property def genesis_hash(self) -> str: """Get the hash of the configured genesis transactions.""" if not self.genesis_hash_cache: + LOGGER.debug("Calculating genesis transactions hash") self.genesis_hash_cache = _hash_txns(self.genesis_txns) + LOGGER.debug("Genesis hash calculated: %s", self.genesis_hash_cache) return self.genesis_hash_cache @property def genesis_txns(self) -> str: """Get the configured genesis transactions.""" if not self.genesis_txns_cache: + LOGGER.debug("Loading genesis transactions from file") try: path = self.cfg_path.joinpath(self.name, "genesis") + LOGGER.debug("Reading genesis file from: %s", path) self.genesis_txns_cache = _normalize_txns(open(path).read()) + LOGGER.debug("Successfully loaded genesis transactions") except FileNotFoundError: + LOGGER.error("Pool config '%s' not found", self.name) raise LedgerConfigError("Pool config '%s' not found", self.name) from None return self.genesis_txns_cache async def create_pool_config(self, genesis_transactions: str, recreate: bool = False): """Create the pool ledger configuration.""" + LOGGER.debug("Creating pool config for '%s', recreate=%s", self.name, recreate) cfg_pool = self.cfg_path.joinpath(self.name) cfg_pool.mkdir(exist_ok=True) + LOGGER.debug("Created pool configuration directory: %s", cfg_pool) + genesis = _normalize_txns(genesis_transactions) if not genesis: + LOGGER.error("Empty genesis transactions provided") raise LedgerConfigError("Empty genesis transactions") genesis_path = cfg_pool.joinpath("genesis") try: + LOGGER.debug("Checking existing genesis file: %s", genesis_path) cmp_genesis = open(genesis_path).read() if _normalize_txns(cmp_genesis) == genesis: LOGGER.debug( @@ -148,66 +323,94 @@ async def create_pool_config(self, genesis_transactions: str, recreate: bool = F ) return elif not recreate: + LOGGER.error( + "Pool ledger '%s' exists with different genesis transactions", + self.name, + ) raise LedgerConfigError( f"Pool ledger '{self.name}' exists with " "different genesis transactions" ) except FileNotFoundError: + LOGGER.debug("No existing genesis file found") pass try: + LOGGER.debug("Writing genesis transactions to: %s", genesis_path) _write_safe(genesis_path, genesis) except OSError as err: + LOGGER.exception("Error writing genesis transactions", exc_info=err) raise LedgerConfigError("Error writing genesis transactions") from err - LOGGER.debug("Wrote pool ledger config '%s'", self.name) + LOGGER.debug("Successfully wrote pool ledger config '%s'", self.name) self.genesis_txns_cache = genesis async def open(self): """Open the pool ledger, creating it if necessary.""" + LOGGER.debug("Opening pool ledger: %s", self.name) if self.init_config: + LOGGER.debug("Initializing pool config with genesis transactions") await self.create_pool_config(self.genesis_txns_cache, recreate=True) self.init_config = False genesis_hash = self.genesis_hash + LOGGER.debug("Using genesis hash: %s", genesis_hash) cfg_pool = self.cfg_path.joinpath(self.name) cfg_pool.mkdir(exist_ok=True) cache_path = cfg_pool.joinpath(f"cache-{genesis_hash}") try: + LOGGER.debug("Attempting to read cached transactions from: %s", cache_path) txns = open(cache_path).read() cached = True + LOGGER.debug("Successfully read cached transactions") except FileNotFoundError: + LOGGER.debug("No cached transactions found, using genesis transactions") txns = self.genesis_txns cached = False + LOGGER.debug("Opening pool with transactions, socks_proxy=%s", self.socks_proxy) self.handle = await open_pool(transactions=txns, socks_proxy=self.socks_proxy) + LOGGER.debug("Pool opened successfully") + upd_txns = _normalize_txns(await self.handle.get_transactions()) if not cached or upd_txns != txns: + LOGGER.debug("Updating cached transactions") try: _write_safe(cache_path, upd_txns) + LOGGER.debug("Successfully wrote updated cached transactions") except OSError: LOGGER.exception("Error writing cached genesis transactions") async def close(self): """Close the pool ledger.""" if self.handle: + LOGGER.debug("Attempting to close pool ledger") exc = None for attempt in range(3): try: + LOGGER.debug("Close attempt %s/3", attempt + 1) self.handle.close() except VdrError as err: + LOGGER.warning( + "Error closing pool ledger (attempt %s/3): %s", + attempt + 1, + str(err), + ) await asyncio.sleep(0.01) exc = err continue self.handle = None exc = None + LOGGER.debug("Successfully closed pool ledger") break if exc: - LOGGER.exception("Exception when closing pool ledger", exc_info=exc) + LOGGER.exception( + "Failed to close pool ledger after 3 attempts", exc_info=exc + ) self.ref_count += 1 # if we are here, we should have self.ref_lock self.close_task = None raise LedgerError("Exception when closing pool ledger") from exc @@ -227,18 +430,43 @@ async def context_close(self): async def closer(timeout: int): """Close the pool ledger after a timeout.""" - await asyncio.sleep(timeout) - async with self.ref_lock: - if not self.ref_count: - LOGGER.debug("Closing pool ledger after timeout") - await self.close() + try: + LOGGER.debug( + "Coroutine will sleep for %d seconds before closing the pool.", + timeout, + ) + await asyncio.sleep(timeout) + async with self.ref_lock: + if not self.ref_count: + LOGGER.debug( + "No more references. Proceeding to close the pool ledger." + ) + await self.close() + else: + LOGGER.debug( + "Reference count is %d. Not closing the pool yet.", + self.ref_count, + ) + except Exception as e: + LOGGER.exception( + "Exception occurred in closer coroutine during pool closure.", + exc_info=e, + ) async with self.ref_lock: self.ref_count -= 1 + LOGGER.debug("Decremented ref_count to %d.", self.ref_count) if not self.ref_count: if self.keepalive: - self.close_task = asyncio.ensure_future(closer(self.keepalive)) + LOGGER.debug( + "Scheduling closer coroutine with keepalive=%s", + self.keepalive, + ) + self.close_task = asyncio.create_task(closer(self.keepalive)) else: + LOGGER.debug( + "No keepalive set. Proceeding to close the pool immediately." + ) await self.close() From 8d783b05fc5a01fd856ea4f7368a0b111ceb9246 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 11:43:48 +0200 Subject: [PATCH 115/152] :test_tube: Update tests Signed-off-by: ff137 --- .../tests/test_indy_ledger_requests.py | 3 ++- .../tests/test_indy_vdr_manager.py | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py b/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py index 4feb805b31..917a48e923 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_indy_ledger_requests.py @@ -24,7 +24,8 @@ async def asyncSetUp(self): "genesis_transactions": "genesis_transactions", } ] - self.ledger = IndyVdrLedger(IndyVdrLedgerPool("test_prod_1"), self.profile) + pool = await IndyVdrLedgerPool.get_or_create(name="test_prod_1") + self.ledger = IndyVdrLedger(pool, self.profile) mock_ledger_manger = mock.MagicMock(BaseMultipleLedgerManager, autospec=True) mock_ledger_manger.extract_did_from_identifier = mock.MagicMock( return_value="WgWxqztrNooG92RXvxSTWv" diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py b/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py index c567b33cf2..1451a5fabb 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_indy_vdr_manager.py @@ -63,17 +63,19 @@ async def asyncSetUp(self): self.context.injector.bind_instance(BaseResponder, self.responder) self.production_ledger = OrderedDict() self.non_production_ledger = OrderedDict() - test_prod_ledger = IndyVdrLedger(IndyVdrLedgerPool("test_prod_1"), self.profile) + test_prod_ledger = IndyVdrLedger( + await IndyVdrLedgerPool.get_or_create(name="test_prod_1"), self.profile + ) writable_ledgers = set() self.production_ledger["test_prod_1"] = test_prod_ledger self.production_ledger["test_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_prod_2"), self.profile ) self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) writable_ledgers.add("test_prod_1") writable_ledgers.add("test_prod_2") @@ -195,10 +197,10 @@ async def test_get_ledger_by_did_self_cert_b( ): self.non_production_ledger = OrderedDict() self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) self.manager = MultiIndyVDRLedgerManager( self.profile, @@ -387,10 +389,10 @@ async def test_lookup_did_in_configured_ledgers_self_cert_non_prod( ): self.non_production_ledger = OrderedDict() self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) self.manager = MultiIndyVDRLedgerManager( self.profile, @@ -420,10 +422,10 @@ async def test_get_ledger_by_did_not_self_cert_non_prod( ): self.non_production_ledger = OrderedDict() self.non_production_ledger["test_non_prod_1"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_1"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_1"), self.profile ) self.non_production_ledger["test_non_prod_2"] = IndyVdrLedger( - IndyVdrLedgerPool("test_non_prod_2"), self.profile + await IndyVdrLedgerPool.get_or_create(name="test_non_prod_2"), self.profile ) self.manager = MultiIndyVDRLedgerManager( self.profile, From 9a144a68d7e7b40f352273f3b38bd52b0a46675d Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 11:49:40 +0200 Subject: [PATCH 116/152] Revert "did:tdw resolver (#3237)" This reverts commit f5c49b0710dd180ea31c45f73bc82ef06f9523b4. Signed-off-by: ff137 --- acapy_agent/messaging/tests/test_valid.py | 19 - acapy_agent/messaging/valid.py | 17 - acapy_agent/resolver/__init__.py | 6 - acapy_agent/resolver/default/tdw.py | 40 - .../resolver/default/tests/test_tdw.py | 36 - acapy_agent/wallet/did_method.py | 8 - poetry.lock | 1071 ++++++++--------- pyproject.toml | 2 - 8 files changed, 478 insertions(+), 721 deletions(-) delete mode 100644 acapy_agent/resolver/default/tdw.py delete mode 100644 acapy_agent/resolver/default/tests/test_tdw.py diff --git a/acapy_agent/messaging/tests/test_valid.py b/acapy_agent/messaging/tests/test_valid.py index b99737c4a8..4e4a348c8e 100644 --- a/acapy_agent/messaging/tests/test_valid.py +++ b/acapy_agent/messaging/tests/test_valid.py @@ -12,7 +12,6 @@ CREDENTIAL_TYPE_VALIDATE, DID_KEY_VALIDATE, DID_POSTURE_VALIDATE, - DID_TDW_VALIDATE, ENDPOINT_TYPE_VALIDATE, ENDPOINT_VALIDATE, INDY_CRED_DEF_ID_VALIDATE, @@ -115,24 +114,6 @@ def test_indy_did(self): INDY_DID_VALIDATE("Q4zqM7aXqm7gDQkUVLng9h") INDY_DID_VALIDATE("did:sov:Q4zqM7aXqm7gDQkUVLng9h") - def test_tdw_did(self): - valid_tdw_dids = [ - "did:tdw:QmUchSB5f5DJQks9CeyLJjhAy4iKJcYzRyiuYq3sjV13px:example.com", - "did:tdw:QmZiKXwQVfyZVuvCsuHpQh4arSUpEmeVVRvSfv3uiEycSr:example.com%3A5000", - ] - for valid_tdw_did in valid_tdw_dids: - DID_TDW_VALIDATE(valid_tdw_did) - - non_valid_tdw_dids = [ - "did:web:QmUchSB5f5DJQks9CeyLJjhAy4iKJcYzRyiuYq3sjV13px", - # Did urls are not allowed - "did:tdw:QmP9VWaTCHcyztDpRj9XSHvZbmYe3m9HZ61KoDtZgWaXVU:example.com%3A5000#z6MkkzY9skorPaoEbCJFKUo7thD8Yb8MBs28aJRopf1TUo9V", - "did:tdw:QmZiKXwQVfyZVuvCsuHpQh4arSUpEmeVVRvSfv3uiEycSr:example.com%3A5000/whois", - ] - for non_valid_tdw_did in non_valid_tdw_dids: - with self.assertRaises(ValidationError): - DID_TDW_VALIDATE(non_valid_tdw_did) - def test_indy_raw_public_key(self): non_indy_raw_public_keys = [ "Q4zqM7aXqm7gDQkUVLng9JQ4zqM7aXqm7gDQkUVLng9I", # 'I' not a base58 char diff --git a/acapy_agent/messaging/valid.py b/acapy_agent/messaging/valid.py index c5026ca382..398ec5a9b9 100644 --- a/acapy_agent/messaging/valid.py +++ b/acapy_agent/messaging/valid.py @@ -319,20 +319,6 @@ def __init__(self): ) -class DIDTdw(Regexp): - """Validate value against did:tdw specification.""" - - EXAMPLE = "did:tdw:QmP9VWaTCHcyztDpRj9XSHvZbmYe3m9HZ61KoDtZgWaXVU:example.com%3A5000" - PATTERN = re.compile(r"^(did:tdw:)([a-zA-Z0-9%._-]*:)*[a-zA-Z0-9%._-]+$") - - def __init__(self): - """Initialize the instance.""" - - super().__init__( - DIDTdw.PATTERN, error="Value {input} is not in W3C did:tdw format" - ) - - class DIDPosture(OneOf): """Validate value against defined DID postures.""" @@ -1010,9 +996,6 @@ def __init__( DID_WEB_VALIDATE = DIDWeb() DID_WEB_EXAMPLE = DIDWeb.EXAMPLE -DID_TDW_VALIDATE = DIDTdw() -DID_TDW_EXAMPLE = DIDTdw.EXAMPLE - ROUTING_KEY_VALIDATE = RoutingKey() ROUTING_KEY_EXAMPLE = RoutingKey.EXAMPLE diff --git a/acapy_agent/resolver/__init__.py b/acapy_agent/resolver/__init__.py index 3998b3da1c..005cce6df9 100644 --- a/acapy_agent/resolver/__init__.py +++ b/acapy_agent/resolver/__init__.py @@ -49,12 +49,6 @@ async def setup(context: InjectionContext): await web_resolver.setup(context) registry.register_resolver(web_resolver) - tdw_resolver = ClassProvider( - "acapy_agent.resolver.default.tdw.TdwDIDResolver" - ).provide(context.settings, context.injector) - await tdw_resolver.setup(context) - registry.register_resolver(tdw_resolver) - if context.settings.get("resolver.universal"): universal_resolver = ClassProvider( "acapy_agent.resolver.default.universal.UniversalResolver" diff --git a/acapy_agent/resolver/default/tdw.py b/acapy_agent/resolver/default/tdw.py deleted file mode 100644 index 4aabd198e8..0000000000 --- a/acapy_agent/resolver/default/tdw.py +++ /dev/null @@ -1,40 +0,0 @@ -"""TDW DID Resolver. - -Resolution is performed by the did_tdw library. -""" - -from re import Pattern -from typing import Optional, Sequence, Text - -from did_tdw.resolver import ResolutionResult, resolve_did - -from ...config.injection_context import InjectionContext -from ...core.profile import Profile -from ...messaging.valid import DIDTdw -from ..base import BaseDIDResolver, ResolverType - - -class TdwDIDResolver(BaseDIDResolver): - """TDW DID Resolver.""" - - def __init__(self): - """Initialize the TDW DID Resolver.""" - super().__init__(ResolverType.NATIVE) - - async def setup(self, context: InjectionContext): - """Perform required setup for TDW DID resolution.""" - - @property - def supported_did_regex(self) -> Pattern: - """Return supported DID regex of TDW DID Resolver.""" - return DIDTdw.PATTERN - - async def _resolve( - self, profile: Profile, did: str, service_accept: Optional[Sequence[Text]] = None - ) -> dict: - """Resolve DID using TDW.""" - response: ResolutionResult = await resolve_did(did) - if response.resolution_metadata and response.resolution_metadata.get("error"): - return response.resolution_metadata - - return response.document diff --git a/acapy_agent/resolver/default/tests/test_tdw.py b/acapy_agent/resolver/default/tests/test_tdw.py deleted file mode 100644 index 8829b9f031..0000000000 --- a/acapy_agent/resolver/default/tests/test_tdw.py +++ /dev/null @@ -1,36 +0,0 @@ -import pytest - -from ....core.profile import Profile -from ....messaging.valid import DIDTdw -from ....utils.testing import create_test_profile -from ..tdw import TdwDIDResolver - -TEST_DID = "did:tdw:Qma6mc1qZw3NqxwX6SB5GPQYzP4pGN2nXD15Jwi4bcDBKu:domain.example" - - -@pytest.fixture -def resolver(): - """Resolver fixture.""" - yield TdwDIDResolver() - - -@pytest.fixture -async def profile(): - """Profile fixture.""" - yield await create_test_profile() - - -@pytest.mark.asyncio -async def test_supported_did_regex(profile, resolver: TdwDIDResolver): - """Test the supported_did_regex.""" - assert resolver.supported_did_regex == DIDTdw.PATTERN - assert await resolver.supports( - profile, - TEST_DID, - ) - - -@pytest.mark.asyncio -async def test_resolve(resolver: TdwDIDResolver, profile: Profile): - """Test resolve method.""" - assert await resolver.resolve(profile, TEST_DID) diff --git a/acapy_agent/wallet/did_method.py b/acapy_agent/wallet/did_method.py index 2acf670837..bf6ff57304 100644 --- a/acapy_agent/wallet/did_method.py +++ b/acapy_agent/wallet/did_method.py @@ -90,13 +90,6 @@ def holder_defined_did(self) -> HolderDefinedDid: holder_defined_did=HolderDefinedDid.NO, ) -TDW = DIDMethod( - name="tdw", - key_types=[ED25519, X25519], - rotation=False, - holder_defined_did=HolderDefinedDid.NO, -) - class DIDMethods: """DID Method class specifying DID methods with supported key types.""" @@ -109,7 +102,6 @@ def __init__(self) -> None: WEB.method_name: WEB, PEER2.method_name: PEER2, PEER4.method_name: PEER4, - TDW.method_name: TDW, } def registered(self, method: str) -> bool: diff --git a/poetry.lock b/poetry.lock index 20f4bb9311..25118dda61 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,110 +1,99 @@ # This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. -[[package]] -name = "aiofiles" -version = "24.1.0" -description = "File support for asyncio." -optional = false -python-versions = ">=3.8" -files = [ - {file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"}, - {file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"}, -] - [[package]] name = "aiohappyeyeballs" -version = "2.4.3" +version = "2.4.4" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, - {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, + {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, + {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, ] [[package]] name = "aiohttp" -version = "3.11.7" +version = "3.11.9" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bedb1f6cb919af3b6353921c71281b1491f948ca64408871465d889b4ee1b66"}, - {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f5022504adab881e2d801a88b748ea63f2a9d130e0b2c430824682a96f6534be"}, - {file = "aiohttp-3.11.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e22d1721c978a6494adc824e0916f9d187fa57baeda34b55140315fa2f740184"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e993676c71288618eb07e20622572b1250d8713e7e00ab3aabae28cb70f3640d"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13a05db87d3b241c186d0936808d0e4e12decc267c617d54e9c643807e968b6"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ba8d043fed7ffa117024d7ba66fdea011c0e7602327c6d73cacaea38abe4491"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda3ed0a7869d2fa16aa41f9961ade73aa2c2e3b2fcb0a352524e7b744881889"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43bfd25113c1e98aec6c70e26d5f4331efbf4aa9037ba9ad88f090853bf64d7f"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3dd3e7e7c9ef3e7214f014f1ae260892286647b3cf7c7f1b644a568fd410f8ca"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78c657ece7a73b976905ab9ec8be9ef2df12ed8984c24598a1791c58ce3b4ce4"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:db70a47987e34494b451a334605bee57a126fe8d290511349e86810b4be53b01"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9e67531370a3b07e49b280c1f8c2df67985c790ad2834d1b288a2f13cd341c5f"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9202f184cc0582b1db15056f2225ab4c1e3dac4d9ade50dd0613ac3c46352ac2"}, - {file = "aiohttp-3.11.7-cp310-cp310-win32.whl", hash = "sha256:2257bdd5cf54a4039a4337162cd8048f05a724380a2283df34620f55d4e29341"}, - {file = "aiohttp-3.11.7-cp310-cp310-win_amd64.whl", hash = "sha256:b7215bf2b53bc6cb35808149980c2ae80a4ae4e273890ac85459c014d5aa60ac"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720"}, - {file = "aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847"}, - {file = "aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd"}, - {file = "aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8"}, - {file = "aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52"}, - {file = "aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e"}, - {file = "aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:17829f37c0d31d89aa6b8b010475a10233774771f9b6dc2cc352ea4f8ce95d9a"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d6177077a31b1aecfc3c9070bd2f11419dbb4a70f30f4c65b124714f525c2e48"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:badda65ac99555791eed75e234afb94686ed2317670c68bff8a4498acdaee935"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de6466b9d742b4ee56fe1b2440706e225eb48c77c63152b1584864a236e7a50"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b0cc74d5a882c9dacaeeccc1444f0233212b6f5be8bc90833feef1e1ce14b9"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c7af3e50e5903d21d7b935aceed901cc2475463bc16ddd5587653548661fdb"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c63f898f683d1379b9be5afc3dd139e20b30b0b1e0bf69a3fc3681f364cf1629"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdadc3f6a32d6eca45f9a900a254757fd7855dfb2d8f8dcf0e88f0fae3ff8eb1"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d329300fb23e14ed1f8c6d688dfd867d1dcc3b1d7cd49b7f8c5b44e797ce0932"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5578cf40440eafcb054cf859964bc120ab52ebe0e0562d2b898126d868749629"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7b2f8107a3c329789f3c00b2daad0e35f548d0a55cda6291579136622099a46e"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:43dd89a6194f6ab02a3fe36b09e42e2df19c211fc2050ce37374d96f39604997"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d2fa6fc7cc865d26ff42480ac9b52b8c9b7da30a10a6442a9cdf429de840e949"}, - {file = "aiohttp-3.11.7-cp39-cp39-win32.whl", hash = "sha256:a7d9a606355655617fee25dd7e54d3af50804d002f1fd3118dd6312d26692d70"}, - {file = "aiohttp-3.11.7-cp39-cp39-win_amd64.whl", hash = "sha256:53c921b58fdc6485d6b2603e0132bb01cd59b8f0620ffc0907f525e0ba071687"}, - {file = "aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668"}, + {file = "aiohttp-3.11.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0411777249f25d11bd2964a230b3ffafcbed6cd65d0f2b132bc2b8f5b8c347c7"}, + {file = "aiohttp-3.11.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:499368eb904566fbdf1a3836a1532000ef1308f34a1bcbf36e6351904cced771"}, + {file = "aiohttp-3.11.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0b5a5009b0159a8f707879dc102b139466d8ec6db05103ec1520394fdd8ea02c"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:176f8bb8931da0613bb0ed16326d01330066bb1e172dd97e1e02b1c27383277b"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6435a66957cdba1a0b16f368bde03ce9c79c57306b39510da6ae5312a1a5b2c1"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:202f40fb686e5f93908eee0c75d1e6fbe50a43e9bd4909bf3bf4a56b560ca180"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39625703540feb50b6b7f938b3856d1f4886d2e585d88274e62b1bd273fae09b"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6beeac698671baa558e82fa160be9761cf0eb25861943f4689ecf9000f8ebd0"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:96726839a42429318017e67a42cca75d4f0d5248a809b3cc2e125445edd7d50d"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3f5461c77649358610fb9694e790956b4238ac5d9e697a17f63619c096469afe"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4313f3bc901255b22f01663eeeae167468264fdae0d32c25fc631d5d6e15b502"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d6e274661c74195708fc4380a4ef64298926c5a50bb10fbae3d01627d7a075b7"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:db2914de2559809fdbcf3e48f41b17a493b58cb7988d3e211f6b63126c55fe82"}, + {file = "aiohttp-3.11.9-cp310-cp310-win32.whl", hash = "sha256:27935716f8d62c1c73010428db310fd10136002cfc6d52b0ba7bdfa752d26066"}, + {file = "aiohttp-3.11.9-cp310-cp310-win_amd64.whl", hash = "sha256:afbe85b50ade42ddff5669947afde9e8a610e64d2c80be046d67ec4368e555fa"}, + {file = "aiohttp-3.11.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:afcda759a69c6a8be3aae764ec6733155aa4a5ad9aad4f398b52ba4037942fe3"}, + {file = "aiohttp-3.11.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5bba6b83fde4ca233cfda04cbd4685ab88696b0c8eaf76f7148969eab5e248a"}, + {file = "aiohttp-3.11.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:442356e8924fe1a121f8c87866b0ecdc785757fd28924b17c20493961b3d6697"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f737fef6e117856400afee4f17774cdea392b28ecf058833f5eca368a18cf1bf"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea142255d4901b03f89cb6a94411ecec117786a76fc9ab043af8f51dd50b5313"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e1e9e447856e9b7b3d38e1316ae9a8c92e7536ef48373de758ea055edfd5db5"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7f6173302f8a329ca5d1ee592af9e628d3ade87816e9958dcf7cdae2841def7"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c6147c6306f537cff59409609508a1d2eff81199f0302dd456bb9e7ea50c39"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e9d036a9a41fc78e8a3f10a86c2fc1098fca8fab8715ba9eb999ce4788d35df0"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2ac9fd83096df36728da8e2f4488ac3b5602238f602706606f3702f07a13a409"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3108f0ad5c6b6d78eec5273219a5bbd884b4aacec17883ceefaac988850ce6e"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:96bbec47beb131bbf4bae05d8ef99ad9e5738f12717cfbbf16648b78b0232e87"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fc726c3fa8f606d07bd2b500e5dc4c0fd664c59be7788a16b9e34352c50b6b6b"}, + {file = "aiohttp-3.11.9-cp311-cp311-win32.whl", hash = "sha256:5720ebbc7a1b46c33a42d489d25d36c64c419f52159485e55589fbec648ea49a"}, + {file = "aiohttp-3.11.9-cp311-cp311-win_amd64.whl", hash = "sha256:17af09d963fa1acd7e4c280e9354aeafd9e3d47eaa4a6bfbd2171ad7da49f0c5"}, + {file = "aiohttp-3.11.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c1f2d7fd583fc79c240094b3e7237d88493814d4b300d013a42726c35a734bc9"}, + {file = "aiohttp-3.11.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4b8a1b6c7a68c73191f2ebd3bf66f7ce02f9c374e309bdb68ba886bbbf1b938"}, + {file = "aiohttp-3.11.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd3f711f4c99da0091ced41dccdc1bcf8be0281dc314d6d9c6b6cf5df66f37a9"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44cb1a1326a0264480a789e6100dc3e07122eb8cd1ad6b784a3d47d13ed1d89c"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a7ddf981a0b953ade1c2379052d47ccda2f58ab678fca0671c7c7ca2f67aac2"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ffa45cc55b18d4ac1396d1ddb029f139b1d3480f1594130e62bceadf2e1a838"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cca505829cdab58c2495ff418c96092d225a1bbd486f79017f6de915580d3c44"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44d323aa80a867cb6db6bebb4bbec677c6478e38128847f2c6b0f70eae984d72"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b2fab23003c4bb2249729a7290a76c1dda38c438300fdf97d4e42bf78b19c810"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:be0c7c98e38a1e3ad7a6ff64af8b6d6db34bf5a41b1478e24c3c74d9e7f8ed42"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5cc5e0d069c56645446c45a4b5010d4b33ac6c5ebfd369a791b5f097e46a3c08"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9bcf97b971289be69638d8b1b616f7e557e1342debc7fc86cf89d3f08960e411"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c7333e7239415076d1418dbfb7fa4df48f3a5b00f8fdf854fca549080455bc14"}, + {file = "aiohttp-3.11.9-cp312-cp312-win32.whl", hash = "sha256:9384b07cfd3045b37b05ed002d1c255db02fb96506ad65f0f9b776b762a7572e"}, + {file = "aiohttp-3.11.9-cp312-cp312-win_amd64.whl", hash = "sha256:f5252ba8b43906f206048fa569debf2cd0da0316e8d5b4d25abe53307f573941"}, + {file = "aiohttp-3.11.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:282e0a7ddd36ebc411f156aeaa0491e8fe7f030e2a95da532cf0c84b0b70bc66"}, + {file = "aiohttp-3.11.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ebd3e6b0c7d4954cca59d241970011f8d3327633d555051c430bd09ff49dc494"}, + {file = "aiohttp-3.11.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:30f9f89ae625d412043f12ca3771b2ccec227cc93b93bb1f994db6e1af40a7d3"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a3b5b2c012d70c63d9d13c57ed1603709a4d9d7d473e4a9dfece0e4ea3d5f51"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ef1550bb5f55f71b97a6a395286db07f7f2c01c8890e613556df9a51da91e8d"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317251b9c9a2f1a9ff9cd093775b34c6861d1d7df9439ce3d32a88c275c995cd"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cbe97839b009826a61b143d3ca4964c8590d7aed33d6118125e5b71691ca46"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:618b18c3a2360ac940a5503da14fa4f880c5b9bc315ec20a830357bcc62e6bae"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0cf4d814689e58f57ecd5d8c523e6538417ca2e72ff52c007c64065cef50fb2"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:15c4e489942d987d5dac0ba39e5772dcbed4cc9ae3710d1025d5ba95e4a5349c"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ec8df0ff5a911c6d21957a9182402aad7bf060eaeffd77c9ea1c16aecab5adbf"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ed95d66745f53e129e935ad726167d3a6cb18c5d33df3165974d54742c373868"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:647ec5bee7e4ec9f1034ab48173b5fa970d9a991e565549b965e93331f1328fe"}, + {file = "aiohttp-3.11.9-cp313-cp313-win32.whl", hash = "sha256:ef2c9499b7bd1e24e473dc1a85de55d72fd084eea3d8bdeec7ee0720decb54fa"}, + {file = "aiohttp-3.11.9-cp313-cp313-win_amd64.whl", hash = "sha256:84de955314aa5e8d469b00b14d6d714b008087a0222b0f743e7ffac34ef56aff"}, + {file = "aiohttp-3.11.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e738aabff3586091221044b7a584865ddc4d6120346d12e28e788307cd731043"}, + {file = "aiohttp-3.11.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28f29bce89c3b401a53d6fd4bee401ee943083bf2bdc12ef297c1d63155070b0"}, + {file = "aiohttp-3.11.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31de2f10f63f96cc19e04bd2df9549559beadd0b2ee2da24a17e7ed877ca8c60"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f31cebd8c27a36af6c7346055ac564946e562080ee1a838da724585c67474f"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0bcb7f6976dc0b6b56efde13294862adf68dd48854111b422a336fa729a82ea6"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8b13b9950d8b2f8f58b6e5842c4b842b5887e2c32e3f4644d6642f1659a530"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9c23e62f3545c2216100603614f9e019e41b9403c47dd85b8e7e5015bf1bde0"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec656680fc53a13f849c71afd0c84a55c536206d524cbc831cde80abbe80489e"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:36df00e0541f264ce42d62280281541a47474dfda500bc5b7f24f70a7f87be7a"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8dcfd14c712aa9dd18049280bfb2f95700ff6a8bde645e09f17c3ed3f05a0130"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14624d96f0d69cf451deed3173079a68c322279be6030208b045ab77e1e8d550"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4b01d9cfcb616eeb6d40f02e66bebfe7b06d9f2ef81641fdd50b8dd981166e0b"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:928f92f80e2e8d6567b87d3316c1fd9860ccfe36e87a9a7f5237d4cda8baa1ba"}, + {file = "aiohttp-3.11.9-cp39-cp39-win32.whl", hash = "sha256:c8a02f74ae419e3955af60f570d83187423e42e672a6433c5e292f1d23619269"}, + {file = "aiohttp-3.11.9-cp39-cp39-win_amd64.whl", hash = "sha256:0a97d657f6cf8782a830bb476c13f7d777cfcab8428ac49dde15c22babceb361"}, + {file = "aiohttp-3.11.9.tar.gz", hash = "sha256:a9266644064779840feec0e34f10a89b3ff1d2d6b751fe90017abcad1864fa7c"}, ] [package.dependencies] @@ -221,13 +210,17 @@ tests = ["apispec[marshmallow,yaml]", "openapi-spec-validator (==0.7.1)", "pytes yaml = ["PyYAML (>=3.10)"] [[package]] -name = "aries_askar" -version = "0.3.2" -description = "" -optional = false +name = "aries-askar-ff137" +version = "0.3.3b0" +description = "UNKNOWN" +optional = true python-versions = ">=3.6.3" -files = [] -develop = false +files = [ + {file = "aries_askar_ff137-0.3.3b0-py3-none-macosx_10_9_universal2.whl", hash = "sha256:32d6ed2366527b733a6025c19fb6f52f4547a3b2693cc11a1175b0ca3bfc8792"}, + {file = "aries_askar_ff137-0.3.3b0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:54214ac04c3f06d7dc302c0592787f9a998c8e104f8f2ee382fc2645efef6e41"}, + {file = "aries_askar_ff137-0.3.3b0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c7f5517c3c910aa34cee9359e184388f320d14bac7296b37d9dca4026c254bba"}, + {file = "aries_askar_ff137-0.3.3b0-py3-none-win_amd64.whl", hash = "sha256:5bdf83bdaacd4dc43a34a3a58c43e165a0b66303c9bddded64cdf6f84e015ee0"}, +] [package.dependencies] cached-property = ">=1.5.2,<1.6.0" @@ -295,29 +288,11 @@ files = [ [package.extras] tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", "pytest-cov", "pytest-flake8"] -[[package]] -name = "bases" -version = "0.3.0" -description = "Python library for general Base-N encodings." -optional = false -python-versions = ">=3.7" -files = [ - {file = "bases-0.3.0-py3-none-any.whl", hash = "sha256:a2fef3366f3e522ff473d2e95c21523fe8e44251038d5c6150c01481585ebf5b"}, - {file = "bases-0.3.0.tar.gz", hash = "sha256:70f04a4a45d63245787f9e89095ca11042685b6b64b542ad916575ba3ccd1570"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0" -typing-validation = ">=1.1.0" - -[package.extras] -dev = ["base58", "mypy", "pylint", "pytest", "pytest-cov"] - [[package]] name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." -optional = false +optional = true python-versions = "*" files = [ {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, @@ -589,73 +564,73 @@ yaml = ["PyYAML"] [[package]] name = "coverage" -version = "7.6.4" +version = "7.6.8" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07"}, - {file = "coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a"}, - {file = "coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa"}, - {file = "coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522"}, - {file = "coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf"}, - {file = "coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5"}, - {file = "coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17"}, - {file = "coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a"}, - {file = "coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e"}, - {file = "coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef"}, - {file = "coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e"}, - {file = "coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901"}, - {file = "coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09"}, - {file = "coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f"}, - {file = "coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e"}, - {file = "coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed"}, + {file = "coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e"}, + {file = "coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0"}, + {file = "coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801"}, + {file = "coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443"}, + {file = "coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad"}, + {file = "coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"}, + {file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"}, + {file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"}, + {file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"}, + {file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea"}, + {file = "coverage-7.6.8-cp39-cp39-win32.whl", hash = "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e"}, + {file = "coverage-7.6.8-cp39-cp39-win_amd64.whl", hash = "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076"}, + {file = "coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce"}, + {file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"}, ] [package.extras] @@ -663,51 +638,53 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "43.0.3" +version = "44.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, - {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, - {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, - {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, - {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, - {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, - {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, - {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, - {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, - {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, - {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, +python-versions = "!=3.9.0,!=3.9.1,>=3.7" +files = [ + {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:60eb32934076fa07e4316b7b2742fa52cbb190b42c2df2863dbc4230a0a9b385"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"}, + {file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"}, + {file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"}, + {file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9abcc2e083cbe8dde89124a47e5e53ec38751f0d7dfd36801008f316a127d7ba"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"}, + {file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"}, + {file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"}, + {file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"}, ] [package.dependencies] cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] @@ -885,25 +862,6 @@ files = [ [package.dependencies] base58 = ">=2.1.1" -[[package]] -name = "did-tdw" -version = "0.2.1" -description = "This repository includes Python libraries for working with `did:tdw` (Trust DID Web) DID documents and the underlying log format." -optional = false -python-versions = "<4.0,>=3.10" -files = [ - {file = "did_tdw-0.2.1-py3-none-any.whl", hash = "sha256:80c727d0bef37e2211d3caddb97ba3c4aa508c67d4ef502da5f326d9bf4c3ffb"}, - {file = "did_tdw-0.2.1.tar.gz", hash = "sha256:a61ed9f49369ea4c365e5e380431feae8cb3988375de37f73be2abe15d0bfde6"}, -] - -[package.dependencies] -aiofiles = ">=24.1.0,<25.0.0" -aiohttp = ">=3.10.5,<4.0.0" -aries-askar = ">=0.3.2,<0.4.0" -base58 = ">=2.1.0,<2.2.0" -jsoncanon = ">=0.2.3,<0.3.0" -multiformats = ">=0.3.1,<0.4.0" - [[package]] name = "didcomm-messaging" version = "0.1.1" @@ -1205,13 +1163,13 @@ files = [ [[package]] name = "identify" -version = "2.6.2" +version = "2.6.3" description = "File identification library for Python" optional = false python-versions = ">=3.9" files = [ - {file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"}, - {file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"}, + {file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"}, + {file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"}, ] [package.extras] @@ -1307,17 +1265,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "jsoncanon" -version = "0.2.3" -description = "Typed Python implementation of JSON Canonicalization Scheme as described in RFC 8785. Currently lacks full floating point support" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "jsoncanon-0.2.3-py3-none-any.whl", hash = "sha256:adb35dac2d0c5dd56f1cb374f1ea6f1fff2ebbb4e844b06d9c96b9ccadf12bf0"}, - {file = "jsoncanon-0.2.3.tar.gz", hash = "sha256:483c1ef14e6c8151ba69c0bf646551f249698dd523e9c6da1339a688c5f96d6d"}, -] - [[package]] name = "jsonpath-ng" version = "1.7.0" @@ -1326,8 +1273,6 @@ optional = false python-versions = "*" files = [ {file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"}, - {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"}, - {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"}, ] [package.dependencies] @@ -1706,44 +1651,6 @@ files = [ {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, ] -[[package]] -name = "multiformats" -version = "0.3.1.post4" -description = "Python implementation of multiformats protocols." -optional = false -python-versions = ">=3.7" -files = [ - {file = "multiformats-0.3.1.post4-py3-none-any.whl", hash = "sha256:5b1d61bd8275c9e817bdbee38dbd501b26629011962ee3c86c46e7ccd0b14129"}, - {file = "multiformats-0.3.1.post4.tar.gz", hash = "sha256:d00074fdbc7d603c2084b4c38fa17bbc28173cf2750f51f46fbbc5c4d5605fbb"}, -] - -[package.dependencies] -bases = ">=0.3.0" -multiformats-config = ">=0.3.0" -typing-extensions = ">=4.6.0" -typing-validation = ">=1.1.0" - -[package.extras] -dev = ["blake3", "mmh3", "mypy", "pycryptodomex", "pylint", "pyskein", "pytest", "pytest-cov", "rich"] -full = ["blake3", "mmh3", "pycryptodomex", "pyskein", "rich"] - -[[package]] -name = "multiformats-config" -version = "0.3.1" -description = "Pre-loading configuration module for the 'multiformats' package." -optional = false -python-versions = ">=3.7" -files = [ - {file = "multiformats-config-0.3.1.tar.gz", hash = "sha256:7eaa80ef5d9c5ee9b86612d21f93a087c4a655cbcb68960457e61adbc62b47a7"}, - {file = "multiformats_config-0.3.1-py3-none-any.whl", hash = "sha256:dec4c9d42ed0d9305889b67440f72e8e8d74b82b80abd7219667764b5b0a8e1d"}, -] - -[package.dependencies] -multiformats = "*" - -[package.extras] -dev = ["mypy", "pylint", "pytest", "pytest-cov"] - [[package]] name = "nest-asyncio" version = "1.6.0" @@ -1966,109 +1873,93 @@ wcwidth = "*" [[package]] name = "propcache" -version = "0.2.0" +version = "0.2.1" description = "Accelerated property cache" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, + {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, + {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, + {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, + {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, + {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, + {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, + {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, + {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -2084,22 +1975,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"}, + {file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = [ - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, -] +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -2107,100 +1995,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] @@ -2268,13 +2167,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.10.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" files = [ - {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, - {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -2333,13 +2232,13 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -2846,20 +2745,6 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] -[[package]] -name = "typing-validation" -version = "1.2.11.post4" -description = "A simple library for runtime type-checking." -optional = false -python-versions = ">=3.7" -files = [ - {file = "typing_validation-1.2.11.post4-py3-none-any.whl", hash = "sha256:73dd504ddebf5210e80d5f65ba9b30efbd0fa42f266728fda7c4f0ba335c699c"}, - {file = "typing_validation-1.2.11.post4.tar.gz", hash = "sha256:7aed04ecfbda07e63b7266f90e5d096f96344f7facfe04bb081b21e4a9781670"}, -] - -[package.extras] -dev = ["mypy", "pylint", "pytest", "pytest-cov", "rich"] - [[package]] name = "unflatten" version = "0.2.0" @@ -2938,13 +2823,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.27.1" +version = "20.28.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, - {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, + {file = "virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0"}, + {file = "virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa"}, ] [package.dependencies] @@ -2991,93 +2876,93 @@ tests = ["Django (>=2.2.0)", "Flask (>=0.12.5)", "aiohttp (>=3.0.8)", "bottle (> [[package]] name = "yarl" -version = "1.17.1" +version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91"}, - {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da"}, - {file = "yarl-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931"}, - {file = "yarl-1.17.1-cp310-cp310-win32.whl", hash = "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b"}, - {file = "yarl-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4"}, - {file = "yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7"}, - {file = "yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199"}, - {file = "yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96"}, - {file = "yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258"}, - {file = "yarl-1.17.1-cp313-cp313-win32.whl", hash = "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2"}, - {file = "yarl-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f"}, - {file = "yarl-1.17.1-cp39-cp39-win32.whl", hash = "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473"}, - {file = "yarl-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138"}, - {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, - {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] @@ -3093,4 +2978,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "c9121c319eb42db81805bec50a15a153e7ef4f8bef5231a6b12a7a74b4ffe290" +content-hash = "cb8b649f6c4779cc8e3680d088b22b35c96b912a3c1ed3c17441d82f3a10f7eb" diff --git a/pyproject.toml b/pyproject.toml index 6ae8e46903..810305c28f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,8 +50,6 @@ uuid_utils = "^0.10.0" # did libraries did-peer-2 = "^0.1.2" did-peer-4 = "^0.1.4" -did-tdw = "^0.2.1" - # askar aries-askar-ff137 = {version = "==0.3.3b0", source = "testpypi", optional = true} From d1920a964c834016b3c70ba412766a282f396ad3 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 12:39:16 +0200 Subject: [PATCH 117/152] 1.1.1b5 Signed-off-by: ff137 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 810305c28f..bab26b42ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "acapy_agent_didx" -version = "1.1.1-20241115" +version = "1.1.1b5" description = "(ACA-Py) A Cloud Agent Python is a foundation for building decentralized identity applications and services running in non-mobile environments. " authors = [] license = "Apache-2.0" From 5147352de750666112265e3c642c36c18ae2d50e Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 13:12:43 +0200 Subject: [PATCH 118/152] :art: Propagate the async changes Signed-off-by: ff137 --- acapy_agent/askar/profile.py | 56 ++++++++++--------- acapy_agent/askar/profile_anon.py | 56 ++++++++++--------- acapy_agent/askar/tests/test_profile.py | 12 ++-- .../tests/test_manager_provider.py | 3 +- acapy_agent/ledger/tests/test_indy_vdr.py | 4 +- acapy_agent/multitenant/manager.py | 2 +- .../single_wallet_askar_manager.py | 4 +- .../tests/test_single_wallet_askar_manager.py | 10 ++-- .../storage/tests/test_askar_storage.py | 2 +- acapy_agent/utils/testing.py | 4 +- 10 files changed, 84 insertions(+), 69 deletions(-) diff --git a/acapy_agent/askar/profile.py b/acapy_agent/askar/profile.py index e80bc569f1..1a5c24f8b3 100644 --- a/acapy_agent/askar/profile.py +++ b/acapy_agent/askar/profile.py @@ -41,13 +41,25 @@ def __init__( *, profile_id: Optional[str] = None, ): - """Create a new AskarProfile instance.""" + """Private constructor. Use 'create' to instantiate.""" super().__init__(context=context, name=opened.name, created=opened.created) self.opened = opened self.ledger_pool: Optional[IndyVdrLedgerPool] = None self.profile_id = profile_id - self.init_ledger_pool() - self.bind_providers() + + @classmethod + async def create( + cls, + opened: AskarOpenStore, + context: Optional[InjectionContext] = None, + *, + profile_id: Optional[str] = None, + ) -> "AskarProfile": + """Asynchronously create a new AskarProfile instance.""" + profile = cls(opened, context, profile_id=profile_id) + await profile.init_ledger_pool() + await profile.bind_providers() + return profile @property def name(self) -> str: @@ -64,7 +76,7 @@ async def remove(self): if self.profile_id: await self.store.remove_profile(self.profile_id) - def init_ledger_pool(self): + async def init_ledger_pool(self): """Initialize the ledger pool.""" if self.settings.get("ledger.disabled"): LOGGER.info("Ledger support is disabled") @@ -78,8 +90,8 @@ def init_ledger_pool(self): LOGGER.warning("Note: setting ledger to read-only mode") genesis_transactions = self.settings.get("ledger.genesis_transactions") cache = self.context.injector.inject_or(BaseCache) - self.ledger_pool = IndyVdrLedgerPool( - pool_name, + self.ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=pool_name, keepalive=keepalive, cache=cache, genesis_transactions=genesis_transactions, @@ -87,7 +99,7 @@ def init_ledger_pool(self): socks_proxy=socks_proxy, ) - def bind_providers(self): + async def bind_providers(self): """Initialize the profile-level instance providers.""" injector = self._context.injector @@ -134,23 +146,17 @@ def bind_providers(self): settings=self.settings ) cache = self.context.injector.inject_or(BaseCache) + ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=write_ledger_config.get("pool_name") + or write_ledger_config.get("id"), + keepalive=write_ledger_config.get("keepalive"), + cache=cache, + genesis_transactions=write_ledger_config.get("genesis_transactions"), + read_only=write_ledger_config.get("read_only"), + socks_proxy=write_ledger_config.get("socks_proxy"), + ) injector.bind_provider( - BaseLedger, - ClassProvider( - IndyVdrLedger, - IndyVdrLedgerPool( - write_ledger_config.get("pool_name") - or write_ledger_config.get("id"), - keepalive=write_ledger_config.get("keepalive"), - cache=cache, - genesis_transactions=write_ledger_config.get( - "genesis_transactions" - ), - read_only=write_ledger_config.get("read_only"), - socks_proxy=write_ledger_config.get("socks_proxy"), - ), - ref(self), - ), + BaseLedger, ClassProvider(IndyVdrLedger, ledger_pool, ref(self)) ) self.settings["ledger.write_ledger"] = write_ledger_config.get("id") if ( @@ -325,7 +331,7 @@ async def provision( """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=True) - return AskarProfile(opened, context) + return await AskarProfile.create(opened, context) async def open( self, context: InjectionContext, config: Mapping[str, Any] = None @@ -333,7 +339,7 @@ async def open( """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=False) - return AskarProfile(opened, context) + return await AskarProfile.create(opened, context) @classmethod async def generate_store_key(self, seed: Optional[str] = None) -> str: diff --git a/acapy_agent/askar/profile_anon.py b/acapy_agent/askar/profile_anon.py index eea73d876f..2698b30387 100644 --- a/acapy_agent/askar/profile_anon.py +++ b/acapy_agent/askar/profile_anon.py @@ -43,13 +43,25 @@ def __init__( *, profile_id: Optional[str] = None, ): - """Create a new AskarProfile instance.""" + """Create a new AskarAnoncredsProfile instance.""" super().__init__(context=context, name=opened.name, created=opened.created) self.opened = opened self.ledger_pool: Optional[IndyVdrLedgerPool] = None self.profile_id = profile_id - self.init_ledger_pool() - self.bind_providers() + + @classmethod + async def create( + cls, + opened: AskarOpenStore, + context: Optional[InjectionContext] = None, + *, + profile_id: Optional[str] = None, + ) -> "AskarAnoncredsProfile": + """Asynchronously create a new AskarAnoncredsProfile instance.""" + profile = cls(opened, context, profile_id=profile_id) + await profile.init_ledger_pool() + await profile.bind_providers() + return profile @property def name(self) -> str: @@ -66,7 +78,7 @@ async def remove(self): if self.profile_id: await self.store.remove_profile(self.profile_id) - def init_ledger_pool(self): + async def init_ledger_pool(self): """Initialize the ledger pool.""" if self.settings.get("ledger.disabled"): LOGGER.info("Ledger support is disabled") @@ -80,8 +92,8 @@ def init_ledger_pool(self): LOGGER.warning("Note: setting ledger to read-only mode") genesis_transactions = self.settings.get("ledger.genesis_transactions") cache = self.context.injector.inject_or(BaseCache) - self.ledger_pool = IndyVdrLedgerPool( - pool_name, + self.ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=pool_name, keepalive=keepalive, cache=cache, genesis_transactions=genesis_transactions, @@ -89,7 +101,7 @@ def init_ledger_pool(self): socks_proxy=socks_proxy, ) - def bind_providers(self): + async def bind_providers(self): """Initialize the profile-level instance providers.""" injector = self._context.injector @@ -123,23 +135,17 @@ def bind_providers(self): settings=self.settings ) cache = self.context.injector.inject_or(BaseCache) + ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=write_ledger_config.get("pool_name") + or write_ledger_config.get("id"), + keepalive=write_ledger_config.get("keepalive"), + cache=cache, + genesis_transactions=write_ledger_config.get("genesis_transactions"), + read_only=write_ledger_config.get("read_only"), + socks_proxy=write_ledger_config.get("socks_proxy"), + ) injector.bind_provider( - BaseLedger, - ClassProvider( - IndyVdrLedger, - IndyVdrLedgerPool( - write_ledger_config.get("pool_name") - or write_ledger_config.get("id"), - keepalive=write_ledger_config.get("keepalive"), - cache=cache, - genesis_transactions=write_ledger_config.get( - "genesis_transactions" - ), - read_only=write_ledger_config.get("read_only"), - socks_proxy=write_ledger_config.get("socks_proxy"), - ), - ref(self), - ), + BaseLedger, ClassProvider(IndyVdrLedger, ledger_pool, ref(self)) ) self.settings["ledger.write_ledger"] = write_ledger_config.get("id") if ( @@ -278,7 +284,7 @@ async def provision( """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=True) - return AskarAnoncredsProfile(opened, context) + return await AskarAnoncredsProfile.create(opened, context) async def open( self, context: InjectionContext, config: Mapping[str, Any] = None @@ -286,7 +292,7 @@ async def open( """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=False) - return AskarAnoncredsProfile(opened, context) + return await AskarAnoncredsProfile.create(opened, context) @classmethod async def generate_store_key(self, seed: Optional[str] = None) -> str: diff --git a/acapy_agent/askar/tests/test_profile.py b/acapy_agent/askar/tests/test_profile.py index 38a0326ded..211166b9e3 100644 --- a/acapy_agent/askar/tests/test_profile.py +++ b/acapy_agent/askar/tests/test_profile.py @@ -16,7 +16,7 @@ def open_store(): @pytest.mark.asyncio async def test_init_success(open_store): - askar_profile = AskarProfile( + askar_profile = await AskarProfile.create( open_store, ) @@ -44,7 +44,7 @@ async def test_init_multi_ledger(open_store): ] } ) - askar_profile = AskarProfile( + askar_profile = await AskarProfile.create( open_store, context=context, ) @@ -67,7 +67,7 @@ async def test_remove_success(open_store): "wallet.askar_profile": profile_id, "ledger.genesis_transactions": mock.MagicMock(), } - askar_profile = AskarProfile(openStore, context, profile_id=profile_id) + askar_profile = await AskarProfile.create(openStore, context, profile_id=profile_id) remove_profile_stub = asyncio.Future() remove_profile_stub.set_result(True) openStore.store.remove_profile.return_value = remove_profile_stub @@ -82,7 +82,7 @@ async def test_remove_profile_not_removed_if_wallet_type_not_askar_profile(open_ openStore = open_store context = InjectionContext() context.settings = {"multitenant.wallet_type": "basic"} - askar_profile = AskarProfile(openStore, context) + askar_profile = await AskarProfile.create(openStore, context) await askar_profile.remove() @@ -94,7 +94,7 @@ async def test_profile_manager_transaction(): profile = "profileId" with mock.patch("acapy_agent.askar.profile.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, True, profile_id=profile) + askar_profile = await AskarProfile.create(None, True, profile_id=profile) askar_profile.profile_id = profile askar_profile_transaction = mock.MagicMock() askar_profile.store.transaction.return_value = askar_profile_transaction @@ -110,7 +110,7 @@ async def test_profile_manager_store(): profile = "profileId" with mock.patch("acapy_agent.askar.profile.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, False, profile_id=profile) + askar_profile = await AskarProfile.create(None, False, profile_id=profile) askar_profile.profile_id = profile askar_profile_session = mock.MagicMock() askar_profile.store.session.return_value = askar_profile_session diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py b/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py index ce9cc002a6..639c46c37f 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py @@ -57,7 +57,8 @@ async def test_provide_askar_manager(self): context = InjectionContext() profile = await create_test_profile() context.injector.bind_instance( - BaseLedger, IndyVdrLedger(IndyVdrLedgerPool("name"), profile) + BaseLedger, + IndyVdrLedger(await IndyVdrLedgerPool.get_or_create(name="name"), profile), ) provider = MultiIndyLedgerManagerProvider(profile) context.settings["ledger.ledger_config_list"] = LEDGER_CONFIG diff --git a/acapy_agent/ledger/tests/test_indy_vdr.py b/acapy_agent/ledger/tests/test_indy_vdr.py index 9b0ee8ce3c..079c444a39 100644 --- a/acapy_agent/ledger/tests/test_indy_vdr.py +++ b/acapy_agent/ledger/tests/test_indy_vdr.py @@ -43,7 +43,9 @@ async def ledger(): profile.context.injector.bind_instance(BaseCache, InMemoryCache()) profile.context.injector.bind_instance(KeyTypes, KeyTypes()) - ledger = IndyVdrLedger(IndyVdrLedgerPool("test-ledger"), profile) + ledger = IndyVdrLedger( + await IndyVdrLedgerPool.get_or_create(name="test-ledger"), profile + ) async def open(): ledger.pool.handle = mock.MagicMock(indy_vdr.Pool) diff --git a/acapy_agent/multitenant/manager.py b/acapy_agent/multitenant/manager.py index 1a6bda9030..8137e9dbe9 100644 --- a/acapy_agent/multitenant/manager.py +++ b/acapy_agent/multitenant/manager.py @@ -88,7 +88,7 @@ async def get_wallet_profile( # return anoncreds profile if explicitly set as wallet type if profile.context.settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( profile.opened, profile.context, ) diff --git a/acapy_agent/multitenant/single_wallet_askar_manager.py b/acapy_agent/multitenant/single_wallet_askar_manager.py index 4e39683247..511da2b9c2 100644 --- a/acapy_agent/multitenant/single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/single_wallet_askar_manager.py @@ -108,13 +108,13 @@ async def get_wallet_profile( # return anoncreds profile if explicitly set as wallet type if profile_context.settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( self._multitenant_profile.opened, profile_context, profile_id=wallet_record.wallet_id, ) - return AskarProfile( + return await AskarProfile.create( self._multitenant_profile.opened, profile_context, profile_id=wallet_record.wallet_id, diff --git a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py index 322a8517ec..c59f098f18 100644 --- a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py @@ -52,7 +52,7 @@ async def test_get_wallet_profile_should_open_store_and_return_profile_with_wall ) as AskarProfile, ): sub_wallet_profile_context = InjectionContext() - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context def side_effect(context, provision): @@ -127,7 +127,7 @@ async def test_get_anoncreds_wallet_profile_should_open_store_and_return_anoncre ) as AskarAnoncredsProfile, ): sub_wallet_profile_context = InjectionContext() - sub_wallet_profile = AskarAnoncredsProfile(None, None) + sub_wallet_profile = await AskarAnoncredsProfile.create(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context def side_effect(context, provision): @@ -150,7 +150,7 @@ async def test_get_wallet_profile_should_create_profile(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() sub_wallet_profile.store.create_profile.return_value = create_profile_stub self.manager._multitenant_profile = sub_wallet_profile @@ -176,7 +176,7 @@ async def test_get_wallet_profile_should_use_custom_subwallet_name(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() def side_effect(context, provision): @@ -207,7 +207,7 @@ async def test_open_profiles(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() sub_wallet_profile.store.create_profile.return_value = create_profile_stub self.manager._multitenant_profile = sub_wallet_profile diff --git a/acapy_agent/storage/tests/test_askar_storage.py b/acapy_agent/storage/tests/test_askar_storage.py index c959c6e3fa..e9ddfce247 100644 --- a/acapy_agent/storage/tests/test_askar_storage.py +++ b/acapy_agent/storage/tests/test_askar_storage.py @@ -385,7 +385,7 @@ async def test_askar_storage_search_session(self): profile = "profileId" with mock.patch("acapy_agent.storage.askar.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, True) + askar_profile = await AskarProfile.create(None, True) askar_profile_scan = mock.MagicMock() askar_profile.store.scan.return_value = askar_profile_scan askar_profile.settings.get.return_value = profile diff --git a/acapy_agent/utils/testing.py b/acapy_agent/utils/testing.py index 2ee34cf125..169bfb3cd8 100644 --- a/acapy_agent/utils/testing.py +++ b/acapy_agent/utils/testing.py @@ -38,11 +38,11 @@ async def create_test_profile( opened = await store_config.open_store(provision=True, in_memory=True) if settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( opened=opened, context=context, ) - return AskarProfile( + return await AskarProfile.create( opened=opened, context=context, ) From a363bc23c11f994404c3068b815acd385796bde8 Mon Sep 17 00:00:00 2001 From: ff137 Date: Mon, 2 Dec 2024 13:12:43 +0200 Subject: [PATCH 119/152] :art: Propagate the async changes Signed-off-by: ff137 --- acapy_agent/askar/profile.py | 56 ++++++++++--------- acapy_agent/askar/profile_anon.py | 56 ++++++++++--------- acapy_agent/askar/tests/test_profile.py | 12 ++-- .../tests/test_manager_provider.py | 3 +- acapy_agent/ledger/tests/test_indy_vdr.py | 4 +- acapy_agent/multitenant/manager.py | 2 +- .../single_wallet_askar_manager.py | 4 +- .../tests/test_single_wallet_askar_manager.py | 10 ++-- .../storage/tests/test_askar_storage.py | 2 +- acapy_agent/utils/testing.py | 4 +- 10 files changed, 84 insertions(+), 69 deletions(-) diff --git a/acapy_agent/askar/profile.py b/acapy_agent/askar/profile.py index e80bc569f1..1a5c24f8b3 100644 --- a/acapy_agent/askar/profile.py +++ b/acapy_agent/askar/profile.py @@ -41,13 +41,25 @@ def __init__( *, profile_id: Optional[str] = None, ): - """Create a new AskarProfile instance.""" + """Private constructor. Use 'create' to instantiate.""" super().__init__(context=context, name=opened.name, created=opened.created) self.opened = opened self.ledger_pool: Optional[IndyVdrLedgerPool] = None self.profile_id = profile_id - self.init_ledger_pool() - self.bind_providers() + + @classmethod + async def create( + cls, + opened: AskarOpenStore, + context: Optional[InjectionContext] = None, + *, + profile_id: Optional[str] = None, + ) -> "AskarProfile": + """Asynchronously create a new AskarProfile instance.""" + profile = cls(opened, context, profile_id=profile_id) + await profile.init_ledger_pool() + await profile.bind_providers() + return profile @property def name(self) -> str: @@ -64,7 +76,7 @@ async def remove(self): if self.profile_id: await self.store.remove_profile(self.profile_id) - def init_ledger_pool(self): + async def init_ledger_pool(self): """Initialize the ledger pool.""" if self.settings.get("ledger.disabled"): LOGGER.info("Ledger support is disabled") @@ -78,8 +90,8 @@ def init_ledger_pool(self): LOGGER.warning("Note: setting ledger to read-only mode") genesis_transactions = self.settings.get("ledger.genesis_transactions") cache = self.context.injector.inject_or(BaseCache) - self.ledger_pool = IndyVdrLedgerPool( - pool_name, + self.ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=pool_name, keepalive=keepalive, cache=cache, genesis_transactions=genesis_transactions, @@ -87,7 +99,7 @@ def init_ledger_pool(self): socks_proxy=socks_proxy, ) - def bind_providers(self): + async def bind_providers(self): """Initialize the profile-level instance providers.""" injector = self._context.injector @@ -134,23 +146,17 @@ def bind_providers(self): settings=self.settings ) cache = self.context.injector.inject_or(BaseCache) + ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=write_ledger_config.get("pool_name") + or write_ledger_config.get("id"), + keepalive=write_ledger_config.get("keepalive"), + cache=cache, + genesis_transactions=write_ledger_config.get("genesis_transactions"), + read_only=write_ledger_config.get("read_only"), + socks_proxy=write_ledger_config.get("socks_proxy"), + ) injector.bind_provider( - BaseLedger, - ClassProvider( - IndyVdrLedger, - IndyVdrLedgerPool( - write_ledger_config.get("pool_name") - or write_ledger_config.get("id"), - keepalive=write_ledger_config.get("keepalive"), - cache=cache, - genesis_transactions=write_ledger_config.get( - "genesis_transactions" - ), - read_only=write_ledger_config.get("read_only"), - socks_proxy=write_ledger_config.get("socks_proxy"), - ), - ref(self), - ), + BaseLedger, ClassProvider(IndyVdrLedger, ledger_pool, ref(self)) ) self.settings["ledger.write_ledger"] = write_ledger_config.get("id") if ( @@ -325,7 +331,7 @@ async def provision( """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=True) - return AskarProfile(opened, context) + return await AskarProfile.create(opened, context) async def open( self, context: InjectionContext, config: Mapping[str, Any] = None @@ -333,7 +339,7 @@ async def open( """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=False) - return AskarProfile(opened, context) + return await AskarProfile.create(opened, context) @classmethod async def generate_store_key(self, seed: Optional[str] = None) -> str: diff --git a/acapy_agent/askar/profile_anon.py b/acapy_agent/askar/profile_anon.py index eea73d876f..2698b30387 100644 --- a/acapy_agent/askar/profile_anon.py +++ b/acapy_agent/askar/profile_anon.py @@ -43,13 +43,25 @@ def __init__( *, profile_id: Optional[str] = None, ): - """Create a new AskarProfile instance.""" + """Create a new AskarAnoncredsProfile instance.""" super().__init__(context=context, name=opened.name, created=opened.created) self.opened = opened self.ledger_pool: Optional[IndyVdrLedgerPool] = None self.profile_id = profile_id - self.init_ledger_pool() - self.bind_providers() + + @classmethod + async def create( + cls, + opened: AskarOpenStore, + context: Optional[InjectionContext] = None, + *, + profile_id: Optional[str] = None, + ) -> "AskarAnoncredsProfile": + """Asynchronously create a new AskarAnoncredsProfile instance.""" + profile = cls(opened, context, profile_id=profile_id) + await profile.init_ledger_pool() + await profile.bind_providers() + return profile @property def name(self) -> str: @@ -66,7 +78,7 @@ async def remove(self): if self.profile_id: await self.store.remove_profile(self.profile_id) - def init_ledger_pool(self): + async def init_ledger_pool(self): """Initialize the ledger pool.""" if self.settings.get("ledger.disabled"): LOGGER.info("Ledger support is disabled") @@ -80,8 +92,8 @@ def init_ledger_pool(self): LOGGER.warning("Note: setting ledger to read-only mode") genesis_transactions = self.settings.get("ledger.genesis_transactions") cache = self.context.injector.inject_or(BaseCache) - self.ledger_pool = IndyVdrLedgerPool( - pool_name, + self.ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=pool_name, keepalive=keepalive, cache=cache, genesis_transactions=genesis_transactions, @@ -89,7 +101,7 @@ def init_ledger_pool(self): socks_proxy=socks_proxy, ) - def bind_providers(self): + async def bind_providers(self): """Initialize the profile-level instance providers.""" injector = self._context.injector @@ -123,23 +135,17 @@ def bind_providers(self): settings=self.settings ) cache = self.context.injector.inject_or(BaseCache) + ledger_pool = await IndyVdrLedgerPool.get_or_create( + name=write_ledger_config.get("pool_name") + or write_ledger_config.get("id"), + keepalive=write_ledger_config.get("keepalive"), + cache=cache, + genesis_transactions=write_ledger_config.get("genesis_transactions"), + read_only=write_ledger_config.get("read_only"), + socks_proxy=write_ledger_config.get("socks_proxy"), + ) injector.bind_provider( - BaseLedger, - ClassProvider( - IndyVdrLedger, - IndyVdrLedgerPool( - write_ledger_config.get("pool_name") - or write_ledger_config.get("id"), - keepalive=write_ledger_config.get("keepalive"), - cache=cache, - genesis_transactions=write_ledger_config.get( - "genesis_transactions" - ), - read_only=write_ledger_config.get("read_only"), - socks_proxy=write_ledger_config.get("socks_proxy"), - ), - ref(self), - ), + BaseLedger, ClassProvider(IndyVdrLedger, ledger_pool, ref(self)) ) self.settings["ledger.write_ledger"] = write_ledger_config.get("id") if ( @@ -278,7 +284,7 @@ async def provision( """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=True) - return AskarAnoncredsProfile(opened, context) + return await AskarAnoncredsProfile.create(opened, context) async def open( self, context: InjectionContext, config: Mapping[str, Any] = None @@ -286,7 +292,7 @@ async def open( """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) opened = await store_config.open_store(provision=False) - return AskarAnoncredsProfile(opened, context) + return await AskarAnoncredsProfile.create(opened, context) @classmethod async def generate_store_key(self, seed: Optional[str] = None) -> str: diff --git a/acapy_agent/askar/tests/test_profile.py b/acapy_agent/askar/tests/test_profile.py index 38a0326ded..211166b9e3 100644 --- a/acapy_agent/askar/tests/test_profile.py +++ b/acapy_agent/askar/tests/test_profile.py @@ -16,7 +16,7 @@ def open_store(): @pytest.mark.asyncio async def test_init_success(open_store): - askar_profile = AskarProfile( + askar_profile = await AskarProfile.create( open_store, ) @@ -44,7 +44,7 @@ async def test_init_multi_ledger(open_store): ] } ) - askar_profile = AskarProfile( + askar_profile = await AskarProfile.create( open_store, context=context, ) @@ -67,7 +67,7 @@ async def test_remove_success(open_store): "wallet.askar_profile": profile_id, "ledger.genesis_transactions": mock.MagicMock(), } - askar_profile = AskarProfile(openStore, context, profile_id=profile_id) + askar_profile = await AskarProfile.create(openStore, context, profile_id=profile_id) remove_profile_stub = asyncio.Future() remove_profile_stub.set_result(True) openStore.store.remove_profile.return_value = remove_profile_stub @@ -82,7 +82,7 @@ async def test_remove_profile_not_removed_if_wallet_type_not_askar_profile(open_ openStore = open_store context = InjectionContext() context.settings = {"multitenant.wallet_type": "basic"} - askar_profile = AskarProfile(openStore, context) + askar_profile = await AskarProfile.create(openStore, context) await askar_profile.remove() @@ -94,7 +94,7 @@ async def test_profile_manager_transaction(): profile = "profileId" with mock.patch("acapy_agent.askar.profile.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, True, profile_id=profile) + askar_profile = await AskarProfile.create(None, True, profile_id=profile) askar_profile.profile_id = profile askar_profile_transaction = mock.MagicMock() askar_profile.store.transaction.return_value = askar_profile_transaction @@ -110,7 +110,7 @@ async def test_profile_manager_store(): profile = "profileId" with mock.patch("acapy_agent.askar.profile.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, False, profile_id=profile) + askar_profile = await AskarProfile.create(None, False, profile_id=profile) askar_profile.profile_id = profile askar_profile_session = mock.MagicMock() askar_profile.store.session.return_value = askar_profile_session diff --git a/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py b/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py index ce9cc002a6..639c46c37f 100644 --- a/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py +++ b/acapy_agent/ledger/multiple_ledger/tests/test_manager_provider.py @@ -57,7 +57,8 @@ async def test_provide_askar_manager(self): context = InjectionContext() profile = await create_test_profile() context.injector.bind_instance( - BaseLedger, IndyVdrLedger(IndyVdrLedgerPool("name"), profile) + BaseLedger, + IndyVdrLedger(await IndyVdrLedgerPool.get_or_create(name="name"), profile), ) provider = MultiIndyLedgerManagerProvider(profile) context.settings["ledger.ledger_config_list"] = LEDGER_CONFIG diff --git a/acapy_agent/ledger/tests/test_indy_vdr.py b/acapy_agent/ledger/tests/test_indy_vdr.py index 9b0ee8ce3c..079c444a39 100644 --- a/acapy_agent/ledger/tests/test_indy_vdr.py +++ b/acapy_agent/ledger/tests/test_indy_vdr.py @@ -43,7 +43,9 @@ async def ledger(): profile.context.injector.bind_instance(BaseCache, InMemoryCache()) profile.context.injector.bind_instance(KeyTypes, KeyTypes()) - ledger = IndyVdrLedger(IndyVdrLedgerPool("test-ledger"), profile) + ledger = IndyVdrLedger( + await IndyVdrLedgerPool.get_or_create(name="test-ledger"), profile + ) async def open(): ledger.pool.handle = mock.MagicMock(indy_vdr.Pool) diff --git a/acapy_agent/multitenant/manager.py b/acapy_agent/multitenant/manager.py index 1a6bda9030..8137e9dbe9 100644 --- a/acapy_agent/multitenant/manager.py +++ b/acapy_agent/multitenant/manager.py @@ -88,7 +88,7 @@ async def get_wallet_profile( # return anoncreds profile if explicitly set as wallet type if profile.context.settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( profile.opened, profile.context, ) diff --git a/acapy_agent/multitenant/single_wallet_askar_manager.py b/acapy_agent/multitenant/single_wallet_askar_manager.py index 157bd287e0..417bdfb572 100644 --- a/acapy_agent/multitenant/single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/single_wallet_askar_manager.py @@ -107,13 +107,13 @@ async def get_wallet_profile( # return anoncreds profile if explicitly set as wallet type if profile_context.settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( self._multitenant_profile.opened, profile_context, profile_id=wallet_record.wallet_id, ) - return AskarProfile( + return await AskarProfile.create( self._multitenant_profile.opened, profile_context, profile_id=wallet_record.wallet_id, diff --git a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py index 322a8517ec..c59f098f18 100644 --- a/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py +++ b/acapy_agent/multitenant/tests/test_single_wallet_askar_manager.py @@ -52,7 +52,7 @@ async def test_get_wallet_profile_should_open_store_and_return_profile_with_wall ) as AskarProfile, ): sub_wallet_profile_context = InjectionContext() - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context def side_effect(context, provision): @@ -127,7 +127,7 @@ async def test_get_anoncreds_wallet_profile_should_open_store_and_return_anoncre ) as AskarAnoncredsProfile, ): sub_wallet_profile_context = InjectionContext() - sub_wallet_profile = AskarAnoncredsProfile(None, None) + sub_wallet_profile = await AskarAnoncredsProfile.create(None, None) sub_wallet_profile.context.copy.return_value = sub_wallet_profile_context def side_effect(context, provision): @@ -150,7 +150,7 @@ async def test_get_wallet_profile_should_create_profile(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() sub_wallet_profile.store.create_profile.return_value = create_profile_stub self.manager._multitenant_profile = sub_wallet_profile @@ -176,7 +176,7 @@ async def test_get_wallet_profile_should_use_custom_subwallet_name(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() def side_effect(context, provision): @@ -207,7 +207,7 @@ async def test_open_profiles(self): with mock.patch( "acapy_agent.multitenant.single_wallet_askar_manager.AskarProfile" ) as AskarProfile: - sub_wallet_profile = AskarProfile(None, None) + sub_wallet_profile = await AskarProfile.create(None, None) sub_wallet_profile.context.copy.return_value = InjectionContext() sub_wallet_profile.store.create_profile.return_value = create_profile_stub self.manager._multitenant_profile = sub_wallet_profile diff --git a/acapy_agent/storage/tests/test_askar_storage.py b/acapy_agent/storage/tests/test_askar_storage.py index c959c6e3fa..e9ddfce247 100644 --- a/acapy_agent/storage/tests/test_askar_storage.py +++ b/acapy_agent/storage/tests/test_askar_storage.py @@ -385,7 +385,7 @@ async def test_askar_storage_search_session(self): profile = "profileId" with mock.patch("acapy_agent.storage.askar.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, True) + askar_profile = await AskarProfile.create(None, True) askar_profile_scan = mock.MagicMock() askar_profile.store.scan.return_value = askar_profile_scan askar_profile.settings.get.return_value = profile diff --git a/acapy_agent/utils/testing.py b/acapy_agent/utils/testing.py index 2ee34cf125..169bfb3cd8 100644 --- a/acapy_agent/utils/testing.py +++ b/acapy_agent/utils/testing.py @@ -38,11 +38,11 @@ async def create_test_profile( opened = await store_config.open_store(provision=True, in_memory=True) if settings.get("wallet.type") == "askar-anoncreds": - return AskarAnoncredsProfile( + return await AskarAnoncredsProfile.create( opened=opened, context=context, ) - return AskarProfile( + return await AskarProfile.create( opened=opened, context=context, ) From dd17d0115c2f87bd7d7cc2c13d10db7540c8f418 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:29:05 -0800 Subject: [PATCH 120/152] Add test wallet config option (#3355) * Add test wallet config option Signed-off-by: jamshale * Change wallet test arg to store true / Fix tests Signed-off-by: jamshale * Add unit test with test wallet config Signed-off-by: jamshale --------- Signed-off-by: jamshale --- acapy_agent/askar/profile.py | 8 ++++-- acapy_agent/askar/profile_anon.py | 8 ++++-- acapy_agent/askar/tests/test_profile.py | 29 ++++++++++++---------- acapy_agent/commands/tests/test_start.py | 1 + acapy_agent/commands/tests/test_upgrade.py | 1 + acapy_agent/config/argparse.py | 26 ++++++++++++++----- acapy_agent/config/tests/test_argparse.py | 6 ++--- acapy_agent/config/wallet.py | 1 + 8 files changed, 53 insertions(+), 27 deletions(-) diff --git a/acapy_agent/askar/profile.py b/acapy_agent/askar/profile.py index e80bc569f1..313c026bf3 100644 --- a/acapy_agent/askar/profile.py +++ b/acapy_agent/askar/profile.py @@ -324,7 +324,9 @@ async def provision( ) -> Profile: """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) - opened = await store_config.open_store(provision=True) + opened = await store_config.open_store( + provision=True, in_memory=config.get("test") + ) return AskarProfile(opened, context) async def open( @@ -332,7 +334,9 @@ async def open( ) -> Profile: """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) - opened = await store_config.open_store(provision=False) + opened = await store_config.open_store( + provision=False, in_memory=config.get("test") + ) return AskarProfile(opened, context) @classmethod diff --git a/acapy_agent/askar/profile_anon.py b/acapy_agent/askar/profile_anon.py index eea73d876f..9a3cb3e622 100644 --- a/acapy_agent/askar/profile_anon.py +++ b/acapy_agent/askar/profile_anon.py @@ -277,7 +277,9 @@ async def provision( ) -> Profile: """Provision a new instance of a profile.""" store_config = AskarStoreConfig(config) - opened = await store_config.open_store(provision=True) + opened = await store_config.open_store( + provision=True, in_memory=config.get("test") + ) return AskarAnoncredsProfile(opened, context) async def open( @@ -285,7 +287,9 @@ async def open( ) -> Profile: """Open an instance of an existing profile.""" store_config = AskarStoreConfig(config) - opened = await store_config.open_store(provision=False) + opened = await store_config.open_store( + provision=False, in_memory=config.get("test") + ) return AskarAnoncredsProfile(opened, context) @classmethod diff --git a/acapy_agent/askar/tests/test_profile.py b/acapy_agent/askar/tests/test_profile.py index 38a0326ded..15bbbba1ef 100644 --- a/acapy_agent/askar/tests/test_profile.py +++ b/acapy_agent/askar/tests/test_profile.py @@ -3,10 +3,11 @@ import pytest -from ...askar.profile import AskarProfile +from ...askar.profile import AskarProfile, AskarProfileManager from ...config.injection_context import InjectionContext from ...ledger.base import BaseLedger from .. import profile as test_module +from ..profile_anon import AskarAnonProfileManager @pytest.fixture @@ -107,15 +108,17 @@ async def test_profile_manager_transaction(): @pytest.mark.asyncio async def test_profile_manager_store(): - profile = "profileId" - - with mock.patch("acapy_agent.askar.profile.AskarProfile") as AskarProfile: - askar_profile = AskarProfile(None, False, profile_id=profile) - askar_profile.profile_id = profile - askar_profile_session = mock.MagicMock() - askar_profile.store.session.return_value = askar_profile_session - - sessionProfile = test_module.AskarProfileSession(askar_profile, False) - - assert sessionProfile._opener == askar_profile_session - askar_profile.store.session.assert_called_once_with(profile) + config = { + "test": True, + } + context = InjectionContext( + settings=config, + ) + await AskarProfileManager().provision( + context=context, + config=config, + ) + await AskarAnonProfileManager().provision( + context=context, + config=config, + ) diff --git a/acapy_agent/commands/tests/test_start.py b/acapy_agent/commands/tests/test_start.py index cac10b8df6..4c9fe32bcb 100644 --- a/acapy_agent/commands/tests/test_start.py +++ b/acapy_agent/commands/tests/test_start.py @@ -55,6 +55,7 @@ def test_exec_start(self): "0.0.0.0", "80", "--no-ledger", + "--wallet-test", ] ) start_app.assert_called_once() diff --git a/acapy_agent/commands/tests/test_upgrade.py b/acapy_agent/commands/tests/test_upgrade.py index 41728221c8..8d24bbc723 100644 --- a/acapy_agent/commands/tests/test_upgrade.py +++ b/acapy_agent/commands/tests/test_upgrade.py @@ -439,6 +439,7 @@ async def test_execute(self): "--from-version", "v0.7.0", "--force-upgrade", + "--wallet-test", ] ) diff --git a/acapy_agent/config/argparse.py b/acapy_agent/config/argparse.py index ec0d3d95e1..87a67aeaf7 100644 --- a/acapy_agent/config/argparse.py +++ b/acapy_agent/config/argparse.py @@ -1610,13 +1610,13 @@ def add_arguments(self, parser: ArgumentParser): "--wallet-type", type=str, metavar="", - default="basic", + default="askar", env_var="ACAPY_WALLET_TYPE", help=( "Specifies the type of wallet provider to use. " - "Supported internal storage types are 'basic' (memory), 'askar' " + "Supported internal storage types are 'askar' " "and 'askar-anoncreds'." - "The default (if not specified) is 'basic'." + "The default (if not specified) is 'askar'." ), ) parser.add_argument( @@ -1627,11 +1627,23 @@ def add_arguments(self, parser: ArgumentParser): env_var="ACAPY_WALLET_STORAGE_TYPE", help=( "Specifies the type of wallet backend to use. " - "Supported internal storage types are 'basic' (memory), " - "'default' (sqlite), and 'postgres_storage'. The default, " + "Supported internal storage types are 'default' (sqlite), " + "and 'postgres_storage'. The default, " "if not specified, is 'default'." ), ) + parser.add_argument( + "--wallet-test", + action="store_true", + default=False, + env_var="ACAPY_WALLET_TEST", + help=( + "Using this option will create a wallet with an in-memory askar wallet " + "storage with a random name. This is useful for testing purposes. " + "The data will not be persisted after the agent is stopped. The default " + "is False. " + ), + ) parser.add_argument( "--wallet-storage-config", type=str, @@ -1714,6 +1726,8 @@ def get_settings(self, args: Namespace) -> dict: settings["wallet.storage_type"] = args.wallet_storage_type if args.wallet_type: settings["wallet.type"] = args.wallet_type + if args.wallet_test: + settings["wallet.test"] = True if args.wallet_key_derivation_method: settings["wallet.key_derivation_method"] = args.wallet_key_derivation_method if args.wallet_rekey_derivation_method: @@ -1731,7 +1745,7 @@ def get_settings(self, args: Namespace) -> dict: # check required settings for persistent wallets if settings["wallet.type"] in ["askar", "askar-anoncreds"]: # requires name, key - if not args.wallet_name or not args.wallet_key: + if not args.wallet_test and (not args.wallet_name or not args.wallet_key): raise ArgsParseError( "Parameters --wallet-name and --wallet-key must be provided " "for persistent wallets" diff --git a/acapy_agent/config/tests/test_argparse.py b/acapy_agent/config/tests/test_argparse.py index b80e478032..c3965de392 100644 --- a/acapy_agent/config/tests/test_argparse.py +++ b/acapy_agent/config/tests/test_argparse.py @@ -525,10 +525,7 @@ async def test_wallet_key_derivation_method_value_parsing(self): group.add_arguments(parser) result = parser.parse_args( - [ - "--wallet-key-derivation-method", - key_derivation_method, - ] + ["--wallet-key-derivation-method", key_derivation_method, "--wallet-test"] ) settings = group.get_settings(result) @@ -545,6 +542,7 @@ async def test_wallet_key_value_parsing(self): [ "--wallet-key", key_value, + "--wallet-test", ] ) diff --git a/acapy_agent/config/wallet.py b/acapy_agent/config/wallet.py index f857b07847..ce5beb8fc3 100644 --- a/acapy_agent/config/wallet.py +++ b/acapy_agent/config/wallet.py @@ -26,6 +26,7 @@ "storage_config", "storage_creds", "storage_type", + "test", } From 80cc329076d3828c562fd6a31b72b27898359555 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:50:15 -0800 Subject: [PATCH 121/152] Week 49 Library upgrades (#3368) Signed-off-by: jamshale --- .pre-commit-config.yaml | 2 +- mkdocs-requirements.txt | 2 +- poetry.lock | 210 ++++++++++++++++++++-------------------- pyproject.toml | 8 +- 4 files changed, 110 insertions(+), 112 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9374f5f431..2cc9bec01f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,7 +8,7 @@ repos: additional_dependencies: ['@commitlint/config-conventional'] - repo: https://github.com/astral-sh/ruff-pre-commit # Ensure this is synced with pyproject.toml - rev: v0.8.0 + rev: v0.8.1 hooks: # Run the linter - id: ruff diff --git a/mkdocs-requirements.txt b/mkdocs-requirements.txt index a6d710f6af..a3290d9569 100644 --- a/mkdocs-requirements.txt +++ b/mkdocs-requirements.txt @@ -1,3 +1,3 @@ -mkdocs-material==9.5.46 +mkdocs-material==9.5.47 mike==2.1.3 diff --git a/poetry.lock b/poetry.lock index 2ec25c70e1..09458d256f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "aiofiles" @@ -24,87 +24,87 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.7" +version = "3.11.9" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" files = [ - {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bedb1f6cb919af3b6353921c71281b1491f948ca64408871465d889b4ee1b66"}, - {file = "aiohttp-3.11.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f5022504adab881e2d801a88b748ea63f2a9d130e0b2c430824682a96f6534be"}, - {file = "aiohttp-3.11.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e22d1721c978a6494adc824e0916f9d187fa57baeda34b55140315fa2f740184"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e993676c71288618eb07e20622572b1250d8713e7e00ab3aabae28cb70f3640d"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13a05db87d3b241c186d0936808d0e4e12decc267c617d54e9c643807e968b6"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ba8d043fed7ffa117024d7ba66fdea011c0e7602327c6d73cacaea38abe4491"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda3ed0a7869d2fa16aa41f9961ade73aa2c2e3b2fcb0a352524e7b744881889"}, - {file = "aiohttp-3.11.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43bfd25113c1e98aec6c70e26d5f4331efbf4aa9037ba9ad88f090853bf64d7f"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3dd3e7e7c9ef3e7214f014f1ae260892286647b3cf7c7f1b644a568fd410f8ca"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78c657ece7a73b976905ab9ec8be9ef2df12ed8984c24598a1791c58ce3b4ce4"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:db70a47987e34494b451a334605bee57a126fe8d290511349e86810b4be53b01"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9e67531370a3b07e49b280c1f8c2df67985c790ad2834d1b288a2f13cd341c5f"}, - {file = "aiohttp-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9202f184cc0582b1db15056f2225ab4c1e3dac4d9ade50dd0613ac3c46352ac2"}, - {file = "aiohttp-3.11.7-cp310-cp310-win32.whl", hash = "sha256:2257bdd5cf54a4039a4337162cd8048f05a724380a2283df34620f55d4e29341"}, - {file = "aiohttp-3.11.7-cp310-cp310-win_amd64.whl", hash = "sha256:b7215bf2b53bc6cb35808149980c2ae80a4ae4e273890ac85459c014d5aa60ac"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08"}, - {file = "aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884"}, - {file = "aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d"}, - {file = "aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720"}, - {file = "aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847"}, - {file = "aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea"}, - {file = "aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129"}, - {file = "aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124"}, - {file = "aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd"}, - {file = "aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8"}, - {file = "aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68"}, - {file = "aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da"}, - {file = "aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791"}, - {file = "aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52"}, - {file = "aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e"}, - {file = "aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:17829f37c0d31d89aa6b8b010475a10233774771f9b6dc2cc352ea4f8ce95d9a"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d6177077a31b1aecfc3c9070bd2f11419dbb4a70f30f4c65b124714f525c2e48"}, - {file = "aiohttp-3.11.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:badda65ac99555791eed75e234afb94686ed2317670c68bff8a4498acdaee935"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de6466b9d742b4ee56fe1b2440706e225eb48c77c63152b1584864a236e7a50"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04b0cc74d5a882c9dacaeeccc1444f0233212b6f5be8bc90833feef1e1ce14b9"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c7af3e50e5903d21d7b935aceed901cc2475463bc16ddd5587653548661fdb"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c63f898f683d1379b9be5afc3dd139e20b30b0b1e0bf69a3fc3681f364cf1629"}, - {file = "aiohttp-3.11.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdadc3f6a32d6eca45f9a900a254757fd7855dfb2d8f8dcf0e88f0fae3ff8eb1"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d329300fb23e14ed1f8c6d688dfd867d1dcc3b1d7cd49b7f8c5b44e797ce0932"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5578cf40440eafcb054cf859964bc120ab52ebe0e0562d2b898126d868749629"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7b2f8107a3c329789f3c00b2daad0e35f548d0a55cda6291579136622099a46e"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:43dd89a6194f6ab02a3fe36b09e42e2df19c211fc2050ce37374d96f39604997"}, - {file = "aiohttp-3.11.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d2fa6fc7cc865d26ff42480ac9b52b8c9b7da30a10a6442a9cdf429de840e949"}, - {file = "aiohttp-3.11.7-cp39-cp39-win32.whl", hash = "sha256:a7d9a606355655617fee25dd7e54d3af50804d002f1fd3118dd6312d26692d70"}, - {file = "aiohttp-3.11.7-cp39-cp39-win_amd64.whl", hash = "sha256:53c921b58fdc6485d6b2603e0132bb01cd59b8f0620ffc0907f525e0ba071687"}, - {file = "aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668"}, + {file = "aiohttp-3.11.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0411777249f25d11bd2964a230b3ffafcbed6cd65d0f2b132bc2b8f5b8c347c7"}, + {file = "aiohttp-3.11.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:499368eb904566fbdf1a3836a1532000ef1308f34a1bcbf36e6351904cced771"}, + {file = "aiohttp-3.11.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0b5a5009b0159a8f707879dc102b139466d8ec6db05103ec1520394fdd8ea02c"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:176f8bb8931da0613bb0ed16326d01330066bb1e172dd97e1e02b1c27383277b"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6435a66957cdba1a0b16f368bde03ce9c79c57306b39510da6ae5312a1a5b2c1"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:202f40fb686e5f93908eee0c75d1e6fbe50a43e9bd4909bf3bf4a56b560ca180"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39625703540feb50b6b7f938b3856d1f4886d2e585d88274e62b1bd273fae09b"}, + {file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6beeac698671baa558e82fa160be9761cf0eb25861943f4689ecf9000f8ebd0"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:96726839a42429318017e67a42cca75d4f0d5248a809b3cc2e125445edd7d50d"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3f5461c77649358610fb9694e790956b4238ac5d9e697a17f63619c096469afe"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4313f3bc901255b22f01663eeeae167468264fdae0d32c25fc631d5d6e15b502"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d6e274661c74195708fc4380a4ef64298926c5a50bb10fbae3d01627d7a075b7"}, + {file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:db2914de2559809fdbcf3e48f41b17a493b58cb7988d3e211f6b63126c55fe82"}, + {file = "aiohttp-3.11.9-cp310-cp310-win32.whl", hash = "sha256:27935716f8d62c1c73010428db310fd10136002cfc6d52b0ba7bdfa752d26066"}, + {file = "aiohttp-3.11.9-cp310-cp310-win_amd64.whl", hash = "sha256:afbe85b50ade42ddff5669947afde9e8a610e64d2c80be046d67ec4368e555fa"}, + {file = "aiohttp-3.11.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:afcda759a69c6a8be3aae764ec6733155aa4a5ad9aad4f398b52ba4037942fe3"}, + {file = "aiohttp-3.11.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5bba6b83fde4ca233cfda04cbd4685ab88696b0c8eaf76f7148969eab5e248a"}, + {file = "aiohttp-3.11.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:442356e8924fe1a121f8c87866b0ecdc785757fd28924b17c20493961b3d6697"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f737fef6e117856400afee4f17774cdea392b28ecf058833f5eca368a18cf1bf"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea142255d4901b03f89cb6a94411ecec117786a76fc9ab043af8f51dd50b5313"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e1e9e447856e9b7b3d38e1316ae9a8c92e7536ef48373de758ea055edfd5db5"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7f6173302f8a329ca5d1ee592af9e628d3ade87816e9958dcf7cdae2841def7"}, + {file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c6147c6306f537cff59409609508a1d2eff81199f0302dd456bb9e7ea50c39"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e9d036a9a41fc78e8a3f10a86c2fc1098fca8fab8715ba9eb999ce4788d35df0"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2ac9fd83096df36728da8e2f4488ac3b5602238f602706606f3702f07a13a409"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3108f0ad5c6b6d78eec5273219a5bbd884b4aacec17883ceefaac988850ce6e"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:96bbec47beb131bbf4bae05d8ef99ad9e5738f12717cfbbf16648b78b0232e87"}, + {file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fc726c3fa8f606d07bd2b500e5dc4c0fd664c59be7788a16b9e34352c50b6b6b"}, + {file = "aiohttp-3.11.9-cp311-cp311-win32.whl", hash = "sha256:5720ebbc7a1b46c33a42d489d25d36c64c419f52159485e55589fbec648ea49a"}, + {file = "aiohttp-3.11.9-cp311-cp311-win_amd64.whl", hash = "sha256:17af09d963fa1acd7e4c280e9354aeafd9e3d47eaa4a6bfbd2171ad7da49f0c5"}, + {file = "aiohttp-3.11.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c1f2d7fd583fc79c240094b3e7237d88493814d4b300d013a42726c35a734bc9"}, + {file = "aiohttp-3.11.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4b8a1b6c7a68c73191f2ebd3bf66f7ce02f9c374e309bdb68ba886bbbf1b938"}, + {file = "aiohttp-3.11.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd3f711f4c99da0091ced41dccdc1bcf8be0281dc314d6d9c6b6cf5df66f37a9"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44cb1a1326a0264480a789e6100dc3e07122eb8cd1ad6b784a3d47d13ed1d89c"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a7ddf981a0b953ade1c2379052d47ccda2f58ab678fca0671c7c7ca2f67aac2"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ffa45cc55b18d4ac1396d1ddb029f139b1d3480f1594130e62bceadf2e1a838"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cca505829cdab58c2495ff418c96092d225a1bbd486f79017f6de915580d3c44"}, + {file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44d323aa80a867cb6db6bebb4bbec677c6478e38128847f2c6b0f70eae984d72"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b2fab23003c4bb2249729a7290a76c1dda38c438300fdf97d4e42bf78b19c810"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:be0c7c98e38a1e3ad7a6ff64af8b6d6db34bf5a41b1478e24c3c74d9e7f8ed42"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5cc5e0d069c56645446c45a4b5010d4b33ac6c5ebfd369a791b5f097e46a3c08"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9bcf97b971289be69638d8b1b616f7e557e1342debc7fc86cf89d3f08960e411"}, + {file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c7333e7239415076d1418dbfb7fa4df48f3a5b00f8fdf854fca549080455bc14"}, + {file = "aiohttp-3.11.9-cp312-cp312-win32.whl", hash = "sha256:9384b07cfd3045b37b05ed002d1c255db02fb96506ad65f0f9b776b762a7572e"}, + {file = "aiohttp-3.11.9-cp312-cp312-win_amd64.whl", hash = "sha256:f5252ba8b43906f206048fa569debf2cd0da0316e8d5b4d25abe53307f573941"}, + {file = "aiohttp-3.11.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:282e0a7ddd36ebc411f156aeaa0491e8fe7f030e2a95da532cf0c84b0b70bc66"}, + {file = "aiohttp-3.11.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ebd3e6b0c7d4954cca59d241970011f8d3327633d555051c430bd09ff49dc494"}, + {file = "aiohttp-3.11.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:30f9f89ae625d412043f12ca3771b2ccec227cc93b93bb1f994db6e1af40a7d3"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a3b5b2c012d70c63d9d13c57ed1603709a4d9d7d473e4a9dfece0e4ea3d5f51"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ef1550bb5f55f71b97a6a395286db07f7f2c01c8890e613556df9a51da91e8d"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317251b9c9a2f1a9ff9cd093775b34c6861d1d7df9439ce3d32a88c275c995cd"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cbe97839b009826a61b143d3ca4964c8590d7aed33d6118125e5b71691ca46"}, + {file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:618b18c3a2360ac940a5503da14fa4f880c5b9bc315ec20a830357bcc62e6bae"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0cf4d814689e58f57ecd5d8c523e6538417ca2e72ff52c007c64065cef50fb2"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:15c4e489942d987d5dac0ba39e5772dcbed4cc9ae3710d1025d5ba95e4a5349c"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ec8df0ff5a911c6d21957a9182402aad7bf060eaeffd77c9ea1c16aecab5adbf"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ed95d66745f53e129e935ad726167d3a6cb18c5d33df3165974d54742c373868"}, + {file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:647ec5bee7e4ec9f1034ab48173b5fa970d9a991e565549b965e93331f1328fe"}, + {file = "aiohttp-3.11.9-cp313-cp313-win32.whl", hash = "sha256:ef2c9499b7bd1e24e473dc1a85de55d72fd084eea3d8bdeec7ee0720decb54fa"}, + {file = "aiohttp-3.11.9-cp313-cp313-win_amd64.whl", hash = "sha256:84de955314aa5e8d469b00b14d6d714b008087a0222b0f743e7ffac34ef56aff"}, + {file = "aiohttp-3.11.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e738aabff3586091221044b7a584865ddc4d6120346d12e28e788307cd731043"}, + {file = "aiohttp-3.11.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28f29bce89c3b401a53d6fd4bee401ee943083bf2bdc12ef297c1d63155070b0"}, + {file = "aiohttp-3.11.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31de2f10f63f96cc19e04bd2df9549559beadd0b2ee2da24a17e7ed877ca8c60"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f31cebd8c27a36af6c7346055ac564946e562080ee1a838da724585c67474f"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0bcb7f6976dc0b6b56efde13294862adf68dd48854111b422a336fa729a82ea6"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8b13b9950d8b2f8f58b6e5842c4b842b5887e2c32e3f4644d6642f1659a530"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9c23e62f3545c2216100603614f9e019e41b9403c47dd85b8e7e5015bf1bde0"}, + {file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec656680fc53a13f849c71afd0c84a55c536206d524cbc831cde80abbe80489e"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:36df00e0541f264ce42d62280281541a47474dfda500bc5b7f24f70a7f87be7a"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8dcfd14c712aa9dd18049280bfb2f95700ff6a8bde645e09f17c3ed3f05a0130"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14624d96f0d69cf451deed3173079a68c322279be6030208b045ab77e1e8d550"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4b01d9cfcb616eeb6d40f02e66bebfe7b06d9f2ef81641fdd50b8dd981166e0b"}, + {file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:928f92f80e2e8d6567b87d3316c1fd9860ccfe36e87a9a7f5237d4cda8baa1ba"}, + {file = "aiohttp-3.11.9-cp39-cp39-win32.whl", hash = "sha256:c8a02f74ae419e3955af60f570d83187423e42e672a6433c5e292f1d23619269"}, + {file = "aiohttp-3.11.9-cp39-cp39-win_amd64.whl", hash = "sha256:0a97d657f6cf8782a830bb476c13f7d777cfcab8428ac49dde15c22babceb361"}, + {file = "aiohttp-3.11.9.tar.gz", hash = "sha256:a9266644064779840feec0e34f10a89b3ff1d2d6b751fe90017abcad1864fa7c"}, ] [package.dependencies] @@ -1325,8 +1325,6 @@ optional = false python-versions = "*" files = [ {file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"}, - {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"}, - {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"}, ] [package.dependencies] @@ -2267,13 +2265,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.10.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" files = [ - {file = "PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15"}, - {file = "pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -2332,13 +2330,13 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -2600,29 +2598,29 @@ test = ["hypothesis (==5.19.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "ruff" -version = "0.8.0" +version = "0.8.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea"}, - {file = "ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b"}, - {file = "ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3"}, - {file = "ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd"}, - {file = "ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426"}, - {file = "ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468"}, - {file = "ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f"}, - {file = "ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6"}, - {file = "ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44"}, + {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"}, + {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"}, + {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"}, + {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"}, + {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"}, + {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"}, + {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"}, ] [[package]] @@ -3092,4 +3090,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "c9121c319eb42db81805bec50a15a153e7ef4f8bef5231a6b12a7a74b4ffe290" +content-hash = "59c846da8c32b9e1eb833391d459aecef062e9ba70fd6e788b2ec21d5fdfb0fd" diff --git a/pyproject.toml b/pyproject.toml index de8a3531bc..8810766495 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ repository = "https://github.com/openwallet-foundation/acapy" [tool.poetry.dependencies] python = "^3.12" -aiohttp = "~3.11.7" +aiohttp = "~3.11.9" aiohttp-apispec-acapy = "~3.0.2" aiohttp-cors = "~0.7.0" apispec = "^6.6.0" @@ -34,7 +34,7 @@ packaging = "~23.2" portalocker = "~2.10.1" prompt_toolkit = ">=2.0.9,<2.1.0" pydid = "^0.5.1" -pyjwt = "~2.10.0" +pyjwt = "~2.10.1" pyld = "^2.0.4" pynacl = "~1.5.0" python-dateutil = "^2.9.0" @@ -69,7 +69,7 @@ canonicaljson = "^2.0.0" [tool.poetry.group.dev.dependencies] pre-commit = "~3.8.0" # Sync with version in .pre-commit-config.yaml -ruff = "0.8.0" +ruff = "0.8.1" sphinx = "^5.3.0" sphinx-rtd-theme = ">=0.4.3" @@ -79,7 +79,7 @@ pydevd = "1.5.1" pydevd-pycharm = "~193.7288.30" # testing -pytest = "^8.3.3" +pytest = "^8.3.4" pytest-asyncio = "^0.24.0" pytest-cov = "^5.0.0" pytest-ruff = "^0.4.1" From 389e9d26405601b9611118aacb289e9aa176c018 Mon Sep 17 00:00:00 2001 From: Mourits de Beer <31511766+ff137@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:26:21 +0200 Subject: [PATCH 122/152] :zap: Add class caching to DeferLoad (#3361) Resolves #3360 Signed-off-by: ff137 Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com> --- acapy_agent/utils/classloader.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/acapy_agent/utils/classloader.py b/acapy_agent/utils/classloader.py index 29fd81bc4d..09d4799aea 100644 --- a/acapy_agent/utils/classloader.py +++ b/acapy_agent/utils/classloader.py @@ -181,18 +181,21 @@ def scan_subpackages(cls, package: str) -> Sequence[str]: class DeferLoad: """Helper to defer loading of a class definition.""" + _class_cache = {} # Shared cache for resolved classes + def __init__(self, cls_path: str): """Initialize the `DeferLoad` instance with a qualified class path.""" self._cls_path = cls_path - self._inst = None def __call__(self, *args, **kwargs): """Magic method to call the `DeferLoad` as a function.""" - return (self.resolved)(*args, **kwargs) + return self.resolved(*args, **kwargs) @property def resolved(self): """Accessor for the resolved class instance.""" - if not self._inst: - self._inst = ClassLoader.load_class(self._cls_path) - return self._inst + if self._cls_path not in DeferLoad._class_cache: + DeferLoad._class_cache[self._cls_path] = ClassLoader.load_class( + self._cls_path + ) + return DeferLoad._class_cache[self._cls_path] From 6e26d0be40806dd966e724a75f8c7e39c788e549 Mon Sep 17 00:00:00 2001 From: Daniel Bluhm Date: Mon, 2 Dec 2024 16:40:56 -0600 Subject: [PATCH 123/152] fix: check routing keys on endpoint refresh Previously we were only checking if the endpoint value had changed but it is possible for the routing keys to update and not the endpoint. This resulted in new attrib txns not getting published when there were new routing keys. Signed-off-by: Daniel Bluhm --- acapy_agent/ledger/indy_vdr.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acapy_agent/ledger/indy_vdr.py b/acapy_agent/ledger/indy_vdr.py index d26734ec6f..aad8963cd5 100644 --- a/acapy_agent/ledger/indy_vdr.py +++ b/acapy_agent/ledger/indy_vdr.py @@ -739,8 +739,11 @@ async def update_endpoint_for_did( if all_exist_endpoints else None ) + existing_routing_keys = ( + all_exist_endpoints.get("routingKeys") if all_exist_endpoints else None + ) - if exist_endpoint_of_type != endpoint: + if exist_endpoint_of_type != endpoint or existing_routing_keys != routing_keys: if self.read_only: raise LedgerError( "Error cannot update endpoint when ledger is in read only mode" From 9a3e93a3098f484d09069fc7d21b8ac92289f902 Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Mon, 2 Dec 2024 15:23:07 -0800 Subject: [PATCH 124/152] 1.1.1rc0 Signed-off-by: Stephen Curran --- CHANGELOG.md | 73 +++++ Managing-ACA-Py-Doc-Site.md | 4 +- PUBLISHING.md | 20 +- docs/UpdateRTD.md | 2 +- docs/features/SupportedRFCs.md | 2 +- docs/features/W3cCredentials.md | 86 +++-- .../acapy_agent.anoncreds.models.rst | 94 +++++- docs/generated/acapy_agent.config.logging.rst | 42 +++ docs/generated/acapy_agent.config.rst | 16 +- .../acapy_agent.core.in_memory.didcomm.rst | 26 -- docs/generated/acapy_agent.core.in_memory.rst | 26 -- docs/generated/acapy_agent.core.rst | 8 - ...ls.issue_credential.v2_0.models.detail.rst | 8 + .../acapy_agent.resolver.default.rst | 8 + docs/generated/acapy_agent.storage.rst | 8 - .../acapy_agent.storage.vc_holder.rst | 8 - docs/generated/acapy_agent.utils.rst | 16 + docs/generated/acapy_agent.wallet.rst | 8 - mkdocs.yml | 1 + open-api/openapi.json | 295 +++++++++++++++--- open-api/swagger.json | 291 ++++++++++++++--- pyproject.toml | 2 +- 22 files changed, 808 insertions(+), 236 deletions(-) create mode 100644 docs/generated/acapy_agent.config.logging.rst delete mode 100644 docs/generated/acapy_agent.core.in_memory.didcomm.rst delete mode 100644 docs/generated/acapy_agent.core.in_memory.rst diff --git a/CHANGELOG.md b/CHANGELOG.md index f4be55b250..c956437784 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,78 @@ # Aries Cloud Agent Python Changelog +## 1.1.1rc0 + +### December 2, 2024 + +Release 1.1.1 is a patch update to ACA-Py that contains a lengthy list of adjustments, improvements and fixes, with a focus on removing Technical Debt. The most visible change is the removal of the "in-memory wallet" implementation in favour of using the SQLite in-memory wallet (`sqlite://:memory:`), including removing the logic for handling that extra wallet type. While arguably a breaking change (and we mention it below), we're confident no one is using the in-memory wallet (right?!?) any where other than in tests. In removing the in-memory wallet, all of the unit and integration tests that used the in-memory wallet were updated to use SQLite's in-memory wallet. + +The first step to full support of [did:tdw](https://identity.foundation/trustdidweb/) (soon to be renamed to `did:webvh` for "`did:web` + Verifiable History") has been added to ACA-Py -- a resolver. We're working on adding new DID Registration for it and other DID Methods, enabling ACA-Py to be used easily with a variety of DID Methods. + +The move to the [OpenWallet Foundation](https://openwallet.foundation/) is now complete. For up to date details on what the repo move means for ACA-Py users, including steps for updating deployments, please see latest in [GitHub Issue #3250]. + +[GitHub Issue #3250]: https://github.com/hyperledger/aries-cloudagent-python/issues/3250 + +### 1.1.1 Deprecation Notices + +The same **[deprecation notices](#101-deprecation-notices)** from the [1.1.0](#110) release about AIP 1.0 protocols still apply. The protocols remain in the 1.1.1 release, but will be moved out of the core and into plugins soon. Please review these notifications carefully! + +### 1.1.1 Breaking Changes + +While there are no breaking changes in this release that might impact production deployments, the removal of the "in-memory" wallet implementation might be break some test scripts. Rather than using the in-memory wallet, tests should be updated to use SQLite's special `sqlite://:memory:` database instead. This results in a better alignment between tests and a production environment. + + +#### 1.1.1 Categorized List of Pull Requests + +- AnonCreds VC Issuance and Presentation Enhancement / Fixes + - Fix tails upload for anoncreds multitenancy [\#3346](https://github.com/openwallet-foundation/acapy/pull/3346) [jamshale](https://github.com/jamshale) + - Fix subwallet anoncreds upgrade check [\#3345](https://github.com/openwallet-foundation/acapy/pull/3345) [jamshale](https://github.com/jamshale) + - Add anoncreds issuance and presentation format [\#3331](https://github.com/openwallet-foundation/acapy/pull/3331) [jamshale](https://github.com/jamshale) + - Fix endorsement setup with existing connection [\#3309](https://github.com/openwallet-foundation/acapy/pull/3309) [jamshale](https://github.com/jamshale) + - Update accumulator value in wallet on repair [\#3299](https://github.com/openwallet-foundation/acapy/pull/3299) [jamshale](https://github.com/jamshale) + +- Middleware Handling and Multi-tenancy + - Restore `--base-wallet-routes` flag functionality [\#3344](https://github.com/openwallet-foundation/acapy/pull/3344) [esune](https://github.com/esune) + - :white_check_mark: Re-add ready_middleware unit tests [\#3330](https://github.com/openwallet-foundation/acapy/pull/3330) [ff137](https://github.com/ff137) + - :sparkles: Handle NotFound and UnprocessableEntity errors in middleware [\#3327](https://github.com/openwallet-foundation/acapy/pull/3327) [ff137](https://github.com/ff137) + - :art: Refactor Multitenant Manager errors and exception handling [\#3323](https://github.com/openwallet-foundation/acapy/pull/3323) [ff137](https://github.com/ff137) + - Don't pass rekey to sub_wallet_profile [\#3312](https://github.com/openwallet-foundation/acapy/pull/3312) [jamshale](https://github.com/jamshale) + +- DID Registration and Resolution + - fix: check routing keys on indy_vdr endpoint refresh [\#3371](https://github.com/openwallet-foundation/acapy/pull/3371) [dbluhm](https://github.com/dbluhm) + - Fix/universal resolver [\#3354](https://github.com/openwallet-foundation/acapy/pull/3354) [jamshale](https://github.com/jamshale) + - More robust verification method selection by did [\#3279](https://github.com/openwallet-foundation/acapy/pull/3279) [dbluhm](https://github.com/dbluhm) + - did:tdw resolver [\#3237](https://github.com/openwallet-foundation/acapy/pull/3237) [jamshale](https://github.com/jamshale) + +- DIDComm Updates and Enhancements + - :bug: Rearrange connection record deletion after hangup [\#3310](https://github.com/openwallet-foundation/acapy/pull/3310) [ff137](https://github.com/ff137) + - :bug: Handle failure to resolve DIDComm services in DIDXManager [\#3298](https://github.com/openwallet-foundation/acapy/pull/3298) [ff137](https://github.com/ff137) + +- Test Suite Updates and Artifact Publishing + - Add test wallet config option [\#3355](https://github.com/openwallet-foundation/acapy/pull/3355) [jamshale](https://github.com/jamshale) + - :art: Fix current test warnings [\#3338](https://github.com/openwallet-foundation/acapy/pull/3338) [ff137](https://github.com/ff137) + - :construction_worker: Fix Nightly Publish to not run on forks [\#3333](https://github.com/openwallet-foundation/acapy/pull/3333) [ff137](https://github.com/ff137) + +- Internal Improvements / Cleanups / Tech Debt Updates + - :zap: Add class caching to DeferLoad [\#3361](https://github.com/openwallet-foundation/acapy/pull/3361) [ff137](https://github.com/ff137 + - :art: Sync Ruff version in configs and apply formatting [\#3358](https://github.com/openwallet-foundation/acapy/pull/3358) [ff137](https://github.com/ff137) + - :art: Replace deprecated ABC decorators [\#3357](https://github.com/openwallet-foundation/acapy/pull/3357) [ff137](https://github.com/ff137) + - :art: Refactor the logging module monolith [\#3319](https://github.com/openwallet-foundation/acapy/pull/3319) [ff137](https://github.com/ff137) + - :wrench: set default fixture scope for pytest-asyncio [\#3318](https://github.com/openwallet-foundation/acapy/pull/3318) [ff137](https://github.com/ff137) + - Docs (devcontainer) Change folder names [\#3317](https://github.com/openwallet-foundation/acapy/pull/3317) [loneil](https://github.com/loneil) + - :art: Refactor string concatenation in model descriptions [\#3313](https://github.com/openwallet-foundation/acapy/pull/3313) [ff137](https://github.com/ff137) + - Remove in memory wallet [\#3311](https://github.com/openwallet-foundation/acapy/pull/3311) [jamshale](https://github.com/jamshale) + +- Consolidate Dependabot updates and other library/dependency updates + - Week 49 Library upgrades [\#3368](https://github.com/openwallet-foundation/acapy/pull/3368) [jamshale](https://github.com/jamshale) + - :arrow_up: Update lock file [\#3296](https://github.com/openwallet-foundation/acapy/pull/3296) [ff137](https://github.com/ff137) + +- Release management pull requests: + - 1.1.1rc0 [\#3372](https://github.com/openwallet-foundation/acapy/pull/3372) [swcurran](https://github.com/swcurran) + +- Dependabot PRs + - [Link to list of Dependabot PRs in this release](https://github.com/openwallet-foundation/acapy/pulls?q=is%3Apr+is%3Amerged+merged%3A2024-10-15..2024-12-02+author%3Aapp%2Fdependabot+) + + ## 1.1.0 ### October 15, 2024 diff --git a/Managing-ACA-Py-Doc-Site.md b/Managing-ACA-Py-Doc-Site.md index 8d6902bd9d..5bafc5ad87 100644 --- a/Managing-ACA-Py-Doc-Site.md +++ b/Managing-ACA-Py-Doc-Site.md @@ -20,7 +20,7 @@ and mkdocs configuration. When the GitHub Action fires, it runs a container that carries out the following steps: -- Checks out the triggering branch, either `main` or `docs-v` (e.g `docs-v1.1.0`). +- Checks out the triggering branch, either `main` or `docs-v` (e.g `docs-v1.1.1`). - Runs the script [scripts/prepmkdocs.sh], which moves and updates some of the markdown files so that they fit into the generated site. See the comments in the scripts for details about the copying and editing done via the script. In @@ -97,7 +97,7 @@ To delete the documentation version, do the following: - Check your `git status` and make sure there are no changes in the branch -- e.g., new files that shouldn't be added to the `gh-pages` branch. If there are any -- delete the files so they are not added. -- Remove the folder for the RC. For example `rm -rf 1.1.0` +- Remove the folder for the RC. For example `rm -rf 1.1.1rc0` - Edit the `versions.json` file and remove the reference to the RC release in the file. - Push the changes via a PR to the ACA-Py `gh-pages` branch (don't PR them into diff --git a/PUBLISHING.md b/PUBLISHING.md index 726557bedf..e7bd48af07 100644 --- a/PUBLISHING.md +++ b/PUBLISHING.md @@ -6,7 +6,7 @@ a major, minor or patch release, per [semver](https://semver.org/) rules. Once ready to do a release, create a local branch that includes the following updates: -1. Create a local PR branch from an updated `main` branch, e.g. "1.1.0". +1. Create a local PR branch from an updated `main` branch, e.g. "1.1.1". 2. See if there are any Document Site `mkdocs` changes needed. Run the script `./scripts/prepmkdocs.sh; mkdocs`. Watch the log, noting particularly if @@ -27,7 +27,7 @@ Once ready to do a release, create a local branch that includes the following up github account. Do not include `dependabot` PRs. For those, we put a live link for the date range of the release (guidance below). - To generate the list, run the script `genChangeLog.sh` command (requires you + To generate the list, run the `./scripts/genChangeLog.sh` scripts (requires you have [gh] and [jq] installed), with the date of the day before the last release. The day before is picked to make sure you get all of the changes. The script generates the list of all PRs, minus the dependabot ones, merged since @@ -78,9 +78,9 @@ Once you have the list of PRs: - Check the dates in the `dependabot` URL to make sure the full period between the previous non-RC release to the date of the non-RC release you are preparing. - Include a PR in the list for this soon-to-be PR, initially with the "next to be issued" number for PRs/Issues. At the end output of the script is the highest numbered PR and issue. Your PR will be one higher than the highest of those two numbers. Note that you still might have to correct the number after you create the PR if someone sneaks an issue or PR in before you submit your PR. -5. Check to see if there are any other PRs that should be included in the release. +1. Check to see if there are any other PRs that should be included in the release. -6. Update the ReadTheDocs in the `/docs` folder by following the instructions in +2. Update the ReadTheDocs in the `/docs` folder by following the instructions in the `docs/UpdateRTD.md` file. That will likely add a number of new and modified files to the PR. Eliminate all of the errors in the generation process, either by mocking external dependencies or by fixing ACA-Py code. If @@ -88,7 +88,7 @@ Once you have the list of PRs: developer. Experience has demonstrated to use that documentation generation errors should be fixed in the code. -7. Search across the repository for the previous version number and update it +3. Search across the repository for the previous version number and update it everywhere that makes sense. The CHANGELOG.md entry for the previous release is a likely exception, and the `pyproject.toml` in the root **MUST** be updated. You can skip (although it won't hurt) to update the files in the @@ -101,28 +101,28 @@ Once you have the list of PRs: have dropped the previously used `-` in the release candidate version string to better follow the semver rules. -8. Regenerate openapi.json and swagger.json by running +4. Regenerate openapi.json and swagger.json by running `scripts/generate-open-api-spec` from within the `acapy_agent` folder. Command: `cd acapy_agent;../scripts/generate-open-api-spec;cd ..` Folders may not be cleaned up by the script, so the following can be run, likely with `sudo` -- `rm -rf open-api/.build`. The folder is `.gitignore`d, so there is not a danger they will be pushed, even if they are not deleted. -9. Double check all of these steps above, and then submit a PR from the branch. +5. Double check all of these steps above, and then submit a PR from the branch. Add this new PR to CHANGELOG.md so that all the PRs are included. If there are still further changes to be merged, mark the PR as "Draft", repeat **ALL** of the steps again, and then mark this PR as ready and then wait until it is merged. It's embarrassing when you have to do a whole new release just because you missed something silly...I know! -10. Immediately after it is merged, create a new GitHub tag representing the +6. Immediately after it is merged, create a new GitHub tag representing the version. The tag name and title of the release should be the same as the version in [pyproject.toml](https://github.com/openwallet-foundation/acapy/tree/main/pyproject.toml). Use the "Generate Release Notes" capability to get a sequential listing of the PRs in the release, to complement the manually curated Changelog. Verify on PyPi that the version is published. -11. New images for the release are automatically published by the GitHubAction +7. New images for the release are automatically published by the GitHubAction Workflows: [publish.yml] and [publish-indy.yml]. The actions are triggered when a release is tagged, so no manual action is needed. The images are published in the [OpenWallet Foundation Package Repository under @@ -140,7 +140,7 @@ Once you have the list of PRs: [publish-indy.yml]: https://github.com/openwallet-foundation/acapy/blob/main/.github/workflows/publish-indy.yml 1. When a new release is tagged, create a new branch at the same commit with - the branch name in the format `docs-v`, for example, `docs-v1.1.0`. + the branch name in the format `docs-v`, for example, `docs-v1.1.1`. The creation of the branch triggers the execution of the [publish-docs] GitHub Action which generates the documentation for the new release, publishing it at [https://aca-py.org]. The GitHub Action also executes when diff --git a/docs/UpdateRTD.md b/docs/UpdateRTD.md index b37e028992..c9307936b2 100644 --- a/docs/UpdateRTD.md +++ b/docs/UpdateRTD.md @@ -17,7 +17,7 @@ and verify the installation on your system. To rebuild the project and settings from scratch: ``` bash -cd docs; rm -rf generated; sphinx-apidoc -f -M -o ./generated ../acapy_agent/ $(find ../acapy_agent/ -name '*tests*', cd ..) +cd docs; rm -rf generated; sphinx-apidoc -f -M -o ./generated ../acapy_agent/ $(find ../acapy_agent/ -name '*tests*'); cd .. ``` Note that the `find` command that is used to exclude any of the `test` python files from the RTD documentation. diff --git a/docs/features/SupportedRFCs.md b/docs/features/SupportedRFCs.md index 23b370c03b..8118b283c7 100644 --- a/docs/features/SupportedRFCs.md +++ b/docs/features/SupportedRFCs.md @@ -8,7 +8,7 @@ ACA-Py or the repository `main` branch. Reminders (and PRs!) to update this page welcome! If you have any questions, please contact us on the #aries channel on [OpenWallet Foundation Discord](https://discord.gg/openwallet-foundation) or through an issue in this repo. -**Last Update**: 2024-10-15, Release 1.1.0 +**Last Update**: 2024-12-02, Release 1.1.1 > The checklist version of this document was created as a joint effort > between [Northern Block](https://northernblock.io/), [Animo Solutions](https://animo.id/) and the Ontario government, on behalf of the Ontario government. diff --git a/docs/features/W3cCredentials.md b/docs/features/W3cCredentials.md index 72d871b7d9..02ddaa7d0c 100644 --- a/docs/features/W3cCredentials.md +++ b/docs/features/W3cCredentials.md @@ -1,62 +1,60 @@ -## Verifiable Credential Data Integrity (VC-DI) Credentials in ACA-Py +# Verifiable Credential Data Integrity (VC-DI) Credentials in ACA-Py This document outlines a new functionality within Aries Agent that facilitates the issuance of credentials and presentations in compliance with the W3C standard. -### Table of Contents - -- [Verifiable Credential Data Integrity (VC-DI) Credentials in ACA-Py](#verifiable-credential-data-integrity-vc-di-credentials-in-aca-py) - - [Table of Contents](#table-of-contents) - - [General Concept](#general-concept) - - [Prerequisites](#prerequisites) - - [Verifiable Credentials Data Model](#verifiable-credentials-data-model) - - [Verifiable Presentations Data Model](#verifiable-presentations-data-model) - - [DIF Presentation Format](#dif-presentation-format) - - [Preparing to Issue a Credential](#preparing-to-issue-a-credential) - - [VC-DI Context](#vc-di-context) - - [Signature Suite](#signature-suite) - - [DID Method](#did-method) - - [`did:key`](#didkey) - - [Issue a Credential](#issue-a-credential) - - [Verify a Credential](#verify-a-credential) - - [Present Proof](#present-proof) - - [Requesting Proof](#requesting-proof) - - [Presenting Proof](#presenting-proof) - - [Verifying Proof](#verifying-proof) - - [Appendix](#appendix) - - [Glossary of Terms](#glossary-of-terms) - - [References and Resources](#references-and-resources) - -### General Concept +## Table of Contents + +- [General Concept](#general-concept) +- [Prerequisites](#prerequisites) + - [Verifiable Credentials Data Model](#verifiable-credentials-data-model) + - [Verifiable Presentations Data Model](#verifiable-presentations-data-model) + - [DIF Presentation Format](#dif-presentation-format) +- [Preparing to Issue a Credential](#preparing-to-issue-a-credential) + - [VC-DI Context](#vc-di-context) + - [Signature Suite](#signature-suite) + - [DID Method](#did-method) + - [`did:key`](#didkey) +- [Issue a Credential](#issue-a-credential) +- [Verify a Credential](#verify-a-credential) +- [Present Proof](#present-proof) + - [Requesting Proof](#requesting-proof) + - [Presenting Proof](#presenting-proof) + - [Verifying Proof](#verifying-proof) +- [Appendix](#appendix) + - [Glossary of Terms](#glossary-of-terms) + - [References and Resources](#references-and-resources) + +## General Concept The introduction of VC-DI credentials in ACA-Py facilitates the issuance of credentials and presentations in adherence to the W3C standard. -### Prerequisites +## Prerequisites Before utilizing this feature, it is essential to have the following: -#### Verifiable Credentials Data Model +### Verifiable Credentials Data Model A basic understanding of the Verifiable Credentials Data Model is required. Resources for reference include: - [Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/) -#### Verifiable Presentations Data Model +### Verifiable Presentations Data Model Familiarity with the Verifiable Presentations Data Model is necessary. Relevant resources can be found at: - [Verifiable Presentations Data Model](https://www.w3.org/TR/vc-data-model/#presentations) -#### DIF Presentation Format +### DIF Presentation Format Understanding the DIF Presentation Format is recommended. Access resources at: - [DIF Presentation Format](https://identity.foundation/presentation-exchange/) -### Preparing to Issue a Credential +## Preparing to Issue a Credential To prepare for credential issuance, the following steps must be taken: -#### VC-DI Context +### VC-DI Context Ensure that every property key in the document is mappable to an IRI. This requires either the property key to be an IRI by default or to have the shorthand property mapped in the `@context` of the document. @@ -72,17 +70,17 @@ Ensure that every property key in the document is mappable to an IRI. This requi } ``` -#### Signature Suite +### Signature Suite Select a signature suite for use. VC-DI format currently supports EdDSA signature suites for issuing credentials. - [`Ed25519Signature2020`](https://w3c.github.io/vc-di-eddsa/#ed25519signature2020-0) -#### DID Method +### DID Method Choose a DID method for issuing the credential. VC-DI format currently supports the `did:key` method. -##### `did:key` +#### `did:key` A `did:key` did is not anchored to a ledger, but embeds the key directly in the identifier part of the did. See the [did:key Method Specification](https://w3c-ccg.github.io/did-method-key/) for more information. @@ -97,7 +95,7 @@ You can create a `did:key` using the `/wallet/did/create` endpoint with the foll } ``` -### Issue a Credential +## Issue a Credential The issuance of W3C credentials is facilitated through the `/issue-credential-2.0/send` endpoint. This process adheres to the formats described in [RFC 0809 VC-DI](https://github.com/hyperledger/aries-rfcs/blob/main/features/0809-w3c-data-integrity-credential-attachment/README.md) and utilizes `didcomm` for communication between agents. @@ -184,7 +182,7 @@ The response should confirm the credential issuance. ``` -### Verify a Credential +## Verify a Credential To verify a credential, follow these steps: @@ -303,9 +301,9 @@ The response should confirm the credential verification. ``` -### Present Proof +## Present Proof -#### Requesting Proof +### Requesting Proof To request proof, follow these steps: @@ -399,7 +397,7 @@ To request proof, follow these steps: ``` -#### Presenting Proof +### Presenting Proof To present proof, follow these steps: @@ -499,7 +497,7 @@ To present proof, follow these steps: ``` -#### Verifying Proof +### Verifying Proof To verify presented proof, follow these steps: @@ -621,9 +619,9 @@ To verify presented proof, follow these steps: ``` -### Appendix +## Appendix -#### Glossary of Terms +### Glossary of Terms - **VC-DI:** Verifiable Credential Data Integrity - **W3C:** World Wide Web Consortium @@ -631,7 +629,7 @@ To verify presented proof, follow these steps: - **EdDSA:** Edwards-curve Digital Signature Algorithm - **DIF:** Decentralized Identity Foundation -#### References and Resources +### References and Resources - [ACA-Py Documentation](https://aca-py.org) - [Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/) diff --git a/docs/generated/acapy_agent.anoncreds.models.rst b/docs/generated/acapy_agent.anoncreds.models.rst index 0539f9285a..58f7a28113 100644 --- a/docs/generated/acapy_agent.anoncreds.models.rst +++ b/docs/generated/acapy_agent.anoncreds.models.rst @@ -9,26 +9,106 @@ acapy\_agent.anoncreds.models package Submodules ---------- -acapy\_agent.anoncreds.models.anoncreds\_cred\_def module +acapy\_agent.anoncreds.models.credential module +----------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.credential + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.credential\_definition module +----------------------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.credential_definition + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.credential\_offer module +------------------------------------------------------ + +.. automodule:: acapy_agent.anoncreds.models.credential_offer + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.credential\_proposal module --------------------------------------------------------- -.. automodule:: acapy_agent.anoncreds.models.anoncreds_cred_def +.. automodule:: acapy_agent.anoncreds.models.credential_proposal + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.credential\_request module +-------------------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.credential_request + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.non\_rev\_interval module +------------------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.non_rev_interval :members: :undoc-members: :show-inheritance: -acapy\_agent.anoncreds.models.anoncreds\_revocation module +acapy\_agent.anoncreds.models.predicate module +---------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.predicate + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.presentation\_request module ---------------------------------------------------------- -.. automodule:: acapy_agent.anoncreds.models.anoncreds_revocation +.. automodule:: acapy_agent.anoncreds.models.presentation_request :members: :undoc-members: :show-inheritance: -acapy\_agent.anoncreds.models.anoncreds\_schema module ------------------------------------------------------- +acapy\_agent.anoncreds.models.proof module +------------------------------------------ + +.. automodule:: acapy_agent.anoncreds.models.proof + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.requested\_credentials module +----------------------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.requested_credentials + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.revocation module +----------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.revocation + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.schema module +------------------------------------------- + +.. automodule:: acapy_agent.anoncreds.models.schema + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.anoncreds.models.utils module +------------------------------------------ -.. automodule:: acapy_agent.anoncreds.models.anoncreds_schema +.. automodule:: acapy_agent.anoncreds.models.utils :members: :undoc-members: :show-inheritance: diff --git a/docs/generated/acapy_agent.config.logging.rst b/docs/generated/acapy_agent.config.logging.rst new file mode 100644 index 0000000000..3db38f2b8b --- /dev/null +++ b/docs/generated/acapy_agent.config.logging.rst @@ -0,0 +1,42 @@ +acapy\_agent.config.logging package +=================================== + +.. automodule:: acapy_agent.config.logging + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +acapy\_agent.config.logging.base module +--------------------------------------- + +.. automodule:: acapy_agent.config.logging.base + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.config.logging.configurator module +----------------------------------------------- + +.. automodule:: acapy_agent.config.logging.configurator + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.config.logging.filters module +------------------------------------------ + +.. automodule:: acapy_agent.config.logging.filters + :members: + :undoc-members: + :show-inheritance: + +acapy\_agent.config.logging.timed\_rotating\_file\_multi\_process\_handler module +--------------------------------------------------------------------------------- + +.. automodule:: acapy_agent.config.logging.timed_rotating_file_multi_process_handler + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/generated/acapy_agent.config.rst b/docs/generated/acapy_agent.config.rst index ad606129b8..51d632e56b 100644 --- a/docs/generated/acapy_agent.config.rst +++ b/docs/generated/acapy_agent.config.rst @@ -6,6 +6,14 @@ acapy\_agent.config package :undoc-members: :show-inheritance: +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + acapy_agent.config.logging + Submodules ---------- @@ -81,14 +89,6 @@ acapy\_agent.config.ledger module :undoc-members: :show-inheritance: -acapy\_agent.config.logging module ----------------------------------- - -.. automodule:: acapy_agent.config.logging - :members: - :undoc-members: - :show-inheritance: - acapy\_agent.config.plugin\_settings module ------------------------------------------- diff --git a/docs/generated/acapy_agent.core.in_memory.didcomm.rst b/docs/generated/acapy_agent.core.in_memory.didcomm.rst deleted file mode 100644 index 3842f254f3..0000000000 --- a/docs/generated/acapy_agent.core.in_memory.didcomm.rst +++ /dev/null @@ -1,26 +0,0 @@ -acapy\_agent.core.in\_memory.didcomm package -============================================ - -.. automodule:: acapy_agent.core.in_memory.didcomm - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -acapy\_agent.core.in\_memory.didcomm.derive\_1pu module -------------------------------------------------------- - -.. automodule:: acapy_agent.core.in_memory.didcomm.derive_1pu - :members: - :undoc-members: - :show-inheritance: - -acapy\_agent.core.in\_memory.didcomm.derive\_ecdh module --------------------------------------------------------- - -.. automodule:: acapy_agent.core.in_memory.didcomm.derive_ecdh - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/generated/acapy_agent.core.in_memory.rst b/docs/generated/acapy_agent.core.in_memory.rst deleted file mode 100644 index ea101cb0b9..0000000000 --- a/docs/generated/acapy_agent.core.in_memory.rst +++ /dev/null @@ -1,26 +0,0 @@ -acapy\_agent.core.in\_memory package -==================================== - -.. automodule:: acapy_agent.core.in_memory - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - acapy_agent.core.in_memory.didcomm - -Submodules ----------- - -acapy\_agent.core.in\_memory.profile module -------------------------------------------- - -.. automodule:: acapy_agent.core.in_memory.profile - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/generated/acapy_agent.core.rst b/docs/generated/acapy_agent.core.rst index 6dbd9e3fb6..aea168d472 100644 --- a/docs/generated/acapy_agent.core.rst +++ b/docs/generated/acapy_agent.core.rst @@ -6,14 +6,6 @@ acapy\_agent.core package :undoc-members: :show-inheritance: -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - acapy_agent.core.in_memory - Submodules ---------- diff --git a/docs/generated/acapy_agent.protocols.issue_credential.v2_0.models.detail.rst b/docs/generated/acapy_agent.protocols.issue_credential.v2_0.models.detail.rst index 52d5cd892d..464c0f5161 100644 --- a/docs/generated/acapy_agent.protocols.issue_credential.v2_0.models.detail.rst +++ b/docs/generated/acapy_agent.protocols.issue_credential.v2_0.models.detail.rst @@ -9,6 +9,14 @@ acapy\_agent.protocols.issue\_credential.v2\_0.models.detail package Submodules ---------- +acapy\_agent.protocols.issue\_credential.v2\_0.models.detail.anoncreds module +----------------------------------------------------------------------------- + +.. automodule:: acapy_agent.protocols.issue_credential.v2_0.models.detail.anoncreds + :members: + :undoc-members: + :show-inheritance: + acapy\_agent.protocols.issue\_credential.v2\_0.models.detail.indy module ------------------------------------------------------------------------ diff --git a/docs/generated/acapy_agent.resolver.default.rst b/docs/generated/acapy_agent.resolver.default.rst index 78165b9692..32a0f44cc9 100644 --- a/docs/generated/acapy_agent.resolver.default.rst +++ b/docs/generated/acapy_agent.resolver.default.rst @@ -73,6 +73,14 @@ acapy\_agent.resolver.default.peer4 module :undoc-members: :show-inheritance: +acapy\_agent.resolver.default.tdw module +---------------------------------------- + +.. automodule:: acapy_agent.resolver.default.tdw + :members: + :undoc-members: + :show-inheritance: + acapy\_agent.resolver.default.universal module ---------------------------------------------- diff --git a/docs/generated/acapy_agent.storage.rst b/docs/generated/acapy_agent.storage.rst index 95998a741d..8eda05694e 100644 --- a/docs/generated/acapy_agent.storage.rst +++ b/docs/generated/acapy_agent.storage.rst @@ -41,14 +41,6 @@ acapy\_agent.storage.error module :undoc-members: :show-inheritance: -acapy\_agent.storage.in\_memory module --------------------------------------- - -.. automodule:: acapy_agent.storage.in_memory - :members: - :undoc-members: - :show-inheritance: - acapy\_agent.storage.record module ---------------------------------- diff --git a/docs/generated/acapy_agent.storage.vc_holder.rst b/docs/generated/acapy_agent.storage.vc_holder.rst index ca74bd8aed..3a1b74eff5 100644 --- a/docs/generated/acapy_agent.storage.vc_holder.rst +++ b/docs/generated/acapy_agent.storage.vc_holder.rst @@ -25,14 +25,6 @@ acapy\_agent.storage.vc\_holder.base module :undoc-members: :show-inheritance: -acapy\_agent.storage.vc\_holder.in\_memory module -------------------------------------------------- - -.. automodule:: acapy_agent.storage.vc_holder.in_memory - :members: - :undoc-members: - :show-inheritance: - acapy\_agent.storage.vc\_holder.vc\_record module ------------------------------------------------- diff --git a/docs/generated/acapy_agent.utils.rst b/docs/generated/acapy_agent.utils.rst index 70c61f2d1a..4a8fd038e3 100644 --- a/docs/generated/acapy_agent.utils.rst +++ b/docs/generated/acapy_agent.utils.rst @@ -49,6 +49,14 @@ acapy\_agent.utils.env module :undoc-members: :show-inheritance: +acapy\_agent.utils.extract\_validation\_error module +---------------------------------------------------- + +.. automodule:: acapy_agent.utils.extract_validation_error + :members: + :undoc-members: + :show-inheritance: + acapy\_agent.utils.general module --------------------------------- @@ -121,6 +129,14 @@ acapy\_agent.utils.task\_queue module :undoc-members: :show-inheritance: +acapy\_agent.utils.testing module +--------------------------------- + +.. automodule:: acapy_agent.utils.testing + :members: + :undoc-members: + :show-inheritance: + acapy\_agent.utils.tracing module --------------------------------- diff --git a/docs/generated/acapy_agent.wallet.rst b/docs/generated/acapy_agent.wallet.rst index 9f075046ae..d09130188d 100644 --- a/docs/generated/acapy_agent.wallet.rst +++ b/docs/generated/acapy_agent.wallet.rst @@ -106,14 +106,6 @@ acapy\_agent.wallet.error module :undoc-members: :show-inheritance: -acapy\_agent.wallet.in\_memory module -------------------------------------- - -.. automodule:: acapy_agent.wallet.in_memory - :members: - :undoc-members: - :show-inheritance: - acapy\_agent.wallet.jwt module ------------------------------ diff --git a/mkdocs.yml b/mkdocs.yml index 0f8593cb94..cebeffcc7e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -97,6 +97,7 @@ nav: - Configuring Multiple Indy Ledgers: features/Multiledger.md - Automatically Endorsing Indy Transations: features/Endorser.md - Using W3C JSON-LD Signed Credentials: features/JsonLdCredentials.md + - Issuing and Presenting W3C Data Integrity VCs: features/W3cCredentials.md - Using SD-JWTs: features/SelectiveDisclosureJWTs.md - AnonCreds Presentation Validation: features/AnoncredsProofValidation.md - Multiple Credential Types: features/Multicredentials.md diff --git a/open-api/openapi.json b/open-api/openapi.json index 444c97fbbe..97913e91f2 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -2,7 +2,7 @@ "openapi" : "3.0.1", "info" : { "title" : "Aries Cloud Agent", - "version" : "v1.1.0" + "version" : "v1.1.1" }, "servers" : [ { "url" : "/" @@ -390,7 +390,7 @@ "description" : "" } }, - "summary" : "Create a credential definition on the connected ledger", + "summary" : "Create a credential definition on the connected datastore", "tags" : [ "anoncreds - credential definitions" ], "x-codegen-request-body-name" : "body" } @@ -549,7 +549,7 @@ "description" : "" } }, - "summary" : "Create and publish a revocation status list on the connected ledger", + "summary" : "Create and publish a revocation status list on the connected datastore", "tags" : [ "anoncreds - revocation" ], "x-codegen-request-body-name" : "body" } @@ -578,7 +578,7 @@ "description" : "" } }, - "summary" : "Create and publish a registration revocation on the connected ledger", + "summary" : "Create and publish a registration revocation on the connected datastore", "tags" : [ "anoncreds - revocation" ], "x-codegen-request-body-name" : "body" } @@ -1012,7 +1012,7 @@ "description" : "" } }, - "summary" : "Create a schema on the connected ledger", + "summary" : "Create a schema on the connected datastore", "tags" : [ "anoncreds - schemas" ], "x-codegen-request-body-name" : "body" } @@ -7747,7 +7747,7 @@ }, "issuerId" : { "description" : "Issuer Identifier of the credential definition or schema", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "type" : "string" }, "name" : { @@ -7763,6 +7763,170 @@ }, "type" : "object" }, + "AnoncredPresentationRequestNonRevoked" : { + "properties" : { + "from" : { + "description" : "Earliest time of interest in non-revocation interval", + "example" : 1640995199, + "maximum" : 18446744073709551615, + "minimum" : 0, + "type" : "integer" + }, + "to" : { + "description" : "Latest time of interest in non-revocation interval", + "example" : 1640995199, + "maximum" : 18446744073709551615, + "minimum" : 0, + "type" : "integer" + } + }, + "type" : "object" + }, + "AnoncredsPresentationReqAttrSpec" : { + "properties" : { + "name" : { + "description" : "Attribute name", + "example" : "favouriteDrink", + "type" : "string" + }, + "names" : { + "description" : "Attribute name group", + "items" : { + "example" : "age", + "type" : "string" + }, + "type" : "array" + }, + "non_revoked" : { + "$ref" : "#/components/schemas/AnoncredsPresentationReqAttrSpecNonRevoked" + }, + "restrictions" : { + "description" : "If present, credential must satisfy one of given restrictions: specify schema_id, schema_issuer_did, schema_name, schema_version, issuer_did, cred_def_id, and/or attr::::value where represents a credential attribute name", + "items" : { + "additionalProperties" : { + "example" : "did:(method):3:CL:20:tag", + "type" : "string" + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "AnoncredsPresentationReqAttrSpecNonRevoked" : { + "properties" : { + "from" : { + "description" : "Earliest time of interest in non-revocation interval", + "example" : 1640995199, + "maximum" : 18446744073709551615, + "minimum" : 0, + "type" : "integer" + }, + "to" : { + "description" : "Latest time of interest in non-revocation interval", + "example" : 1640995199, + "maximum" : 18446744073709551615, + "minimum" : 0, + "type" : "integer" + } + }, + "type" : "object" + }, + "AnoncredsPresentationReqPredSpec" : { + "properties" : { + "name" : { + "description" : "Attribute name", + "example" : "index", + "type" : "string" + }, + "non_revoked" : { + "$ref" : "#/components/schemas/AnoncredsPresentationReqPredSpecNonRevoked" + }, + "p_type" : { + "description" : "Predicate type ('<', '<=', '>=', or '>')", + "enum" : [ "<", "<=", ">=", ">" ], + "example" : ">=", + "type" : "string" + }, + "p_value" : { + "description" : "Threshold value", + "type" : "integer" + }, + "restrictions" : { + "description" : "If present, credential must satisfy one of given restrictions: specify schema_id, schema_issuer_did, schema_name, schema_version, issuer_did, cred_def_id, and/or attr::::value where represents a credential attribute name", + "items" : { + "additionalProperties" : { + "example" : "did:(method):3:CL:20:tag", + "type" : "string" + }, + "type" : "object" + }, + "type" : "array" + } + }, + "required" : [ "name", "p_type", "p_value" ], + "type" : "object" + }, + "AnoncredsPresentationReqPredSpecNonRevoked" : { + "properties" : { + "from" : { + "description" : "Earliest time of interest in non-revocation interval", + "example" : 1640995199, + "maximum" : 18446744073709551615, + "minimum" : 0, + "type" : "integer" + }, + "to" : { + "description" : "Latest time of interest in non-revocation interval", + "example" : 1640995199, + "maximum" : 18446744073709551615, + "minimum" : 0, + "type" : "integer" + } + }, + "type" : "object" + }, + "AnoncredsPresentationRequest" : { + "properties" : { + "name" : { + "description" : "Proof request name", + "example" : "Proof request", + "type" : "string" + }, + "non_revoked" : { + "$ref" : "#/components/schemas/AnoncredPresentationRequestNonRevoked" + }, + "nonce" : { + "description" : "Nonce", + "example" : "1", + "pattern" : "^[1-9][0-9]*$", + "type" : "string" + }, + "requested_attributes" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/AnoncredsPresentationReqAttrSpec" + }, + "description" : "Requested attribute specifications of proof request", + "type" : "object" + }, + "requested_predicates" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/AnoncredsPresentationReqPredSpec" + }, + "description" : "Requested predicate specifications of proof request", + "type" : "object" + }, + "version" : { + "description" : "Proof request version", + "example" : "1.0", + "pattern" : "^[0-9.]+$", + "type" : "string" + } + }, + "required" : [ "requested_attributes", "requested_predicates" ], + "type" : "object" + }, "AttachDecorator" : { "properties" : { "@id" : { @@ -8376,12 +8540,12 @@ "type" : "string" }, "kid" : { - "description" : "Optional kid to bind to the keypair, such as a verificationMethod.", + "description" : "Optional kid to bind to the keypair, such as a verificationMethod.", "example" : "did:web:example.com#key-01", "type" : "string" }, "seed" : { - "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode.", + "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode.", "example" : "00000000000000000000000000000000", "type" : "string" } @@ -8450,7 +8614,7 @@ }, "wallet_type" : { "description" : "Type of the wallet to create. Must be same as base wallet.", - "enum" : [ "askar", "askar-anoncreds", "in_memory" ], + "enum" : [ "askar", "askar-anoncreds" ], "example" : "askar", "type" : "string" }, @@ -8555,12 +8719,12 @@ "properties" : { "issuerId" : { "description" : "Issuer Identifier of the credential definition or schema", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "type" : "string" }, "schemaId" : { "description" : "Schema identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "type" : "string" }, "tag" : { @@ -8643,7 +8807,7 @@ }, "credential_definition_id" : { "description" : "credential definition id", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "example" : "did:(method):3:CL:20:tag", "nullable" : true, "type" : "string" }, @@ -9322,7 +9486,7 @@ "type" : "string" }, "mediation_id" : { - "description" : "Medation ID to use for endpoint information.", + "description" : "Mediation ID to use for endpoint information.", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", "type" : "string" @@ -9553,47 +9717,47 @@ "additionalProperties" : true, "properties" : { "challenge" : { - "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks.", + "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks.", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", "type" : "string" }, "created" : { - "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string", + "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string", "example" : "2010-01-01T19:23:24Z", "type" : "string" }, "cryptosuite" : { - "description" : "An identifier for the cryptographic suite that can be used to verify the proof.", + "description" : "An identifier for the cryptographic suite that can be used to verify the proof.", "example" : "eddsa-jcs-2022", "type" : "string" }, "domain" : { - "description" : "It conveys one or more security domains in which the proof is meant to be used.", + "description" : "It conveys one or more security domains in which the proof is meant to be used.", "example" : "example.com", "type" : "string" }, "expires" : { - "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string", + "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string", "example" : "2010-01-01T19:23:24Z", "type" : "string" }, "id" : { - "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN", + "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", "type" : "string" }, "nonce" : { - "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures.", + "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures.", "example" : "CF69iO3nfvqRsRBNElE8b4wO39SyJHPM7Gg1nExltW5vSfQA1lvDCR/zXX1To0/4NLo==", "type" : "string" }, "previousProof" : { - "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed.", + "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed.", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", "type" : "string" }, "proofPurpose" : { - "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended.", + "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended.", "example" : "assertionMethod", "type" : "string" }, @@ -9603,12 +9767,12 @@ "type" : "string" }, "type" : { - "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL].", + "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL].", "example" : "DataIntegrityProof", "type" : "string" }, "verificationMethod" : { - "description" : "A verification method is the means and information needed to verify the proof. ", + "description" : "A verification method is the means and information needed to verify the proof.", "example" : "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL", "pattern" : "\\w+:(\\/?\\/?)[^\\s]+", "type" : "string" @@ -9862,7 +10026,7 @@ }, "credential_definition_id" : { "description" : "credential definition id", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "example" : "did:(method):3:CL:20:tag", "type" : "string" }, "credential_definitions_metadata" : { @@ -9935,7 +10099,7 @@ }, "schema_id" : { "description" : "Schema identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "type" : "string" }, "schema_metadata" : { @@ -9950,7 +10114,7 @@ "schema_ids" : { "items" : { "description" : "Schema identifiers", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "type" : "string" }, "type" : "array" @@ -11015,12 +11179,12 @@ "properties" : { "issuerId" : { "description" : "Issuer Identifier of the credential definition", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "type" : "string" }, "schemaId" : { "description" : "Schema identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "type" : "string" }, "tag" : { @@ -11036,12 +11200,12 @@ "properties" : { "credDefId" : { "description" : "Credential definition identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "type" : "string" }, "issuerId" : { "description" : "Issuer Identifier of the credential definition or schema", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "type" : "string" }, "maxCredNum" : { @@ -12813,12 +12977,12 @@ }, "issuerId" : { "description" : "Issuer Identifier of the credential definition or schema", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "type" : "string" }, "revRegDefId" : { "description" : "The ID of the revocation registry definition", - "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "example" : "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0", "type" : "string" }, "revocationList" : { @@ -12843,7 +13007,7 @@ }, "rev_reg_def_id" : { "description" : "Revocation registry definition identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "example" : "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0", "type" : "string" } }, @@ -12932,12 +13096,12 @@ "properties" : { "credDefId" : { "description" : "Credential definition identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "example" : "did:(method):3:CL:20:tag", "type" : "string" }, "issuerId" : { "description" : "Issuer Identifier of the credential definition or schema", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "type" : "string" }, "revocDefType" : { @@ -12999,7 +13163,7 @@ }, "revocation_registry_definition_id" : { "description" : "revocation registry definition id", - "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "example" : "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0", "type" : "string" }, "state" : { @@ -13559,7 +13723,7 @@ }, "schema_id" : { "description" : "Schema identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "type" : "string" }, "state" : { @@ -14085,7 +14249,7 @@ "UpdateKeyRequest" : { "properties" : { "kid" : { - "description" : "New kid to bind to the key pair, such as a verificationMethod.", + "description" : "New kid to bind to the key pair, such as a verificationMethod.", "example" : "did:web:example.com#key-02", "type" : "string" }, @@ -15335,6 +15499,13 @@ }, "V20CredFilter" : { "properties" : { + "anoncreds" : { + "allOf" : [ { + "$ref" : "#/components/schemas/V20CredFilterAnoncreds" + } ], + "description" : "Credential filter for anoncreds", + "type" : "object" + }, "indy" : { "allOf" : [ { "$ref" : "#/components/schemas/V20CredFilterIndy" @@ -15359,6 +15530,31 @@ }, "type" : "object" }, + "V20CredFilterAnoncreds" : { + "properties" : { + "cred_def_id" : { + "description" : "Credential definition identifier", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", + "type" : "string" + }, + "epoch" : { + "description" : "Credential epoch time", + "example" : "2021-08-24", + "type" : "string" + }, + "issuer_id" : { + "description" : "Credential issuer DID", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", + "type" : "string" + }, + "schema_id" : { + "description" : "Schema identifier", + "example" : "did:(method):2:schema_name:1.0", + "type" : "string" + } + }, + "type" : "object" + }, "V20CredFilterIndy" : { "properties" : { "cred_def_id" : { @@ -16192,6 +16388,13 @@ }, "V20PresProposalByFormat" : { "properties" : { + "anoncreds" : { + "allOf" : [ { + "$ref" : "#/components/schemas/AnoncredsPresentationRequest" + } ], + "description" : "Presentation proposal for anoncreds", + "type" : "object" + }, "dif" : { "allOf" : [ { "$ref" : "#/components/schemas/DIFProofProposal" @@ -16281,6 +16484,13 @@ }, "V20PresRequestByFormat" : { "properties" : { + "anoncreds" : { + "allOf" : [ { + "$ref" : "#/components/schemas/AnoncredsPresentationRequest" + } ], + "description" : "Presentation proposal for anoncreds", + "type" : "object" + }, "dif" : { "allOf" : [ { "$ref" : "#/components/schemas/DIFProofRequest" @@ -16332,6 +16542,13 @@ }, "V20PresSpecByFormatRequest" : { "properties" : { + "anoncreds" : { + "allOf" : [ { + "$ref" : "#/components/schemas/IndyPresSpec" + } ], + "description" : "Presentation specification for anoncreds", + "type" : "object" + }, "auto_remove" : { "description" : "Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting)", "type" : "boolean" diff --git a/open-api/swagger.json b/open-api/swagger.json index 3267ac846e..fd4823dd48 100644 --- a/open-api/swagger.json +++ b/open-api/swagger.json @@ -1,7 +1,7 @@ { "swagger" : "2.0", "info" : { - "version" : "v1.1.0", + "version" : "v1.1.1", "title" : "Aries Cloud Agent" }, "tags" : [ { @@ -333,7 +333,7 @@ "/anoncreds/credential-definition" : { "post" : { "tags" : [ "anoncreds - credential definitions" ], - "summary" : "Create a credential definition on the connected ledger", + "summary" : "Create a credential definition on the connected datastore", "produces" : [ "application/json" ], "parameters" : [ { "in" : "body", @@ -464,7 +464,7 @@ "/anoncreds/revocation-list" : { "post" : { "tags" : [ "anoncreds - revocation" ], - "summary" : "Create and publish a revocation status list on the connected ledger", + "summary" : "Create and publish a revocation status list on the connected datastore", "produces" : [ "application/json" ], "parameters" : [ { "in" : "body", @@ -487,7 +487,7 @@ "/anoncreds/revocation-registry-definition" : { "post" : { "tags" : [ "anoncreds - revocation" ], - "summary" : "Create and publish a registration revocation on the connected ledger", + "summary" : "Create and publish a registration revocation on the connected datastore", "produces" : [ "application/json" ], "parameters" : [ { "in" : "body", @@ -843,7 +843,7 @@ "/anoncreds/schema" : { "post" : { "tags" : [ "anoncreds - schemas" ], - "summary" : "Create a schema on the connected ledger", + "summary" : "Create a schema on the connected datastore", "produces" : [ "application/json" ], "parameters" : [ { "in" : "body", @@ -6381,7 +6381,7 @@ }, "issuerId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "description" : "Issuer Identifier of the credential definition or schema" }, "name" : { @@ -6396,6 +6396,170 @@ } } }, + "AnoncredPresentationRequestNonRevoked" : { + "type" : "object", + "properties" : { + "from" : { + "type" : "integer", + "example" : 1640995199, + "description" : "Earliest time of interest in non-revocation interval", + "minimum" : 0, + "maximum" : 18446744073709551615 + }, + "to" : { + "type" : "integer", + "example" : 1640995199, + "description" : "Latest time of interest in non-revocation interval", + "minimum" : 0, + "maximum" : 18446744073709551615 + } + } + }, + "AnoncredsPresentationReqAttrSpec" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string", + "example" : "favouriteDrink", + "description" : "Attribute name" + }, + "names" : { + "type" : "array", + "description" : "Attribute name group", + "items" : { + "type" : "string", + "example" : "age" + } + }, + "non_revoked" : { + "$ref" : "#/definitions/AnoncredsPresentationReqAttrSpecNonRevoked" + }, + "restrictions" : { + "type" : "array", + "description" : "If present, credential must satisfy one of given restrictions: specify schema_id, schema_issuer_did, schema_name, schema_version, issuer_did, cred_def_id, and/or attr::::value where represents a credential attribute name", + "items" : { + "type" : "object", + "additionalProperties" : { + "type" : "string", + "example" : "did:(method):3:CL:20:tag" + } + } + } + } + }, + "AnoncredsPresentationReqAttrSpecNonRevoked" : { + "type" : "object", + "properties" : { + "from" : { + "type" : "integer", + "example" : 1640995199, + "description" : "Earliest time of interest in non-revocation interval", + "minimum" : 0, + "maximum" : 18446744073709551615 + }, + "to" : { + "type" : "integer", + "example" : 1640995199, + "description" : "Latest time of interest in non-revocation interval", + "minimum" : 0, + "maximum" : 18446744073709551615 + } + } + }, + "AnoncredsPresentationReqPredSpec" : { + "type" : "object", + "required" : [ "name", "p_type", "p_value" ], + "properties" : { + "name" : { + "type" : "string", + "example" : "index", + "description" : "Attribute name" + }, + "non_revoked" : { + "$ref" : "#/definitions/AnoncredsPresentationReqPredSpecNonRevoked" + }, + "p_type" : { + "type" : "string", + "example" : ">=", + "description" : "Predicate type ('<', '<=', '>=', or '>')", + "enum" : [ "<", "<=", ">=", ">" ] + }, + "p_value" : { + "type" : "integer", + "description" : "Threshold value" + }, + "restrictions" : { + "type" : "array", + "description" : "If present, credential must satisfy one of given restrictions: specify schema_id, schema_issuer_did, schema_name, schema_version, issuer_did, cred_def_id, and/or attr::::value where represents a credential attribute name", + "items" : { + "type" : "object", + "additionalProperties" : { + "type" : "string", + "example" : "did:(method):3:CL:20:tag" + } + } + } + } + }, + "AnoncredsPresentationReqPredSpecNonRevoked" : { + "type" : "object", + "properties" : { + "from" : { + "type" : "integer", + "example" : 1640995199, + "description" : "Earliest time of interest in non-revocation interval", + "minimum" : 0, + "maximum" : 18446744073709551615 + }, + "to" : { + "type" : "integer", + "example" : 1640995199, + "description" : "Latest time of interest in non-revocation interval", + "minimum" : 0, + "maximum" : 18446744073709551615 + } + } + }, + "AnoncredsPresentationRequest" : { + "type" : "object", + "required" : [ "requested_attributes", "requested_predicates" ], + "properties" : { + "name" : { + "type" : "string", + "example" : "Proof request", + "description" : "Proof request name" + }, + "non_revoked" : { + "$ref" : "#/definitions/AnoncredPresentationRequestNonRevoked" + }, + "nonce" : { + "type" : "string", + "example" : "1", + "description" : "Nonce", + "pattern" : "^[1-9][0-9]*$" + }, + "requested_attributes" : { + "type" : "object", + "description" : "Requested attribute specifications of proof request", + "additionalProperties" : { + "$ref" : "#/definitions/AnoncredsPresentationReqAttrSpec" + } + }, + "requested_predicates" : { + "type" : "object", + "description" : "Requested predicate specifications of proof request", + "additionalProperties" : { + "$ref" : "#/definitions/AnoncredsPresentationReqPredSpec" + } + }, + "version" : { + "type" : "string", + "example" : "1.0", + "description" : "Proof request version", + "pattern" : "^[0-9.]+$" + } + } + }, "AttachDecorator" : { "type" : "object", "required" : [ "data" ], @@ -7007,12 +7171,12 @@ "kid" : { "type" : "string", "example" : "did:web:example.com#key-01", - "description" : "Optional kid to bind to the keypair, such as a verificationMethod." + "description" : "Optional kid to bind to the keypair, such as a verificationMethod." }, "seed" : { "type" : "string", "example" : "00000000000000000000000000000000", - "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode." + "description" : "Optional seed to generate the key pair. Must enable insecure wallet mode." } } }, @@ -7081,7 +7245,7 @@ "type" : "string", "example" : "askar", "description" : "Type of the wallet to create. Must be same as base wallet.", - "enum" : [ "askar", "askar-anoncreds", "in_memory" ] + "enum" : [ "askar", "askar-anoncreds" ] }, "wallet_webhook_urls" : { "type" : "array", @@ -7184,12 +7348,12 @@ "properties" : { "issuerId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "description" : "Issuer Identifier of the credential definition or schema" }, "schemaId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "description" : "Schema identifier" }, "tag" : { @@ -7268,7 +7432,7 @@ }, "credential_definition_id" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "example" : "did:(method):3:CL:20:tag", "description" : "credential definition id", "x-nullable" : true }, @@ -7909,7 +8073,7 @@ "mediation_id" : { "type" : "string", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "description" : "Medation ID to use for endpoint information.", + "description" : "Mediation ID to use for endpoint information.", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } } @@ -8135,47 +8299,47 @@ "challenge" : { "type" : "string", "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks." + "description" : "The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks." }, "created" : { "type" : "string", "example" : "2010-01-01T19:23:24Z", - "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string" + "description" : "The date and time the proof was created is OPTIONAL and, if included, MUST be specified as an [XMLSCHEMA11-2] dateTimeStamp string" }, "cryptosuite" : { "type" : "string", "example" : "eddsa-jcs-2022", - "description" : "An identifier for the cryptographic suite that can be used to verify the proof." + "description" : "An identifier for the cryptographic suite that can be used to verify the proof." }, "domain" : { "type" : "string", "example" : "example.com", - "description" : "It conveys one or more security domains in which the proof is meant to be used." + "description" : "It conveys one or more security domains in which the proof is meant to be used." }, "expires" : { "type" : "string", "example" : "2010-01-01T19:23:24Z", - "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string" + "description" : "The expires property is OPTIONAL and, if present, specifies when the proof expires. If present, it MUST be an [XMLSCHEMA11-2] dateTimeStamp string" }, "id" : { "type" : "string", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", - "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN" + "description" : "An optional identifier for the proof, which MUST be a URL [URL], such as a UUID as a URN" }, "nonce" : { "type" : "string", "example" : "CF69iO3nfvqRsRBNElE8b4wO39SyJHPM7Gg1nExltW5vSfQA1lvDCR/zXX1To0/4NLo==", - "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures." + "description" : "One use of this field is to increase privacy by decreasing linkability that is the result of deterministically generated signatures." }, "previousProof" : { "type" : "string", "example" : "urn:uuid:6a1676b8-b51f-11ed-937b-d76685a20ff5", - "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed." + "description" : "Each value identifies another data integrity proof that MUST verify before the current proof is processed." }, "proofPurpose" : { "type" : "string", "example" : "assertionMethod", - "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended." + "description" : "The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended." }, "proofValue" : { "type" : "string", @@ -8185,12 +8349,12 @@ "type" : { "type" : "string", "example" : "DataIntegrityProof", - "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL]." + "description" : "The specific type of proof MUST be specified as a string that maps to a URL [URL]." }, "verificationMethod" : { "type" : "string", "example" : "did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL", - "description" : "A verification method is the means and information needed to verify the proof. ", + "description" : "A verification method is the means and information needed to verify the proof.", "pattern" : "\\w+:(\\/?\\/?)[^\\s]+" } }, @@ -8426,7 +8590,7 @@ }, "credential_definition_id" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "example" : "did:(method):3:CL:20:tag", "description" : "credential definition id" }, "credential_definitions_metadata" : { @@ -8499,7 +8663,7 @@ }, "schema_id" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "description" : "Schema identifier" }, "schema_metadata" : { @@ -8515,7 +8679,7 @@ "type" : "array", "items" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "description" : "Schema identifiers" } } @@ -9530,12 +9694,12 @@ "properties" : { "issuerId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "description" : "Issuer Identifier of the credential definition" }, "schemaId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "description" : "Schema identifier" }, "tag" : { @@ -9550,12 +9714,12 @@ "properties" : { "credDefId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "description" : "Credential definition identifier" }, "issuerId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "description" : "Issuer Identifier of the credential definition or schema" }, "maxCredNum" : { @@ -11245,12 +11409,12 @@ }, "issuerId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "description" : "Issuer Identifier of the credential definition or schema" }, "revRegDefId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "example" : "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0", "description" : "The ID of the revocation registry definition" }, "revocationList" : { @@ -11276,7 +11440,7 @@ }, "rev_reg_def_id" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "example" : "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0", "description" : "Revocation registry definition identifier" } } @@ -11361,12 +11525,12 @@ "properties" : { "credDefId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "example" : "did:(method):3:CL:20:tag", "description" : "Credential definition identifier" }, "issuerId" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", "description" : "Issuer Identifier of the credential definition or schema" }, "revocDefType" : { @@ -11424,7 +11588,7 @@ }, "revocation_registry_definition_id" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "example" : "did:(method):4:did::3:CL:20:tag:CL_ACCUM:0", "description" : "revocation registry definition id" }, "state" : { @@ -11978,7 +12142,7 @@ }, "schema_id" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "example" : "did:(method):2:schema_name:1.0", "description" : "Schema identifier" }, "state" : { @@ -12479,7 +12643,7 @@ "kid" : { "type" : "string", "example" : "did:web:example.com#key-02", - "description" : "New kid to bind to the key pair, such as a verificationMethod." + "description" : "New kid to bind to the key pair, such as a verificationMethod." }, "multikey" : { "type" : "string", @@ -13634,6 +13798,9 @@ "V20CredFilter" : { "type" : "object", "properties" : { + "anoncreds" : { + "$ref" : "#/definitions/V20CredFilter_anoncreds" + }, "indy" : { "$ref" : "#/definitions/V20CredFilter_indy" }, @@ -13645,6 +13812,31 @@ } } }, + "V20CredFilterAnoncreds" : { + "type" : "object", + "properties" : { + "cred_def_id" : { + "type" : "string", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", + "description" : "Credential definition identifier" + }, + "epoch" : { + "type" : "string", + "example" : "2021-08-24", + "description" : "Credential epoch time" + }, + "issuer_id" : { + "type" : "string", + "example" : "did:(method):WgWxqztrNooG92RXvxSTWv", + "description" : "Credential issuer DID" + }, + "schema_id" : { + "type" : "string", + "example" : "did:(method):2:schema_name:1.0", + "description" : "Schema identifier" + } + } + }, "V20CredFilterIndy" : { "type" : "object", "properties" : { @@ -14427,6 +14619,9 @@ "V20PresProposalByFormat" : { "type" : "object", "properties" : { + "anoncreds" : { + "$ref" : "#/definitions/V20PresProposalByFormat_anoncreds" + }, "dif" : { "$ref" : "#/definitions/V20PresProposalByFormat_dif" }, @@ -14508,6 +14703,9 @@ "V20PresRequestByFormat" : { "type" : "object", "properties" : { + "anoncreds" : { + "$ref" : "#/definitions/V20PresProposalByFormat_anoncreds" + }, "dif" : { "$ref" : "#/definitions/V20PresRequestByFormat_dif" }, @@ -14551,6 +14749,9 @@ "V20PresSpecByFormatRequest" : { "type" : "object", "properties" : { + "anoncreds" : { + "$ref" : "#/definitions/V20PresSpecByFormatRequest_anoncreds" + }, "auto_remove" : { "type" : "boolean", "description" : "Whether to remove the presentation exchange record on completion (overrides --preserve-exchange-records configuration setting)" @@ -15245,6 +15446,10 @@ "type" : "object", "description" : "Credential exchange record" }, + "V20CredFilter_anoncreds" : { + "type" : "object", + "description" : "Credential filter for anoncreds" + }, "V20CredFilter_indy" : { "type" : "object", "description" : "Credential filter for indy" @@ -15281,6 +15486,10 @@ "type" : "object", "description" : "Presentation message" }, + "V20PresProposalByFormat_anoncreds" : { + "type" : "object", + "description" : "Presentation proposal for anoncreds" + }, "V20PresProposalByFormat_dif" : { "type" : "object", "description" : "Presentation proposal for DIF" @@ -15297,6 +15506,10 @@ "type" : "object", "description" : "Presentation request for indy" }, + "V20PresSpecByFormatRequest_anoncreds" : { + "type" : "object", + "description" : "Presentation specification for anoncreds" + }, "V20PresSpecByFormatRequest_dif" : { "type" : "object", "description" : "Optional Presentation specification for DIF, overrides the PresentationExchange record's PresRequest" diff --git a/pyproject.toml b/pyproject.toml index de8a3531bc..45983ccf3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "acapy_agent" -version = "1.1.0" +version = "1.1.1" description = "(ACA-Py) A Cloud Agent Python is a foundation for building decentralized identity applications and services running in non-mobile environments. " authors = [] license = "Apache-2.0" From 18d1dc97d3796140561da2b13209874071969033 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:15:20 -0800 Subject: [PATCH 125/152] Make vc libraries mandatory (#3356) * Make vc libraries mandatory Signed-off-by: jamshale * Make indy-vdr library required Signed-off-by: jamshale * Update dockerfiles after removed extras Signed-off-by: jamshale --------- Signed-off-by: jamshale --- docker/Dockerfile | 2 +- docker/Dockerfile.demo | 2 +- docker/Dockerfile.run | 2 +- docker/Dockerfile.test | 2 +- poetry.lock | 785 ++++++++++++++++++++--------------------- pyproject.toml | 12 +- 6 files changed, 401 insertions(+), 404 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index ab9dc1861a..8917d6ce7e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,7 +14,7 @@ ARG uid=1001 ARG user=aries ARG acapy_name="aries-cloudagent" ARG acapy_version -ARG acapy_reqs=[askar,didcommv2] +ARG acapy_reqs=[didcommv2] ENV HOME="/home/$user" \ APP_ROOT="$HOME" \ diff --git a/docker/Dockerfile.demo b/docker/Dockerfile.demo index cfb6c6c868..db63f2cb28 100644 --- a/docker/Dockerfile.demo +++ b/docker/Dockerfile.demo @@ -15,7 +15,7 @@ RUN pip install --no-cache-dir poetry ADD README.md pyproject.toml poetry.lock ./ ARG all_extras=0 -RUN if ! [ -z ${all_extras} ]; then poetry install --no-root --no-directory --all-extras; else poetry install --no-root --no-directory -E "askar didcommv2"; fi +RUN if ! [ -z ${all_extras} ]; then poetry install --no-root --no-directory --all-extras; else poetry install --no-root --no-directory -E "didcommv2"; fi ADD acapy_agent ./acapy_agent ADD scripts ./scripts diff --git a/docker/Dockerfile.run b/docker/Dockerfile.run index 7211df51cb..90bfb05ad9 100644 --- a/docker/Dockerfile.run +++ b/docker/Dockerfile.run @@ -19,7 +19,7 @@ ADD pyproject.toml poetry.lock README.md ./ RUN mkdir -p log && chmod -R ug+rw log ARG all_extras=0 -RUN if ! [ -z ${all_extras} ]; then poetry install --all-extras; else poetry install -E "askar didcommv2"; fi +RUN if ! [ -z ${all_extras} ]; then poetry install --all-extras; else poetry install -E "didcommv2"; fi ADD . . diff --git a/docker/Dockerfile.test b/docker/Dockerfile.test index ad8b66de2a..5351bccdcd 100644 --- a/docker/Dockerfile.test +++ b/docker/Dockerfile.test @@ -15,7 +15,7 @@ ADD ./README.md pyproject.toml ./poetry.lock ./ RUN mkdir acapy_agent && touch acapy_agent/__init__.py ARG all_extras=0 -RUN if ! [ -z ${all_extras} ]; then poetry install --no-directory --all-extras --with=dev; else poetry install --no-directory -E "askar didcommv2" --with=dev; fi +RUN if ! [ -z ${all_extras} ]; then poetry install --no-directory --all-extras --with=dev; else poetry install --no-directory -E "didcommv2" --with=dev; fi ADD . . diff --git a/poetry.lock b/poetry.lock index 09458d256f..869ff36e0e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiofiles" @@ -13,13 +13,13 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.3" +version = "2.4.4" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, - {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, + {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, + {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, ] [[package]] @@ -190,7 +190,7 @@ files = [ name = "anoncreds" version = "0.2.0" description = "" -optional = true +optional = false python-versions = ">=3.6.3" files = [ {file = "anoncreds-0.2.0-py3-none-macosx_10_9_universal2.whl", hash = "sha256:ec57e224d5f1b8749c3d6ff75bb61229a4f9c31df1ee863835f025c78ec10cd0"}, @@ -588,73 +588,73 @@ yaml = ["PyYAML"] [[package]] name = "coverage" -version = "7.6.4" +version = "7.6.8" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07"}, - {file = "coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51"}, - {file = "coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea"}, - {file = "coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a"}, - {file = "coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa"}, - {file = "coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b"}, - {file = "coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b"}, - {file = "coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db"}, - {file = "coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522"}, - {file = "coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf"}, - {file = "coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2"}, - {file = "coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27"}, - {file = "coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1"}, - {file = "coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5"}, - {file = "coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17"}, - {file = "coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9"}, - {file = "coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06"}, - {file = "coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21"}, - {file = "coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a"}, - {file = "coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e"}, - {file = "coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f"}, - {file = "coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3"}, - {file = "coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70"}, - {file = "coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef"}, - {file = "coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e"}, - {file = "coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3"}, - {file = "coverage-7.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376"}, - {file = "coverage-7.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111"}, - {file = "coverage-7.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901"}, - {file = "coverage-7.6.4-cp39-cp39-win32.whl", hash = "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09"}, - {file = "coverage-7.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f"}, - {file = "coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e"}, - {file = "coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, + {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6"}, + {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638"}, + {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed"}, + {file = "coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e"}, + {file = "coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4"}, + {file = "coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1"}, + {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a"}, + {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0"}, + {file = "coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801"}, + {file = "coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee"}, + {file = "coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb"}, + {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c"}, + {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443"}, + {file = "coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad"}, + {file = "coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"}, + {file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"}, + {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"}, + {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"}, + {file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"}, + {file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"}, + {file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"}, + {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"}, + {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"}, + {file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"}, + {file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e"}, + {file = "coverage-7.6.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779"}, + {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc"}, + {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea"}, + {file = "coverage-7.6.8-cp39-cp39-win32.whl", hash = "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e"}, + {file = "coverage-7.6.8-cp39-cp39-win_amd64.whl", hash = "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076"}, + {file = "coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce"}, + {file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"}, ] [package.extras] @@ -662,51 +662,53 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "43.0.3" +version = "44.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false -python-versions = ">=3.7" -files = [ - {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, - {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, - {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, - {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, - {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, - {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, - {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, - {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, - {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, - {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, - {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, - {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, - {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, - {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, - {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, +python-versions = "!=3.9.0,!=3.9.1,>=3.7" +files = [ + {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"}, + {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:60eb32934076fa07e4316b7b2742fa52cbb190b42c2df2863dbc4230a0a9b385"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"}, + {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"}, + {file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"}, + {file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"}, + {file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"}, + {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9abcc2e083cbe8dde89124a47e5e53ec38751f0d7dfd36801008f316a127d7ba"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"}, + {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"}, + {file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"}, + {file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"}, + {file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"}, + {file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"}, ] [package.dependencies] cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] -nox = ["nox"] -pep8test = ["check-sdist", "click", "mypy", "ruff"] -sdist = ["build"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] @@ -1204,13 +1206,13 @@ files = [ [[package]] name = "identify" -version = "2.6.2" +version = "2.6.3" description = "File identification library for Python" optional = false python-versions = ">=3.9" files = [ - {file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"}, - {file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"}, + {file = "identify-2.6.3-py2.py3-none-any.whl", hash = "sha256:9edba65473324c2ea9684b1f944fe3191db3345e50b6d04571d10ed164f8d7bd"}, + {file = "identify-2.6.3.tar.gz", hash = "sha256:62f5dae9b5fef52c84cc188514e9ea4f3f636b1d8799ab5ebc475471f9e47a02"}, ] [package.extras] @@ -1245,7 +1247,7 @@ files = [ name = "indy-credx" version = "1.1.1" description = "" -optional = true +optional = false python-versions = ">=3.6.3" files = [ {file = "indy_credx-1.1.1-py3-none-macosx_10_9_universal2.whl", hash = "sha256:522b90a2362de681e8224b7e5173a9a6093dc48b2ed13599c9eca3df36e29128"}, @@ -1258,7 +1260,7 @@ files = [ name = "indy-vdr" version = "0.4.2" description = "" -optional = true +optional = false python-versions = ">=3.6.3" files = [ {file = "indy_vdr-0.4.2-py3-none-macosx_10_9_universal2.whl", hash = "sha256:21e4cc22bdb1de581e4abe00e2201d970f46e05d2420437fe023052614867553"}, @@ -1325,6 +1327,8 @@ optional = false python-versions = "*" files = [ {file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"}, + {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"}, + {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"}, ] [package.dependencies] @@ -1963,109 +1967,93 @@ wcwidth = "*" [[package]] name = "propcache" -version = "0.2.0" +version = "0.2.1" description = "Accelerated property cache" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, + {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, + {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, + {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, + {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, + {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, + {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, + {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, + {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, + {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, + {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, + {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, + {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, + {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, + {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, + {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, + {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, + {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, + {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, + {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, + {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -2081,22 +2069,19 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.3" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, + {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.23.4" -typing-extensions = [ - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, - {version = ">=4.6.1", markers = "python_version < \"3.13\""}, -] +pydantic-core = "2.27.1" +typing-extensions = ">=4.12.2" [package.extras] email = ["email-validator (>=2.0.0)"] @@ -2104,100 +2089,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, - {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, - {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, - {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, - {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, - {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, - {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, - {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, - {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, - {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, - {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, - {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, + {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, + {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, + {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, + {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, + {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, + {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, + {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, + {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, + {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, + {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, + {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [package.dependencies] @@ -2935,13 +2931,13 @@ files = [ [[package]] name = "virtualenv" -version = "20.27.1" +version = "20.28.0" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ - {file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"}, - {file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"}, + {file = "virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0"}, + {file = "virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa"}, ] [package.dependencies] @@ -2988,93 +2984,93 @@ tests = ["Django (>=2.2.0)", "Flask (>=0.12.5)", "aiohttp (>=3.0.8)", "bottle (> [[package]] name = "yarl" -version = "1.17.1" +version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ - {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91"}, - {file = "yarl-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da"}, - {file = "yarl-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3"}, - {file = "yarl-1.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f"}, - {file = "yarl-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931"}, - {file = "yarl-1.17.1-cp310-cp310-win32.whl", hash = "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b"}, - {file = "yarl-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4"}, - {file = "yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7"}, - {file = "yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199"}, - {file = "yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96"}, - {file = "yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374"}, - {file = "yarl-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e"}, - {file = "yarl-1.17.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299"}, - {file = "yarl-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258"}, - {file = "yarl-1.17.1-cp313-cp313-win32.whl", hash = "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2"}, - {file = "yarl-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159"}, - {file = "yarl-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934"}, - {file = "yarl-1.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5"}, - {file = "yarl-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f"}, - {file = "yarl-1.17.1-cp39-cp39-win32.whl", hash = "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473"}, - {file = "yarl-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138"}, - {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, - {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] @@ -3083,11 +3079,10 @@ multidict = ">=4.0" propcache = ">=0.2.0" [extras] -askar = ["anoncreds", "aries-askar", "indy-credx", "indy-vdr"] bbs = ["ursa-bbs-signatures"] didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "59c846da8c32b9e1eb833391d459aecef062e9ba70fd6e788b2ec21d5fdfb0fd" +content-hash = "6db2eb06e99764e6bd25fd0af73398153a1d6b5da9e2577c5e5772d9969a46ef" diff --git a/pyproject.toml b/pyproject.toml index 8810766495..d4a6874cd3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,12 +52,15 @@ did-peer-2 = "^0.1.2" did-peer-4 = "^0.1.4" did-tdw = "^0.2.1" +# Verifiable Credentials +indy-credx = "~1.1.1" +anoncreds = "0.2.0" # askar -aries-askar = { version = "~0.3.2", optional = true } -indy-credx = { version = "~1.1.1", optional = true } -indy-vdr = { version = "~0.4.0", optional = true } -anoncreds = { version = "0.2.0", optional = true } +aries-askar = "~0.3.2" + +# indy +indy-vdr = "~0.4.0" # bbs ursa-bbs-signatures = { version = "~1.0.1", optional = true } @@ -87,7 +90,6 @@ pytest-xdist = "^3.6.1" debugpy = "^1.8.9" [tool.poetry.extras] -askar = ["aries-askar", "indy-credx", "indy-vdr", "anoncreds"] bbs = ["ursa-bbs-signatures"] didcommv2 = ["didcomm-messaging"] From 4bb6edaf8f45e505275b504c56f3fc91532ac75c Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Tue, 3 Dec 2024 10:43:12 -0800 Subject: [PATCH 126/152] Update the PR for release Signed-off-by: Stephen Curran --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c956437784..a2b64dd82b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 1.1.1rc0 -### December 2, 2024 +### December 3, 2024 Release 1.1.1 is a patch update to ACA-Py that contains a lengthy list of adjustments, improvements and fixes, with a focus on removing Technical Debt. The most visible change is the removal of the "in-memory wallet" implementation in favour of using the SQLite in-memory wallet (`sqlite://:memory:`), including removing the logic for handling that extra wallet type. While arguably a breaking change (and we mention it below), we're confident no one is using the in-memory wallet (right?!?) any where other than in tests. In removing the in-memory wallet, all of the unit and integration tests that used the in-memory wallet were updated to use SQLite's in-memory wallet. From ce51d71a65f386d4a6fd64ff9a3fb8898d02d9c2 Mon Sep 17 00:00:00 2001 From: jamshale Date: Tue, 3 Dec 2024 22:29:09 +0000 Subject: [PATCH 127/152] Repair release bdd tests Signed-off-by: jamshale --- demo/features/steps/0453-issue-credential.py | 50 ++++++++++++-------- demo/features/steps/0454-present-proof.py | 2 +- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/demo/features/steps/0453-issue-credential.py b/demo/features/steps/0453-issue-credential.py index d96fdae10a..b85e5b6ef3 100644 --- a/demo/features/steps/0453-issue-credential.py +++ b/demo/features/steps/0453-issue-credential.py @@ -170,8 +170,9 @@ def step_impl(context, holder): agent["agent"], "/issue-credential-2.0/records/" + cred_ex_id ) context.cred_exchange = cred_exchange - print("rev_reg_id:", cred_exchange["indy"]["rev_reg_id"]) - print("cred_rev_id:", cred_exchange["indy"]["cred_rev_id"]) + _format = "indy" if cred_exchange.get("indy") else "anoncreds" + print("rev_reg_id:", cred_exchange[_format]["rev_reg_id"]) + print("cred_rev_id:", cred_exchange[_format]["cred_rev_id"]) print("connection_id:", cred_exchange["cred_ex_record"]["connection_id"]) # revoke the credential @@ -184,8 +185,8 @@ def step_impl(context, holder): agent["agent"], endpoint, data={ - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "rev_reg_id": cred_exchange[_format]["rev_reg_id"], + "cred_rev_id": cred_exchange[_format]["cred_rev_id"], "publish": "Y", "connection_id": cred_exchange["cred_ex_record"]["connection_id"], }, @@ -208,19 +209,22 @@ def step_impl(context, holder): # get the required revocation info from the last credential exchange cred_exchange = context.cred_exchange - print("rev_reg_id:", cred_exchange["indy"]["rev_reg_id"]) - print("cred_rev_id:", cred_exchange["indy"]["cred_rev_id"]) + _format = "indy" if cred_exchange.get("indy") else "anoncreds" + print("rev_reg_id:", cred_exchange[_format]["rev_reg_id"]) + print("cred_rev_id:", cred_exchange[_format]["cred_rev_id"]) print("connection_id:", cred_exchange["cred_ex_record"]["connection_id"]) # check wallet status wallet_revoked_creds = agent_container_GET( agent["agent"], - "/revocation/registry/" + cred_exchange["indy"]["rev_reg_id"] + "/issued/details", + "/revocation/registry/" + + cred_exchange[_format]["rev_reg_id"] + + "/issued/details", ) print("wallet_revoked_creds:", wallet_revoked_creds) matched = False for rec in wallet_revoked_creds: - if rec["cred_rev_id"] == cred_exchange["indy"]["cred_rev_id"]: + if rec["cred_rev_id"] == cred_exchange[_format]["cred_rev_id"]: matched = True assert rec["state"] == "revoked" assert matched @@ -229,18 +233,18 @@ def step_impl(context, holder): ledger_revoked_creds = agent_container_GET( agent["agent"], "/revocation/registry/" - + cred_exchange["indy"]["rev_reg_id"] + + cred_exchange[_format]["rev_reg_id"] + "/issued/indy_recs", ) print("ledger_revoked_creds:", ledger_revoked_creds) print( "assert", - cred_exchange["indy"]["cred_rev_id"], + cred_exchange[_format]["cred_rev_id"], "in", ledger_revoked_creds["rev_reg_delta"]["value"]["revoked"], ) assert ( - int(cred_exchange["indy"]["cred_rev_id"]) + int(cred_exchange[_format]["cred_rev_id"]) in ledger_revoked_creds["rev_reg_delta"]["value"]["revoked"] ) @@ -265,8 +269,9 @@ def step_impl(context, holder): agent["agent"], "/issue-credential-2.0/records/" + cred_ex_id ) context.cred_exchange = cred_exchange - print("rev_reg_id:", cred_exchange["indy"]["rev_reg_id"]) - print("cred_rev_id:", cred_exchange["indy"]["cred_rev_id"]) + _format = "indy" if cred_exchange.get("indy") else "anoncreds" + print("rev_reg_id:", cred_exchange[_format]["rev_reg_id"]) + print("cred_rev_id:", cred_exchange[_format]["cred_rev_id"]) print("connection_id:", cred_exchange["cred_ex_record"]["connection_id"]) # revoke the credential @@ -275,8 +280,8 @@ def step_impl(context, holder): agent["agent"], "/revocation/revoke", data={ - "rev_reg_id": cred_exchange["indy"]["rev_reg_id"], - "cred_rev_id": cred_exchange["indy"]["cred_rev_id"], + "rev_reg_id": cred_exchange[_format]["rev_reg_id"], + "cred_rev_id": cred_exchange[_format]["cred_rev_id"], "publish": "Y", "connection_id": cred_exchange["cred_ex_record"]["connection_id"], }, @@ -297,18 +302,21 @@ def step_impl(context, holder): # get the required revocation info from the last credential exchange cred_exchange = context.cred_exchange - print("rev_reg_id:", cred_exchange["indy"]["rev_reg_id"]) - print("cred_rev_id:", cred_exchange["indy"]["cred_rev_id"]) + _format = "indy" if cred_exchange.get("indy") else "anoncreds" + print("rev_reg_id:", cred_exchange[_format]["rev_reg_id"]) + print("cred_rev_id:", cred_exchange[_format]["cred_rev_id"]) print("connection_id:", cred_exchange["cred_ex_record"]["connection_id"]) # check wallet status wallet_revoked_creds = agent_container_GET( agent["agent"], - "/revocation/registry/" + cred_exchange["indy"]["rev_reg_id"] + "/issued/details", + "/revocation/registry/" + + cred_exchange[_format]["rev_reg_id"] + + "/issued/details", ) matched = False for rec in wallet_revoked_creds: - if rec["cred_rev_id"] == cred_exchange["indy"]["cred_rev_id"]: + if rec["cred_rev_id"] == cred_exchange[_format]["cred_rev_id"]: matched = True assert rec["state"] == "revoked" assert matched @@ -317,12 +325,12 @@ def step_impl(context, holder): ledger_revoked_creds = agent_container_GET( agent["agent"], "/revocation/registry/" - + cred_exchange["indy"]["rev_reg_id"] + + cred_exchange[_format]["rev_reg_id"] + "/issued/indy_recs", ) print("ledger_revoked_creds:", ledger_revoked_creds) assert ( - int(cred_exchange["indy"]["cred_rev_id"]) + int(cred_exchange[_format]["cred_rev_id"]) not in ledger_revoked_creds["rev_reg_delta"]["value"]["revoked"] ) diff --git a/demo/features/steps/0454-present-proof.py b/demo/features/steps/0454-present-proof.py index 31e91930f5..166712f4e0 100644 --- a/demo/features/steps/0454-present-proof.py +++ b/demo/features/steps/0454-present-proof.py @@ -37,7 +37,7 @@ def step_impl(context, verifier, request_for_proof, prover): proof_exchange = aries_container_request_proof( agent["agent"], proof_request_info, - agent["agent"].wallet_type == "askar-anoncreds", + is_anoncreds=agent["agent"].wallet_type == "askar-anoncreds", ) context.proof_request = proof_request_info From 937ff584e1ec8b6082e14f7b88d3d2b4cd7f4461 Mon Sep 17 00:00:00 2001 From: Stephen Curran Date: Tue, 3 Dec 2024 14:43:34 -0800 Subject: [PATCH 128/152] Add in PR to Changelog Signed-off-by: Stephen Curran --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2b64dd82b..a418c79077 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ While there are no breaking changes in this release that might impact production #### 1.1.1 Categorized List of Pull Requests - AnonCreds VC Issuance and Presentation Enhancement / Fixes + - Repair release bdd tests [\#3376](https://github.com/openwallet-foundation/acapy/pull/3376) [jamshale](https://github.com/jamshale) - Fix tails upload for anoncreds multitenancy [\#3346](https://github.com/openwallet-foundation/acapy/pull/3346) [jamshale](https://github.com/jamshale) - Fix subwallet anoncreds upgrade check [\#3345](https://github.com/openwallet-foundation/acapy/pull/3345) [jamshale](https://github.com/jamshale) - Add anoncreds issuance and presentation format [\#3331](https://github.com/openwallet-foundation/acapy/pull/3331) [jamshale](https://github.com/jamshale) @@ -70,7 +71,7 @@ While there are no breaking changes in this release that might impact production - 1.1.1rc0 [\#3372](https://github.com/openwallet-foundation/acapy/pull/3372) [swcurran](https://github.com/swcurran) - Dependabot PRs - - [Link to list of Dependabot PRs in this release](https://github.com/openwallet-foundation/acapy/pulls?q=is%3Apr+is%3Amerged+merged%3A2024-10-15..2024-12-02+author%3Aapp%2Fdependabot+) + - [Link to list of Dependabot PRs in this release](https://github.com/openwallet-foundation/acapy/pulls?q=is%3Apr+is%3Amerged+merged%3A2024-10-15..2024-12-03+author%3Aapp%2Fdependabot+) ## 1.1.0 From 909c15abd0098cfd48e770369b40d9a96e89d5f7 Mon Sep 17 00:00:00 2001 From: ff137 Date: Wed, 4 Dec 2024 15:06:39 +0200 Subject: [PATCH 129/152] :art: Reduce repetition Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index fd04b4e36c..a74facdcb7 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -714,21 +714,18 @@ def dispatch_complete(self, message: InboundMessage, completed: CompletedTask): """Handle completion of message dispatch.""" if completed.exc_info: LOGGER.exception("Exception in message handler:", exc_info=completed.exc_info) - if isinstance(completed.exc_info[1], LedgerConfigError) or isinstance( - completed.exc_info[1], LedgerTransactionError - ): + exc_class, exc, _ = completed.exc_info + if isinstance(exc, (LedgerConfigError, LedgerTransactionError)): LOGGER.error( "%shutdown on ledger error %s", "S" if self.admin_server else "No admin server to s", - str(completed.exc_info[1]), + str(exc), ) if self.admin_server: self.admin_server.notify_fatal_error() else: LOGGER.error( - "DON'T shutdown on %s %s", - completed.exc_info[0].__name__, - str(completed.exc_info[1]), + "DON'T shutdown on %s %s", exc_class.__name__, str(exc) ) self.inbound_transport_manager.dispatch_complete(message, completed) From 31451c099c96df3b29363c33346aa4672a4714d0 Mon Sep 17 00:00:00 2001 From: Ian Costanzo Date: Wed, 4 Dec 2024 10:34:21 -0800 Subject: [PATCH 130/152] Fix for demo initial cred_type override (#3378) Signed-off-by: Ian Costanzo --- demo/runners/agent_container.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/runners/agent_container.py b/demo/runners/agent_container.py index 61b07f4ef7..e529e6aefe 100644 --- a/demo/runners/agent_container.py +++ b/demo/runners/agent_container.py @@ -1366,7 +1366,7 @@ def arg_parser(ident: str = None, port: int = 8020): type=str, default=CRED_FORMAT_INDY, metavar=(""), - help="Credential type (indy, json-ld)", + help="Credential type (indy, json-ld, vc_di)", ) parser.add_argument( "--aip", @@ -1571,7 +1571,7 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non # Set anoncreds agent to use anoncreds credential format wallet_type = arg_file_dict.get("wallet-type") or args.wallet_type - if wallet_type == "askar-anoncreds": + if wallet_type == "askar-anoncreds" and cred_type == CRED_FORMAT_INDY: cred_type = CRED_FORMAT_ANONCREDS log_msg( From b10440112f6d1d5ca1e542d2a334065bb55d252b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:16:19 +0000 Subject: [PATCH 131/152] chore(deps): Bump dawidd6/action-download-artifact (#3370) Bumps the all-actions group with 1 update: [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact). Updates `dawidd6/action-download-artifact` from 6 to 7 - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-type: direct:production update-type: version-update:semver-major dependency-group: all-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com> --- .github/workflows/sonar-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sonar-pr.yml b/.github/workflows/sonar-pr.yml index 51558d2ad6..df9f5e06ff 100644 --- a/.github/workflows/sonar-pr.yml +++ b/.github/workflows/sonar-pr.yml @@ -15,7 +15,7 @@ jobs: with: fetch-depth: 0 - name: Download PR number artifact - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@v7 with: workflow: Tests run_id: ${{ github.event.workflow_run.id }} @@ -26,7 +26,7 @@ jobs: with: path: ./PR_NUMBER - name: Download Test Coverage - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@v7 with: workflow: Tests run_id: ${{ github.event.workflow_run.id }} From 33ab9a0728e9d18384057908f8cd36ad310103f2 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 11:50:27 +0200 Subject: [PATCH 132/152] :art: Log warning when StorageNotFoundError encountered, instead of exception stacktrace Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 13 ++++++++++--- .../v2_0/handlers/cred_problem_report_handler.py | 8 ++++++-- .../v2_0/handlers/pres_problem_report_handler.py | 8 ++++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index a74facdcb7..3acdb1fd66 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -13,6 +13,7 @@ import logging from typing import Optional +from aries_askar import AskarError from packaging import version as package_version from qrcode import QRCode @@ -713,7 +714,6 @@ def inbound_message_router( def dispatch_complete(self, message: InboundMessage, completed: CompletedTask): """Handle completion of message dispatch.""" if completed.exc_info: - LOGGER.exception("Exception in message handler:", exc_info=completed.exc_info) exc_class, exc, _ = completed.exc_info if isinstance(exc, (LedgerConfigError, LedgerTransactionError)): LOGGER.error( @@ -723,9 +723,16 @@ def dispatch_complete(self, message: InboundMessage, completed: CompletedTask): ) if self.admin_server: self.admin_server.notify_fatal_error() + elif isinstance(exc, (AskarError, StorageNotFoundError)): + LOGGER.warning( + "Storage error occurred in message handler: %s: %s", + exc_class.__name__, + str(exc), + exc_info=completed.exc_info, + ) else: - LOGGER.error( - "DON'T shutdown on %s %s", exc_class.__name__, str(exc) + LOGGER.exception( + "Exception in message handler:", exc_info=completed.exc_info ) self.inbound_transport_manager.dispatch_complete(message, completed) diff --git a/acapy_agent/protocols/issue_credential/v2_0/handlers/cred_problem_report_handler.py b/acapy_agent/protocols/issue_credential/v2_0/handlers/cred_problem_report_handler.py index b8f56f119d..f513496c79 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/handlers/cred_problem_report_handler.py +++ b/acapy_agent/protocols/issue_credential/v2_0/handlers/cred_problem_report_handler.py @@ -40,7 +40,11 @@ async def handle(self, context: RequestContext, responder: BaseResponder): context.message, context.connection_record.connection_id, ) - except (StorageError, StorageNotFoundError): + except StorageNotFoundError: + self._logger.warning( + "Record not found while processing issue-credential v2.0 problem report" + ) + except StorageError: self._logger.exception( - "Error processing issue-credential v2.0 problem report message" + "Storage error while processing issue-credential v2.0 problem report" ) diff --git a/acapy_agent/protocols/present_proof/v2_0/handlers/pres_problem_report_handler.py b/acapy_agent/protocols/present_proof/v2_0/handlers/pres_problem_report_handler.py index be4aab8620..e10df27e2e 100644 --- a/acapy_agent/protocols/present_proof/v2_0/handlers/pres_problem_report_handler.py +++ b/acapy_agent/protocols/present_proof/v2_0/handlers/pres_problem_report_handler.py @@ -34,7 +34,11 @@ async def handle(self, context: RequestContext, responder: BaseResponder): else None ), ) - except (StorageError, StorageNotFoundError): + except StorageNotFoundError: + self._logger.warning( + "Record not found while processing present-proof v2.0 problem report" + ) + except StorageError: self._logger.exception( - "Error processing present-proof v2.0 problem report message" + "Storage error while processing present-proof v2.0 problem report" ) From 340ec9edf87dc7645c83ef5c932fc92e17843b42 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 11:50:47 +0200 Subject: [PATCH 133/152] :art: Set Shutdown log level to fatal, with exc_info Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 3acdb1fd66..45841635d6 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -716,10 +716,11 @@ def dispatch_complete(self, message: InboundMessage, completed: CompletedTask): if completed.exc_info: exc_class, exc, _ = completed.exc_info if isinstance(exc, (LedgerConfigError, LedgerTransactionError)): - LOGGER.error( + LOGGER.fatal( "%shutdown on ledger error %s", "S" if self.admin_server else "No admin server to s", str(exc), + exc_info=completed.exc_info, ) if self.admin_server: self.admin_server.notify_fatal_error() From be2f30249d0ffc0ea5861b70e006c3c28ff92804 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 11:53:50 +0200 Subject: [PATCH 134/152] :art: Log warning for bad credential format, instead of always exception stacktrace Signed-off-by: ff137 --- acapy_agent/protocols/issue_credential/v2_0/routes.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acapy_agent/protocols/issue_credential/v2_0/routes.py b/acapy_agent/protocols/issue_credential/v2_0/routes.py index 9128f7aeac..3993eadfca 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/routes.py @@ -846,7 +846,12 @@ async def credential_exchange_send(request: web.BaseRequest): V20CredManagerError, V20CredFormatError, ) as err: - LOGGER.exception("Error preparing credential offer") + # Only log full exception for unexpected errors + if isinstance(err, (V20CredFormatError, V20CredManagerError)): + LOGGER.warning(f"Error preparing credential offer: {err.roll_up}") + else: + LOGGER.exception("Error preparing credential offer") + if cred_ex_record: async with profile.session() as session: await cred_ex_record.save_error_state(session, reason=err.roll_up) From ce6bf7b3781f1d0e17b32ef50f5e9fcaebb1a0b6 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 11:54:12 +0200 Subject: [PATCH 135/152] :construction: Add exc_info to error log for debugging Signed-off-by: ff137 --- acapy_agent/core/dispatcher.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/acapy_agent/core/dispatcher.py b/acapy_agent/core/dispatcher.py index 962b69d97c..dfa476e444 100644 --- a/acapy_agent/core/dispatcher.py +++ b/acapy_agent/core/dispatcher.py @@ -176,9 +176,6 @@ async def handle_v1_message( inbound_message: The inbound message instance send_outbound: Async function to send outbound messages - # Raises: - # MessageParseError: If the message type version is not supported - Returns: The response from the handler @@ -193,7 +190,9 @@ async def handle_v1_message( except ProblemReportParseError: pass # avoid problem report recursion except MessageParseError as e: - self.logger.error(f"Message parsing failed: {str(e)}, sending problem report") + self.logger.error( + f"Message parsing failed: {str(e)}, sending problem report", exc_info=e + ) error_result = ProblemReport( description={ "en": str(e), From eb2684b1bcbd6d7eba3182f0d1e18466f678b566 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 11:56:01 +0200 Subject: [PATCH 136/152] :art: Make `ensure_supported_did` method public Signed-off-by: ff137 --- acapy_agent/protocols/did_rotate/v1_0/manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acapy_agent/protocols/did_rotate/v1_0/manager.py b/acapy_agent/protocols/did_rotate/v1_0/manager.py index 8c5e508e06..684bb20dc6 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/manager.py +++ b/acapy_agent/protocols/did_rotate/v1_0/manager.py @@ -128,7 +128,7 @@ async def receive_rotate(self, conn: ConnRecord, rotate: Rotate) -> RotateRecord ) try: - await self._ensure_supported_did(rotate.to_did) + await self.ensure_supported_did(rotate.to_did) except ReportableDIDRotateError as err: responder = self.profile.inject(BaseResponder) err.message.assign_thread_from(rotate) @@ -234,7 +234,7 @@ async def receive_hangup(self, conn: ConnRecord): async with self.profile.session() as session: await conn.delete_record(session) - async def _ensure_supported_did(self, did: str): + async def ensure_supported_did(self, did: str): """Check if the DID is supported.""" resolver = self.profile.inject(DIDResolver) conn_mgr = BaseConnectionManager(self.profile) From 07b9ff334fca9ff44aa118084e3c3ee5b80f7668 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 12:03:17 +0200 Subject: [PATCH 137/152] :bug: Ensure supported DID before calling Rotate Resolves: #3379 Signed-off-by: ff137 --- acapy_agent/protocols/did_rotate/v1_0/routes.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/acapy_agent/protocols/did_rotate/v1_0/routes.py b/acapy_agent/protocols/did_rotate/v1_0/routes.py index f441ded27b..15c485371f 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/routes.py +++ b/acapy_agent/protocols/did_rotate/v1_0/routes.py @@ -12,7 +12,12 @@ from ....messaging.models.openapi import OpenAPISchema from ....messaging.valid import DID_WEB_EXAMPLE, UUID4_EXAMPLE from ....storage.error import StorageNotFoundError -from .manager import DIDRotateManager +from .manager import ( + DIDRotateManager, + UnresolvableDIDCommServicesError, + UnresolvableDIDError, + UnsupportedDIDMethodError, +) from .message_types import SPEC_URI from .messages.hangup import HangupSchema as HangupMessageSchema from .messages.rotate import RotateSchema as RotateMessageSchema @@ -63,6 +68,16 @@ async def rotate(request: web.BaseRequest): body = await request.json() to_did = body["to_did"] + # Validate DID before proceeding + try: + await did_rotate_mgr.ensure_supported_did(to_did) + except ( + UnsupportedDIDMethodError, + UnresolvableDIDError, + UnresolvableDIDCommServicesError, + ) as err: + raise web.HTTPBadRequest(reason=str(err)) from err + async with context.session() as session: try: conn = await ConnRecord.retrieve_by_id(session, connection_id) From 655ac1200d9087662d4a7680993b035057f63e0f Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 12:09:17 +0200 Subject: [PATCH 138/152] :white_check_mark: Fix existing tests Signed-off-by: ff137 --- .../protocols/did_rotate/v1_0/tests/test_manager.py | 2 +- .../protocols/did_rotate/v1_0/tests/test_routes.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py b/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py index cf72da930e..2383bfdc17 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py +++ b/acapy_agent/protocols/did_rotate/v1_0/tests/test_manager.py @@ -94,7 +94,7 @@ async def test_receive_rotate_x(self): with ( mock.patch.object( - self.manager, "_ensure_supported_did", side_effect=test_problem_report + self.manager, "ensure_supported_did", side_effect=test_problem_report ), mock.patch.object(self.responder, "send", mock.CoroutineMock()) as mock_send, ): diff --git a/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py b/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py index 932d413ed9..6829d50394 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py @@ -57,7 +57,8 @@ async def asyncSetUp(self): "DIDRotateManager", autospec=True, return_value=mock.MagicMock( - rotate_my_did=mock.CoroutineMock(return_value=generate_mock_rotate_message()) + rotate_my_did=mock.CoroutineMock(return_value=generate_mock_rotate_message()), + ensure_supported_did=mock.CoroutineMock(), ), ) async def test_rotate(self, *_): @@ -102,7 +103,15 @@ async def test_hangup(self, *_): } ) - async def test_rotate_conn_not_found(self): + @mock.patch.object( + test_module, + "DIDRotateManager", + autospec=True, + return_value=mock.MagicMock( + ensure_supported_did=mock.CoroutineMock(), + ), + ) + async def test_rotate_conn_not_found(self, *_): self.request.match_info = {"conn_id": test_conn_id} self.request.json = mock.CoroutineMock(return_value=test_valid_rotate_request) From add68a90ee248ae8263734158dae44090314e444 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 12:13:27 +0200 Subject: [PATCH 139/152] :white_check_mark: Test coverage for new DID validation Signed-off-by: ff137 --- .../did_rotate/v1_0/tests/test_routes.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py b/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py index 6829d50394..22ec03fed2 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py +++ b/acapy_agent/protocols/did_rotate/v1_0/tests/test_routes.py @@ -123,6 +123,28 @@ async def test_rotate_conn_not_found(self, *_): with self.assertRaises(test_module.web.HTTPNotFound): await test_module.rotate(self.request) + async def test_rotate_did_validation_errors(self): + self.request.match_info = {"conn_id": test_conn_id} + self.request.json = mock.CoroutineMock(return_value=test_valid_rotate_request) + + for error_class in [ + test_module.UnsupportedDIDMethodError, + test_module.UnresolvableDIDError, + test_module.UnresolvableDIDCommServicesError, + ]: + with mock.patch.object( + test_module, + "DIDRotateManager", + autospec=True, + return_value=mock.MagicMock( + ensure_supported_did=mock.CoroutineMock( + side_effect=error_class("test error") + ), + ), + ): + with self.assertRaises(test_module.web.HTTPBadRequest): + await test_module.rotate(self.request) + if __name__ == "__main__": unittest.main() From db1c0f201b33185afb5242ffe493ff2cc7d83a0e Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 12:46:49 +0200 Subject: [PATCH 140/152] :art: Shorten config key --- acapy_agent/ledger/indy_vdr.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/acapy_agent/ledger/indy_vdr.py b/acapy_agent/ledger/indy_vdr.py index e966f04c50..bd8efbb24c 100644 --- a/acapy_agent/ledger/indy_vdr.py +++ b/acapy_agent/ledger/indy_vdr.py @@ -156,14 +156,7 @@ async def get_or_create( socks_proxy, ) - config_key = ( - name, - keepalive, - cache_duration, - genesis_transactions, - read_only, - socks_proxy, - ) + config_key = (name, keepalive, cache_duration, read_only, socks_proxy) LOGGER.debug("Generated config key: %s", config_key) async with cls._lock: From a7870dd1c8ee93e762e8540320dd226e5ed1b813 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 13:27:53 +0200 Subject: [PATCH 141/152] :art: Fix lying method return type Signed-off-by: ff137 --- acapy_agent/ledger/indy_vdr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acapy_agent/ledger/indy_vdr.py b/acapy_agent/ledger/indy_vdr.py index aad8963cd5..5a9b7a2ba0 100644 --- a/acapy_agent/ledger/indy_vdr.py +++ b/acapy_agent/ledger/indy_vdr.py @@ -624,7 +624,7 @@ async def credential_definition_id2schema_id(self, credential_definition_id): seq_no = tokens[3] return (await self.get_schema(seq_no))["id"] - async def get_key_for_did(self, did: str) -> str: + async def get_key_for_did(self, did: str) -> Optional[str]: """Fetch the verkey for a ledger DID. Args: From f86406fe29136da19439f5980878078c5baf300c Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 14:33:54 +0200 Subject: [PATCH 142/152] :art: Replace AskarError with ProfileError Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 45841635d6..e44bbead93 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -13,7 +13,6 @@ import logging from typing import Optional -from aries_askar import AskarError from packaging import version as package_version from qrcode import QRCode @@ -78,7 +77,7 @@ from ..wallet.anoncreds_upgrade import upgrade_wallet_to_anoncreds_if_requested from ..wallet.did_info import DIDInfo from .dispatcher import Dispatcher -from .error import StartupError +from .error import ProfileError, StartupError from .oob_processor import OobMessageProcessor from .util import SHUTDOWN_EVENT_TOPIC, STARTUP_EVENT_TOPIC @@ -724,7 +723,7 @@ def dispatch_complete(self, message: InboundMessage, completed: CompletedTask): ) if self.admin_server: self.admin_server.notify_fatal_error() - elif isinstance(exc, (AskarError, StorageNotFoundError)): + elif isinstance(exc, (ProfileError, StorageNotFoundError)): LOGGER.warning( "Storage error occurred in message handler: %s: %s", exc_class.__name__, From 45c910a7f0158b41453636d3f2504076a46821f9 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 14:47:14 +0200 Subject: [PATCH 143/152] :construction: Skip exception log for ProfileError Signed-off-by: ff137 --- acapy_agent/core/dispatcher.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/acapy_agent/core/dispatcher.py b/acapy_agent/core/dispatcher.py index dfa476e444..d4846ce518 100644 --- a/acapy_agent/core/dispatcher.py +++ b/acapy_agent/core/dispatcher.py @@ -32,7 +32,7 @@ from ..utils.stats import Collector from ..utils.task_queue import CompletedTask, PendingTask, TaskQueue from ..utils.tracing import get_timer, trace_event -from .error import ProtocolMinorVersionNotSupported +from .error import ProfileError, ProtocolMinorVersionNotSupported from .protocol_registry import ProtocolRegistry @@ -84,9 +84,14 @@ def log_task(self, task: CompletedTask): """Log a completed task using the stats collector.""" if task.exc_info and not issubclass(task.exc_info[0], HTTPException): # skip errors intentionally returned to HTTP clients - self.logger.exception( - "Handler error: %s", task.ident or "", exc_info=task.exc_info - ) + if not issubclass(task.exc_info[0], ProfileError): + self.logger.exception( + "Handler error: %s", task.ident or "", exc_info=task.exc_info + ) + else: + self.logger.warning( + "Handler error: %s", task.ident or "", exc_info=task.exc_info + ) if self.collector: timing = task.timing if "queued" in timing: From 6bf8fc8530ce2a6c7af31798cc476000f7f4c4b8 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 14:48:01 +0200 Subject: [PATCH 144/152] :bug: Fix message type class mapping Signed-off-by: ff137 --- acapy_agent/protocols/did_rotate/v1_0/message_types.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acapy_agent/protocols/did_rotate/v1_0/message_types.py b/acapy_agent/protocols/did_rotate/v1_0/message_types.py index 2d0c0bfb6e..7cb418fc91 100644 --- a/acapy_agent/protocols/did_rotate/v1_0/message_types.py +++ b/acapy_agent/protocols/did_rotate/v1_0/message_types.py @@ -15,8 +15,8 @@ MESSAGE_TYPES = DIDCommPrefix.qualify_all( { ROTATE: f"{PROTOCOL_PACKAGE}.messages.rotate.Rotate", - ACK: f"{PROTOCOL_PACKAGE}.messages.ack.Ack", + ACK: f"{PROTOCOL_PACKAGE}.messages.ack.RotateAck", HANGUP: f"{PROTOCOL_PACKAGE}.messages.hangup.Hangup", - PROBLEM_REPORT: f"{PROTOCOL_PACKAGE}.messages.problem_report.ProblemReport", + PROBLEM_REPORT: f"{PROTOCOL_PACKAGE}.messages.problem_report.RotateProblemReport", } ) From c9022e22209c242e3dae4621edca2a0bb0dc5114 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 14:51:22 +0200 Subject: [PATCH 145/152] :construction: Debug message parse error Signed-off-by: ff137 --- acapy_agent/core/dispatcher.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acapy_agent/core/dispatcher.py b/acapy_agent/core/dispatcher.py index d4846ce518..1ce41af02b 100644 --- a/acapy_agent/core/dispatcher.py +++ b/acapy_agent/core/dispatcher.py @@ -292,7 +292,9 @@ async def make_message(self, profile: Profile, parsed_msg: dict) -> BaseMessage: message_type = parsed_msg.get("@type") if not message_type: - raise MessageParseError("Message does not contain '@type' parameter") + raise MessageParseError( + f"Message does not contain '@type' parameter. Got: {parsed_msg}" + ) if message_type.startswith("did:sov"): warnings.warn( From 8a3920414ee61c875a4002224bbdcf3063421f12 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 15:29:41 +0200 Subject: [PATCH 146/152] :construction: Log warning instead of error for MessageParseError Signed-off-by: ff137 --- acapy_agent/core/dispatcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acapy_agent/core/dispatcher.py b/acapy_agent/core/dispatcher.py index 1ce41af02b..e430fe9f32 100644 --- a/acapy_agent/core/dispatcher.py +++ b/acapy_agent/core/dispatcher.py @@ -195,7 +195,7 @@ async def handle_v1_message( except ProblemReportParseError: pass # avoid problem report recursion except MessageParseError as e: - self.logger.error( + self.logger.warning( f"Message parsing failed: {str(e)}, sending problem report", exc_info=e ) error_result = ProblemReport( From c56fb866ab4ec6252ef706e1108519abb4b5f52b Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 20:12:50 +0200 Subject: [PATCH 147/152] :arrow_up: Bump version Signed-off-by: ff137 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5f5e55ea32..b13065d41c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "acapy_agent_didx" -version = "1.1.1b5" +version = "1.2.0-20241205" description = "(ACA-Py) A Cloud Agent Python is a foundation for building decentralized identity applications and services running in non-mobile environments. " authors = [] license = "Apache-2.0" @@ -56,7 +56,7 @@ indy-credx = "~1.1.1" anoncreds = "0.2.0" # askar -aries-askar-ff137 = {version = "==0.3.3b0", source = "testpypi", optional = true} +aries-askar-ff137 = {version = "==0.3.3b0", source = "testpypi"} # indy indy-vdr = "~0.4.0" From d8c6d5bf964ab2841afa3b9aab1b05d41b8c0fe4 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 20:13:08 +0200 Subject: [PATCH 148/152] :arrow_up: Update lock file Signed-off-by: ff137 --- poetry.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index f1599a1b9f..3c259443fd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -213,7 +213,7 @@ yaml = ["PyYAML (>=3.10)"] name = "aries-askar-ff137" version = "0.3.3b0" description = "UNKNOWN" -optional = true +optional = false python-versions = ">=3.6.3" files = [ {file = "aries_askar_ff137-0.3.3b0-py3-none-macosx_10_9_universal2.whl", hash = "sha256:32d6ed2366527b733a6025c19fb6f52f4547a3b2693cc11a1175b0ca3bfc8792"}, @@ -292,7 +292,7 @@ tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", " name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." -optional = true +optional = false python-versions = "*" files = [ {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, @@ -2542,13 +2542,13 @@ pyyaml = ">=5.4" [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] @@ -2977,4 +2977,4 @@ didcommv2 = ["didcomm-messaging"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "79e47828c3dccc5d4232e8f1f88932cba8fc2091c23bcebc27c24e43f9d52d13" +content-hash = "0ec4a165fc3c5503157ee57736700b931a6c920d7cacc39b91463dad311676e7" From c55d1d4c691f5382080952b250f3edc4d420299d Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 20:54:36 +0200 Subject: [PATCH 149/152] :art: Fix model name for consistency From Anoncred to Anoncreds Signed-off-by: ff137 --- acapy_agent/anoncreds/models/presentation_request.py | 2 +- open-api/openapi.json | 4 ++-- open-api/swagger.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/acapy_agent/anoncreds/models/presentation_request.py b/acapy_agent/anoncreds/models/presentation_request.py index 05881dfdc8..12855e1ee6 100644 --- a/acapy_agent/anoncreds/models/presentation_request.py +++ b/acapy_agent/anoncreds/models/presentation_request.py @@ -299,7 +299,7 @@ class Meta: }, ), }, - name="AnoncredPresentationRequestNonRevokedSchema", + name="AnoncredsPresentationRequestNonRevokedSchema", ), allow_none=True, required=False, diff --git a/open-api/openapi.json b/open-api/openapi.json index 97913e91f2..07c228d3a8 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -7763,7 +7763,7 @@ }, "type" : "object" }, - "AnoncredPresentationRequestNonRevoked" : { + "AnoncredsPresentationRequestNonRevoked" : { "properties" : { "from" : { "description" : "Earliest time of interest in non-revocation interval", @@ -7895,7 +7895,7 @@ "type" : "string" }, "non_revoked" : { - "$ref" : "#/components/schemas/AnoncredPresentationRequestNonRevoked" + "$ref" : "#/components/schemas/AnoncredsPresentationRequestNonRevoked" }, "nonce" : { "description" : "Nonce", diff --git a/open-api/swagger.json b/open-api/swagger.json index fd4823dd48..c49ae1134d 100644 --- a/open-api/swagger.json +++ b/open-api/swagger.json @@ -6396,7 +6396,7 @@ } } }, - "AnoncredPresentationRequestNonRevoked" : { + "AnoncredsPresentationRequestNonRevoked" : { "type" : "object", "properties" : { "from" : { @@ -6530,7 +6530,7 @@ "description" : "Proof request name" }, "non_revoked" : { - "$ref" : "#/definitions/AnoncredPresentationRequestNonRevoked" + "$ref" : "#/definitions/AnoncredsPresentationRequestNonRevoked" }, "nonce" : { "type" : "string", From 5a3b99ae17ac5b3d1c8bd19e352ac3c08222d401 Mon Sep 17 00:00:00 2001 From: ff137 Date: Thu, 5 Dec 2024 21:32:54 +0200 Subject: [PATCH 150/152] :art: Set wallet upgrade exception log to warning Signed-off-by: ff137 --- acapy_agent/core/conductor.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/acapy_agent/core/conductor.py b/acapy_agent/core/conductor.py index 81b5b9fc79..199101b8c8 100644 --- a/acapy_agent/core/conductor.py +++ b/acapy_agent/core/conductor.py @@ -636,9 +636,10 @@ async def start(self) -> None: LOGGER.debug("Checking for wallet upgrades in progress.") await self.check_for_wallet_upgrades_in_progress() LOGGER.debug("Wallet upgrades check completed.") - except Exception: - LOGGER.exception( - "An exception was caught while checking for wallet upgrades in progress." + except Exception as e: + LOGGER.warning( + "An exception was caught while checking for wallet upgrades in progress.", + exc_info=e, ) # notify protocols of startup status From 5806f5cb1b02dbb94e27e86a15673a231e3960e4 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Thu, 5 Dec 2024 11:58:35 -0800 Subject: [PATCH 151/152] Update anoncreds format names (#3374) * Update anoncreds format names Signed-off-by: jamshale * Add a unit test Signed-off-by: jamshale --------- Signed-off-by: jamshale --- .../issue_credential/v2_0/message_types.py | 8 +++--- .../protocols/issue_credential/v2_0/routes.py | 25 +++++++++++++++---- .../v2_0/tests/test_routes.py | 23 +++++++++++++++++ .../present_proof/v2_0/message_types.py | 6 ++--- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/acapy_agent/protocols/issue_credential/v2_0/message_types.py b/acapy_agent/protocols/issue_credential/v2_0/message_types.py index e34ce0385d..80e56d2309 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/message_types.py +++ b/acapy_agent/protocols/issue_credential/v2_0/message_types.py @@ -37,25 +37,25 @@ # Format specifications ATTACHMENT_FORMAT = { CRED_20_PROPOSAL: { - V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-filter@v2.0", + V20CredFormat.Format.ANONCREDS.api: "anoncreds/credential-filter@v1.0", V20CredFormat.Format.INDY.api: "hlindy/cred-filter@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc@v0.1", }, CRED_20_OFFER: { - V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-abstract@v2.0", + V20CredFormat.Format.ANONCREDS.api: "anoncreds/credential-offer@v1.0", V20CredFormat.Format.INDY.api: "hlindy/cred-abstract@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc-offer@v0.1", }, CRED_20_REQUEST: { - V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred-req@v2.0", + V20CredFormat.Format.ANONCREDS.api: "anoncreds/credential-request@v1.0", V20CredFormat.Format.INDY.api: "hlindy/cred-req@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc-detail@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc-request@v0.1", }, CRED_20_ISSUE: { - V20CredFormat.Format.ANONCREDS.api: "anoncreds/cred@v2.0", + V20CredFormat.Format.ANONCREDS.api: "anoncreds/credential@v1.0", V20CredFormat.Format.INDY.api: "hlindy/cred@v2.0", V20CredFormat.Format.LD_PROOF.api: "aries/ld-proof-vc@v1.0", V20CredFormat.Format.VC_DI.api: "didcomm/w3c-di-vc@v0.1", diff --git a/acapy_agent/protocols/issue_credential/v2_0/routes.py b/acapy_agent/protocols/issue_credential/v2_0/routes.py index 9128f7aeac..de7c61f2e0 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/routes.py @@ -28,6 +28,7 @@ from ....messaging.models.openapi import OpenAPISchema from ....messaging.models.paginated_query import PaginatedQuerySchema, get_limit_offset from ....messaging.valid import ( + ANONCREDS_CRED_DEF_ID_EXAMPLE, ANONCREDS_DID_EXAMPLE, ANONCREDS_SCHEMA_ID_EXAMPLE, INDY_CRED_DEF_ID_EXAMPLE, @@ -137,13 +138,24 @@ class V20CredStoreRequestSchema(OpenAPISchema): class V20CredFilterAnoncredsSchema(OpenAPISchema): """Anoncreds credential filtration criteria.""" - cred_def_id = fields.Str( + schema_issuer_id = fields.Str( required=False, metadata={ - "description": "Credential definition identifier", + "description": "Schema issuer ID", "example": ANONCREDS_DID_EXAMPLE, }, ) + schema_name = fields.Str( + required=False, + metadata={"description": "Schema name", "example": "preferences"}, + ) + schema_version = fields.Str( + required=False, + metadata={ + "description": "Schema version", + "example": MAJOR_MINOR_VERSION_EXAMPLE, + }, + ) schema_id = fields.Str( required=False, metadata={ @@ -154,13 +166,16 @@ class V20CredFilterAnoncredsSchema(OpenAPISchema): issuer_id = fields.Str( required=False, metadata={ - "description": "Credential issuer DID", + "description": "Credential issuer ID", "example": ANONCREDS_DID_EXAMPLE, }, ) - epoch = fields.Str( + cred_def_id = fields.Str( required=False, - metadata={"description": "Credential epoch time", "example": "2021-08-24"}, + metadata={ + "description": "Credential definition identifier", + "example": ANONCREDS_CRED_DEF_ID_EXAMPLE, + }, ) diff --git a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py index 9e3663d5ed..8691862f0d 100644 --- a/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py +++ b/acapy_agent/protocols/issue_credential/v2_0/tests/test_routes.py @@ -61,6 +61,29 @@ async def test_validate_cred_filter_schema(self): with self.assertRaises(test_module.ValidationError): schema.validate_fields({"veres-one": {"no": "support"}}) + async def test_validate_cred_filter_anoncreds_schema(self): + schema = test_module.V20CredFilterSchema() + schema.validate_fields({"anoncreds": {"issuer_id": TEST_DID}}) + schema.validate_fields( + {"anoncreds": {"issuer_id": TEST_DID, "schema_version": "1.0"}} + ) + schema.validate_fields( + { + "anoncreds": {"issuer_id": TEST_DID}, + } + ) + schema.validate_fields( + { + "anoncreds": {}, + } + ) + with self.assertRaises(test_module.ValidationError): + schema.validate_fields({}) + with self.assertRaises(test_module.ValidationError): + schema.validate_fields(["hopeless", "stop"]) + with self.assertRaises(test_module.ValidationError): + schema.validate_fields({"veres-one": {"no": "support"}}) + async def test_validate_create_schema(self): schema = test_module.V20IssueCredSchemaCore() schema.validate( diff --git a/acapy_agent/protocols/present_proof/v2_0/message_types.py b/acapy_agent/protocols/present_proof/v2_0/message_types.py index 5654ef7d42..3c24ef7d72 100644 --- a/acapy_agent/protocols/present_proof/v2_0/message_types.py +++ b/acapy_agent/protocols/present_proof/v2_0/message_types.py @@ -32,17 +32,17 @@ # Format specifications ATTACHMENT_FORMAT = { PRES_20_PROPOSAL: { - V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-req@v2.0", + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-proposal@v1.0", V20PresFormat.Format.INDY.api: "hlindy/proof-req@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/definitions@v1.0", }, PRES_20_REQUEST: { - V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-req@v2.0", + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof-request@v1.0", V20PresFormat.Format.INDY.api: "hlindy/proof-req@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/definitions@v1.0", }, PRES_20: { - V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof@v2.0", + V20PresFormat.Format.ANONCREDS.api: "anoncreds/proof@v1.0", V20PresFormat.Format.INDY.api: "hlindy/proof@v2.0", V20PresFormat.Format.DIF.api: "dif/presentation-exchange/submission@v1.0", }, From 6ddb592c9929be4a76b329aeaeb874b76316ee24 Mon Sep 17 00:00:00 2001 From: Mourits de Beer <31511766+ff137@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:23:29 +0200 Subject: [PATCH 152/152] :art: Fix model name for consistency (#3382) From Anoncred to Anoncreds Signed-off-by: ff137 Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com> --- acapy_agent/anoncreds/models/presentation_request.py | 2 +- open-api/openapi.json | 4 ++-- open-api/swagger.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/acapy_agent/anoncreds/models/presentation_request.py b/acapy_agent/anoncreds/models/presentation_request.py index 05881dfdc8..12855e1ee6 100644 --- a/acapy_agent/anoncreds/models/presentation_request.py +++ b/acapy_agent/anoncreds/models/presentation_request.py @@ -299,7 +299,7 @@ class Meta: }, ), }, - name="AnoncredPresentationRequestNonRevokedSchema", + name="AnoncredsPresentationRequestNonRevokedSchema", ), allow_none=True, required=False, diff --git a/open-api/openapi.json b/open-api/openapi.json index 97913e91f2..07c228d3a8 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -7763,7 +7763,7 @@ }, "type" : "object" }, - "AnoncredPresentationRequestNonRevoked" : { + "AnoncredsPresentationRequestNonRevoked" : { "properties" : { "from" : { "description" : "Earliest time of interest in non-revocation interval", @@ -7895,7 +7895,7 @@ "type" : "string" }, "non_revoked" : { - "$ref" : "#/components/schemas/AnoncredPresentationRequestNonRevoked" + "$ref" : "#/components/schemas/AnoncredsPresentationRequestNonRevoked" }, "nonce" : { "description" : "Nonce", diff --git a/open-api/swagger.json b/open-api/swagger.json index fd4823dd48..c49ae1134d 100644 --- a/open-api/swagger.json +++ b/open-api/swagger.json @@ -6396,7 +6396,7 @@ } } }, - "AnoncredPresentationRequestNonRevoked" : { + "AnoncredsPresentationRequestNonRevoked" : { "type" : "object", "properties" : { "from" : { @@ -6530,7 +6530,7 @@ "description" : "Proof request name" }, "non_revoked" : { - "$ref" : "#/definitions/AnoncredPresentationRequestNonRevoked" + "$ref" : "#/definitions/AnoncredsPresentationRequestNonRevoked" }, "nonce" : { "type" : "string",