From b9038e8b1559dda2967366863ee95c40d1945a40 Mon Sep 17 00:00:00 2001 From: Daniel Bluhm Date: Mon, 25 Sep 2023 12:33:43 -0400 Subject: [PATCH] style: ruff fixes Signed-off-by: Daniel Bluhm --- conftest.py | 13 +++++- controller/controller.py | 9 +--- controller/logging.py | 5 +++ controller/onboarding.py | 21 +++++++++ controller/protocols.py | 45 +++++++------------ .../presenting_revoked_credential/example.py | 2 + examples/tunnels/example.py | 2 + pyproject.toml | 3 ++ 8 files changed, 63 insertions(+), 37 deletions(-) diff --git a/conftest.py b/conftest.py index ad62d47..0ef7d7a 100644 --- a/conftest.py +++ b/conftest.py @@ -1,3 +1,5 @@ +"""Pytest fixtures and configuration.""" + from pathlib import Path import subprocess @@ -12,6 +14,8 @@ class ExampleFailedException(Exception): """Raised when an example fails.""" def __init__(self, message: str, exit_status: int): + """Initialize ExampleFailedException.""" + super().__init__(message) self.exit_status = exit_status @@ -20,6 +24,8 @@ class ExampleRunner: """Run the docker-compose of a given example.""" def __init__(self, compose_file: str): + """Initialize ExampleRunner.""" + self.compose_file = compose_file def compose(self, *command: str) -> int: @@ -37,7 +43,7 @@ def compose(self, *command: str) -> int: return e.returncode def cleanup(self): - """Runs docker-compose down -v for cleanup""" + """Runs docker-compose down -v for cleanup.""" exit_status = self.compose("down", "-v") if exit_status != 0: raise ExampleFailedException( @@ -45,7 +51,7 @@ def cleanup(self): ) def handle_run(self, *command: str): - """Handles the run of docker-compose/ + """Handles the run of docker-compose/. raises exception if exit status is non-zero. """ @@ -97,10 +103,12 @@ class ExmapleItem(pytest.Item): """ def __init__(self, name: str, parent: pytest.File, compose_file: str): + """Initialize ExampleItem.""" super().__init__(name, parent) self.compose_file = compose_file def runtest(self) -> None: + """Run the test.""" ExampleRunner(self.compose_file).handle_run("run", "example") def repr_failure(self, excinfo): @@ -115,4 +123,5 @@ def repr_failure(self, excinfo): return f"Some other exectpion happened: {excinfo.value}" def reportinfo(self): + """Report info about the example.""" return self.fspath, 0, f"example: {self.name}" diff --git a/controller/controller.py b/controller/controller.py index bb4b0e5..0f9ed8d 100644 --- a/controller/controller.py +++ b/controller/controller.py @@ -120,6 +120,7 @@ def __init__( event_queue: Optional[Queue[Event]] = None, session: Optional[ClientSession] = None, ): + """Initialize and ACA-Py Controller.""" self.base_url = base_url self.label = label or "ACA-Py" self.headers = dict(headers or {}) @@ -350,7 +351,6 @@ async def post( params: Optional[Mapping[str, Any]] = None, headers: Optional[Mapping[str, str]] = None, ) -> Mapping[str, Any]: - """HTTP Post and return json.""" ... @overload @@ -364,7 +364,6 @@ async def post( headers: Optional[Mapping[str, str]] = None, response: None, ) -> Mapping[str, Any]: - """HTTP Post and return json.""" ... @overload @@ -378,7 +377,6 @@ async def post( headers: Optional[Mapping[str, str]] = None, response: Type[T], ) -> T: - """HTTP Post and parse returned json as type T.""" ... async def post( @@ -419,7 +417,6 @@ async def put( params: Optional[Mapping[str, Any]] = None, headers: Optional[Mapping[str, str]] = None, ) -> Mapping[str, Any]: - """HTTP Put and return json.""" ... @overload @@ -433,7 +430,6 @@ async def put( headers: Optional[Mapping[str, str]] = None, response: None, ) -> Mapping[str, Any]: - """HTTP Put and return json.""" ... @overload @@ -447,7 +443,6 @@ async def put( headers: Optional[Mapping[str, str]] = None, response: Type[T], ) -> T: - """HTTP Put and parse returned json as type T.""" ... async def put( @@ -564,7 +559,7 @@ async def record_with_values( event = await self.event_queue.get( lambda event: event.topic == topic and all( - [event.payload.get(key) == value for key, value in values.items()] + event.payload.get(key) == value for key, value in values.items() ), timeout=timeout, ) diff --git a/controller/logging.py b/controller/logging.py index 83c3fdd..89ed5d8 100644 --- a/controller/logging.py +++ b/controller/logging.py @@ -82,6 +82,11 @@ def pause_for_input( prompt: Optional[str] = None, file: TextIO = sys.stdout, ): + """Pause the program and wait for the user to hit enter. + + This helps the user to see the output of the program before it proceeds + past a step. + """ if file == sys.stdout and sys.stdout.isatty(): term = Terminal() prompt = prompt or "Press Enter to continue..." diff --git a/controller/onboarding.py b/controller/onboarding.py index b7ac377..4379575 100644 --- a/controller/onboarding.py +++ b/controller/onboarding.py @@ -1,3 +1,10 @@ +"""Functions for onboarding a DID to an Indy ledger. + +This uses common "self-serve" tools for onboarding, such as those provided by +VON network images or the self-serve apps provided by Indicio for their +networks. +""" + from abc import ABC, abstractmethod import json import logging @@ -20,6 +27,8 @@ def get_onboarder(genesis_url: str) -> Optional["Onboarder"]: + """Determine which onboarder to use based on genesis URL.""" + if genesis_url.endswith("/genesis"): # infer VonOnboarder return VonOnboarder(genesis_url.replace("/genesis", "register")) @@ -42,16 +51,23 @@ class OnboardingError(Exception): class Onboarder(ABC): + """Abstract base class for onboarders.""" + @abstractmethod async def onboard(self, did: str, verkey: str): """Onboard a DID.""" class VonOnboarder(Onboarder): + """Onboard a DID to a VON network.""" + def __init__(self, registration_url: str): + """Initialize the onboarder.""" self.registration_url = registration_url async def onboard(self, did: str, verkey: str): + """Onboard a DID to a VON network.""" + async with ClientSession() as session: async with session.post( self.registration_url, @@ -67,11 +83,16 @@ async def onboard(self, did: str, verkey: str): class SelfServeOnboarder(Onboarder): + """Onboard a DID to an Indicio network using self-serve.""" + def __init__(self, registration_url: str, network: str): + """Initialize the onboarder.""" self.registration_url = registration_url self.network = network async def onboard(self, did: str, verkey: str): + """Onboard a DID to an Indicio network using self-serve.""" + LOGGER.debug( "Anchoring DID %s using self-serve on network: %s", did, self.network ) diff --git a/controller/protocols.py b/controller/protocols.py index f4ad8e7..5d822a7 100644 --- a/controller/protocols.py +++ b/controller/protocols.py @@ -1,6 +1,5 @@ """Defintions of protocols flows.""" -from dataclasses import dataclass import json import logging from secrets import randbelow, token_hex @@ -35,6 +34,7 @@ LDProofVCDetail, LDProofVCDetailOptions, MediationRecord, + OobRecord, PingRequest, PresentationDefinition, ReceiveInvitationRequest, @@ -140,23 +140,6 @@ async def connection(inviter: Controller, invitee: Controller): return inviter_conn, invitee_conn -# TODO No model for OOBRecord in ACA-Py OpenAPI... -@dataclass -class OOBRecord: - oob_id: str - state: str - invi_msg_id: str - invitation: dict - connection_id: str - role: str - created_at: str - updated_at: str - trace: bool - their_service: Optional[dict] = None - attach_thread_id: Optional[str] = None - our_recipient_key: Optional[str] = None - - async def didexchange( inviter: Controller, invitee: Controller, @@ -171,10 +154,12 @@ async def didexchange( if not invite: invite_record = await inviter.post( "/out-of-band/create-invitation", - json=InvitationCreateRequest( - handshake_protocols=["https://didcomm.org/didexchange/1.0"], - use_public_did=use_public_did, - ), # pyright: ignore + json=InvitationCreateRequest.parse_obj( + { + "handshake_protocols": ["https://didcomm.org/didexchange/1.0"], + "use_public_did": use_public_did, + } + ), params=_make_params( auto_accept=auto_accept, multi_use=multi_use, @@ -197,14 +182,14 @@ async def didexchange( params=_make_params( use_existing_connection=use_existing_connection, ), - response=OOBRecord, + response=OobRecord, ) if use_existing_connection and invitee_oob_record == "reuse-accepted": inviter_oob_record = await inviter.record_with_values( topic="out_of_band", - record_type=OOBRecord, invi_msg_id=invite.id, + record_type=OobRecord, ) inviter_conn = await inviter.get( f"/connections/{inviter_oob_record.connection_id}", @@ -223,7 +208,7 @@ async def didexchange( ) inviter_oob_record = await inviter.record_with_values( topic="out_of_band", - record_type=OOBRecord, + record_type=OobRecord, connection_id=inviter_conn.connection_id, state="done", ) @@ -386,6 +371,7 @@ async def indy_issue_credential_v1( attributes: Mapping[str, str], ) -> Tuple[V10CredentialExchange, V10CredentialExchange]: """Issue an indy credential using issue-credential/1.0. + Issuer and holder should already be connected. """ issuer_cred_ex = await issuer.post( @@ -473,6 +459,7 @@ async def indy_issue_credential_v2( attributes: Mapping[str, str], ) -> Tuple[V20CredExRecordDetail, V20CredExRecordDetail]: """Issue an indy credential using issue-credential/2.0. + Issuer and holder should already be connected. """ @@ -803,8 +790,9 @@ async def indy_anoncreds_revoke( notify_version: str = "v1_0", ): """Revoking an Indy credential using revocation revoke. + V1.0: V10CredentialExchange - V2.0: V20CredExRecordDetail + V2.0: V20CredExRecordDetail. """ if notify and holder_connection_id is None: return ( @@ -853,9 +841,10 @@ async def indy_anoncreds_publish_revocation( publish: bool = False, notify: bool = True, ): - """Publishing revocation of indy credential + """Publishing revocation of indy credential. + V1.0: V10CredentialExchange - V2.0: V20CredExRecordDetail + V2.0: V20CredExRecordDetail. """ if isinstance(cred_ex, V10CredentialExchange): await issuer.post( diff --git a/examples/presenting_revoked_credential/example.py b/examples/presenting_revoked_credential/example.py index 32eb517..59eb29a 100644 --- a/examples/presenting_revoked_credential/example.py +++ b/examples/presenting_revoked_credential/example.py @@ -1,4 +1,5 @@ """Minimal reproducible example script. + This script is for you to use to reproduce a bug or demonstrate a feature. """ @@ -25,6 +26,7 @@ def summary(presentation: V20PresExRecord) -> str: + """Summarize a presentation exchange record.""" request = presentation.pres_request return "Summary: " + json.dumps( { diff --git a/examples/tunnels/example.py b/examples/tunnels/example.py index 32eb517..59eb29a 100644 --- a/examples/tunnels/example.py +++ b/examples/tunnels/example.py @@ -1,4 +1,5 @@ """Minimal reproducible example script. + This script is for you to use to reproduce a bug or demonstrate a feature. """ @@ -25,6 +26,7 @@ def summary(presentation: V20PresExRecord) -> str: + """Summarize a presentation exchange record.""" request = presentation.pres_request return "Summary: " + json.dumps( { diff --git a/pyproject.toml b/pyproject.toml index d3db371..fc6bb94 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,9 @@ ignore = [ "D104", # Don't require docstring in public package ] +# The models module is generated +extend-exclude = ["controller/models.py"] + line-length = 90 [tool.ruff.per-file-ignores]