diff --git a/aries_cloudagent/anoncreds/base.py b/aries_cloudagent/anoncreds/base.py index 6627beab8a..402895357a 100644 --- a/aries_cloudagent/anoncreds/base.py +++ b/aries_cloudagent/anoncreds/base.py @@ -13,14 +13,13 @@ from .models.anoncreds_revocation import ( GetRevListResult, GetRevRegDefResult, - RevRegDef, - RevRegDefResult, RevList, RevListResult, + RevRegDef, + RevRegDefResult, ) from .models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult - T = TypeVar("T") diff --git a/aries_cloudagent/anoncreds/default/legacy_indy/registry.py b/aries_cloudagent/anoncreds/default/legacy_indy/registry.py index 9f1f95ed16..e3168c8974 100644 --- a/aries_cloudagent/anoncreds/default/legacy_indy/registry.py +++ b/aries_cloudagent/anoncreds/default/legacy_indy/registry.py @@ -636,6 +636,12 @@ async def register_revocation_list( profile, rev_list, rev_reg_def.type, rev_reg_entry ) + seq_no = None + try: + seq_no = rev_entry_res["result"]["txnMetadata"]["seqNo"] + except KeyError: + LOGGER.warning("Failed to parse sequence number from ledger response") + return RevListResult( job_id=None, revocation_list_state=RevListState( @@ -643,8 +649,10 @@ async def register_revocation_list( revocation_list=rev_list, ), registration_metadata={}, - revocation_list_metadata={ - "seqNo": rev_entry_res["result"]["txnMetadata"]["seqNo"], + revocation_list_metadata={} + if seq_no is None + else { + "seqNo": seq_no, }, ) diff --git a/aries_cloudagent/anoncreds/issuer.py b/aries_cloudagent/anoncreds/issuer.py index 2e99cef3b4..9a5333f577 100644 --- a/aries_cloudagent/anoncreds/issuer.py +++ b/aries_cloudagent/anoncreds/issuer.py @@ -6,8 +6,6 @@ from time import time from typing import Optional, Sequence -from aries_askar import AskarError - from anoncreds import ( AnoncredsError, Credential, @@ -15,7 +13,7 @@ CredentialOffer, Schema, ) - +from aries_askar import AskarError from ..askar.profile_anon import ( AskarAnoncredsProfile, diff --git a/aries_cloudagent/anoncreds/models/anoncreds_cred_def.py b/aries_cloudagent/anoncreds/models/anoncreds_cred_def.py index aad704980b..70dc3619c5 100644 --- a/aries_cloudagent/anoncreds/models/anoncreds_cred_def.py +++ b/aries_cloudagent/anoncreds/models/anoncreds_cred_def.py @@ -1,14 +1,19 @@ """Anoncreds cred def OpenAPI validators.""" from typing import Optional -from typing_extensions import Literal from anoncreds import CredentialDefinition from marshmallow import EXCLUDE, fields from marshmallow.validate import OneOf +from typing_extensions import Literal from ...messaging.models.base import BaseModel, BaseModelSchema -from ...messaging.valid import NUM_STR_WHOLE_VALIDATE, NUM_STR_WHOLE_EXAMPLE - +from ...messaging.valid import ( + INDY_CRED_DEF_ID_EXAMPLE, + INDY_OR_KEY_DID_EXAMPLE, + INDY_SCHEMA_ID_EXAMPLE, + NUM_STR_WHOLE_EXAMPLE, + NUM_STR_WHOLE_VALIDATE, +) NUM_STR_WHOLE = {"validate": NUM_STR_WHOLE_VALIDATE, "example": NUM_STR_WHOLE_EXAMPLE} @@ -239,12 +244,18 @@ class Meta: issuer_id = fields.Str( description="Issuer Identifier of the credential definition or schema", data_key="issuerId", + example=INDY_OR_KEY_DID_EXAMPLE, + ) + schema_id = fields.Str( + data_key="schemaId", + description="Schema identifier", + example=INDY_SCHEMA_ID_EXAMPLE, ) - schema_id = fields.Str(data_key="schemaId", description="Schema identifier") type = fields.Str(validate=OneOf(["CL"])) tag = fields.Str( description="""The tag value passed in by the Issuer to - an AnonCred's Credential Definition create and store implementation.""" + an AnonCred's Credential Definition create and store implementation.""", + example="default", ) value = fields.Nested(CredDefValueSchema()) @@ -303,7 +314,9 @@ class Meta: ) ) credential_definition_id = fields.Str( - description="credential definition id", allow_none=True + description="credential definition id", + allow_none=True, + example=INDY_CRED_DEF_ID_EXAMPLE, ) credential_definition = fields.Nested( CredDefSchema(), description="credential definition" @@ -403,7 +416,10 @@ class Meta: model_class = GetCredDefResult unknown = EXCLUDE - credential_definition_id = fields.Str(description="credential definition id") + credential_definition_id = fields.Str( + description="credential definition id", + example=INDY_CRED_DEF_ID_EXAMPLE, + ) credential_definition = fields.Nested( CredDefSchema(), description="credential definition" ) diff --git a/aries_cloudagent/anoncreds/models/anoncreds_revocation.py b/aries_cloudagent/anoncreds/models/anoncreds_revocation.py index 6e5bb830b0..3adde8bfa6 100644 --- a/aries_cloudagent/anoncreds/models/anoncreds_revocation.py +++ b/aries_cloudagent/anoncreds/models/anoncreds_revocation.py @@ -1,10 +1,18 @@ """Anoncreds cred def OpenAPI validators.""" from typing import Any, Dict, List, Optional -from typing_extensions import Literal from anoncreds import RevocationRegistryDefinition, RevocationStatusList from marshmallow import EXCLUDE, fields from marshmallow.validate import OneOf +from typing_extensions import Literal + +from aries_cloudagent.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 @@ -52,10 +60,17 @@ class Meta: model_class = RevRegDefValue unknown = EXCLUDE - public_keys = fields.Dict(data_key="publicKeys") - max_cred_num = fields.Int(data_key="maxCredNum") - tails_location = fields.Str(data_key="tailsLocation") - tails_hash = fields.Str(data_key="tailsHash") + public_keys = fields.Dict( + data_key="publicKeys", example=INDY_RAW_PUBLIC_KEY_EXAMPLE + ) + max_cred_num = fields.Int(data_key="maxCredNum", example=666) + tails_location = fields.Str( + data_key="tailsLocation", + example="https://tails-server.com/hash/7Qen9RDyemMuV7xGQvp7NjwMSpyHieJyBakycxN7dX7P", + ) + tails_hash = fields.Str( + data_key="tailsHash", example="7Qen9RDyemMuV7xGQvp7NjwMSpyHieJyBakycxN7dX7P" + ) class RevRegDef(BaseModel): @@ -116,13 +131,17 @@ class Meta: issuer_id = fields.Str( description="Issuer Identifier of the credential definition or schema", data_key="issuerId", + example=INDY_OR_KEY_DID_EXAMPLE, ) type = fields.Str(data_key="revocDefType") cred_def_id = fields.Str( description="Credential definition identifier", data_key="credDefId", + example=INDY_CRED_DEF_ID_EXAMPLE, + ) + tag = fields.Str( + description="tag for the revocation registry definition", example="default" ) - tag = fields.Str(description="tag for the revocation registry definition") value = fields.Nested(RevRegDefValueSchema()) @@ -184,7 +203,8 @@ class Meta: ) ) revocation_registry_definition_id = fields.Str( - description="revocation registry definition id" + description="revocation registry definition id", + example=INDY_REV_REG_ID_EXAMPLE, ) revocation_registry_definition = fields.Nested( RevRegDefSchema(), description="revocation registry definition" @@ -362,20 +382,28 @@ class Meta: issuer_id = fields.Str( description="Issuer Identifier of the credential definition or schema", data_key="issuerId", + example=INDY_OR_KEY_DID_EXAMPLE, ) rev_reg_def_id = fields.Str( - description="", + description="The ID of the revocation registry definition", data_key="revRegDefId", + example=INDY_REV_REG_ID_EXAMPLE, ) revocation_list = fields.List( fields.Int(), description="Bit list representing revoked credentials", data_key="revocationList", + example=[0, 1, 1, 0], + ) + current_accumulator = fields.Str( + description="The current accumalator value", + example="21 118...1FB", + data_key="currentAccumulator", ) - current_accumulator = fields.Str(data_key="currentAccumulator") timestamp = fields.Int( description="Timestamp at which revocation list is applicable", required=False, + example=INDY_ISO8601_DATETIME_EXAMPLE, ) diff --git a/aries_cloudagent/anoncreds/models/anoncreds_schema.py b/aries_cloudagent/anoncreds/models/anoncreds_schema.py index b70639d5c1..9528eb5ab7 100644 --- a/aries_cloudagent/anoncreds/models/anoncreds_schema.py +++ b/aries_cloudagent/anoncreds/models/anoncreds_schema.py @@ -2,10 +2,14 @@ from typing import Any, Dict, List, Optional +from anoncreds import Schema from marshmallow import EXCLUDE, fields from marshmallow.validate import OneOf -from anoncreds import Schema +from aries_cloudagent.messaging.valid import ( + INDY_OR_KEY_DID_EXAMPLE, + INDY_SCHEMA_ID_EXAMPLE, +) from ...messaging.models.base import BaseModel, BaseModelSchema @@ -60,6 +64,7 @@ class Meta: issuer_id = fields.Str( description="Issuer Identifier of the credential definition or schema", data_key="issuerId", + example=INDY_OR_KEY_DID_EXAMPLE, ) attr_names = fields.List( fields.Str( @@ -69,10 +74,8 @@ class Meta: description="Schema attribute names", data_key="attrNames", ) - name = fields.Str( - description="Schema name", - ) - version = fields.Str(description="Schema version") + name = fields.Str(description="Schema name", example="Example schema") + version = fields.Str(description="Schema version", example="1.0") class GetSchemaResult(BaseModel): @@ -127,7 +130,9 @@ class Meta: unknown = EXCLUDE schema_value = fields.Nested(AnonCredsSchemaSchema(), data_key="schema") - schema_id = fields.Str(data_key="schemaId", description="Schema identifier") + schema_id = fields.Str( + description="Schema identifier", example=INDY_SCHEMA_ID_EXAMPLE + ) resolution_metadata = fields.Dict() schema_metadata = fields.Dict() @@ -179,7 +184,10 @@ class Meta: ] ) ) - schema_id = fields.Str(description="Schema identifier") + schema_id = fields.Str( + description="Schema identifier", + example=INDY_SCHEMA_ID_EXAMPLE, + ) schema_value = fields.Nested(AnonCredsSchemaSchema(), data_key="schema") diff --git a/aries_cloudagent/anoncreds/registry.py b/aries_cloudagent/anoncreds/registry.py index 9a47203c05..e205bc0150 100644 --- a/aries_cloudagent/anoncreds/registry.py +++ b/aries_cloudagent/anoncreds/registry.py @@ -53,6 +53,10 @@ async def _resolver_for_identifier(self, identifier: str) -> BaseAnonCredsResolv for resolver in self.resolvers if await resolver.supports(identifier) ] + if len(resolvers) == 0: + raise AnonCredsResolutionError( + f"No resolver available for identifier {identifier}" + ) if len(resolvers) > 1: raise AnonCredsResolutionError( f"More than one resolver found for identifier {identifier}" @@ -67,6 +71,11 @@ async def _registrar_for_identifier( for registrar in self.registrars if await registrar.supports(identifier) ] + if len(registrars) == 0: + raise AnonCredsRegistrationError( + f"No registrar available for identifier {identifier}" + ) + if len(registrars) > 1: raise AnonCredsRegistrationError( f"More than one registrar found for identifier {identifier}" diff --git a/aries_cloudagent/anoncreds/routes.py b/aries_cloudagent/anoncreds/routes.py index fe7aea77b1..2320515e10 100644 --- a/aries_cloudagent/anoncreds/routes.py +++ b/aries_cloudagent/anoncreds/routes.py @@ -12,11 +12,19 @@ ) from marshmallow import fields +from aries_cloudagent.ledger.error import LedgerError + from ..admin.request_context import AdminRequestContext from ..askar.profile import AskarProfile from ..core.event_bus import EventBus from ..messaging.models.openapi import OpenAPISchema -from ..messaging.valid import UUIDFour +from ..messaging.valid import ( + INDY_CRED_DEF_ID_EXAMPLE, + INDY_OR_KEY_DID_EXAMPLE, + INDY_REV_REG_ID_EXAMPLE, + INDY_SCHEMA_ID_EXAMPLE, + UUIDFour, +) from ..revocation.error import RevocationError, RevocationNotSupportedError from ..revocation_anoncreds.manager import RevocationManager, RevocationManagerError from ..revocation_anoncreds.routes import ( @@ -27,7 +35,11 @@ TxnOrPublishRevocationsResultSchema, ) from ..storage.error import StorageError, StorageNotFoundError -from .base import AnonCredsObjectNotFound, AnonCredsRegistrationError +from .base import ( + AnonCredsObjectNotFound, + AnonCredsRegistrationError, + AnonCredsResolutionError, +) from .issuer import AnonCredsIssuer, AnonCredsIssuerError from .models.anoncreds_cred_def import CredDefResultSchema, GetCredDefResultSchema from .models.anoncreds_revocation import RevListResultSchema, RevRegDefResultSchema @@ -48,33 +60,43 @@ class SchemaIdMatchInfo(OpenAPISchema): """Path parameters and validators for request taking schema id.""" - schema_id = fields.Str(data_key="schemaId", description="Schema identifier") + schema_id = fields.Str( + description="Schema identifier", + example=INDY_SCHEMA_ID_EXAMPLE, + ) class CredIdMatchInfo(OpenAPISchema): """Path parameters and validators for request taking credential id.""" cred_def_id = fields.Str( - description="Credential identifier", required=True, example=UUIDFour.EXAMPLE + description="Credential identifier", + required=True, + example=INDY_CRED_DEF_ID_EXAMPLE, ) class InnerCredDefSchema(OpenAPISchema): """Parameters and validators for credential definition.""" - tag = fields.Str(description="Credential definition tag") - schemaId = fields.Str(data_key="schemaId", description="Schema identifier") - issuerId = fields.Str( - description="Issuer Identifier of the credential definition or schema", + tag = fields.Str(description="Credential definition tag", example="default") + schema_id = fields.Str( + description="Schema identifier", + data_key="schemaId", + example=INDY_SCHEMA_ID_EXAMPLE, + ) + issuer_id = fields.Str( + data_key="issuerId", + example=INDY_OR_KEY_DID_EXAMPLE, ) class CredDefPostOptionsSchema(OpenAPISchema): """Parameters and validators for credential definition options.""" - endorser_connection_id = fields.Str(required=False) + endorser_connection_id = fields.Str(required=False, example=UUIDFour.EXAMPLE) support_revocation = fields.Bool(required=False) - revocation_registry_size = fields.Int(required=False) + revocation_registry_size = fields.Int(required=False, example=666) class CredDefPostRequestSchema(OpenAPISchema): @@ -89,12 +111,14 @@ class CredDefsQueryStringSchema(OpenAPISchema): issuer_id = fields.Str( description="Issuer Identifier of the credential definition", + example=INDY_OR_KEY_DID_EXAMPLE, ) - schema_id = fields.Str(data_key="schemaId", description="Schema identifier") - schema_name = fields.Str( - description="Schema name", + schema_id = fields.Str( + description="Schema identifier", + example=INDY_SCHEMA_ID_EXAMPLE, ) - schema_version = fields.Str(description="Schema version") + schema_name = fields.Str(description="Schema name", example="Example schema") + schema_version = fields.Str(description="Schema version", example="1.0") class SchemaPostOptionSchema(OpenAPISchema): @@ -114,7 +138,7 @@ class SchemaPostRequestSchema(OpenAPISchema): options = fields.Nested(SchemaPostOptionSchema()) -@docs(tags=["anoncreds"], summary="") +@docs(tags=["anoncreds"], summary="Create a schema on the connected ledger") @request_schema(SchemaPostRequestSchema()) @response_schema(SchemaResultSchema(), 200, description="") async def schemas_post(request: web.BaseRequest): @@ -155,22 +179,28 @@ async def schemas_post(request: web.BaseRequest): context: AdminRequestContext = request["context"] body = await request.json() - options = body.get("option") + options = body.get("options") schema_data = body.get("schema") + if schema_data is None: + raise web.HTTPBadRequest(reason="schema object is required") + issuer_id = schema_data.get("issuerId") attr_names = schema_data.get("attrNames") name = schema_data.get("name") version = schema_data.get("version") issuer = AnonCredsIssuer(context.profile) - result = await issuer.create_and_register_schema( - issuer_id, name, version, attr_names, options=options - ) - return web.json_response(result.serialize()) + try: + result = await issuer.create_and_register_schema( + issuer_id, name, version, attr_names, options=options + ) + return web.json_response(result.serialize()) + except (AnonCredsIssuerError, AnonCredsRegistrationError) as e: + raise web.HTTPBadRequest(reason=e.roll_up) from e -@docs(tags=["anoncreds"], summary="") +@docs(tags=["anoncreds"], summary="Retrieve an individual schemas details") @match_info_schema(SchemaIdMatchInfo()) @response_schema(GetSchemaResultSchema(), 200, description="") async def schema_get(request: web.BaseRequest): @@ -185,24 +215,24 @@ async def schema_get(request: web.BaseRequest): """ context: AdminRequestContext = request["context"] anoncreds_registry = context.inject(AnonCredsRegistry) - schema_id = request.match_info["schemaId"] + schema_id = request.match_info["schema_id"] try: schema = await anoncreds_registry.get_schema(context.profile, schema_id) return web.json_response(schema.serialize()) except AnonCredsObjectNotFound: raise web.HTTPNotFound(reason=f"Schema not found: {schema_id}") + except AnonCredsResolutionError as e: + raise web.HTTPBadRequest(reason=e.roll_up) class SchemasQueryStringSchema(OpenAPISchema): """Parameters and validators for query string in schemas list query.""" - schema_name = fields.Str( - description="Schema name", - example="example-schema", - ) - schema_version = fields.Str(description="Schema version") + schema_name = fields.Str(description="Schema name", example="example-schema") + schema_version = fields.Str(description="Schema version", example="1.0") schema_issuer_id = fields.Str( - description="Issuer Identifier of the credential definition or schema", + description="Issuer identifier of the schema", + example=INDY_OR_KEY_DID_EXAMPLE, ) @@ -210,14 +240,11 @@ class GetSchemasResponseSchema(OpenAPISchema): """Parameters and validators for schema list all response.""" schema_ids = fields.List( - fields.Str( - data_key="schemaIds", - description="Schema identifier", - ) + fields.Str(description="Schema identifier", example=INDY_SCHEMA_ID_EXAMPLE) ) -@docs(tags=["anoncreds"], summary="") +@docs(tags=["anoncreds"], summary="Retrieve all schema ids") @querystring_schema(SchemasQueryStringSchema()) @response_schema(GetSchemasResponseSchema(), 200, description="") async def schemas_get(request: web.BaseRequest): @@ -243,7 +270,9 @@ async def schemas_get(request: web.BaseRequest): return web.json_response({"schema_ids": schema_ids}) -@docs(tags=["anoncreds"], summary="") +@docs( + tags=["anoncreds"], summary="Create a credential definition on the connected ledger" +) @request_schema(CredDefPostRequestSchema()) @response_schema(CredDefResultSchema(), 200, description="") async def cred_def_post(request: web.BaseRequest): @@ -260,22 +289,36 @@ async def cred_def_post(request: web.BaseRequest): body = await request.json() options = body.get("options") cred_def = body.get("credential_definition") + + if cred_def is None: + raise web.HTTPBadRequest(reason="cred_def object is required") + issuer_id = cred_def.get("issuerId") schema_id = cred_def.get("schemaId") tag = cred_def.get("tag") issuer = AnonCredsIssuer(context.profile) - result = await issuer.create_and_register_credential_definition( - issuer_id, - schema_id, - tag, - options=options, - ) - - return web.json_response(result.serialize()) + try: + result = await issuer.create_and_register_credential_definition( + issuer_id, + schema_id, + tag, + options=options, + ) + return web.json_response(result.serialize()) + except ( + AnonCredsObjectNotFound, + AnonCredsResolutionError, + ValueError, + ) as e: + raise web.HTTPBadRequest(reason=e.roll_up) + except AnonCredsIssuerError as e: + raise web.HTTPServerError(reason=e.roll_up) -@docs(tags=["anoncreds"], summary="") +@docs( + tags=["anoncreds"], summary="Retrieve an individual credential definition details" +) @match_info_schema(CredIdMatchInfo()) @response_schema(GetCredDefResultSchema(), 200, description="") async def cred_def_get(request: web.BaseRequest): @@ -291,10 +334,15 @@ async def cred_def_get(request: web.BaseRequest): context: AdminRequestContext = request["context"] anon_creds_registry = context.inject(AnonCredsRegistry) credential_id = request.match_info["cred_def_id"] - result = await anon_creds_registry.get_credential_definition( - context.profile, credential_id - ) - return web.json_response(result.serialize()) + try: + result = await anon_creds_registry.get_credential_definition( + context.profile, credential_id + ) + return web.json_response(result.serialize()) + except AnonCredsObjectNotFound: + raise web.HTTPBadRequest( + reason=f"Credential definition {credential_id} not found" + ) class GetCredDefsResponseSchema(OpenAPISchema): @@ -303,11 +351,12 @@ class GetCredDefsResponseSchema(OpenAPISchema): credential_definition_ids = fields.List( fields.Str( description="credential definition identifiers", + example="GvLGiRogTJubmj5B36qhYz:3:CL:8:faber.agent.degree_schema", ) ) -@docs(tags=["anoncreds"], summary="") +@docs(tags=["anoncreds"], summary="Retrieve all credential definition ids") @querystring_schema(CredDefsQueryStringSchema()) @response_schema(GetCredDefsResponseSchema(), 200, description="") async def cred_defs_get(request: web.BaseRequest): @@ -329,41 +378,70 @@ async def cred_defs_get(request: web.BaseRequest): schema_name=request.query.get("schema_name"), schema_version=request.query.get("schema_version"), ) - return web.json_response(cred_def_ids) + return web.json_response({"credential_definition_ids": cred_def_ids}) -class RevRegCreateRequestSchema(OpenAPISchema): +class InnerRevRegDefSchema(OpenAPISchema): """Request schema for revocation registry creation request.""" issuer_id = fields.Str( description="Issuer Identifier of the credential definition or schema", data_key="issuerId", + example=INDY_OR_KEY_DID_EXAMPLE, ) cred_def_id = fields.Str( description="Credential definition identifier", data_key="credDefId", + example=INDY_SCHEMA_ID_EXAMPLE, + ) + tag = fields.Str(description="tag for revocation registry", example="default") + max_cred_num = fields.Int( + description="Maximum number of credential revocations per registry", + data_key="maxCredNum", + example=666, ) - tag = fields.Str(description="tag for revocation registry") - max_cred_num = fields.Int(data_key="maxCredNum") - registry_type = fields.Str( - description="Revocation registry type", - data_key="type", + + +class RevRegDefOptionsSchema(OpenAPISchema): + """Parameters and validators for rev reg def options.""" + + endorser_connection_id = fields.Str( + description="Connection identifier (optional) (this is an example)", required=False, + example=UUIDFour.EXAMPLE, ) -@docs(tags=["anoncreds"], summary="") +class RevRegCreateRequestSchema(OpenAPISchema): + """Wrapper for revocation registry creation request.""" + + revocation_registry_definition = fields.Nested(InnerRevRegDefSchema()) + options = fields.Nested(RevRegDefOptionsSchema()) + + +@docs( + tags=["anoncreds"], + summary="Create and publish a registration revocation on the connected ledger", +) @request_schema(RevRegCreateRequestSchema()) @response_schema(RevRegDefResultSchema(), 200, description="") async def rev_reg_def_post(request: web.BaseRequest): """Request handler for creating revocation registry definition.""" context: AdminRequestContext = request["context"] body = await request.json() - issuer_id = body.get("issuerId") - cred_def_id = body.get("credDefId") - max_cred_num = body.get("maxCredNum") + + revocation_registry_definition = body.get("revocation_registry_definition") options = body.get("options") + if revocation_registry_definition is None: + raise web.HTTPBadRequest( + reason="revocation_registry_definition object is required" + ) + + issuer_id = revocation_registry_definition.get("issuerId") + cred_def_id = revocation_registry_definition.get("credDefId") + max_cred_num = revocation_registry_definition.get("maxCredNum") + issuer = AnonCredsIssuer(context.profile) revocation = AnonCredsRevocation(context.profile) # check we published this cred def @@ -384,12 +462,9 @@ async def rev_reg_def_post(request: web.BaseRequest): options=options, ) ) - except RevocationNotSupportedError as e: - raise web.HTTPBadRequest(reason=e.message) from e - except AnonCredsRevocationError as e: - raise web.HTTPBadRequest(reason=e.message) from e - - return web.json_response(result.serialize()) + return web.json_response(result.serialize()) + except (RevocationNotSupportedError, AnonCredsRevocationError) as e: + raise web.HTTPBadRequest(reason=e.roll_up) from e class RevListCreateRequestSchema(OpenAPISchema): @@ -397,18 +472,21 @@ class RevListCreateRequestSchema(OpenAPISchema): rev_reg_def_id = fields.Str( description="Revocation registry definition identifier", - data_key="revRegDefId", + example=INDY_REV_REG_ID_EXAMPLE, ) -@docs(tags=["anoncreds"], summary="") +@docs( + tags=["anoncreds"], + summary="Create and publish a revocation status list on the connected ledger", +) @request_schema(RevListCreateRequestSchema()) @response_schema(RevListResultSchema(), 200, description="") async def rev_list_post(request: web.BaseRequest): """Request handler for creating registering a revocation list.""" context: AdminRequestContext = request["context"] body = await request.json() - rev_reg_def_id = body.get("revRegDefId") + rev_reg_def_id = body.get("rev_reg_def_id") options = body.get("options") revocation = AnonCredsRevocation(context.profile) @@ -420,14 +498,12 @@ async def rev_list_post(request: web.BaseRequest): ) ) LOGGER.debug("published revocation list for: %s", rev_reg_def_id) - + return web.json_response(result.serialize()) except StorageNotFoundError as err: raise web.HTTPNotFound(reason=err.roll_up) from err - except AnonCredsRevocationError as err: + except (AnonCredsRevocationError, LedgerError) as err: raise web.HTTPBadRequest(reason=err.roll_up) from err - return web.json_response(result.serialize()) - @docs( tags=["anoncreds"], @@ -454,21 +530,19 @@ async def upload_tails_file(request: web.BaseRequest): raise web.HTTPNotFound(reason="No rev reg def found") await revocation.upload_tails_file(rev_reg_def) - + return web.json_response({}) except AnonCredsIssuerError as e: raise web.HTTPInternalServerError(reason=str(e)) from e - return web.json_response({}) - @docs( tags=["anoncreds"], - summary="Upload local tails file to server", + summary="Update the active registry", ) @match_info_schema(RevRegIdMatchInfoSchema()) @response_schema(RevocationModuleResponseSchema(), description="") async def set_active_registry(request: web.BaseRequest): - """Request handler to upload local tails file for revocation registry. + """Request handler to set the active registry. Args: request: aiohttp request object @@ -479,11 +553,10 @@ async def set_active_registry(request: web.BaseRequest): try: revocation = AnonCredsRevocation(context.profile) await revocation.set_active_registry(rev_reg_id) + return web.json_response({}) except AnonCredsRevocationError as e: raise web.HTTPInternalServerError(reason=str(e)) from e - return web.json_response({}) - @docs( tags=["anoncreds"], @@ -526,6 +599,7 @@ async def revoke(request: web.BaseRequest): else: # no cred_ex_id so we can safely splat the body await rev_manager.revoke_credential(**body) + return web.json_response({}) except ( RevocationManagerError, AnonCredsRevocationError, @@ -535,8 +609,6 @@ async def revoke(request: web.BaseRequest): ) as err: raise web.HTTPBadRequest(reason=err.roll_up) from err - return web.json_response({}) - @docs(tags=["revocation"], summary="Publish pending revocations to ledger") @request_schema(PublishRevocationsSchema()) @@ -561,6 +633,7 @@ async def publish_revocations(request: web.BaseRequest): rev_reg_resp = await rev_manager.publish_pending_revocations( rrid2crid, ) + return web.json_response({"rrid2crid": rev_reg_resp}) except ( RevocationError, StorageError, @@ -569,8 +642,6 @@ async def publish_revocations(request: web.BaseRequest): ) as err: raise web.HTTPBadRequest(reason=err.roll_up) from err - return web.json_response({"rrid2crid": rev_reg_resp}) - async def register(app: web.Application): """Register routes.""" @@ -578,7 +649,7 @@ async def register(app: web.Application): app.add_routes( [ web.post("/anoncreds/schema", schemas_post), - web.get("/anoncreds/schema/{schemaId}", schema_get, allow_head=False), + web.get("/anoncreds/schema/{schema_id}", schema_get, allow_head=False), web.get("/anoncreds/schemas", schemas_get, allow_head=False), web.post("/anoncreds/credential-definition", cred_def_post), web.get( diff --git a/aries_cloudagent/anoncreds/tests/mock_objects.py b/aries_cloudagent/anoncreds/tests/mock_objects.py index 8398dd4494..0968da95e2 100644 --- a/aries_cloudagent/anoncreds/tests/mock_objects.py +++ b/aries_cloudagent/anoncreds/tests/mock_objects.py @@ -236,3 +236,16 @@ "rev_reg": None, "witness": None, } + +MOCK_REV_REG_DEF = { + "issuerId": "did:web:example.org", + "revocDefType": "CL_ACCUM", + "credDefId": "Gs6cQcvrtWoZKsbBhD3dQJ:3:CL:140384:mctc", + "tag": "MyCustomCredentialDefinition", + "value": { + "publicKeys": {"accumKey": {"z": "1 0BB...386"}}, + "maxCredNum": 666, + "tailsLocation": "https://my.revocations.tails/tailsfile.txt", + "tailsHash": "91zvq2cFmBZmHCcLqFyzv7bfehHH5rMhdAG5wTjqy2PE", + }, +} diff --git a/aries_cloudagent/anoncreds/tests/test_revocation.py b/aries_cloudagent/anoncreds/tests/test_revocation.py new file mode 100644 index 0000000000..015cc7e1e4 --- /dev/null +++ b/aries_cloudagent/anoncreds/tests/test_revocation.py @@ -0,0 +1,1354 @@ +import http +import json +import os + +import pytest +from anoncreds import ( + Credential, + CredentialDefinition, + RevocationRegistryDefinition, + RevocationStatusList, + Schema, +) +from aries_askar import AskarError, AskarErrorCode +from asynctest import TestCase +from requests import RequestException, Session + +from aries_cloudagent.anoncreds.issuer import AnonCredsIssuer +from aries_cloudagent.anoncreds.models.anoncreds_revocation import ( + RevList, + RevListResult, + RevListState, + RevRegDef, + RevRegDefResult, + RevRegDefState, + RevRegDefValue, +) +from aries_cloudagent.anoncreds.models.anoncreds_schema import ( + AnonCredsSchema, + GetSchemaResult, +) +from aries_cloudagent.anoncreds.tests.mock_objects import ( + MOCK_REV_REG_DEF, +) +from aries_cloudagent.askar.profile_anon import ( + AskarAnoncredsProfile, +) +from aries_cloudagent.core.event_bus import Event, MockEventBus +from aries_cloudagent.core.in_memory.profile import ( + InMemoryProfile, + InMemoryProfileSession, +) +from aries_cloudagent.tests import mock + +from .. import revocation as test_module + +rev_reg_def = RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", +) + +rev_list = RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[0, 1, 1, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", +) + + +class MockRevRegDefEntry: + def __init__(self, name="name"): + self.name = name + + tags = { + "state": RevRegDefState.STATE_ACTION, + } + value = "mock_value" + value_json = { + "value": { + "maxCredNum": 100, + "publicKeys": {"accumKey": {"z": "1 0BB...386"}}, + "tailsHash": "string", + "tailsLocation": "string", + }, + "credDefId": "CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + "issuerId": "CsQY9MGeD3CQP4EyuVFo5m", + "revocDefType": "CL_ACCUM", + "tag": "string", + } + + +class MockEntry: + def __init__( + self, name="name", value_json="", raw_value="raw-value", value="value", tags={} + ) -> None: + self.name = name + self.value_json = value_json + self.raw_value = raw_value + self.value = value + self.tags = tags + + +class MockRevListEntry: + tags = { + "state": RevListState.STATE_ACTION, + } + value = "mock_value" + value_json = { + "rev_list": { + "issuerId": "CsQY9MGeD3CQP4EyuVFo5m", + "revRegDefId": "4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + "revocationList": [0, 1, 1, 0], + "currentAccumulator": "21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + "timestamp": 1669640864487, + } + } + + +@pytest.mark.anoncreds +class TestAnonCredsRevocation(TestCase): + def setUp(self) -> None: + self.profile = InMemoryProfile.test_profile( + settings={ + "wallet-type": "askar-anoncreds", + "tails_server_base_url": "http://tails-server.com", + }, + profile_class=AskarAnoncredsProfile, + ) + self.revocation = test_module.AnonCredsRevocation(self.profile) + + async def test_init(self): + assert self.revocation.profile == self.profile + + async def test_notify(self): + self.profile.inject = mock.Mock(return_value=MockEventBus()) + await self.revocation.notify(Event(topic="test-topic")) + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_create_and_register_revocation_registry_definition_fails_to_get_cred_def( + self, mock_handle + ): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + None, + ] + ) + + # Anoncreds error + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.create_and_register_revocation_registry_definition( + issuer_id="test-issuer-id", + cred_def_id="test-cred-def-id", + registry_type="test-registry-type", + tag="test-tag", + max_cred_num=100, + ) + # fetch returns None + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.create_and_register_revocation_registry_definition( + issuer_id="test-issuer-id", + cred_def_id="test-cred-def-id", + registry_type="test-registry-type", + tag="test-tag", + max_cred_num=100, + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch.object( + test_module.AnonCredsRevocation, + "generate_public_tails_uri", + return_value="https://tails.uri", + ) + @mock.patch.object( + test_module.AnonCredsRevocation, + "notify", + return_value=None, + ) + async def test_create_and_register_revocation_registry_definition( + self, mock_notify, mock_tails_uri, mock_handle + ): + self.profile.inject = mock.Mock( + return_value=mock.MagicMock( + register_revocation_registry_definition=mock.CoroutineMock( + return_value=RevRegDefResult( + job_id="test-job-id", + revocation_registry_definition_state=RevRegDefState( + state=RevRegDefState.STATE_FINISHED, + revocation_registry_definition_id="active-reg-reg", + revocation_registry_definition=RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", + ), + ), + registration_metadata={}, + revocation_registry_definition_metadata={}, + ) + ) + ) + ) + self.profile.transaction = mock.Mock( + return_value=mock.MagicMock( + insert=mock.CoroutineMock(return_value=None), + commit=mock.CoroutineMock(return_value=None), + ) + ) + schema = Schema.create( + name="MYCO Biomarker", + attr_names=["biomarker_id"], + issuer_id="did:indy:sovrin:SGrjRL82Y9ZZbzhUDXokvQ", + version="1.0", + ) + + (cred_def, _, _) = CredentialDefinition.create( + schema_id="CsQY9MGeD3CQP4EyuVFo5m:2:MYCO Biomarker:0.0.3", + schema=schema, + issuer_id="did:indy:sovrin:SGrjRL82Y9ZZbzhUDXokvQ", + tag="tag", + support_revocation=True, + signature_type="CL", + ) + mock_handle.fetch = mock.CoroutineMock( + return_value=MockEntry(raw_value=cred_def.to_json_buffer()) + ) + + result = ( + await self.revocation.create_and_register_revocation_registry_definition( + issuer_id="did:indy:sovrin:SGrjRL82Y9ZZbzhUDXokvQ", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + registry_type="CL_ACCUM", + tag="tag", + max_cred_num=100, + ) + ) + + assert result is not None + assert mock_handle.fetch.call_count == 1 + assert mock_tails_uri.call_count == 1 + assert mock_notify.call_count == 1 + + # create fails - bad issue id + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.create_and_register_revocation_registry_definition( + issuer_id="", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + registry_type="CL_ACCUM", + tag="tag", + max_cred_num=100, + ) + + # register registry response missing rev_reg_def_id and job_id + self.profile.inject = mock.Mock( + return_value=mock.MagicMock( + register_revocation_registry_definition=mock.CoroutineMock( + side_effect=[ + RevRegDefResult( + job_id=None, + revocation_registry_definition_state=RevRegDefState( + state=RevRegDefState.STATE_FINISHED, + revocation_registry_definition_id="active-reg-reg", + revocation_registry_definition=RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", + ), + ), + registration_metadata={}, + revocation_registry_definition_metadata={}, + ), + RevRegDefResult( + job_id="test-job-id", + revocation_registry_definition_state=RevRegDefState( + state=RevRegDefState.STATE_FINISHED, + revocation_registry_definition_id=None, + revocation_registry_definition=RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", + ), + ), + registration_metadata={}, + revocation_registry_definition_metadata={}, + ), + RevRegDefResult( + job_id=None, + revocation_registry_definition_state=RevRegDefState( + state=RevRegDefState.STATE_FINISHED, + revocation_registry_definition_id=None, + revocation_registry_definition=RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", + ), + ), + registration_metadata={}, + revocation_registry_definition_metadata={}, + ), + ] + ) + ) + ) + + await self.revocation.create_and_register_revocation_registry_definition( + issuer_id="did:indy:sovrin:SGrjRL82Y9ZZbzhUDXokvQ", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + registry_type="CL_ACCUM", + tag="tag", + max_cred_num=100, + ) + await self.revocation.create_and_register_revocation_registry_definition( + issuer_id="did:indy:sovrin:SGrjRL82Y9ZZbzhUDXokvQ", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + registry_type="CL_ACCUM", + tag="tag", + max_cred_num=100, + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.create_and_register_revocation_registry_definition( + issuer_id="did:indy:sovrin:SGrjRL82Y9ZZbzhUDXokvQ", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + registry_type="CL_ACCUM", + tag="tag", + max_cred_num=100, + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch.object(RevRegDef, "from_json", return_value="rev-reg-def") + @mock.patch.object(test_module.AnonCredsRevocation, "notify") + async def test_finish_revocation_registry_definition( + self, mock_notify, mock_from_json, mock_handle + ): + mock_handle.fetch = mock.CoroutineMock(return_value=MockEntry()) + mock_handle.insert = mock.CoroutineMock(return_value=None) + mock_handle.remove = mock.CoroutineMock(return_value=None) + + await self.revocation.finish_revocation_registry_definition( + job_id="job-id", + rev_reg_def_id="rev-reg-def-id", + ) + + # None response + mock_handle.fetch = mock.CoroutineMock(return_value=None) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.finish_revocation_registry_definition( + job_id="job-id", + rev_reg_def_id="rev-reg-def-id", + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_get_created_revocation_registry_definitions(self, mock_handle): + mock_handle.fetch_all = mock.CoroutineMock( + return_value=[ + MockEntry("revocation_reg_def_0"), + MockEntry("revocation_reg_def_1"), + ] + ) + result = await self.revocation.get_created_revocation_registry_definitions() + assert result == ["revocation_reg_def_0", "revocation_reg_def_1"] + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_get_created_revocation_registry_definition_state(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock(side_effect=[MockEntry(), None]) + result = await self.revocation.get_created_revocation_registry_definition_state( + "test-rev-reg-def-id" + ) + assert result == RevRegDefState.STATE_FINISHED + result = await self.revocation.get_created_revocation_registry_definition_state( + "test-rev-reg-def-id" + ) + assert result is None + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_get_created_revocation_registry_definition(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockEntry( + value_json=RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", + ).to_json() + ), + None, + ] + ) + result = await self.revocation.get_created_revocation_registry_definition( + "test-rev-reg-def-id" + ) + assert isinstance(result, RevRegDef) + result = await self.revocation.get_created_revocation_registry_definition( + "test-rev-reg-def-id" + ) + assert result is None + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_set_active_registry(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock(return_value=None) + mock_handle.replace = mock.CoroutineMock(return_value=None) + inactive_tags = { + "active": "false", + "cred_def_id": "test-cred-def-id", + } + + # fetch returns None + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.set_active_registry( + rev_reg_def_id="test-rev-reg-def-id", + ) + # Already active + mock_handle.fetch = mock.CoroutineMock( + return_value=MockEntry( + tags={ + "active": "true", + "cred_def_id": "test-cred-def-id", + } + ) + ) + await self.revocation.set_active_registry( + rev_reg_def_id="test-rev-reg-def-id", + ) + + mock_handle.fetch = mock.CoroutineMock( + return_value=MockEntry(tags=inactive_tags) + ) + mock_handle.fetch_all = mock.CoroutineMock( + return_value=[MockEntry(tags=inactive_tags), MockEntry(tags=inactive_tags)] + ) + await self.revocation.set_active_registry( + rev_reg_def_id="test-rev-reg-def-id", + ) + + assert mock_handle.fetch.call_count == 1 + assert mock_handle.fetch_all.call_count == 1 + assert mock_handle.replace.call_count == 3 + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_create_and_register_revocation_list_errors(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + None, + ] + ) + # askar error + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.create_and_register_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + ) + # fetch returns None + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.create_and_register_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + ) + + assert mock_handle.fetch.call_count == 2 + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch.object(RevRegDef, "deserialize") + @mock.patch.object(RevocationStatusList, "create") + async def test_create_and_register_revocation_list( + self, mock_list_create, mock_deserialize, mock_handle + ): + mock_list_create.return_value = RevocationStatusList.load( + { + "issuerId": "CsQY9MGeD3CQP4EyuVFo5m", + "revRegDefId": "4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + "revocationList": [0, 1, 1, 0], + "currentAccumulator": "21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + "timestamp": 1669640864487, + } + ) + mock_handle.fetch = mock.CoroutineMock( + return_value=MockEntry( + value_json={ + "credDefId": "CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + "issuerId": "CsQY9MGeD3CQP4EyuVFo5m", + "revocDefType": "CL_ACCUM", + "tag": "string", + "value": { + "maxCredNum": 0, + "publicKeys": { + "accumKey": {"z": "1 0BB...386"}, + }, + "tailsHash": "string", + "tailsLocation": "string", + }, + } + ) + ) + mock_handle.insert = mock.CoroutineMock(return_value=None) + + self.profile.inject = mock.Mock( + return_value=mock.MagicMock( + register_revocation_list=mock.CoroutineMock( + return_value=RevListResult( + job_id="test-job-id", + revocation_list_state=RevListState( + revocation_list=rev_list, + state=RevListState.STATE_FINISHED, + ), + registration_metadata={}, + revocation_list_metadata={}, + ) + ) + ) + ) + await self.revocation.create_and_register_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + ) + + assert mock_handle.fetch.called + assert mock_handle.insert.called + assert mock_list_create.called + assert mock_deserialize.called + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_finish_revocation_list(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + None, + MockEntry( + tags={ + "state": RevListState.STATE_FINISHED, + } + ), + ] + ) + mock_handle.replace = mock.CoroutineMock(return_value=None) + + # fetch returns None + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.finish_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + ) + assert mock_handle.fetch.call_count == 1 + assert mock_handle.replace.call_count == 0 + + # valid + await self.revocation.finish_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + ) + assert mock_handle.fetch.call_count == 2 + assert mock_handle.replace.call_count == 1 + assert ( + mock_handle.replace.call_args.kwargs["tags"]["state"] + == RevListState.STATE_FINISHED + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_update_revocation_list_get_rev_reg_errors(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + None, + ] + ) + # askar error + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=rev_list, + revoked=[1, 1, 0, 0], + ) + # fetch returns None + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=rev_list, + revoked=[1, 1, 0, 0], + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_update_revocation_list(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + MockRevListEntry(), + MockRevListEntry(), + ] + ) + mock_handle.replace = mock.CoroutineMock(return_value=None) + + self.profile.inject = mock.Mock( + return_value=mock.MagicMock( + update_revocation_list=mock.CoroutineMock( + return_value=RevListResult( + job_id="test-job-id", + revocation_list_state=RevListState( + revocation_list=rev_list, + state=RevListState.STATE_FINISHED, + ), + registration_metadata={}, + revocation_list_metadata={}, + ) + ) + ) + ) + + # valid with no errors + result = await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=rev_list, + revoked=[1, 1, 0, 0], + ) + + assert mock_handle.fetch.call_count == 3 + assert mock_handle.replace.called + assert result is not None + + # askar error fetching list is caught + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + ] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=rev_list, + revoked=[1, 1, 0, 0], + ) + + # fail to get list + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + None, + ] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=rev_list, + revoked=[1, 1, 0, 0], + ) + + # revocation lists don't match + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + MockRevListEntry(), + ] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[1, 0, 1, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ), + revoked=[1, 1, 0, 0], + ) + + # update fail states are caught + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + MockRevListEntry(), + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + ] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=rev_list, + revoked=[1, 1, 0, 0], + ) + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + MockRevListEntry(), + None, + ] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.update_revocation_list( + rev_reg_def_id="test-rev-reg-def-id", + prev=rev_list, + curr=rev_list, + revoked=[1, 1, 0, 0], + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_get_created_revocation_list(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevListEntry(), + None, + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + ] + ) + result = await self.revocation.get_created_revocation_list("rev-reg-def-id") + assert mock_handle.fetch.call_count == 1 + assert result is not None + + # fetch returns None + result = await self.revocation.get_created_revocation_list("rev-reg-def-id") + assert result is None + + # askar error + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.get_created_revocation_list("rev-reg-def-id") + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_get_revocation_lists_with_pending_revocations(self, mock_handle): + mock_handle.fetch_all = mock.CoroutineMock( + side_effect=[ + [MockEntry("rev_list_0"), MockEntry("rev_list_1")], + [], + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + ] + ) + result = await self.revocation.get_revocation_lists_with_pending_revocations() + assert result == ["rev_list_0", "rev_list_1"] + + # fetch returns None + result = await self.revocation.get_revocation_lists_with_pending_revocations() + assert result == [] + + # askar error + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.get_revocation_lists_with_pending_revocations() + + @mock.patch.object(Session, "get") + @mock.patch.object(os, "remove") + async def test_retrieve_tails(self, mock_remove, mock_get): + class MockResponse: + def __init__(self, status=http.HTTPStatus.OK): + self.status_code = status + + def iter_content(self, chunk_size: int = 1): + yield b"tails-hash" + + mock_get.side_effect = [ + MockResponse(), + MockResponse(), + RequestException(request=mock.AsyncMock(), response=mock.AsyncMock()), + MockResponse(status=http.HTTPStatus.BAD_REQUEST), + ] + + result = await self.revocation.retrieve_tails(rev_reg_def) + + assert isinstance(result, str) + assert mock_get.call_count == 1 + + # tails hash does not match + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.retrieve_tails( + RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="not-correct-hash", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", + ) + ) + assert mock_remove.call_count == 1 + + # http request fails + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.retrieve_tails(rev_reg_def) + + # doesn't crash on non 200 response + await self.revocation.retrieve_tails(rev_reg_def) + + def test_generate_public_tails_uri(self): + self.revocation.generate_public_tails_uri(rev_reg_def) + + # invalid url + self.profile.settings["tails_server_base_url"] = "invalid-url" + with self.assertRaises(test_module.AnonCredsRevocationError): + self.revocation.generate_public_tails_uri(rev_reg_def) + + # tails server base url setting is missing + del self.profile.settings["tails_server_base_url"] + with self.assertRaises(test_module.AnonCredsRevocationError): + self.revocation.generate_public_tails_uri(rev_reg_def) + + 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"), + ] + ) + ) + ) + # valid + await self.revocation.upload_tails_file(rev_reg_def) + # upload fails + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.upload_tails_file(rev_reg_def) + # tails location does not match + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.upload_tails_file(rev_reg_def) + + # tails server base url setting is missing + self.profile.inject_or = mock.Mock(return_value=None) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.upload_tails_file(rev_reg_def) + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch.object( + test_module.AnonCredsRevocation, "set_active_registry", return_value=None + ) + @mock.patch.object( + test_module.AnonCredsRevocation, + "create_and_register_revocation_registry_definition", + return_value="backup", + ) + async def test_handle_full_registry( + self, mock_create_and_register, mock_set_active_registry, mock_handle + ): + mock_handle.fetch = mock.CoroutineMock(return_value=MockRevRegDefEntry()) + mock_handle.fetch_all = mock.CoroutineMock( + return_value=[ + MockRevRegDefEntry(), + MockRevRegDefEntry(), + ] + ) + mock_handle.replace = mock.CoroutineMock(return_value=None) + + await self.revocation.handle_full_registry("test-rev-reg-def-id") + assert mock_create_and_register.called + assert mock_set_active_registry.called + assert mock_handle.fetch.call_count == 2 + assert mock_handle.fetch_all.called + assert mock_handle.replace.called + + # no backup registry available + mock_handle.fetch_all = mock.CoroutineMock(return_value=[]) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.handle_full_registry("test-rev-reg-def-id") + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_decommission_registry(self, mock_handle): + mock_handle.fetch_all = mock.CoroutineMock( + return_value=[ + MockEntry( + name="active-reg-reg", + tags={ + "state": RevRegDefState.STATE_FINISHED, + "active": True, + }, + ), + MockEntry( + name="new-rev-reg", + tags={ + "state": RevRegDefState.STATE_FINISHED, + "active": True, + }, + ), + ] + ) + # active registry + self.revocation.get_or_create_active_registry = mock.CoroutineMock( + return_value=RevRegDefResult( + job_id="test-job-id", + revocation_registry_definition_state=RevRegDefState( + state=RevRegDefState.STATE_FINISHED, + revocation_registry_definition_id="active-reg-reg", + revocation_registry_definition=rev_reg_def, + ), + registration_metadata={}, + revocation_registry_definition_metadata={}, + ) + ) + # new active + self.revocation.create_and_register_revocation_registry_definition = ( + mock.CoroutineMock( + return_value=RevRegDefResult( + job_id="test-job-id", + revocation_registry_definition_state=RevRegDefState( + state=RevRegDefState.STATE_ACTION, + revocation_registry_definition_id="new-rev-reg", + revocation_registry_definition=rev_reg_def, + ), + registration_metadata={}, + revocation_registry_definition_metadata={}, + ) + ) + ) + self.revocation.set_active_registry = mock.CoroutineMock(return_value=None) + mock_handle.replace = mock.CoroutineMock(return_value=None) + + result = await self.revocation.decommission_registry("test-rev-reg-def-id") + + assert isinstance(result, list) + assert len(result) == 2 + assert result[0].tags["active"] == "false" + assert result[0].tags["state"] == RevRegDefState.STATE_DECOMMISSIONED + assert mock_handle.fetch_all.called + assert mock_handle.replace.called + # # One for backup + assert ( + self.revocation.create_and_register_revocation_registry_definition.call_count + == 2 + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_get_or_create_active_registry(self, mock_handle): + mock_handle.fetch_all = mock.CoroutineMock( + side_effect=[ + [MockRevRegDefEntry("reg-1"), MockRevRegDefEntry("reg-0")], + None, + ] + ) + + # valid + result = await self.revocation.get_or_create_active_registry( + "test-rev-reg-def-id" + ) + assert isinstance(result, RevRegDefResult) + assert result.revocation_registry_definition_state.state == ( + RevRegDefState.STATE_FINISHED + ) + assert ( + result.revocation_registry_definition_state.revocation_registry_definition_id + == ("reg-1") + ) + + # no active registry, todo: create one + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.get_or_create_active_registry("test-rev-reg-def-id") + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch.object(Credential, "create", return_value=mock.MagicMock()) + async def test_create_credential_private_no_rev_reg_or_tails( + self, mock_create, mock_handle + ): + mock_handle.fetch = mock.CoroutineMock(side_effect=[MockEntry(), MockEntry()]) + await self.revocation._create_credential( + credential_definition_id="test-cred-def-id", + schema_attributes=["attr1", "attr2"], + credential_offer={ + "schema_id": "CsQY9MGeD3CQP4EyuVFo5m:2:MYCO Biomarker:0.0.3", + "cred_def_id": "CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + "key_correctness_proof": {}, + "nonce": "nonce", + }, + credential_request={}, + credential_values={ + "attr1": "value1", + "attr2": "value2", + }, + ) + assert mock_create.called + + # askar error retrieving cred def + mock_handle.fetch = mock.CoroutineMock( + side_effect=AskarError(AskarErrorCode.UNEXPECTED, "test") + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation._create_credential( + credential_definition_id="test-cred-def-id", + schema_attributes=["attr1", "attr2"], + credential_offer={}, + credential_request={}, + credential_values={}, + ) + + # missing cred def or cred def private + mock_handle.fetch = mock.CoroutineMock(side_effect=[None, MockEntry()]) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation._create_credential( + credential_definition_id="test-cred-def-id", + schema_attributes=["attr1", "attr2"], + credential_offer={}, + credential_request={}, + credential_values={}, + ) + mock_handle.fetch = mock.CoroutineMock(side_effect=[MockEntry(), None]) + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation._create_credential( + credential_definition_id="test-cred-def-id", + schema_attributes=["attr1", "attr2"], + credential_offer={}, + credential_request={}, + credential_values={}, + ) + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch.object( + RevocationRegistryDefinition, "load", return_value=rev_reg_def.value + ) + @mock.patch("aries_cloudagent.anoncreds.revocation.CredentialRevocationConfig") + @mock.patch.object(Credential, "create", return_value=mock.MagicMock()) + async def test_create_credential_private_with_rev_reg_and_tails( + self, mock_create, mock_config, mock_load_rev_reg_def, mock_handle + ): + async def call_test_func(): + await self.revocation._create_credential( + credential_definition_id="test-cred-def-id", + schema_attributes=["attr1", "attr2"], + credential_offer={ + "schema_id": "CsQY9MGeD3CQP4EyuVFo5m:2:MYCO Biomarker:0.0.3", + "cred_def_id": "CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + "key_correctness_proof": {}, + "nonce": "nonce", + }, + credential_request={}, + credential_values={ + "attr1": "value1", + "attr2": "value2", + }, + rev_reg_def_id="test-rev-reg-def-id", + tails_file_path="tails-file-path", + ) + + # missing rev list + mock_handle.fetch = mock.CoroutineMock( + side_effect=[MockEntry(), MockEntry(), None, MockEntry(), MockEntry()] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await call_test_func() + # missing rev def + mock_handle.fetch = mock.CoroutineMock( + side_effect=[MockEntry(), MockEntry(), MockEntry(), None, MockEntry()] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await call_test_func() + # missing rev key + mock_handle.fetch = mock.CoroutineMock( + side_effect=[MockEntry(), MockEntry(), MockEntry(), MockEntry(), None] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await call_test_func() + + # valid + mock_handle.replace = mock.CoroutineMock(return_value=None) + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockEntry(), + MockEntry(), + MockEntry( + value_json={ + "rev_list": rev_list.serialize(), + "next_index": 0, + } + ), + MockEntry(raw_value=rev_reg_def.serialize()), + MockEntry(), + ] + ) + await call_test_func() + assert mock_create.called + assert mock_handle.replace.called + assert mock_handle.fetch.call_count == 5 + + # revocation registry is full + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockEntry(), + MockEntry(), + MockEntry( + value_json={ + "rev_list": rev_list.serialize(), + "next_index": 101, + } + ), + MockEntry(raw_value=rev_reg_def.serialize()), + MockEntry(), + ] + ) + with self.assertRaises(test_module.AnonCredsRevocationError): + await call_test_func() + + @mock.patch.object( + AnonCredsIssuer, "cred_def_supports_revocation", return_value=True + ) + async def test_create_credential(self, mock_supports_revocation): + self.profile.inject = mock.Mock( + return_value=mock.MagicMock( + get_schema=mock.CoroutineMock( + return_value=GetSchemaResult( + schema_id="CsQY9MGeD3CQP4EyuVFo5m:2:MYCO Biomarker:0.0.3", + schema=AnonCredsSchema( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + name="MYCO Biomarker:0.0.3", + version="1.0", + attr_names=["attr1", "attr2"], + ), + schema_metadata={}, + resolution_metadata={}, + ) + ) + ) + ) + self.revocation.get_or_create_active_registry = mock.CoroutineMock( + return_value=RevRegDefResult( + job_id="test-job-id", + revocation_registry_definition_state=RevRegDefState( + state=RevRegDefState.STATE_FINISHED, + revocation_registry_definition_id="active-reg-reg", + revocation_registry_definition=rev_reg_def, + ), + registration_metadata={}, + revocation_registry_definition_metadata={}, + ) + ) + + # Test private funtion seperately - very large + self.revocation._create_credential = mock.CoroutineMock( + return_value=({"cred": "cred"}, 98) + ) + + result = await self.revocation.create_credential( + credential_offer={ + "schema_id": "CsQY9MGeD3CQP4EyuVFo5m:2:MYCO Biomarker:0.0.3", + "cred_def_id": "CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + "key_correctness_proof": {}, + "nonce": "nonce", + }, + credential_request={}, + credential_values={}, + ) + + assert isinstance(result, tuple) + assert mock_supports_revocation.call_count == 1 + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch.object(RevList, "to_native") + @mock.patch.object(RevList, "from_native", return_value=None) + @mock.patch.object(RevRegDef, "to_native") + async def test_revoke_pending_credentials( + self, + mock_rev_reg_to_native, + mock_rev_list_from_native, + mock_rev_list_to_native, + mock_handle, + ): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + # askar error + AskarError(code=AskarErrorCode.UNEXPECTED, message="test"), + # missing rev reg def + None, + MockEntry( + value_json=json.dumps( + { + "pending": [1], + "rev_list": rev_list.serialize(), + } + ) + ), + # missing rev list + MockEntry(value_json=json.dumps(MOCK_REV_REG_DEF)), + None, + ] + ) + + # askar error + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.revoke_pending_credentials( + revoc_reg_id="test-rev-reg-id", + ) + # rev reg def not found + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.revoke_pending_credentials( + revoc_reg_id="test-rev-reg-id", + ) + # rev list not found + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.revoke_pending_credentials( + revoc_reg_id="test-rev-reg-id", + ) + + # valid + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + # rev_reg_def_entry + MockEntry(value_json=json.dumps(MOCK_REV_REG_DEF)), + # rev_list_entry + MockEntry( + value_json={ + "pending": [0, 1, 4, 3], + "next_index": 4, + "rev_list": rev_list.serialize(), + } + ), + # updated rev list entry + MockEntry( + value_json={ + "pending": [0, 1, 4, 3], + "next_index": 4, + "rev_list": rev_list.serialize(), + }, + tags={"pending": []}, + ), + ] + ) + mock_handle.replace = mock.CoroutineMock(return_value=None) + + result = await self.revocation.revoke_pending_credentials( + revoc_reg_id="test-rev-reg-id", + ) + + assert mock_handle.fetch.call_count == 3 + assert mock_handle.replace.called + assert mock_rev_list_from_native.called + assert mock_rev_list_to_native.called + assert mock_rev_reg_to_native.called + assert isinstance(result, test_module.RevokeResult) + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_mark_pending_revocations(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + None, + MockEntry( + value_json={ + "pending": [1], + } + ), + ] + ) + mock_handle.replace = mock.CoroutineMock(return_value=None) + + # rev list entry not found + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.mark_pending_revocations( + "test-rev-reg-id", int("200") + ) + + # valid + await self.revocation.mark_pending_revocations("test-rev-reg-id", int("200")) + assert mock_handle.replace.call_count == 1 + + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_get_pending_revocations(self, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + None, + MockEntry( + value_json={ + "pending": [1, 2], + } + ), + ] + ) + + result = await self.revocation.get_pending_revocations("test-rev-reg-id") + assert result == [] + + result = await self.revocation.get_pending_revocations("test-rev-reg-id") + assert result == [1, 2] + + @mock.patch.object(InMemoryProfileSession, "handle") + @mock.patch("aries_cloudagent.anoncreds.revocation.isinstance") + async def test_clear_pending_revocations(self, mock_is_instance, mock_handle): + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + None, + MockEntry( + value_json={ + "pending": [1, 2], + } + ), + MockEntry( + value_json={ + "pending": [1, 2], + } + ), + ] + ) + mock_handle.replace = mock.CoroutineMock(return_value=None) + + # fetch is None + with self.assertRaises(test_module.AnonCredsRevocationError): + await self.revocation.clear_pending_revocations( + self.profile.session(), rev_reg_def_id="test-rev-reg-id" + ) + # valid + await self.revocation.clear_pending_revocations( + self.profile.session(), rev_reg_def_id="test-rev-reg-id" + ) + assert mock_handle.replace.called + # with crid mask + await self.revocation.clear_pending_revocations( + self.profile.session(), rev_reg_def_id="test-rev-reg-id", crid_mask=[1, 2] + ) + + async def test_clear_pending_revocations_with_non_anoncreds_session(self): + with self.assertRaises(ValueError): + await self.revocation.clear_pending_revocations( + self.profile.session(), rev_reg_def_id="test-rev-reg-id" + ) diff --git a/aries_cloudagent/anoncreds/tests/test_routes.py b/aries_cloudagent/anoncreds/tests/test_routes.py index 38059de375..e539a93e73 100644 --- a/aries_cloudagent/anoncreds/tests/test_routes.py +++ b/aries_cloudagent/anoncreds/tests/test_routes.py @@ -86,14 +86,13 @@ async def test_schemas_post(self, mock_create_and_register_schema): assert mock_create_and_register_schema.call_count == 1 - # TODO: consider handling missing schema attribute better - with self.assertRaises(AttributeError): + with self.assertRaises(web.HTTPBadRequest): await test_module.schemas_post(self.request) await test_module.schemas_post(self.request) async def test_get_schema(self): - self.request.match_info = {"schemaId": "schema_id"} + self.request.match_info = {"schema_id": "schema_id"} self.context.inject = mock.Mock( return_value=mock.MagicMock( get_schema=mock.CoroutineMock( @@ -113,7 +112,7 @@ async def test_get_schema(self): await test_module.schema_get(self.request) # schema not found - self.request.match_info = {"schemaId": "schema_id"} + self.request.match_info = {"schema_id": "schema_id"} with self.assertRaises(web.HTTPNotFound): await test_module.schema_get(self.request) @@ -167,8 +166,7 @@ async def test_cred_def_post(self, mock_create_cred_def): assert json.loads(result.body)["credential_definition_id"] == "credDefId" assert mock_create_cred_def.call_count == 1 - # TODO: consider handling missing cred_def attribute better - with self.assertRaises(AttributeError): + with self.assertRaises(web.HTTPBadRequest): await test_module.cred_def_post(self.request) await test_module.cred_def_post(self.request) @@ -202,10 +200,10 @@ async def test_cred_def_get(self): ) async def test_cred_defs_get(self, mock_get_cred_defs): result = await test_module.cred_defs_get(self.request) - assert json.loads(result.body).__len__() == 2 + assert len(json.loads(result.body)["credential_definition_ids"]) == 2 result = await test_module.cred_defs_get(self.request) - assert json.loads(result.body).__len__() == 0 + assert len(json.loads(result.body)["credential_definition_ids"]) == 0 assert mock_get_cred_defs.call_count == 2 @@ -232,6 +230,24 @@ async def test_rev_reg_def_post(self, mock_match, mock_create): } ) + # Must be in wrapper object + with self.assertRaises(web.HTTPBadRequest): + await test_module.rev_reg_def_post(self.request) + + self.request.json = mock.CoroutineMock( + return_value={ + "revocation_registry_definition": { + "credDefId": "cred_def_id", + "issuerId": "issuer_id", + "maxCredNum": 100, + "options": { + "tails_public_uri": "http://tails_public_uri", + "tails_local_uri": "http://tails_local_uri", + }, + } + } + ) + result = await test_module.rev_reg_def_post(self.request) assert ( diff --git a/aries_cloudagent/config/argparse.py b/aries_cloudagent/config/argparse.py index 4cd6d730e6..4c288aa6cf 100644 --- a/aries_cloudagent/config/argparse.py +++ b/aries_cloudagent/config/argparse.py @@ -1170,6 +1170,12 @@ def add_arguments(self, parser: ArgumentParser): "using unencrypted rather than encrypted tags" ), ) + parser.add_argument( + "--emit-did-peer-2", + action="store_true", + env_var="ACAPY_EMIT_DID_PEER_2", + help=("Emit did:peer:2 DIDs in DID Exchange Protocol"), + ) def get_settings(self, args: Namespace) -> dict: """Get protocol settings.""" @@ -1236,6 +1242,10 @@ def get_settings(self, args: Namespace) -> dict: if args.exch_use_unencrypted_tags: settings["exch_use_unencrypted_tags"] = True environ["EXCH_UNENCRYPTED_TAGS"] = "True" + + if args.emit_did_peer_2: + settings["emit_did_peer_2"] = True + return settings diff --git a/aries_cloudagent/config/default_per_tenant_logging_config.ini b/aries_cloudagent/config/default_per_tenant_logging_config.ini index bb763dd56f..2c799198f1 100644 --- a/aries_cloudagent/config/default_per_tenant_logging_config.ini +++ b/aries_cloudagent/config/default_per_tenant_logging_config.ini @@ -1,27 +1,28 @@ [loggers] -keys=root +keys = root [handlers] -keys=stream_handler, timed_file_handler +keys = stream_handler, timed_file_handler [formatters] -keys=formatter +keys = formatter [logger_root] -level=ERROR -handlers=stream_handler, timed_file_handler +level = ERROR +handlers = stream_handler, timed_file_handler [handler_stream_handler] -class=StreamHandler -level=DEBUG -formatter=formatter -args=(sys.stderr,) +class = StreamHandler +level = DEBUG +formatter = formatter +args = (sys.stderr,) [handler_timed_file_handler] -class=logging.handlers.TimedRotatingFileMultiProcessHandler -level=DEBUG -formatter=formatter -args=('/home/aries/log/acapy-agent.log', 'd', 7, 1,) +class = logging.handlers.TimedRotatingFileMultiProcessHandler +level = DEBUG +formatter = formatter +args = ('test.log', 'd', 7, 1) [formatter_formatter] -format=%(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s \ No newline at end of file +format = %(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s + diff --git a/aries_cloudagent/config/default_per_tenant_logging_config.yml b/aries_cloudagent/config/default_per_tenant_logging_config.yml index dc7c0e53d0..6239db2f0f 100644 --- a/aries_cloudagent/config/default_per_tenant_logging_config.yml +++ b/aries_cloudagent/config/default_per_tenant_logging_config.yml @@ -1,23 +1,23 @@ -version: 1 formatters: default: format: '%(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s' handlers: console: class: logging.StreamHandler - level: DEBUG formatter: default + level: DEBUG stream: ext://sys.stderr rotating_file: - class: logging.handlers.TimedRotatingFileMultiProcessHandler - level: DEBUG - filename: '/home/aries/log/acapy-agent.log' - when: 'd' - interval: 7 backupCount: 1 + class: logging.handlers.TimedRotatingFileMultiProcessHandler + filename: test.log formatter: default + interval: 7 + level: DEBUG + when: d root: - level: INFO handlers: - - console - - rotating_file \ No newline at end of file + - console + - rotating_file + level: INFO +version: 1 diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index 433a8334b3..4ce19c81b1 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -7,6 +7,8 @@ import logging from typing import List, Optional, Sequence, Text, Tuple, Union +from base58 import b58decode +from did_peer_2 import KeySpec, generate from pydid import ( BaseDIDDocument as ResolvedDocument, DIDCommService, @@ -17,6 +19,7 @@ Ed25519VerificationKey2018, Ed25519VerificationKey2020, JsonWebKey2020, + Multikey, ) from ..cache.base import BaseCache @@ -44,8 +47,8 @@ from ..utils.multiformats import multibase, multicodec from ..wallet.base import BaseWallet from ..wallet.crypto import create_keypair, seed_to_did -from ..wallet.did_info import DIDInfo -from ..wallet.did_method import SOV +from ..wallet.did_info import DIDInfo, KeyInfo +from ..wallet.did_method import PEER2, SOV from ..wallet.error import WalletNotFoundError from ..wallet.key_type import ED25519 from ..wallet.util import b64_to_bytes, bytes_to_b58 @@ -74,6 +77,69 @@ def __init__(self, profile: Profile): self._route_manager = profile.inject(RouteManager) self._logger = logging.getLogger(__name__) + @staticmethod + def _key_info_to_multikey(key_info: KeyInfo) -> str: + """Convert a KeyInfo to a multikey.""" + return multibase.encode( + multicodec.wrap("ed25519-pub", b58decode(key_info.verkey)), "base58btc" + ) + + async def create_did_peer_2( + self, + svc_endpoints: Optional[Sequence[str]] = None, + mediation_records: Optional[List[MediationRecord]] = None, + ) -> DIDInfo: + """Create a did:peer:2 DID for a connection. + + Args: + svc_endpoints: Custom endpoints for the DID Document + mediation_record: The record for mediation that contains routing_keys and + service endpoint + + Returns: + The new `DIDInfo` instance + """ + routing_keys: List[str] = [] + if mediation_records: + for mediation_record in mediation_records: + ( + mediator_routing_keys, + endpoint, + ) = await self._route_manager.routing_info( + self._profile, mediation_record + ) + routing_keys = [*routing_keys, *(mediator_routing_keys or [])] + if endpoint: + svc_endpoints = [endpoint] + + services = [] + for index, endpoint in enumerate(svc_endpoints or []): + services.append( + { + "id": f"#didcomm-{index}", + "type": "did-communication", + "priority": index, + "recipientKeys": ["#key-1"], + "routingKeys": routing_keys, + "serviceEndpoint": endpoint, + } + ) + + async with self._profile.session() as session: + wallet = session.inject(BaseWallet) + key = await wallet.create_key(ED25519) + + did = generate( + [KeySpec.verification(self._key_info_to_multikey(key))], services + ) + + did_info = DIDInfo( + did=did, method=PEER2, verkey=key.verkey, metadata={}, key_type=ED25519 + ) + await wallet.store_did(did_info) + + return did_info + async def create_did_document( self, did_info: DIDInfo, @@ -375,6 +441,13 @@ def _extract_key_material_in_base58_format(method: VerificationMethod) -> str: f"Key type {type(method).__name__} " f"with kty {method.public_key_jwk.get('kty')} is not supported" ) + elif isinstance(method, Multikey): + codec, key = multicodec.unwrap(multibase.decode(method.material)) + if codec != multicodec.multicodec("ed25519-pub"): + raise BaseConnectionManagerError( + "Expected ed25519 multicodec, got: %s", codec + ) + return bytes_to_b58(key) else: raise BaseConnectionManagerError( f"Key type {type(method).__name__} is not supported" diff --git a/aries_cloudagent/messaging/decorators/attach_decorator.py b/aries_cloudagent/messaging/decorators/attach_decorator.py index 56791449e2..9b602e8f27 100644 --- a/aries_cloudagent/messaging/decorators/attach_decorator.py +++ b/aries_cloudagent/messaging/decorators/attach_decorator.py @@ -597,6 +597,40 @@ def content(self) -> Union[Mapping, Tuple[Sequence[str], str]]: else: return None + @classmethod + def data_base64_string( + cls, + content: str, + *, + ident: str = None, + description: str = None, + filename: str = None, + lastmod_time: str = None, + byte_count: int = None, + ): + """Create `AttachDecorator` instance on base64-encoded string data. + + Given string content, base64-encode, and embed it as data; mark + `text/string` MIME type. + + Args: + content: string content + ident: optional attachment identifier (default random UUID4) + description: optional attachment description + filename: optional attachment filename + lastmod_time: optional attachment last modification time + byte_count: optional attachment byte count + """ + return AttachDecorator( + ident=ident or str(uuid.uuid4()), + description=description, + filename=filename, + mime_type="text/string", + lastmod_time=lastmod_time, + byte_count=byte_count, + data=AttachDecoratorData(base64_=bytes_to_b64(content.encode())), + ) + @classmethod def data_base64( cls, diff --git a/aries_cloudagent/messaging/tests/test_valid.py b/aries_cloudagent/messaging/tests/test_valid.py index 025f06e7c2..8983d27964 100644 --- a/aries_cloudagent/messaging/tests/test_valid.py +++ b/aries_cloudagent/messaging/tests/test_valid.py @@ -502,9 +502,7 @@ def test_credential_type(self): with self.assertRaises(ValidationError): CREDENTIAL_TYPE_VALIDATE(["WrongType", "AnotherWrongType"]) - with self.assertRaises(ValidationError): - CREDENTIAL_TYPE_VALIDATE(["VerifiableCredential"]) - + CREDENTIAL_TYPE_VALIDATE(["VerifiableCredential"]) CREDENTIAL_TYPE_VALIDATE(["VerifiableCredential", "AnotherType"]) CREDENTIAL_TYPE_VALIDATE(["SomeType", "AnotherType", "VerifiableCredential"]) diff --git a/aries_cloudagent/messaging/valid.py b/aries_cloudagent/messaging/valid.py index 0838f84af6..96522cadfc 100644 --- a/aries_cloudagent/messaging/valid.py +++ b/aries_cloudagent/messaging/valid.py @@ -772,11 +772,6 @@ def __call__(self, value): length = len(value) if length < 1 or CredentialType.CREDENTIAL_TYPE not in value: raise ValidationError(f"type must include {CredentialType.CREDENTIAL_TYPE}") - if length == 1: - raise ValidationError( - "type must include additional, more narrow," - " types (e.g. UniversityDegreeCredential)" - ) return value diff --git a/aries_cloudagent/protocols/didexchange/v1_0/manager.py b/aries_cloudagent/protocols/didexchange/v1_0/manager.py index 55d68ecb57..c35d50130e 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/manager.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/manager.py @@ -4,7 +4,6 @@ import logging from typing import Optional, Sequence, Union - from ....connections.base_manager import BaseConnectionManager from ....connections.models.conn_record import ConnRecord from ....connections.models.connection_target import ConnectionTarget @@ -294,10 +293,24 @@ async def create_request( my_info = None + # Create connection request message + if my_endpoint: + my_endpoints = [my_endpoint] + else: + my_endpoints = [] + default_endpoint = self.profile.settings.get("default_endpoint") + if default_endpoint: + my_endpoints.append(default_endpoint) + my_endpoints.extend(self.profile.settings.get("additional_endpoints", [])) + + emit_did_peer_2 = self.profile.settings.get("emit_did_peer_2") if conn_rec.my_did: async with self.profile.session() as session: wallet = session.inject(BaseWallet) my_info = await wallet.get_local_did(conn_rec.my_did) + elif emit_did_peer_2: + my_info = await self.create_did_peer_2(my_endpoints, mediation_records) + conn_rec.my_did = my_info.did else: # Create new DID for connection async with self.profile.session() as session: @@ -308,17 +321,7 @@ async def create_request( ) conn_rec.my_did = my_info.did - # Create connection request message - if my_endpoint: - my_endpoints = [my_endpoint] - else: - my_endpoints = [] - default_endpoint = self.profile.settings.get("default_endpoint") - if default_endpoint: - my_endpoints.append(default_endpoint) - my_endpoints.extend(self.profile.settings.get("additional_endpoints", [])) - - if use_public_did: + if use_public_did or emit_did_peer_2: # Omit DID Doc attachment if we're using a public DID did_doc = None attach = None @@ -605,6 +608,18 @@ async def create_response( async with self.profile.session() as session: request = await conn_rec.retrieve_request(session) + if my_endpoint: + my_endpoints = [my_endpoint] + else: + my_endpoints = [] + default_endpoint = self.profile.settings.get("default_endpoint") + if default_endpoint: + my_endpoints.append(default_endpoint) + my_endpoints.extend(self.profile.settings.get("additional_endpoints", [])) + + respond_with_did_peer_2 = self.profile.settings.get("emit_did_peer_2") or ( + conn_rec.their_did and conn_rec.their_did.startswith("did:peer:2") + ) if conn_rec.my_did: async with self.profile.session() as session: wallet = session.inject(BaseWallet) @@ -620,6 +635,10 @@ async def create_response( did = my_info.did if not did.startswith("did:"): did = f"did:sov:{did}" + elif respond_with_did_peer_2: + my_info = await self.create_did_peer_2(my_endpoints, mediation_records) + conn_rec.my_did = my_info.did + did = my_info.did else: async with self.profile.session() as session: wallet = session.inject(BaseWallet) @@ -635,20 +654,17 @@ async def create_response( self.profile, conn_rec, mediation_records ) - # Create connection response message - if my_endpoint: - my_endpoints = [my_endpoint] - else: - my_endpoints = [] - default_endpoint = self.profile.settings.get("default_endpoint") - if default_endpoint: - my_endpoints.append(default_endpoint) - my_endpoints.extend(self.profile.settings.get("additional_endpoints", [])) - - if use_public_did: + if use_public_did or respond_with_did_peer_2: # Omit DID Doc attachment if we're using a public DID - did_doc = None - attach = None + attach = AttachDecorator.data_base64_string(did) + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + if conn_rec.invitation_key is not None: + await attach.data.sign(conn_rec.invitation_key, wallet) + else: + self._logger.warning("Invitation key was not set for connection") + attach = None + response = DIDXResponse(did=did, did_rotate_attach=attach) else: did_doc = await self.create_did_document( my_info, @@ -659,8 +675,8 @@ async def create_response( async with self.profile.session() as session: wallet = session.inject(BaseWallet) await attach.data.sign(conn_rec.invitation_key, wallet) + response = DIDXResponse(did=did, did_doc_attach=attach) - response = DIDXResponse(did=did, did_doc_attach=attach) # Assign thread information response.assign_thread_from(request) response.assign_trace_from(request) @@ -783,6 +799,23 @@ async def accept_response( if response.did is None: raise DIDXManagerError("No DID in response") + if response.did_rotate_attach is None: + raise DIDXManagerError( + "did_rotate~attach required if no signed doc attachment" + ) + + self._logger.debug("did_rotate~attach found; verifying signature") + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + signed_did = await self.verify_rotate( + wallet, response.did_rotate_attach, conn_rec.invitation_key + ) + if their_did != response.did: + raise DIDXManagerError( + f"Connection DID {their_did} " + f"does not match singed DID rotate {signed_did}" + ) + self._logger.debug( "No DID Doc attachment in response; doc will be resolved from DID" ) @@ -955,6 +988,23 @@ async def verify_diddoc( return json.loads(signed_diddoc_bytes.decode()) + async def verify_rotate( + self, + wallet: BaseWallet, + attached: AttachDecorator, + invi_key: str = None, + ) -> str: + """Verify a signed DID rotate attachment and return did.""" + signed_diddoc_bytes = attached.data.signed + if not signed_diddoc_bytes: + raise DIDXManagerError("DID rotate attachment is not signed.") + if not await attached.data.verify(wallet, invi_key): + raise DIDXManagerError( + "DID rotate attachment signature failed verification" + ) + + return signed_diddoc_bytes.decode() + async def manager_error_to_problem_report( self, e: DIDXManagerError, diff --git a/aries_cloudagent/protocols/didexchange/v1_0/messages/response.py b/aries_cloudagent/protocols/didexchange/v1_0/messages/response.py index ae00ac2181..927a038dec 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/messages/response.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/messages/response.py @@ -29,6 +29,7 @@ def __init__( *, did: str = None, did_doc_attach: Optional[AttachDecorator] = None, + did_rotate_attach: Optional[AttachDecorator] = None, **kwargs, ): """Initialize DID exchange response object under RFC 23. @@ -40,6 +41,7 @@ def __init__( super().__init__(**kwargs) self.did = did self.did_doc_attach = did_doc_attach + self.did_rotate_attach = did_rotate_attach class DIDXResponseSchema(AgentMessageSchema): @@ -61,3 +63,9 @@ class Meta: data_key="did_doc~attach", metadata={"description": "As signed attachment, DID Doc associated with DID"}, ) + did_rotate_attach = fields.Nested( + AttachDecoratorSchema, + required=False, + data_key="did_rotate~attach", + metadata={"description": "As signed attachment, DID signed by invitation key"}, + ) diff --git a/aries_cloudagent/protocols/didexchange/v1_0/messages/tests/test_response.py b/aries_cloudagent/protocols/didexchange/v1_0/messages/tests/test_response.py index b13711e078..45fe24dba6 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/messages/tests/test_response.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/messages/tests/test_response.py @@ -59,10 +59,13 @@ async def asyncSetUp(self): did_doc_attach = AttachDecorator.data_base64(self.make_did_doc().serialize()) await did_doc_attach.data.sign(self.did_info.verkey, self.wallet) + did_rotate_attach = AttachDecorator.data_base64_string(self.test_verkey) + await did_rotate_attach.data.sign(self.did_info.verkey, self.wallet) self.response = DIDXResponse( did=TestConfig.test_did, did_doc_attach=did_doc_attach, + did_rotate_attach=did_rotate_attach, ) def test_init(self): @@ -116,13 +119,17 @@ async def asyncSetUp(self): did_doc_attach = AttachDecorator.data_base64(self.make_did_doc().serialize()) await did_doc_attach.data.sign(self.did_info.verkey, self.wallet) + did_rotate_attach = AttachDecorator.data_base64_string(self.test_verkey) + await did_rotate_attach.data.sign(self.did_info.verkey, self.wallet) self.response = DIDXResponse( did=TestConfig.test_did, did_doc_attach=did_doc_attach, + did_rotate_attach=did_rotate_attach, ) async def test_make_model(self): data = self.response.serialize() model_instance = DIDXResponse.deserialize(data) assert isinstance(model_instance, DIDXResponse) + assert model_instance.did_rotate_attach diff --git a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py index ed5550020d..2addc3a668 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py @@ -1,10 +1,10 @@ import json - from unittest import IsolatedAsyncioTestCase -from aries_cloudagent.tests import mock + from pydid import DIDDocument -from .. import manager as test_module +from aries_cloudagent.tests import mock + from .....cache.base import BaseCache from .....cache.in_memory import InMemoryCache from .....connections.models.conn_record import ConnRecord @@ -22,7 +22,7 @@ from .....storage.error import StorageNotFoundError from .....transport.inbound.receipt import MessageReceipt from .....wallet.did_info import DIDInfo -from .....wallet.did_method import DIDMethods, SOV +from .....wallet.did_method import PEER2, SOV, DIDMethods from .....wallet.error import WalletError from .....wallet.in_memory import InMemoryWallet from .....wallet.key_type import ED25519 @@ -34,6 +34,7 @@ from ....out_of_band.v1_0.manager import OutOfBandManager from ....out_of_band.v1_0.messages.invitation import HSProto, InvitationMessage from ....out_of_band.v1_0.messages.service import Service as OOBService +from .. import manager as test_module from ..manager import DIDXManager, DIDXManagerError from ..messages.problem_report import DIDXProblemReport, ProblemReportReason @@ -47,6 +48,8 @@ class TestConfig: test_target_did = "GbuDUYXaUZRfHD2jeDuQuP" test_target_verkey = "9WCgWKUaAJj3VWxxtzvvMQN3AoFxoBtBDo9ntwJnVVCC" + test_did_peer_2 = "did:peer:2.Vz6MkeobNdKHDnMXhob5GPWmpEyNx3r9j6gqiKYJQ9J2wEPvx.SeyJpZCI6IiNkaWRjb21tLTAiLCJ0IjoiZGlkLWNvbW11bmljYXRpb24iLCJwcmlvcml0eSI6MCwicmVjaXBpZW50S2V5cyI6WyIja2V5LTEiXSwiciI6W10sInMiOiJodHRwOi8vaG9zdC5kb2NrZXIuaW50ZXJuYWw6OTA3MCJ9" + def make_did_doc(self, did, verkey): doc = DIDDoc(did=did) controller = did @@ -526,7 +529,7 @@ async def test_create_request_public_did(self): connection_id="dummy", my_did=self.did_info.did, their_did=TestConfig.test_target_did, - their_role=ConnRecord.Role.RESPONDER.rfc23, + their_role=ConnRecord.Role.REQUESTER.rfc23, state=ConnRecord.State.REQUEST.rfc23, retrieve_invitation=mock.CoroutineMock( return_value=mock.MagicMock( @@ -539,6 +542,29 @@ async def test_create_request_public_did(self): request = await self.manager.create_request(mock_conn_rec, use_public_did=True) assert request.did_doc_attach is None + async def test_create_request_emit_did_peer_2(self): + mock_conn_rec = mock.MagicMock( + connection_id="dummy", + retrieve_invitation=mock.CoroutineMock( + return_value=mock.MagicMock( + services=[TestConfig.test_target_did], + ) + ), + my_did=None, + save=mock.CoroutineMock(), + ) + + self.profile.context.update_settings({"emit_did_peer_2": True}) + + with mock.patch.object( + self.manager, "create_did_peer_2", mock.AsyncMock() + ) as mock_create_did_peer_2: + request = await self.manager.create_request( + mock_conn_rec, use_public_did=True + ) + assert request.did_doc_attach is None + mock_create_did_peer_2.assert_called_once() + async def test_receive_request_explicit_public_did(self): async with self.profile.session() as session: mock_request = mock.MagicMock( @@ -1598,9 +1624,38 @@ async def test_create_response_conn_rec_my_did(self): data=mock.MagicMock(sign=mock.CoroutineMock()) ) ) - await self.manager.create_response(conn_rec, "http://10.20.30.40:5060/") + async def test_create_response_inkind_peer_did(self): + # created did:peer:2 when receiving a did:peer:2, even if setting is False + conn_rec = ConnRecord( + connection_id="dummy", + their_did=TestConfig.test_did_peer_2, + state=ConnRecord.State.REQUEST.rfc23, + ) + + 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() + ) as mock_retrieve_req, mock.patch.object( + conn_rec, "save", mock.CoroutineMock() + ) as mock_save: + mock_create_did_peer_2.return_value = DIDInfo( + TestConfig.test_did_peer_2, + TestConfig.test_verkey, + None, + method=PEER2, + key_type=ED25519, + ) + response = await self.manager.create_response( + conn_rec, "http://10.20.30.40:5060/" + ) + mock_create_did_peer_2.assert_called_once() + assert response.did.startswith("did:peer:2") + async def test_create_response_bad_state(self): with self.assertRaises(DIDXManagerError): await self.manager.create_response( @@ -1904,8 +1959,8 @@ async def test_accept_response_find_by_thread_id_bad_state(self): await self.manager.accept_response(mock_response, receipt) async def test_accept_response_find_by_thread_id_no_did_doc_attached(self): - mock_response = mock.MagicMock() - mock_response._thread = mock.MagicMock() + mock_response = mock.AsyncMock() + mock_response._thread = mock.AsyncMock() mock_response.did = TestConfig.test_target_did mock_response.did_doc_attach = None diff --git a/aries_cloudagent/resolver/__init__.py b/aries_cloudagent/resolver/__init__.py index bee29b84be..93f48bc5a3 100644 --- a/aries_cloudagent/resolver/__init__.py +++ b/aries_cloudagent/resolver/__init__.py @@ -4,7 +4,6 @@ from ..config.injection_context import InjectionContext from ..config.provider import ClassProvider - from ..resolver.did_resolver import DIDResolver LOGGER = logging.getLogger(__name__) @@ -74,3 +73,9 @@ async def setup(context: InjectionContext): ).provide(context.settings, context.injector) await peer_did_3_resolver.setup(context) registry.register_resolver(peer_did_3_resolver) + + peer_did_4_resolver = ClassProvider( + "aries_cloudagent.resolver.default.peer4.PeerDID4Resolver" + ).provide(context.settings, context.injector) + await peer_did_4_resolver.setup(context) + registry.register_resolver(peer_did_4_resolver) diff --git a/aries_cloudagent/resolver/default/peer4.py b/aries_cloudagent/resolver/default/peer4.py new file mode 100644 index 0000000000..153dde999c --- /dev/null +++ b/aries_cloudagent/resolver/default/peer4.py @@ -0,0 +1,78 @@ +"""Peer DID 4 Resolver. + +Resolution is performed using the peer-did-python library https://github.com/decentralized-identity/did-peer-4. +""" + +from re import compile +from typing import Optional, Pattern, Sequence, Text + +from did_peer_4 import ( + LONG_PATTERN, + SHORT_PATTERN, + long_to_short, + resolve, + resolve_short, +) + +from ...config.injection_context import InjectionContext +from ...core.profile import Profile +from ...storage.base import BaseStorage +from ...storage.error import StorageNotFoundError +from ...storage.record import StorageRecord +from ..base import BaseDIDResolver, DIDNotFound, ResolverType + + +class PeerDID4Resolver(BaseDIDResolver): + """Peer DID 4 Resolver.""" + + RECORD_TYPE = "long_peer_did_4_doc" + + def __init__(self): + """Initialize Key Resolver.""" + super().__init__(ResolverType.NATIVE) + + async def setup(self, context: InjectionContext): + """Perform required setup for Key DID resolution.""" + + @property + def supported_did_regex(self) -> Pattern: + """Return supported_did_regex of Key DID Resolver.""" + # accepts both, return a Regex OR + return compile(f"{LONG_PATTERN.pattern}|{SHORT_PATTERN.pattern}") + + async def _resolve( + self, + profile: Profile, + did: str, + service_accept: Optional[Sequence[Text]] = None, + ) -> dict: + """Resolve a Key DID.""" + if LONG_PATTERN.match(did): + short_did_peer_4 = long_to_short(did) + # resolve and save long form + async with profile.session() as session: + storage = session.inject(BaseStorage) + try: + record = await storage.get_record( + self.RECORD_TYPE, short_did_peer_4 + ) + except StorageNotFoundError: + record = StorageRecord(self.RECORD_TYPE, did, {}, short_did_peer_4) + await storage.add_record(record) + document = resolve(did) + + elif SHORT_PATTERN.match(did): + async with profile.session() as session: + storage = session.inject(BaseStorage) + try: + record = await storage.get_record(self.RECORD_TYPE, did) + except StorageNotFoundError: + raise DIDNotFound( + f"short did:peer:4 does not correspond to a \ + known long did:peer:4 {did}" + ) + document = resolve_short(record.value) + else: + raise ValueError(f"{did} did not match long or short form of did:peer:4") + + return document diff --git a/aries_cloudagent/resolver/default/tests/test_peer4.py b/aries_cloudagent/resolver/default/tests/test_peer4.py new file mode 100644 index 0000000000..3622e9c6fd --- /dev/null +++ b/aries_cloudagent/resolver/default/tests/test_peer4.py @@ -0,0 +1,57 @@ +"""Test PeerDIDResolver.""" + +import pytest + +from aries_cloudagent.core.event_bus import EventBus + +from ....core.in_memory import InMemoryProfile +from ....core.profile import Profile +from .. import peer4 as test_module +from ..peer4 import PeerDID4Resolver + +# https://identity.foundation/peer-did-method-spec/#method-4-short-form-and-long-form +TEST_LONG_DP4 = "did:peer:4zQmd8CpeFPci817KDsbSAKWcXAE2mjvCQSasRewvbSF54Bd:z2M1k7h4psgp4CmJcnQn2Ljp7Pz7ktsd7oBhMU3dWY5s4fhFNj17qcRTQ427C7QHNT6cQ7T3XfRh35Q2GhaNFZmWHVFq4vL7F8nm36PA9Y96DvdrUiRUaiCuXnBFrn1o7mxFZAx14JL4t8vUWpuDPwQuddVo1T8myRiVH7wdxuoYbsva5x6idEpCQydJdFjiHGCpNc2UtjzPQ8awSXkctGCnBmgkhrj5gto3D4i3EREXYq4Z8r2cWGBr2UzbSmnxW2BuYddFo9Yfm6mKjtJyLpF74ytqrF5xtf84MnGFg1hMBmh1xVx1JwjZ2BeMJs7mNS8DTZhKC7KH38EgqDtUZzfjhpjmmUfkXg2KFEA3EGbbVm1DPqQXayPYKAsYPS9AyKkcQ3fzWafLPP93UfNhtUPL8JW5pMcSV3P8v6j3vPXqnnGknNyBprD6YGUVtgLiAqDBDUF3LSxFQJCVYYtghMTv8WuSw9h1a1SRFrDQLGHE4UrkgoRvwaGWr64aM87T1eVGkP5Dt4L1AbboeK2ceLArPScrdYGTpi3BpTkLwZCdjdiFSfTy9okL1YNRARqUf2wm8DvkVGUU7u5nQA3ZMaXWJAewk6k1YUxKd7LvofGUK4YEDtoxN5vb6r1Q2godrGqaPkjfL3RoYPpDYymf9XhcgG8Kx3DZaA6cyTs24t45KxYAfeCw4wqUpCH9HbpD78TbEUr9PPAsJgXBvBj2VVsxnr7FKbK4KykGcg1W8M1JPz21Z4Y72LWgGQCmixovrkHktcTX1uNHjAvKBqVD5C7XmVfHgXCHj7djCh3vzLNuVLtEED8J1hhqsB1oCBGiuh3xXr7fZ9wUjJCQ1HYHqxLJKdYKtoCiPmgKM7etVftXkmTFETZmpM19aRyih3bao76LdpQtbw636r7a3qt8v4WfxsXJetSL8c7t24SqQBcAY89FBsbEnFNrQCMK3JEseKHVaU388ctvRD45uQfe5GndFxthj4iSDomk4uRFd1uRbywoP1tRuabHTDX42UxPjz" +TEST_SHORT_DP4 = "did:peer:4zQmd8CpeFPci817KDsbSAKWcXAE2mjvCQSasRewvbSF54Bd" + + +@pytest.fixture +def event_bus(): + yield EventBus() + + +@pytest.fixture +def profile(event_bus: EventBus): + """Profile fixture.""" + profile = InMemoryProfile.test_profile() + profile.context.injector.bind_instance(EventBus, event_bus) + yield profile + + +@pytest.fixture +async def resolver(profile): + """Resolver fixture.""" + instance = PeerDID4Resolver() + await instance.setup(profile.context) + yield instance + + +@pytest.mark.asyncio +async def test_resolve_2_then_3(profile: Profile, resolver: PeerDID4Resolver): + """Test resolver setup.""" + assert resolver.supported_did_regex + assert await resolver.supports(profile, TEST_LONG_DP4) + assert await resolver.supports(profile, TEST_SHORT_DP4) + + long_doc = await resolver.resolve(profile, TEST_LONG_DP4) + short_doc = await resolver.resolve(profile, TEST_SHORT_DP4) + + assert long_doc["id"] == TEST_LONG_DP4 + assert TEST_SHORT_DP4 in long_doc["alsoKnownAs"] + assert short_doc["id"] == TEST_SHORT_DP4 + + +@pytest.mark.asyncio +async def test_resolve_x_no_long(profile: Profile, resolver: PeerDID4Resolver): + """Test resolver setup.""" + with pytest.raises(test_module.DIDNotFound): + await resolver.resolve(profile, TEST_SHORT_DP4) diff --git a/aries_cloudagent/wallet/askar.py b/aries_cloudagent/wallet/askar.py index 3f530a28bb..c7a55501ca 100644 --- a/aries_cloudagent/wallet/askar.py +++ b/aries_cloudagent/wallet/askar.py @@ -4,7 +4,7 @@ import json import logging -from typing import List, Sequence, Tuple, Union +from typing import List, Optional, Sequence, Tuple, Union from aries_askar import ( AskarError, @@ -59,7 +59,10 @@ def session(self) -> AskarProfileSession: return self._session async def create_signing_key( - self, key_type: KeyType, seed: str = None, metadata: dict = None + self, + key_type: KeyType, + seed: Optional[str] = None, + metadata: Optional[dict] = None, ) -> KeyInfo: """Create a new public/private signing keypair. @@ -76,7 +79,28 @@ async def create_signing_key( WalletError: If there is another backend error """ + return await self.create_key(key_type, seed, metadata) + + async def create_key( + self, + key_type: KeyType, + seed: Optional[str] = None, + metadata: Optional[dict] = None, + ) -> KeyInfo: + """Create a new public/private keypair. + Args: + key_type: Key type to create + seed: Seed for key + metadata: Optional metadata to store with the keypair + + Returns: + A `KeyInfo` representing the new record + + Raises: + WalletDuplicateError: If the resulting verkey already exists in the wallet + WalletError: If there is another backend error + """ if metadata is None: metadata = {} try: @@ -146,9 +170,9 @@ async def create_local_did( self, method: DIDMethod, key_type: KeyType, - seed: str = None, - did: str = None, - metadata: dict = None, + seed: Optional[str] = None, + did: Optional[str] = None, + metadata: Optional[dict] = None, ) -> DIDInfo: """Create and store a new local DID. @@ -230,6 +254,46 @@ async def create_local_did( did=did, verkey=verkey, metadata=metadata, method=method, key_type=key_type ) + async def store_did(self, did_info: DIDInfo) -> DIDInfo: + """Store a DID in the wallet. + + This enables components external to the wallet to define how a DID + is created and then store it in the wallet for later use. + + Args: + did_info: The DID to store + + Returns: + The stored `DIDInfo` + """ + try: + item = await self._session.handle.fetch( + CATEGORY_DID, did_info.did, for_update=True + ) + if item: + raise WalletDuplicateError("DID already present in wallet") + else: + await self._session.handle.insert( + CATEGORY_DID, + did_info.did, + value_json={ + "did": did_info.did, + "method": did_info.method.method_name, + "verkey": did_info.verkey, + "verkey_type": did_info.key_type.key_type, + "metadata": did_info.metadata, + }, + tags={ + "method": did_info.method.method_name, + "verkey": did_info.verkey, + "verkey_type": did_info.key_type.key_type, + }, + ) + except AskarError as err: + raise WalletError("Error when storing DID") from err + + return did_info + async def get_local_dids(self) -> Sequence[DIDInfo]: """Get list of defined local DIDs. @@ -711,7 +775,7 @@ def _load_did_entry(self, entry: Entry) -> DIDInfo: ) -def _create_keypair(key_type: KeyType, seed: Union[str, bytes] = None) -> Key: +def _create_keypair(key_type: KeyType, seed: Union[str, bytes, None] = None) -> Key: """Instantiate a new keypair with an optional seed value.""" if key_type == ED25519: alg = KeyAlg.ED25519 diff --git a/aries_cloudagent/wallet/base.py b/aries_cloudagent/wallet/base.py index 65e871a692..06404cebea 100644 --- a/aries_cloudagent/wallet/base.py +++ b/aries_cloudagent/wallet/base.py @@ -1,7 +1,7 @@ """Wallet base class.""" from abc import ABC, abstractmethod -from typing import List, Sequence, Tuple, Union +from typing import List, Optional, Sequence, Tuple, Union from ..ledger.base import BaseLedger from ..ledger.endpoint_type import EndpointType @@ -17,7 +17,10 @@ class BaseWallet(ABC): @abstractmethod async def create_signing_key( - self, key_type: KeyType, seed: str = None, metadata: dict = None + self, + key_type: KeyType, + seed: Optional[str] = None, + metadata: Optional[dict] = None, ) -> KeyInfo: """Create a new public/private signing keypair. @@ -31,6 +34,28 @@ async def create_signing_key( """ + @abstractmethod + async def create_key( + self, + key_type: KeyType, + seed: Optional[str] = None, + metadata: Optional[dict] = None, + ) -> KeyInfo: + """Create a new public/private keypair. + + Args: + key_type: Key type to create + seed: Seed for key + metadata: Optional metadata to store with the keypair + + Returns: + A `KeyInfo` representing the new record + + Raises: + WalletDuplicateError: If the resulting verkey already exists in the wallet + WalletError: If there is another backend error + """ + @abstractmethod async def get_signing_key(self, verkey: str) -> KeyInfo: """Fetch info for a signing keypair. @@ -87,9 +112,9 @@ async def create_local_did( self, method: DIDMethod, key_type: KeyType, - seed: str = None, - did: str = None, - metadata: dict = None, + seed: Optional[str] = None, + did: Optional[str] = None, + metadata: Optional[dict] = None, ) -> DIDInfo: """Create and store a new local DID. @@ -105,6 +130,20 @@ async def create_local_did( """ + @abstractmethod + async def store_did(self, did_info: DIDInfo) -> DIDInfo: + """Store a DID in the wallet. + + This enables components external to the wallet to define how a DID + is created and then store it in the wallet for later use. + + Args: + did_info: The DID to store + + Returns: + The stored `DIDInfo` + """ + async def create_public_did( self, method: DIDMethod, diff --git a/aries_cloudagent/wallet/crypto.py b/aries_cloudagent/wallet/crypto.py index b5e7f2d3b7..86b1c1ec79 100644 --- a/aries_cloudagent/wallet/crypto.py +++ b/aries_cloudagent/wallet/crypto.py @@ -102,7 +102,7 @@ def sign_pk_from_sk(secret: bytes) -> bytes: return secret[seed_len:] -def validate_seed(seed: Union[str, bytes]) -> bytes: +def validate_seed(seed: Union[str, bytes, None]) -> bytes: """Convert a seed parameter to standard format and check length. Args: diff --git a/aries_cloudagent/wallet/did_method.py b/aries_cloudagent/wallet/did_method.py index bcf65eb967..d18d81caa8 100644 --- a/aries_cloudagent/wallet/did_method.py +++ b/aries_cloudagent/wallet/did_method.py @@ -4,7 +4,7 @@ from typing import Dict, List, Mapping, Optional from .error import BaseError -from .key_type import BLS12381G2, ED25519, KeyType +from .key_type import BLS12381G2, ED25519, X25519, KeyType class HolderDefinedDid(Enum): @@ -76,6 +76,12 @@ def holder_defined_did(self) -> HolderDefinedDid: rotation=True, holder_defined_did=HolderDefinedDid.REQUIRED, ) +PEER2 = DIDMethod( + name="did:peer:2", + key_types=[ED25519, X25519], + rotation=False, + holder_defined_did=HolderDefinedDid.NO, +) class DIDMethods: @@ -87,6 +93,7 @@ def __init__(self) -> None: SOV.method_name: SOV, KEY.method_name: KEY, WEB.method_name: WEB, + PEER2.method_name: PEER2, } def registered(self, method: str) -> bool: diff --git a/aries_cloudagent/wallet/in_memory.py b/aries_cloudagent/wallet/in_memory.py index 2514ca805f..022fe4f8f3 100644 --- a/aries_cloudagent/wallet/in_memory.py +++ b/aries_cloudagent/wallet/in_memory.py @@ -1,7 +1,7 @@ """In-memory implementation of BaseWallet interface.""" import asyncio -from typing import List, Sequence, Tuple, Union +from typing import List, Optional, Sequence, Tuple, Union from .did_parameters_validation import DIDParametersValidation from ..core.in_memory import InMemoryProfile @@ -38,8 +38,8 @@ def __init__(self, profile: InMemoryProfile): async def create_signing_key( self, key_type: KeyType, - seed: str = None, - metadata: dict = None, + seed: Optional[str] = None, + metadata: Optional[dict] = None, ) -> KeyInfo: """Create a new public/private signing keypair. @@ -55,8 +55,30 @@ async def create_signing_key( WalletDuplicateError: If the resulting verkey already exists in the wallet """ - seed = validate_seed(seed) or random_seed() - verkey, secret = create_keypair(key_type, seed) + return await self.create_key(key_type, seed, metadata) + + async def create_key( + self, + key_type: KeyType, + seed: Optional[str] = None, + metadata: Optional[dict] = None, + ) -> KeyInfo: + """Create a new public/private keypair. + + Args: + key_type: Key type to create + seed: Seed for key + metadata: Optional metadata to store with the keypair + + Returns: + A `KeyInfo` representing the new record + + Raises: + WalletDuplicateError: If the resulting verkey already exists in the wallet + WalletError: If there is another backend error + """ + seed_or_random = validate_seed(seed) or random_seed() + verkey, secret = create_keypair(key_type, seed_or_random) verkey_enc = bytes_to_b58(verkey) if verkey_enc in self.profile.keys: raise WalletDuplicateError("Verification key already present in wallet") @@ -183,9 +205,9 @@ async def create_local_did( self, method: DIDMethod, key_type: KeyType, - seed: str = None, - did: str = None, - metadata: dict = None, + seed: Optional[str] = None, + did: Optional[str] = None, + metadata: Optional[dict] = None, ) -> DIDInfo: """Create and store a new local DID. @@ -236,6 +258,33 @@ async def create_local_did( key_type=key_type, ) + async def store_did(self, did_info: DIDInfo) -> DIDInfo: + """Store a DID in the wallet. + + This enables components external to the wallet to define how a DID + is created and then store it in the wallet for later use. + + Args: + did_info: The DID to store + + Returns: + The stored `DIDInfo` + """ + if did_info.did in self.profile.local_dids: + raise WalletDuplicateError("DID already exists in wallet") + + key = self.profile.keys[did_info.verkey] + + self.profile.local_dids[did_info.did] = { + "seed": key.get("seed"), + "secret": key.get("secret"), + "verkey": did_info.verkey, + "metadata": did_info.metadata.copy(), + "key_type": did_info.key_type, + "method": did_info.method, + } + return did_info + def _get_did_info(self, did: str) -> DIDInfo: """Convert internal DID record to DIDInfo. diff --git a/aries_cloudagent/wallet/indy.py b/aries_cloudagent/wallet/indy.py index 3e570f4d62..e8d33b6652 100644 --- a/aries_cloudagent/wallet/indy.py +++ b/aries_cloudagent/wallet/indy.py @@ -3,7 +3,7 @@ import json import logging -from typing import List, Sequence, Tuple, Union +from typing import List, Optional, Sequence, Tuple, Union import indy.anoncreds import indy.did @@ -136,7 +136,10 @@ async def __create_keypair_signing_key( return verkey async def create_signing_key( - self, key_type: KeyType, seed: str = None, metadata: dict = None + self, + key_type: KeyType, + seed: Optional[str] = None, + metadata: Optional[dict] = None, ) -> KeyInfo: """Create a new public/private signing keypair. @@ -152,6 +155,28 @@ async def create_signing_key( WalletError: If there is a libindy error """ + return await self.create_key(key_type, seed, metadata) + + async def create_key( + self, + key_type: KeyType, + seed: Optional[str] = None, + metadata: Optional[dict] = None, + ) -> KeyInfo: + """Create a new public/private keypair. + + Args: + key_type: Key type to create + seed: Seed for key + metadata: Optional metadata to store with the keypair + + Returns: + A `KeyInfo` representing the new record + + Raises: + WalletDuplicateError: If the resulting verkey already exists in the wallet + WalletError: If there is another backend error + """ # must save metadata to allow identity check # otherwise get_key_metadata just returns WalletItemNotFound @@ -415,9 +440,9 @@ async def create_local_did( self, method: DIDMethod, key_type: KeyType, - seed: str = None, - did: str = None, - metadata: dict = None, + seed: Optional[str] = None, + did: Optional[str] = None, + metadata: Optional[dict] = None, ) -> DIDInfo: """Create and store a new local DID. @@ -458,6 +483,20 @@ async def create_local_did( method, key_type, metadata, seed ) + async def store_did(self, did_info: DIDInfo) -> DIDInfo: + """Store a DID in the wallet. + + This enables components external to the wallet to define how a DID + is created and then store it in the wallet for later use. + + Args: + did_info: The DID to store + + Returns: + The stored `DIDInfo` + """ + raise WalletError("This operation is not supported by Indy-SDK wallets") + async def get_local_dids(self) -> Sequence[DIDInfo]: """Get list of defined local DIDs. diff --git a/demo/bdd_support/agent_backchannel_client.py b/demo/bdd_support/agent_backchannel_client.py index 907f159f75..7dd2c24828 100644 --- a/demo/bdd_support/agent_backchannel_client.py +++ b/demo/bdd_support/agent_backchannel_client.py @@ -29,8 +29,8 @@ def async_sleep(delay): ###################################################################### # high level aries agent interface ###################################################################### -def create_agent_container_with_args(in_args: list): - return run_coroutine(create_agent_with_args_list, in_args) +def create_agent_container_with_args(in_args: list, extra_args: list = None): + return run_coroutine(create_agent_with_args_list, in_args, extra_args) def aries_container_initialize( diff --git a/demo/features/0160-connection.feature b/demo/features/0160-connection.feature index 1a7bf68a76..a614b3ea93 100644 --- a/demo/features/0160-connection.feature +++ b/demo/features/0160-connection.feature @@ -3,29 +3,35 @@ Feature: RFC 0160 Aries agent connection functions @T001-RFC0160 Scenario Outline: establish a connection between two agents Given we have "2" agents - | name | role | capabilities | - | Acme | inviter | | - | Bob | invitee | | + | name | role | capabilities | extra | + | Acme | inviter | | | + | Bob | invitee | | | When "Acme" generates a connection invitation And "Bob" receives the connection invitation Then "Acme" has an active connection And "Bob" has an active connection + @GHA @UnqualifiedDids + Examples: + | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | + | --public-did --did-exchange | --emit-did-peer-2 | --did-exchange |--emit-did-peer-2 | + | --public-did --did-exchange | --emit-did-peer-2 | --did-exchange | | + @GHA @WalletType_Askar Examples: - | Acme_capabilities | Bob_capabilities | - | --public-did | | - | --public-did --did-exchange | --did-exchange | - | --public-did --mediation | --mediation | - | --public-did --multitenant | --multitenant | - | --public-did --mediation --multitenant --log-file | --mediation --multitenant --log-file | + | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | + | --public-did | | | | + | --public-did --did-exchange | | --did-exchange | | + | --public-did --mediation | | --mediation | | + | --public-did --multitenant | | --multitenant | | + | --public-did --mediation --multitenant --log-file | | --mediation --multitenant --log-file | | @GHA @WalletType_Askar_AnonCreds Examples: - | Acme_capabilities | Bob_capabilities | - | --public-did --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | - | --public-did --wallet-type askar-anoncreds | | - | --public-did | --wallet-type askar-anoncreds | - | --public-did --did-exchange --wallet-type askar-anoncreds | --did-exchange --wallet-type askar-anoncreds | - | --public-did --mediation --wallet-type askar-anoncreds | --mediation --wallet-type askar-anoncreds | - | --public-did --multitenant --wallet-type askar-anoncreds | --multitenant --wallet-type askar-anoncreds | + | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | + | --public-did --wallet-type askar-anoncreds | | --wallet-type askar-anoncreds | | + | --public-did --wallet-type askar-anoncreds | | | | + | --public-did | | --wallet-type askar-anoncreds | | + | --public-did --did-exchange --wallet-type askar-anoncreds | | --did-exchange --wallet-type askar-anoncreds | | + | --public-did --mediation --wallet-type askar-anoncreds | | --mediation --wallet-type askar-anoncreds | | + | --public-did --multitenant --wallet-type askar-anoncreds | | --multitenant --wallet-type askar-anoncreds | | diff --git a/demo/features/steps/0160-connection.py b/demo/features/steps/0160-connection.py index 4d3582aadf..1f26148959 100644 --- a/demo/features/steps/0160-connection.py +++ b/demo/features/steps/0160-connection.py @@ -18,10 +18,7 @@ aries_container_generate_invitation, aries_container_receive_invitation, aries_container_detect_connection, - agent_container_GET, - agent_container_POST, ) -from runners.agent_container import AgentContainer BDD_EXTRA_AGENT_ARGS = os.getenv("BDD_EXTRA_AGENT_ARGS") @@ -44,6 +41,7 @@ def step_impl(context, n): agent_name = row["name"] agent_role = row["role"] agent_params = row["capabilities"] + agent_extra_args = row.get("extra") in_args = [ "--ident", agent_name, @@ -59,6 +57,8 @@ def step_impl(context, n): extra_args.get("wallet-type"), ] ) + if agent_extra_args: + agent_extra_args = agent_extra_args.split(" ") context.active_agents[agent_name] = { "name": agent_name, @@ -67,8 +67,8 @@ def step_impl(context, n): } # startup an agent with the provided params - print("Create agent with:", in_args) - agent = create_agent_container_with_args(in_args) + print("Create agent with:", in_args, agent_extra_args) + agent = create_agent_container_with_args(in_args, agent_extra_args or None) # keep reference to the agent so we can shut it down later context.active_agents[agent_name]["agent"] = agent @@ -95,7 +95,7 @@ def step_impl(context, invitee): agent = context.active_agents[invitee] invite_data = context.inviter_invitation - connection = aries_container_receive_invitation(agent["agent"], invite_data) + aries_container_receive_invitation(agent["agent"], invite_data) # get connection and verify status # assert expected_agent_state(invitee_url, "connection", context.connection_id_dict[invitee][context.inviter_name], "invited") diff --git a/demo/runners/agent_container.py b/demo/runners/agent_container.py index 5d86e7ecaf..86537399cf 100644 --- a/demo/runners/agent_container.py +++ b/demo/runners/agent_container.py @@ -6,6 +6,7 @@ import random import sys import time +from typing import List import yaml from qrcode import QRCode @@ -60,9 +61,10 @@ def __init__( log_file: str = None, log_config: str = None, log_level: str = None, + extra_args: List[str] = None, **kwargs, ): - extra_args = [] + extra_args = extra_args or [] if not no_auto: extra_args.extend( ( @@ -711,6 +713,7 @@ def __init__( log_file: str = None, log_config: str = None, log_level: str = None, + extra_args: List[str] = None, ): # configuration parameters self.genesis_txns = genesis_txns @@ -750,6 +753,7 @@ def __init__( self.agent = None self.mediator_agent = None self.taa_accept = taa_accept + self.extra_args = extra_args async def initialize( self, @@ -786,6 +790,7 @@ async def initialize( log_file=self.log_file, log_config=self.log_config, log_level=self.log_level, + extra_args=self.extra_args, ) else: self.agent = the_agent @@ -1159,8 +1164,7 @@ async def register_did(self, did, verkey, role): ) async def admin_GET(self, path, text=False, params=None) -> dict: - """ - Execute an admin GET request in the context of the current wallet. + """Execute an admin GET request in the context of the current wallet. path = /path/of/request text = True if the expected response is text, False if json data @@ -1169,8 +1173,7 @@ async def admin_GET(self, path, text=False, params=None) -> dict: return await self.agent.admin_GET(path, text=text, params=params) async def admin_POST(self, path, data=None, text=False, params=None) -> dict: - """ - Execute an admin POST request in the context of the current wallet. + """Execute an admin POST request in the context of the current wallet. path = /path/of/request data = payload to post with the request @@ -1180,8 +1183,7 @@ async def admin_POST(self, path, data=None, text=False, params=None) -> dict: return await self.agent.admin_POST(path, data=data, text=text, params=params) async def admin_PATCH(self, path, data=None, text=False, params=None) -> dict: - """ - Execute an admin PATCH request in the context of the current wallet. + """Execute an admin PATCH request in the context of the current wallet. path = /path/of/request data = payload to post with the request @@ -1191,8 +1193,7 @@ async def admin_PATCH(self, path, data=None, text=False, params=None) -> dict: return await self.agent.admin_PATCH(path, data=data, text=text, params=params) async def admin_PUT(self, path, data=None, text=False, params=None) -> dict: - """ - Execute an admin PUT request in the context of the current wallet. + """Execute an admin PUT request in the context of the current wallet. path = /path/of/request data = payload to post with the request @@ -1202,18 +1203,16 @@ async def admin_PUT(self, path, data=None, text=False, params=None) -> dict: return await self.agent.admin_PUT(path, data=data, text=text, params=params) async def admin_DELETE(self, path, data=None, text=False, params=None) -> dict: - """ - Execute an admin DELETE request in the context of the current wallet. + """Execute an admin DELETE request in the context of the current wallet. path = /path/of/request data = payload to post with the request text = True if the expected response is text, False if json data - params = any additional parameters to pass with the request + params = any additional parameters to pass with the request. """ return await self.agent.admin_DELETE(path, data=data, text=text, params=params) async def agency_admin_GET(self, path, text=False, params=None) -> dict: - """ - Execute an agency GET request in the context of the base wallet (multitenant only). + """Execute an agency GET request in the context of the base wallet (multitenant only). path = /path/of/request text = True if the expected response is text, False if json data @@ -1222,8 +1221,7 @@ async def agency_admin_GET(self, path, text=False, params=None) -> dict: return await self.agent.agency_admin_GET(path, text=text, params=params) async def agency_admin_POST(self, path, data=None, text=False, params=None) -> dict: - """ - Execute an agency POST request in the context of the base wallet (multitenant only). + """Execute an agency POST request in the context of the base wallet (multitenant only). path = /path/of/request data = payload to post with the request @@ -1236,8 +1234,7 @@ async def agency_admin_POST(self, path, data=None, text=False, params=None) -> d def arg_parser(ident: str = None, port: int = 8020): - """ - Standard command-line arguments. + """Standard command-line arguments. "ident", if specified, refers to one of the standard demo personas - alice, faber, acme or performance. """ @@ -1390,14 +1387,14 @@ def arg_parser(ident: str = None, port: int = 8020): return parser -async def create_agent_with_args_list(in_args: list): +async def create_agent_with_args_list(in_args: list, extra_args: list = None): parser = arg_parser() args = parser.parse_args(in_args) - return await create_agent_with_args(args) + return await create_agent_with_args(args, extra_args=extra_args) -async def create_agent_with_args(args, ident: str = None): +async def create_agent_with_args(args, ident: str = None, extra_args: list = None): if ("did_exchange" in args and args.did_exchange) and args.mediation: raise Exception( "DID-Exchange connection protocol is not (yet) compatible with mediation" @@ -1507,6 +1504,7 @@ async def create_agent_with_args(args, ident: str = None): log_file=log_file, log_config=log_config, log_level=log_level, + extra_args=extra_args, ) return agent @@ -1581,7 +1579,7 @@ async def test_main( # alice accept invitation invite_details = invite["invitation"] - connection = await alice_container.input_invitation(invite_details) + await alice_container.input_invitation(invite_details) # wait for faber connection to activate await faber_container.detect_connection() diff --git a/demo/runners/support/agent.py b/demo/runners/support/agent.py index 2da2f5db62..a114ef00a3 100644 --- a/demo/runners/support/agent.py +++ b/demo/runners/support/agent.py @@ -313,9 +313,7 @@ async def fetch_cred_defs( return cred_defs_saved elif wallet_type == WALLET_TYPE_ANONCREDS: cred_defs_saved = await self.admin_GET("/anoncreds/credential-definitions") - return { - "credential_definition_ids": cred_defs_saved, - } + return cred_defs_saved else: raise Exception("Invalid wallet_type: " + str(wallet_type)) diff --git a/poetry.lock b/poetry.lock index 669778489d..6977e876b7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,88 +1,89 @@ -# 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.4.2 and should not be changed by hand. [[package]] name = "aiohttp" -version = "3.9.0" +version = "3.9.1" description = "Async http client/server framework (asyncio)" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.9.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6896b8416be9ada4d22cd359d7cb98955576ce863eadad5596b7cdfbf3e17c6c"}, - {file = "aiohttp-3.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1736d87dad8ef46a8ec9cddd349fa9f7bd3a064c47dd6469c0d6763d3d49a4fc"}, - {file = "aiohttp-3.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c9e5f4d7208cda1a2bb600e29069eecf857e6980d0ccc922ccf9d1372c16f4b"}, - {file = "aiohttp-3.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8488519aa05e636c5997719fe543c8daf19f538f4fa044f3ce94bee608817cff"}, - {file = "aiohttp-3.9.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ab16c254e2312efeb799bc3c06897f65a133b38b69682bf75d1f1ee1a9c43a9"}, - {file = "aiohttp-3.9.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7a94bde005a8f926d0fa38b88092a03dea4b4875a61fbcd9ac6f4351df1b57cd"}, - {file = "aiohttp-3.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b777c9286b6c6a94f50ddb3a6e730deec327e9e2256cb08b5530db0f7d40fd8"}, - {file = "aiohttp-3.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:571760ad7736b34d05597a1fd38cbc7d47f7b65deb722cb8e86fd827404d1f6b"}, - {file = "aiohttp-3.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:deac0a32aec29608eb25d730f4bc5a261a65b6c48ded1ed861d2a1852577c932"}, - {file = "aiohttp-3.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4ee1b4152bc3190cc40ddd6a14715e3004944263ea208229ab4c297712aa3075"}, - {file = "aiohttp-3.9.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:3607375053df58ed6f23903aa10cf3112b1240e8c799d243bbad0f7be0666986"}, - {file = "aiohttp-3.9.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:65b0a70a25456d329a5e1426702dde67be0fb7a4ead718005ba2ca582d023a94"}, - {file = "aiohttp-3.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5a2eb5311a37fe105aa35f62f75a078537e1a9e4e1d78c86ec9893a3c97d7a30"}, - {file = "aiohttp-3.9.0-cp310-cp310-win32.whl", hash = "sha256:2cbc14a13fb6b42d344e4f27746a4b03a2cb0c1c3c5b932b0d6ad8881aa390e3"}, - {file = "aiohttp-3.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ac9669990e2016d644ba8ae4758688534aabde8dbbc81f9af129c3f5f01ca9cd"}, - {file = "aiohttp-3.9.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f8e05f5163528962ce1d1806fce763ab893b1c5b7ace0a3538cd81a90622f844"}, - {file = "aiohttp-3.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4afa8f71dba3a5a2e1e1282a51cba7341ae76585345c43d8f0e624882b622218"}, - {file = "aiohttp-3.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f929f4c9b9a00f3e6cc0587abb95ab9c05681f8b14e0fe1daecfa83ea90f8318"}, - {file = "aiohttp-3.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28185e36a78d247c55e9fbea2332d16aefa14c5276a582ce7a896231c6b1c208"}, - {file = "aiohttp-3.9.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a486ddf57ab98b6d19ad36458b9f09e6022de0381674fe00228ca7b741aacb2f"}, - {file = "aiohttp-3.9.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70e851f596c00f40a2f00a46126c95c2e04e146015af05a9da3e4867cfc55911"}, - {file = "aiohttp-3.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5b7bf8fe4d39886adc34311a233a2e01bc10eb4e842220235ed1de57541a896"}, - {file = "aiohttp-3.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c67a51ea415192c2e53e4e048c78bab82d21955b4281d297f517707dc836bf3d"}, - {file = "aiohttp-3.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:694df243f394629bcae2d8ed94c589a181e8ba8604159e6e45e7b22e58291113"}, - {file = "aiohttp-3.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3dd8119752dd30dd7bca7d4bc2a92a59be6a003e4e5c2cf7e248b89751b8f4b7"}, - {file = "aiohttp-3.9.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:eb6dfd52063186ac97b4caa25764cdbcdb4b10d97f5c5f66b0fa95052e744eb7"}, - {file = "aiohttp-3.9.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:d97c3e286d0ac9af6223bc132dc4bad6540b37c8d6c0a15fe1e70fb34f9ec411"}, - {file = "aiohttp-3.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:816f4db40555026e4cdda604a1088577c1fb957d02f3f1292e0221353403f192"}, - {file = "aiohttp-3.9.0-cp311-cp311-win32.whl", hash = "sha256:3abf0551874fecf95f93b58f25ef4fc9a250669a2257753f38f8f592db85ddea"}, - {file = "aiohttp-3.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:e18d92c3e9e22553a73e33784fcb0ed484c9874e9a3e96c16a8d6a1e74a0217b"}, - {file = "aiohttp-3.9.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:99ae01fb13a618b9942376df77a1f50c20a281390dad3c56a6ec2942e266220d"}, - {file = "aiohttp-3.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:05857848da443c8c12110d99285d499b4e84d59918a21132e45c3f0804876994"}, - {file = "aiohttp-3.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:317719d7f824eba55857fe0729363af58e27c066c731bc62cd97bc9c3d9c7ea4"}, - {file = "aiohttp-3.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1e3b3c107ccb0e537f309f719994a55621acd2c8fdf6d5ce5152aed788fb940"}, - {file = "aiohttp-3.9.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45820ddbb276113ead8d4907a7802adb77548087ff5465d5c554f9aa3928ae7d"}, - {file = "aiohttp-3.9.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:05a183f1978802588711aed0dea31e697d760ce9055292db9dc1604daa9a8ded"}, - {file = "aiohttp-3.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a4cd44788ea0b5e6bb8fa704597af3a30be75503a7ed1098bc5b8ffdf6c982"}, - {file = "aiohttp-3.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:673343fbc0c1ac44d0d2640addc56e97a052504beacd7ade0dc5e76d3a4c16e8"}, - {file = "aiohttp-3.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7e8a3b79b6d186a9c99761fd4a5e8dd575a48d96021f220ac5b5fa856e5dd029"}, - {file = "aiohttp-3.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6777a390e41e78e7c45dab43a4a0196c55c3b8c30eebe017b152939372a83253"}, - {file = "aiohttp-3.9.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7ae5f99a32c53731c93ac3075abd3e1e5cfbe72fc3eaac4c27c9dd64ba3b19fe"}, - {file = "aiohttp-3.9.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:f1e4f254e9c35d8965d377e065c4a8a55d396fe87c8e7e8429bcfdeeb229bfb3"}, - {file = "aiohttp-3.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11ca808f9a6b63485059f5f6e164ef7ec826483c1212a44f268b3653c91237d8"}, - {file = "aiohttp-3.9.0-cp312-cp312-win32.whl", hash = "sha256:de3cc86f4ea8b4c34a6e43a7306c40c1275e52bfa9748d869c6b7d54aa6dad80"}, - {file = "aiohttp-3.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca4fddf84ac7d8a7d0866664936f93318ff01ee33e32381a115b19fb5a4d1202"}, - {file = "aiohttp-3.9.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f09960b5bb1017d16c0f9e9f7fc42160a5a49fa1e87a175fd4a2b1a1833ea0af"}, - {file = "aiohttp-3.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8303531e2c17b1a494ffaeba48f2da655fe932c4e9a2626c8718403c83e5dd2b"}, - {file = "aiohttp-3.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4790e44f46a4aa07b64504089def5744d3b6780468c4ec3a1a36eb7f2cae9814"}, - {file = "aiohttp-3.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1d7edf74a36de0e5ca50787e83a77cf352f5504eb0ffa3f07000a911ba353fb"}, - {file = "aiohttp-3.9.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94697c7293199c2a2551e3e3e18438b4cba293e79c6bc2319f5fd652fccb7456"}, - {file = "aiohttp-3.9.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a1b66dbb8a7d5f50e9e2ea3804b01e766308331d0cac76eb30c563ac89c95985"}, - {file = "aiohttp-3.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9623cfd9e85b76b83ef88519d98326d4731f8d71869867e47a0b979ffec61c73"}, - {file = "aiohttp-3.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f32c86dc967ab8c719fd229ce71917caad13cc1e8356ee997bf02c5b368799bf"}, - {file = "aiohttp-3.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f50b4663c3e0262c3a361faf440761fbef60ccdde5fe8545689a4b3a3c149fb4"}, - {file = "aiohttp-3.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dcf71c55ec853826cd70eadb2b6ac62ec577416442ca1e0a97ad875a1b3a0305"}, - {file = "aiohttp-3.9.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:42fe4fd9f0dfcc7be4248c162d8056f1d51a04c60e53366b0098d1267c4c9da8"}, - {file = "aiohttp-3.9.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76a86a9989ebf82ee61e06e2bab408aec4ea367dc6da35145c3352b60a112d11"}, - {file = "aiohttp-3.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f9e09a1c83521d770d170b3801eea19b89f41ccaa61d53026ed111cb6f088887"}, - {file = "aiohttp-3.9.0-cp38-cp38-win32.whl", hash = "sha256:a00ce44c21612d185c5275c5cba4bab8d7c1590f248638b667ed8a782fa8cd6f"}, - {file = "aiohttp-3.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:d5b9345ab92ebe6003ae11d8092ce822a0242146e6fa270889b9ba965457ca40"}, - {file = "aiohttp-3.9.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:98d21092bf2637c5fa724a428a69e8f5955f2182bff61f8036827cf6ce1157bf"}, - {file = "aiohttp-3.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:35a68cd63ca6aaef5707888f17a70c36efe62b099a4e853d33dc2e9872125be8"}, - {file = "aiohttp-3.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7f6235c7475658acfc1769d968e07ab585c79f6ca438ddfecaa9a08006aee2"}, - {file = "aiohttp-3.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db04d1de548f7a62d1dd7e7cdf7c22893ee168e22701895067a28a8ed51b3735"}, - {file = "aiohttp-3.9.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:536b01513d67d10baf6f71c72decdf492fb7433c5f2f133e9a9087379d4b6f31"}, - {file = "aiohttp-3.9.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c8b0a6487e8109427ccf638580865b54e2e3db4a6e0e11c02639231b41fc0f"}, - {file = "aiohttp-3.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7276fe0017664414fdc3618fca411630405f1aaf0cc3be69def650eb50441787"}, - {file = "aiohttp-3.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23170247ef89ffa842a02bbfdc425028574d9e010611659abeb24d890bc53bb8"}, - {file = "aiohttp-3.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b1a2ea8252cacc7fd51df5a56d7a2bb1986ed39be9397b51a08015727dfb69bd"}, - {file = "aiohttp-3.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2d71abc15ff7047412ef26bf812dfc8d0d1020d664617f4913df2df469f26b76"}, - {file = "aiohttp-3.9.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:2d820162c8c2bdbe97d328cd4f417c955ca370027dce593345e437b2e9ffdc4d"}, - {file = "aiohttp-3.9.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:2779f5e7c70f7b421915fd47db332c81de365678180a9f3ab404088f87ba5ff9"}, - {file = "aiohttp-3.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:366bc870d7ac61726f32a489fbe3d1d8876e87506870be66b01aeb84389e967e"}, - {file = "aiohttp-3.9.0-cp39-cp39-win32.whl", hash = "sha256:1df43596b826022b14998f0460926ce261544fedefe0d2f653e1b20f49e96454"}, - {file = "aiohttp-3.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:9c196b30f1b1aa3363a69dd69079ae9bec96c2965c4707eaa6914ba099fb7d4f"}, - {file = "aiohttp-3.9.0.tar.gz", hash = "sha256:09f23292d29135025e19e8ff4f0a68df078fe4ee013bca0105b2e803989de92d"}, + {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1f80197f8b0b846a8d5cf7b7ec6084493950d0882cc5537fb7b96a69e3c8590"}, + {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72444d17777865734aa1a4d167794c34b63e5883abb90356a0364a28904e6c0"}, + {file = "aiohttp-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b05d5cbe9dafcdc733262c3a99ccf63d2f7ce02543620d2bd8db4d4f7a22f83"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c4fa235d534b3547184831c624c0b7c1e262cd1de847d95085ec94c16fddcd5"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:289ba9ae8e88d0ba16062ecf02dd730b34186ea3b1e7489046fc338bdc3361c4"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bff7e2811814fa2271be95ab6e84c9436d027a0e59665de60edf44e529a42c1f"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81b77f868814346662c96ab36b875d7814ebf82340d3284a31681085c051320f"}, + {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b9c7426923bb7bd66d409da46c41e3fb40f5caf679da624439b9eba92043fa6"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8d44e7bf06b0c0a70a20f9100af9fcfd7f6d9d3913e37754c12d424179b4e48f"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22698f01ff5653fe66d16ffb7658f582a0ac084d7da1323e39fd9eab326a1f26"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ca7ca5abfbfe8d39e653870fbe8d7710be7a857f8a8386fc9de1aae2e02ce7e4"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8d7f98fde213f74561be1d6d3fa353656197f75d4edfbb3d94c9eb9b0fc47f5d"}, + {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5216b6082c624b55cfe79af5d538e499cd5f5b976820eac31951fb4325974501"}, + {file = "aiohttp-3.9.1-cp310-cp310-win32.whl", hash = "sha256:0e7ba7ff228c0d9a2cd66194e90f2bca6e0abca810b786901a569c0de082f489"}, + {file = "aiohttp-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:c7e939f1ae428a86e4abbb9a7c4732bf4706048818dfd979e5e2839ce0159f23"}, + {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df9cf74b9bc03d586fc53ba470828d7b77ce51b0582d1d0b5b2fb673c0baa32d"}, + {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecca113f19d5e74048c001934045a2b9368d77b0b17691d905af18bd1c21275e"}, + {file = "aiohttp-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8cef8710fb849d97c533f259103f09bac167a008d7131d7b2b0e3a33269185c0"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea94403a21eb94c93386d559bce297381609153e418a3ffc7d6bf772f59cc35"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91c742ca59045dce7ba76cab6e223e41d2c70d79e82c284a96411f8645e2afff"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c93b7c2e52061f0925c3382d5cb8980e40f91c989563d3d32ca280069fd6a87"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee2527134f95e106cc1653e9ac78846f3a2ec1004cf20ef4e02038035a74544d"}, + {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11ff168d752cb41e8492817e10fb4f85828f6a0142b9726a30c27c35a1835f01"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b8c3a67eb87394386847d188996920f33b01b32155f0a94f36ca0e0c635bf3e3"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c7b5d5d64e2a14e35a9240b33b89389e0035e6de8dbb7ffa50d10d8b65c57449"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:69985d50a2b6f709412d944ffb2e97d0be154ea90600b7a921f95a87d6f108a2"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c9110c06eaaac7e1f5562caf481f18ccf8f6fdf4c3323feab28a93d34cc646bd"}, + {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737e69d193dac7296365a6dcb73bbbf53bb760ab25a3727716bbd42022e8d7a"}, + {file = "aiohttp-3.9.1-cp311-cp311-win32.whl", hash = "sha256:4ee8caa925aebc1e64e98432d78ea8de67b2272252b0a931d2ac3bd876ad5544"}, + {file = "aiohttp-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a34086c5cc285be878622e0a6ab897a986a6e8bf5b67ecb377015f06ed316587"}, + {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f800164276eec54e0af5c99feb9494c295118fc10a11b997bbb1348ba1a52065"}, + {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:500f1c59906cd142d452074f3811614be04819a38ae2b3239a48b82649c08821"}, + {file = "aiohttp-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0b0a6a36ed7e164c6df1e18ee47afbd1990ce47cb428739d6c99aaabfaf1b3af"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69da0f3ed3496808e8cbc5123a866c41c12c15baaaead96d256477edf168eb57"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176df045597e674fa950bf5ae536be85699e04cea68fa3a616cf75e413737eb5"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b796b44111f0cab6bbf66214186e44734b5baab949cb5fb56154142a92989aeb"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f27fdaadce22f2ef950fc10dcdf8048407c3b42b73779e48a4e76b3c35bca26c"}, + {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcb6532b9814ea7c5a6a3299747c49de30e84472fa72821b07f5a9818bce0f66"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:54631fb69a6e44b2ba522f7c22a6fb2667a02fd97d636048478db2fd8c4e98fe"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4b4c452d0190c5a820d3f5c0f3cd8a28ace48c54053e24da9d6041bf81113183"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:cae4c0c2ca800c793cae07ef3d40794625471040a87e1ba392039639ad61ab5b"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:565760d6812b8d78d416c3c7cfdf5362fbe0d0d25b82fed75d0d29e18d7fc30f"}, + {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54311eb54f3a0c45efb9ed0d0a8f43d1bc6060d773f6973efd90037a51cd0a3f"}, + {file = "aiohttp-3.9.1-cp312-cp312-win32.whl", hash = "sha256:85c3e3c9cb1d480e0b9a64c658cd66b3cfb8e721636ab8b0e746e2d79a7a9eed"}, + {file = "aiohttp-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:11cb254e397a82efb1805d12561e80124928e04e9c4483587ce7390b3866d213"}, + {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a22a34bc594d9d24621091d1b91511001a7eea91d6652ea495ce06e27381f70"}, + {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:598db66eaf2e04aa0c8900a63b0101fdc5e6b8a7ddd805c56d86efb54eb66672"}, + {file = "aiohttp-3.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c9376e2b09895c8ca8b95362283365eb5c03bdc8428ade80a864160605715f1"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41473de252e1797c2d2293804e389a6d6986ef37cbb4a25208de537ae32141dd"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c5857612c9813796960c00767645cb5da815af16dafb32d70c72a8390bbf690"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffcd828e37dc219a72c9012ec44ad2e7e3066bec6ff3aaa19e7d435dbf4032ca"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:219a16763dc0294842188ac8a12262b5671817042b35d45e44fd0a697d8c8361"}, + {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f694dc8a6a3112059258a725a4ebe9acac5fe62f11c77ac4dcf896edfa78ca28"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bcc0ea8d5b74a41b621ad4a13d96c36079c81628ccc0b30cfb1603e3dfa3a014"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:90ec72d231169b4b8d6085be13023ece8fa9b1bb495e4398d847e25218e0f431"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cf2a0ac0615842b849f40c4d7f304986a242f1e68286dbf3bd7a835e4f83acfd"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:0e49b08eafa4f5707ecfb321ab9592717a319e37938e301d462f79b4e860c32a"}, + {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c59e0076ea31c08553e868cec02d22191c086f00b44610f8ab7363a11a5d9d8"}, + {file = "aiohttp-3.9.1-cp38-cp38-win32.whl", hash = "sha256:4831df72b053b1eed31eb00a2e1aff6896fb4485301d4ccb208cac264b648db4"}, + {file = "aiohttp-3.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:3135713c5562731ee18f58d3ad1bf41e1d8883eb68b363f2ffde5b2ea4b84cc7"}, + {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cfeadf42840c1e870dc2042a232a8748e75a36b52d78968cda6736de55582766"}, + {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:70907533db712f7aa791effb38efa96f044ce3d4e850e2d7691abd759f4f0ae0"}, + {file = "aiohttp-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdefe289681507187e375a5064c7599f52c40343a8701761c802c1853a504558"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7481f581251bb5558ba9f635db70908819caa221fc79ee52a7f58392778c636"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49f0c1b3c2842556e5de35f122fc0f0b721334ceb6e78c3719693364d4af8499"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d406b01a9f5a7e232d1b0d161b40c05275ffbcbd772dc18c1d5a570961a1ca4"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d8e4450e7fe24d86e86b23cc209e0023177b6d59502e33807b732d2deb6975f"}, + {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c0266cd6f005e99f3f51e583012de2778e65af6b73860038b968a0a8888487a"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab221850108a4a063c5b8a70f00dd7a1975e5a1713f87f4ab26a46e5feac5a0e"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c88a15f272a0ad3d7773cf3a37cc7b7d077cbfc8e331675cf1346e849d97a4e5"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:237533179d9747080bcaad4d02083ce295c0d2eab3e9e8ce103411a4312991a0"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:02ab6006ec3c3463b528374c4cdce86434e7b89ad355e7bf29e2f16b46c7dd6f"}, + {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04fa38875e53eb7e354ece1607b1d2fdee2d175ea4e4d745f6ec9f751fe20c7c"}, + {file = "aiohttp-3.9.1-cp39-cp39-win32.whl", hash = "sha256:82eefaf1a996060602f3cc1112d93ba8b201dbf5d8fd9611227de2003dddb3b7"}, + {file = "aiohttp-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:9b05d33ff8e6b269e30a7957bd3244ffbce2a7a35a81b81c382629b80af1a8bf"}, + {file = "aiohttp-3.9.1.tar.gz", hash = "sha256:8fc49a87ac269d4529da45871e2ffb6874e87779c3d0e2ccd813c0899221239d"}, ] [package.dependencies] @@ -100,6 +101,7 @@ speedups = ["Brotli", "aiodns", "brotlicffi"] name = "aiohttp-apispec" version = "2.2.3" description = "Build and document REST APIs with aiohttp and apispec" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -116,6 +118,7 @@ webargs = "<6.0" name = "aiohttp-cors" version = "0.7.0" description = "CORS support for aiohttp" +category = "main" optional = false python-versions = "*" files = [ @@ -130,6 +133,7 @@ aiohttp = ">=1.1" name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -144,6 +148,7 @@ frozenlist = ">=1.1.0" name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -155,6 +160,7 @@ files = [ name = "anoncreds" version = "0.1.0" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -168,6 +174,7 @@ files = [ name = "apispec" version = "3.3.2" description = "A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -187,6 +194,7 @@ yaml = ["PyYAML (>=3.10)"] name = "aries-askar" version = "0.3.0" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -203,6 +211,7 @@ cached-property = ">=1.5,<2.0" name = "async-case" version = "10.1.0" description = "Backport of Python 3.8's unittest.async_case" +category = "dev" optional = false python-versions = "*" files = [ @@ -213,6 +222,7 @@ files = [ name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -224,6 +234,7 @@ files = [ name = "asynctest" version = "0.13.0" description = "Enhance the standard unittest package with features for testing asyncio libraries" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -233,36 +244,36 @@ files = [ [[package]] name = "attrs" -version = "23.1.0" +version = "23.2.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] +dev = ["attrs[tests]", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "babel" -version = "2.13.1" +version = "2.14.0" description = "Internationalization utilities" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, - {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, ] -[package.dependencies] -setuptools = {version = "*", markers = "python_version >= \"3.12\""} - [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] @@ -270,6 +281,7 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] name = "base58" version = "2.1.1" description = "Base58 and Base58Check implementation." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -284,6 +296,7 @@ tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", " name = "black" version = "23.7.0" description = "The uncompromising code formatter." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -330,6 +343,7 @@ uvloop = ["uvloop (>=0.15.2)"] name = "cached-property" version = "1.5.2" description = "A decorator for caching properties in classes." +category = "main" optional = true python-versions = "*" files = [ @@ -341,6 +355,7 @@ files = [ name = "cachetools" version = "5.3.2" description = "Extensible memoizing collections and decorators" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -352,6 +367,7 @@ files = [ name = "certifi" version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -363,6 +379,7 @@ files = [ name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -427,6 +444,7 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -438,6 +456,7 @@ files = [ name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -537,6 +556,7 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -551,6 +571,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -562,6 +583,7 @@ files = [ name = "configargparse" version = "1.5.5" description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -575,63 +597,64 @@ yaml = ["PyYAML"] [[package]] name = "coverage" -version = "7.3.2" +version = "7.4.0" description = "Code coverage measurement for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, - {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, - {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, - {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, - {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, - {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, - {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, - {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, - {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, - {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, - {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, - {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, - {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, - {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, - {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, - {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, - {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, - {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, - {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, - {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, - {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, - {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, - {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, - {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, - {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, - {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, - {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, - {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, + {file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"}, + {file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"}, + {file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"}, + {file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"}, + {file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"}, + {file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"}, + {file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"}, + {file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"}, + {file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"}, + {file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"}, + {file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"}, + {file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"}, + {file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"}, + {file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"}, ] [package.dependencies] @@ -642,34 +665,35 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "41.0.6" +version = "41.0.7" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.6-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:0f27acb55a4e77b9be8d550d762b0513ef3fc658cd3eb15110ebbcbd626db12c"}, - {file = "cryptography-41.0.6-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:ae236bb8760c1e55b7a39b6d4d32d2279bc6c7c8500b7d5a13b6fb9fc97be35b"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afda76d84b053923c27ede5edc1ed7d53e3c9f475ebaf63c68e69f1403c405a8"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da46e2b5df770070412c46f87bac0849b8d685c5f2679771de277a422c7d0b86"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ff369dd19e8fe0528b02e8df9f2aeb2479f89b1270d90f96a63500afe9af5cae"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b648fe2a45e426aaee684ddca2632f62ec4613ef362f4d681a9a6283d10e079d"}, - {file = "cryptography-41.0.6-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5daeb18e7886a358064a68dbcaf441c036cbdb7da52ae744e7b9207b04d3908c"}, - {file = "cryptography-41.0.6-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:068bc551698c234742c40049e46840843f3d98ad7ce265fd2bd4ec0d11306596"}, - {file = "cryptography-41.0.6-cp37-abi3-win32.whl", hash = "sha256:2132d5865eea673fe6712c2ed5fb4fa49dba10768bb4cc798345748380ee3660"}, - {file = "cryptography-41.0.6-cp37-abi3-win_amd64.whl", hash = "sha256:48783b7e2bef51224020efb61b42704207dde583d7e371ef8fc2a5fb6c0aabc7"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:8efb2af8d4ba9dbc9c9dd8f04d19a7abb5b49eab1f3694e7b5a16a5fc2856f5c"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5a550dc7a3b50b116323e3d376241829fd326ac47bc195e04eb33a8170902a9"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:85abd057699b98fce40b41737afb234fef05c67e116f6f3650782c10862c43da"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f39812f70fc5c71a15aa3c97b2bbe213c3f2a460b79bd21c40d033bb34a9bf36"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:742ae5e9a2310e9dade7932f9576606836ed174da3c7d26bc3d3ab4bd49b9f65"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:35f3f288e83c3f6f10752467c48919a7a94b7d88cc00b0668372a0d2ad4f8ead"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4d03186af98b1c01a4eda396b137f29e4e3fb0173e30f885e27acec8823c1b09"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b27a7fd4229abef715e064269d98a7e2909ebf92eb6912a9603c7e14c181928c"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:398ae1fc711b5eb78e977daa3cbf47cec20f2c08c5da129b7a296055fbb22aed"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7e00fb556bda398b99b0da289ce7053639d33b572847181d6483ad89835115f6"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:60e746b11b937911dc70d164060d28d273e31853bb359e2b2033c9e93e6f3c43"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3288acccef021e3c3c10d58933f44e8602cf04dba96d9796d70d537bb2f4bbc4"}, - {file = "cryptography-41.0.6.tar.gz", hash = "sha256:422e3e31d63743855e43e5a6fcc8b4acab860f560f9321b0ee6269cc7ed70cc3"}, + {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"}, + {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"}, + {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"}, + {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"}, + {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"}, + {file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"}, + {file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"}, + {file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"}, + {file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"}, + {file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"}, + {file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"}, ] [package.dependencies] @@ -689,6 +713,7 @@ test-randomorder = ["pytest-randomly"] name = "cytoolz" version = "0.12.2" description = "Cython implementation of Toolz: High performance functional utilities" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -797,6 +822,7 @@ cython = ["cython"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -808,6 +834,7 @@ files = [ name = "deepmerge" version = "0.3.0" description = "a toolset to deeply merge python dictionaries." +category = "main" optional = false python-versions = ">=3" files = [ @@ -819,6 +846,7 @@ files = [ name = "deprecated" version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -836,6 +864,7 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] name = "did-peer-2" version = "0.1.2" description = "An implementation of did:peer:2" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -846,32 +875,50 @@ files = [ [package.dependencies] base58 = ">=2.1.1" +[[package]] +name = "did-peer-4" +version = "0.1.4" +description = "An implementation of did:peer:4" +category = "main" +optional = false +python-versions = ">=3.9" +files = [ + {file = "did_peer_4-0.1.4-py3-none-any.whl", hash = "sha256:4c2bb42a55e4fec08fe008a1585db2f11fe19e36121f8919991add027d7c816f"}, + {file = "did_peer_4-0.1.4.tar.gz", hash = "sha256:b367922067b428d33458ca36158eaed40c863cde2fbab6a18a523dccad533c8e"}, +] + +[package.dependencies] +base58 = ">=2.1.1" + [[package]] name = "distlib" -version = "0.3.7" +version = "0.3.8" description = "Distribution utilities" +category = "dev" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, - {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] [[package]] name = "docutils" -version = "0.20.1" +version = "0.18.1" description = "Docutils -- Python Documentation Utilities" +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ - {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, - {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, + {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, + {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] [[package]] name = "ecdsa" version = "0.16.1" description = "ECDSA cryptographic signature library (pure python)" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -890,6 +937,7 @@ gmpy2 = ["gmpy2"] name = "eth-hash" version = "0.3.3" description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (erroneously) called sha3" +category = "main" optional = false python-versions = ">=3.5, <4" files = [ @@ -909,6 +957,7 @@ test = ["pytest (==5.4.1)", "pytest-xdist", "tox (==3.14.6)"] name = "eth-typing" version = "2.3.0" description = "eth-typing: Common type annotations for ethereum python packages" +category = "main" optional = false python-versions = ">=3.5, <4" files = [ @@ -926,6 +975,7 @@ test = ["pytest (>=4.4,<4.5)", "pytest-xdist", "tox (>=2.9.1,<3)"] name = "eth-utils" version = "1.10.0" description = "eth-utils: Common utility functions for python code that interacts with Ethereum" +category = "main" optional = false python-versions = ">=3.5,!=3.5.2,<4" files = [ @@ -949,6 +999,7 @@ test = ["hypothesis (>=4.43.0,<5.0.0)", "pytest (==5.4.1)", "pytest-xdist", "tox name = "exceptiongroup" version = "1.2.0" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -963,6 +1014,7 @@ test = ["pytest (>=6)"] name = "filelock" version = "3.13.1" description = "A platform independent file lock." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -977,129 +1029,147 @@ typing = ["typing-extensions (>=4.8)"] [[package]] name = "frozendict" -version = "2.3.9" +version = "2.4.0" description = "A simple immutable dictionary" +category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "frozendict-2.3.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb949eaf12d53b1e4034865516c6a1945d6d6f1cb102fa7417c017d7cefcc7a7"}, - {file = "frozendict-2.3.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b57205e9ca00733064e9abfc5b2ced46d65370e5451502a17162d42a7d527d0"}, - {file = "frozendict-2.3.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1262df1e9bea434d5859398522e8d8e393721ea6a3a1ccb0e36a27022a52fa5e"}, - {file = "frozendict-2.3.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:561ddd000da66360142a81996f0ae5b806c267868e77bae2f5ab459334bf6b89"}, - {file = "frozendict-2.3.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a82ffff413d70eab71b9cfcf6f9fb9ad7a1d414a1d664470a214771c332d3c8"}, - {file = "frozendict-2.3.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c04aa367a21bd3af396b64b2021ea13325faa11b832be77791a987dda3fa543c"}, - {file = "frozendict-2.3.9-cp310-cp310-win_amd64.whl", hash = "sha256:48e9a94e4beba7dbb880dab9d33b656ef3a608da3d43105335225b06cb6ae139"}, - {file = "frozendict-2.3.9-cp310-cp310-win_arm64.whl", hash = "sha256:a9331ddde2cdf4fc7d5ad09c6078643517663a3028346cc765fc4145be9d8dd2"}, - {file = "frozendict-2.3.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:38f2f43b44d7d3ac4924116017578ec81812ba385c8f710abda58617eae20afe"}, - {file = "frozendict-2.3.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45d517af1aaede930a7b22b21ff80c09f22bd296a902f681ca58fd5acb5dd33b"}, - {file = "frozendict-2.3.9-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d0dc4c36c0342c5748aab2fcca0c07f33876e41caf62fbdfeac951c2a3bcb5"}, - {file = "frozendict-2.3.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9c63147ce90b2b7e45d3f0923063d624892ed0c7a13fa95787e57dbb27b376a7"}, - {file = "frozendict-2.3.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:9286378eecfe993b803842e2c14c65efd1b12e99e3ac5c25d05661630cedff6d"}, - {file = "frozendict-2.3.9-cp36-cp36m-win_amd64.whl", hash = "sha256:7e89b56f3c13749fd1bf8d20325a572063b5ad8dbf880e7881b8eb8cf41e1743"}, - {file = "frozendict-2.3.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:56117a0104ce68445d6856b5585133f667ae04098f0dcecd7786a510dc121818"}, - {file = "frozendict-2.3.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45071ad048ca6feb4b7a90383aa64377d130b5245bffdd8204debb4f5e9ccf0a"}, - {file = "frozendict-2.3.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75b02cb3473b0da9003b3d71ef8fc76bb97092543035a47000a63352cab2c125"}, - {file = "frozendict-2.3.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ff2e07b94abed60ef233117d5ffc6cac6353c6856fbba898b12a556e5698e440"}, - {file = "frozendict-2.3.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e135a2dd22cf668ce45cb697522497ba2e2bd9cf6c239d06856b69eeae0a557b"}, - {file = "frozendict-2.3.9-cp37-cp37m-win_amd64.whl", hash = "sha256:d3de16b88214874ac1caa1c9527441bdfa0c20bce809d2efbffb307a05f5fafd"}, - {file = "frozendict-2.3.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fa04e7561d10c2feef423963818e43bc24a0fb65f5ea21ffb00f11ae8e6129e3"}, - {file = "frozendict-2.3.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8ce979138e0d5f04e879c9f732a7deba5bf3d55708e1f02533b8301326e1ffda"}, - {file = "frozendict-2.3.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:525da194ad0407c97d23339c19200fa0b464ff16ca2624f7adfc95ec1da17a42"}, - {file = "frozendict-2.3.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bff7ff522ee2a53103a4ae848826d9212a0d61a025562eaac245e93a6aa6285"}, - {file = "frozendict-2.3.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094d43bff2f65371734832385d1a457c5da10399e638e01f85dd71a9e12b9408"}, - {file = "frozendict-2.3.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9c69650ed54670d73652b0880229c8356defbdc4663cf3cb5f844169c7c71666"}, - {file = "frozendict-2.3.9-cp38-cp38-win_amd64.whl", hash = "sha256:21af4b67c1bb7075b5a2e5c1d128f69331ee405bd34028416d9106a0ef6c84eb"}, - {file = "frozendict-2.3.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:06b586394d8e654558fcf2e79ac8511a47d484de8e55a20ecdc6667d87ec1730"}, - {file = "frozendict-2.3.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0196d6f50db96b26aa4144782930caf019aabf68c368b66c79490552128e3472"}, - {file = "frozendict-2.3.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53fb48e8929309a62f1402f0feb2db76a80faa45b69d9cf23bd1e42de8730c62"}, - {file = "frozendict-2.3.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac297f91e101b89514e0dbe8a70c3f6a6185107d8306c3b800440bcdab1bd853"}, - {file = "frozendict-2.3.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bd12f907e378a9796d449aa292607672ba59e6ba3153d7bfa1d891c0b0a1160b"}, - {file = "frozendict-2.3.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95f2f6def297eaa00e8aff4e72cc251b91c7c318507f15643c8f4b0647248da2"}, - {file = "frozendict-2.3.9-cp39-cp39-win_amd64.whl", hash = "sha256:f2d2146ae474e3478263932d363128b1bab6e7ddd9cd79fd142247a15c710f76"}, - {file = "frozendict-2.3.9-cp39-cp39-win_arm64.whl", hash = "sha256:87f6cf5513d0920836df067ae79296e3d52be88abcee1629b7010ed2af1ee121"}, - {file = "frozendict-2.3.9-py3-none-any.whl", hash = "sha256:ecabff354ec0ea070770f6556e6e23deaca2053e18322163fce76cdd93a3845f"}, - {file = "frozendict-2.3.9.tar.gz", hash = "sha256:8c4771eec34a8a47a62d3520465e7ac2d8f583d8ed99fea8dbba4218756e9360"}, + {file = "frozendict-2.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:475c65202a6f5421df8cacb8a2f29c5087134a0542b0540ae95fbf4db7af2ff9"}, + {file = "frozendict-2.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2607e82efdd2c277224a58bda3994d4cd48e49eff7fa31e404cf3066e8dbfeae"}, + {file = "frozendict-2.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fd4583194baabe100c135883017da76259a315d34e303eddf198541b7e02e44"}, + {file = "frozendict-2.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efca7281184b54f7abab6980cf25837b709f72ced62791f62dabcd7b184d958a"}, + {file = "frozendict-2.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fc4cba1ced988ce9020dfcaae6fe3f5521eebc00c5772b511aaf691b0be91e6"}, + {file = "frozendict-2.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8fab616e7c0fea2ac928f107c740bd9ba516fc083adfcd1c391d6bfc9164403d"}, + {file = "frozendict-2.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:09ba8ee37d260adde311b8eb4cd12bf27f64071242f736757ae6a11d331eb860"}, + {file = "frozendict-2.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:0615ed71570eec3cc96df063930ea6e563211efeeac86e3f3cc8bdfc9c9bfab7"}, + {file = "frozendict-2.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc754117a7d60ba8e55b3c39abd67f37fbc05dd63cdcb03d1717a382fe0a3421"}, + {file = "frozendict-2.4.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2804ea4bd2179bb33b99483cc8d69246630cc00632b9affe2914e8666f1cc7e5"}, + {file = "frozendict-2.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd4700c3f0aebdc8f4375c35590135794b1dbf2aca132f4756b584fa9910af2d"}, + {file = "frozendict-2.4.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:da4406d95c340e0b1cc43a3858fac729f52689325bcf61a9182eb94aff7451dc"}, + {file = "frozendict-2.4.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:1875e7b70a5724bf964354da8fd542240d2cead0d80053ac96bf4494ce3517fa"}, + {file = "frozendict-2.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a60f353496637ca21396289a7d969af1eb4ec4d11a7c37a0e7f25fc1761a0c97"}, + {file = "frozendict-2.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b666f9c6c8a9e794d2713a944b10a65480ff459579d75b5f686c75031c2c2dfc"}, + {file = "frozendict-2.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9d81fb396ea81fcba3b3dde4a4b51adcb74ff31632014fbfd030f8acd5a7292"}, + {file = "frozendict-2.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4925c8e82d2bd23d45996cd0827668a52b9c51103897c98ce409a763d0c00c61"}, + {file = "frozendict-2.4.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aa86325da6a6071284b4ed3d9d2cd9db068560aebad503b658d6a889a0575683"}, + {file = "frozendict-2.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5bb5b62d4e2bce12e91800496d94de41bec8f16e4d8a7b16e8f263676ae2031a"}, + {file = "frozendict-2.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3909df909516cfd7bcefd9a3003948970a12a50c5648d8bbddafcef171f2117f"}, + {file = "frozendict-2.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:204f2c5c10fc018d1ba8ccc67758aa83fe769c782547bd26dc250317a7ccba71"}, + {file = "frozendict-2.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d8d1d269874c94b1ed2b6667e5e43dcf4541838019b1caa4c48f848ac73634df"}, + {file = "frozendict-2.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:809f1cffb602cf06e5186c69c0e3b74bec7a3684593145331f9aa2a65b5ba3b7"}, + {file = "frozendict-2.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b017cba5f73869b04c2977139ad08e57a7480de1e384c34193939698119baa1d"}, + {file = "frozendict-2.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0b75e5e231621dedaef88334997e79fbd137dd89895543d3862fe0220fc3572c"}, + {file = "frozendict-2.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:df3819a5d48ab3aae1548e62093d0111ad7c3b62ff9392421b7bbf149c08b629"}, + {file = "frozendict-2.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:42a9b33ccf9d417b22146e59803c53d5c39d7d9151d2df8df59c235f6a1a5ed7"}, + {file = "frozendict-2.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3f51bfa64e0c4a6608e3f2878bab1211a6b3b197de6fa57151bbe73f1184457"}, + {file = "frozendict-2.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a1d232f092dc686e6ef23d436bde30f82c018f31cef1b89b31caef03814b1617"}, + {file = "frozendict-2.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e530658134e88607ff8c2c8934a07b2bb5e9fffab5045f127746f6542c6c77e"}, + {file = "frozendict-2.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23a52bbea30c9e35b89291273944393770fb031e522a172e3aff19b62cc50047"}, + {file = "frozendict-2.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f91acaff475d0ef0d3436b805c9b91fc627a6a8a281771a24f7ab7f458a0b34f"}, + {file = "frozendict-2.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:08d9c7c1aa92b94538b3a79c43999f999012e174588435f197794d5e5a80e0f5"}, + {file = "frozendict-2.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:05c5a77957ecba4286c7ab33861a8f4f2badc7ea86fc82b834fb360d3aa4c108"}, + {file = "frozendict-2.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:c8af8a6a39e0050d3f3193cda56c42b43534a9b3995c44241bb9527e3c3fd451"}, + {file = "frozendict-2.4.0.tar.gz", hash = "sha256:c26758198e403337933a92b01f417a8240c954f553e1d4b5e0f8e39d9c8e3f0a"}, ] [[package]] name = "frozenlist" -version = "1.4.0" +version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab"}, - {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559"}, - {file = "frozenlist-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62"}, - {file = "frozenlist-1.4.0-cp310-cp310-win32.whl", hash = "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0"}, - {file = "frozenlist-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb"}, - {file = "frozenlist-1.4.0-cp311-cp311-win32.whl", hash = "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431"}, - {file = "frozenlist-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8"}, - {file = "frozenlist-1.4.0-cp38-cp38-win32.whl", hash = "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc"}, - {file = "frozenlist-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3"}, - {file = "frozenlist-1.4.0-cp39-cp39-win32.whl", hash = "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f"}, - {file = "frozenlist-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167"}, - {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, + {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 = "identify" -version = "2.5.32" +version = "2.5.33" description = "File identification library for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "identify-2.5.32-py2.py3-none-any.whl", hash = "sha256:0b7656ef6cba81664b783352c73f8c24b39cf82f926f78f4550eda928e5e0545"}, - {file = "identify-2.5.32.tar.gz", hash = "sha256:5d9979348ec1a21c768ae07e0a652924538e8bce67313a73cb0f681cf08ba407"}, + {file = "identify-2.5.33-py2.py3-none-any.whl", hash = "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34"}, + {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"}, ] [package.extras] @@ -1109,6 +1179,7 @@ license = ["ukkonen"] name = "idna" version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1120,6 +1191,7 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1131,6 +1203,7 @@ files = [ name = "indy-credx" version = "1.1.1" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -1142,21 +1215,23 @@ files = [ [[package]] name = "indy-vdr" -version = "0.4.0" +version = "0.4.1" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ - {file = "indy_vdr-0.4.0-py3-none-macosx_10_9_universal2.whl", hash = "sha256:c45e5d403ecf754b2c939746bca2b79998181bebb38cfbf575b55c4c9f60f26c"}, - {file = "indy_vdr-0.4.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:609eff2ee9ad9e400eaa2392462a95c207605b5b8eda9562305a1ef0c7558808"}, - {file = "indy_vdr-0.4.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:dfdfd701dee453e646da66471d5450cffb4c7963b8cb7f25b55b26dbfc667393"}, - {file = "indy_vdr-0.4.0-py3-none-win_amd64.whl", hash = "sha256:987092ebda89739266b11e5c71deecffe07c2a280c39b96eb64254f4bb168e07"}, + {file = "indy_vdr-0.4.1-py3-none-macosx_10_9_universal2.whl", hash = "sha256:62d18b411e6c2ca7204299306a08cf65a43dec0982f1d9749d44f02f4817ff0a"}, + {file = "indy_vdr-0.4.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:826c128170a42ccb06d24c9018876cdfdc94fc6870661b21d47ffa022a1570bb"}, + {file = "indy_vdr-0.4.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cbcd760059c8410c09948f8f64dbf8a80a47fe8072d7d865fcfffe7e867266b"}, + {file = "indy_vdr-0.4.1-py3-none-win_amd64.whl", hash = "sha256:c67de1c4498806ad5afaec104ca4edc2b4c7bb59e02d588c3bfd85164e017158"}, ] [[package]] name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1168,6 +1243,7 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1179,6 +1255,7 @@ files = [ name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1196,6 +1273,7 @@ i18n = ["Babel (>=2.7)"] name = "jsonpath-ng" version = "1.5.2" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +category = "main" optional = false python-versions = "*" files = [ @@ -1210,12 +1288,13 @@ six = "*" [[package]] name = "jwcrypto" -version = "1.5.0" +version = "1.5.1" description = "Implementation of JOSE Web standards" +category = "main" optional = false python-versions = ">= 3.6" files = [ - {file = "jwcrypto-1.5.0.tar.gz", hash = "sha256:2c1dc51cf8e38ddf324795dfe9426dee9dd46caf47f535ccbc18781fba810b8d"}, + {file = "jwcrypto-1.5.1.tar.gz", hash = "sha256:48bb9bf433777136253579e52b75ffe0f9a4a721d133d01f45a0b91ed5f4f1ae"}, ] [package.dependencies] @@ -1224,115 +1303,113 @@ deprecated = "*" [[package]] name = "lxml" -version = "4.9.3" +version = "5.0.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ - {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, - {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, - {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, - {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, - {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, - {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, - {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, - {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, - {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, - {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, - {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, - {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, - {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, - {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, - {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, - {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, - {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, - {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, - {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, - {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, - {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, - {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, - {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, - {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, - {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, + {file = "lxml-5.0.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73bfab795d354aaf2f4eb7a5b0db513031734fd371047342d5803834ce19ec18"}, + {file = "lxml-5.0.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cb564bbe55ff0897d9cf1225041a44576d7ae87f06fd60163544c91de2623d3f"}, + {file = "lxml-5.0.0-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6a5501438dd521bb7e0dde5008c40c7bfcfaafaf86eccb3f9bd27509abb793da"}, + {file = "lxml-5.0.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7ba26a7dc929a1b3487d51bbcb0099afed2fc06e891b82845c8f37a2d7d7fbbd"}, + {file = "lxml-5.0.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:9b59c429e1a2246da86ae237ffc3565efcdc71c281cd38ca8b44d5fb6a3b993a"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:3ffa066db40b0347e48334bd4465de768e295a3525b9a59831228b5f4f93162d"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8ce8b468ab50f9e944719d1134709ec11fe0d2840891a6cae369e22141b1094c"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:583c0e15ae06adc81035346ae2abb2e748f0b5197e7740d8af31222db41bbf7b"}, + {file = "lxml-5.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:904d36165848b59c4e04ae5b969072e602bd987485076fca8ec42c6cd7a7aedc"}, + {file = "lxml-5.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ac21aace6712472e77ea9dfc38329f53830c4259ece54c786107105ebb069053"}, + {file = "lxml-5.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f92d73faa0b1a76d1932429d684b7ce95829e93c3eef3715ec9b98ab192c9d31"}, + {file = "lxml-5.0.0-cp310-cp310-win32.whl", hash = "sha256:03290e2f714f2e7431c8430c08b48167f657da7bc689c6248e828ff3c66d5b1b"}, + {file = "lxml-5.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e6cbb68bf70081f036bfc018649cf4b46c4e7eaf7860a277cae92dee2a57f69"}, + {file = "lxml-5.0.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5382612ba2424cea5d2c89e2c29077023d8de88f8d60d5ceff5f76334516df9e"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:07a900735bad9af7be3085480bf384f68ed5580ba465b39a098e6a882c060d6b"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:980ba47c8db4b9d870014c7040edb230825b79017a6a27aa54cdb6fcc02d8cc0"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6507c58431dbd95b50654b3313c5ad54f90e54e5f2cdacf733de61eae478eec5"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:4a45a278518e4308865c1e9dbb2c42ce84fb154efb03adeb16fdae3c1687c7c9"}, + {file = "lxml-5.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:59cea9ba1c675fbd6867ca1078fc717a113e7f5b7644943b74137b7cc55abebf"}, + {file = "lxml-5.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dd39ef87fd1f7bb5c4aa53454936e6135cbfe03fe3744e8218be193f9e4fef16"}, + {file = "lxml-5.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e6bb39d91bf932e7520cb5718ae3c2f498052aca53294d5d59fdd9068fe1a7f2"}, + {file = "lxml-5.0.0-cp311-cp311-win32.whl", hash = "sha256:21af2c3862db6f4f486cddf73ec1157b40d5828876c47cd880edcbad8240ea1b"}, + {file = "lxml-5.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:c1249aa4eaced30b59ecf8b8cae0b1ccede04583c74ca7d10b6f8bbead908b2c"}, + {file = "lxml-5.0.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:f30e697b6215e759d0824768b2c5b0618d2dc19abe6c67eeed2b0460f52470d1"}, + {file = "lxml-5.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:d1bb64646480c36a4aa1b6a44a5b6e33d0fcbeab9f53f1b39072cd3bb2c6243a"}, + {file = "lxml-5.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4e69c36c8618707a90ed3fb6f48a6cc9254ffcdbf7b259e439a5ae5fbf9c5206"}, + {file = "lxml-5.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9ca498f8554a09fbc3a2f8fc4b23261e07bc27bef99b3df98e2570688033f6fc"}, + {file = "lxml-5.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0326e9b8176ea77269fb39e7af4010906e73e9496a9f8eaf06d253b1b1231ceb"}, + {file = "lxml-5.0.0-cp312-cp312-win32.whl", hash = "sha256:5fb988e15378d6e905ca8f60813950a0c56da9469d0e8e5d8fe785b282684ec5"}, + {file = "lxml-5.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:bb58e8f4b2cfe012cd312239b8d5139995fe8f5945c7c26d5fbbbb1ddb9acd47"}, + {file = "lxml-5.0.0-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:81509dffd8aba3bdb43e90cbd218c9c068a1f4047d97bc9546b3ac9e3a4ae81d"}, + {file = "lxml-5.0.0-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e675a4b95208e74c34ac0751cc4bab9170e7728b61601fb0f4746892c2bb7e0b"}, + {file = "lxml-5.0.0-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:405e3760f83a8ba3bdb6e622ec79595cdc20db916ce37377bbcb95b5711fa4ca"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f15844a1b93dcaa09c2b22e22a73384f3ae4502347c3881cfdd674e14ac04e21"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88f559f8beb6b90e41a7faae4aca4c8173a4819874a9bf8e74c8d7c1d51f3162"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e8c63f5c7d87e7044880b01851ac4e863c3349e6f6b6ab456fe218d9346e816d"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:0d277d4717756fe8816f0beeff229cb72f9dd02a43b70e1d3f07c8efadfb9fe1"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8954da15403db1acfc0544b3c3f963a6ef4e428283ab6555e3e298bbbff1cf6"}, + {file = "lxml-5.0.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:aebd8fd378e074b22e79cad329dcccd243c40ff1cafaa512d19276c5bb9554e1"}, + {file = "lxml-5.0.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b6d4e148edee59c2ad38af15810dbcb8b5d7b13e5de3509d8cf3edfe74c0adca"}, + {file = "lxml-5.0.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:70ab4e02f7aa5fb4131c8b222a111ce7676f3767e36084fba3a4e7338dc82dcd"}, + {file = "lxml-5.0.0-cp36-cp36m-win32.whl", hash = "sha256:de1a8b54170024cf1c0c2718c82412bca42cd82e390556e3d8031af9541b416f"}, + {file = "lxml-5.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5b39f63edbe7e018c2ac1cf0259ee0dd2355274e8a3003d404699b040782e55e"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:77b73952534967a4497d9e4f26fbeebfba19950cbc66b7cc3a706214429d8106"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8cc0a951e5616ac626f7036309c41fb9774adcd4aa7db0886463da1ce5b65edb"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:4b9d5b01900a760eb3acf6cef50aead4ef2fa79e7ddb927084244e41dfe37b65"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:173bcead3af5d87c7bca9a030675073ddaad8e0a9f0b04be07cd9390453e7226"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:44fa9afd632210f1eeda51cf284ed8dbab0c7ec8b008dd39ba02818e0e114e69"}, + {file = "lxml-5.0.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fef10f27d6318d2d7c88680e113511ddecf09ee4f9559b3623b73ee89fa8f6cc"}, + {file = "lxml-5.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3663542aee845129a981889c19b366beab0b1dadcf5ca164696aabfe1aa51667"}, + {file = "lxml-5.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7188495c1bf71bfda87d78ed50601e72d252119ce11710d6e71ff36e35fea5a0"}, + {file = "lxml-5.0.0-cp37-cp37m-win32.whl", hash = "sha256:6a2de85deabf939b0af89e2e1ea46bfb1239545e2da6f8ac96522755a388025f"}, + {file = "lxml-5.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ea56825c1e23c9c8ea385a191dac75f9160477057285b88c88736d9305e6118f"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:3f908afd0477cace17f941d1b9cfa10b769fe1464770abe4cfb3d9f35378d0f8"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52a9ab31853d3808e7cf0183b3a5f7e8ffd622ea4aee1deb5252dbeaefd5b40d"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c7fe19abb3d3c55a9e65d289b12ad73b3a31a3f0bda3c539a890329ae9973bd6"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:1ef0793e1e2dd221fce7c142177008725680f7b9e4a184ab108d90d5d3ab69b7"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:581a78f299a9f5448b2c3aea904bfcd17c59bf83016d221d7f93f83633bb2ab2"}, + {file = "lxml-5.0.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:affdd833f82334fdb10fc9a1c7b35cdb5a86d0b672b4e14dd542e1fe7bcea894"}, + {file = "lxml-5.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6bba06d8982be0f0f6432d289a8d104417a0ab9ed04114446c4ceb6d4a40c65d"}, + {file = "lxml-5.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:80209b31dd3908bc5b014f540fd192c97ea52ab179713a730456c5baf7ce80c1"}, + {file = "lxml-5.0.0-cp38-cp38-win32.whl", hash = "sha256:dac2733fe4e159b0aae0439db6813b7b1d23ff96d0b34c0107b87faf79208c4e"}, + {file = "lxml-5.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:ee60f33456ff34b2dd1d048a740a2572798356208e4c494301c931de3a0ab3a2"}, + {file = "lxml-5.0.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:5eff173f0ff408bfa578cbdafd35a7e0ca94d1a9ffe09a8a48e0572d0904d486"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:78d6d8e5b54ed89dc0f0901eaaa579c384ad8d59fa43cc7fb06e9bb89115f8f4"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:71a7cee869578bc17b18050532bb2f0bc682a7b97dda77041741a1bd2febe6c7"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:7df433d08d4587dc3932f7fcfc3194519a6824824104854e76441fd3bc000d29"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:793be9b4945c2dfd69828fb5948d7d9569b78e0599e4a2e88d92affeb0ff3aa3"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7cfb6af73602c8d288581df8a225989d7e9d5aab0a174be0e19fcfa800b6797"}, + {file = "lxml-5.0.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bfdc4668ac56687a89ca3eca44231144a2e9d02ba3b877558db74ba20e2bd9fa"}, + {file = "lxml-5.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2992591e2294bb07faf7f5f6d5cb60710c046404f4bfce09fb488b85d2a8f58f"}, + {file = "lxml-5.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4786b0af7511ea614fd86407a52a7bc161aa5772d311d97df2591ed2351de768"}, + {file = "lxml-5.0.0-cp39-cp39-win32.whl", hash = "sha256:016de3b29a262655fc3d2075dc1b2611f84f4c3d97a71d579c883d45e201eee4"}, + {file = "lxml-5.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:52c0acc2f29b0a204efc11a5ed911a74f50a25eb7d7d5069c2b1fd3b3346ce11"}, + {file = "lxml-5.0.0-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:96095bfc0c02072fc89afa67626013a253596ea5118b8a7f4daaae049dafa096"}, + {file = "lxml-5.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:992029258ed719f130d5a9c443d142c32843046f1263f2c492862b2a853be570"}, + {file = "lxml-5.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:db40e85cffd22f7d65dcce30e85af565a66401a6ed22fc0c56ed342cfa4ffc43"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:cfa8a4cdc3765574b7fd0c7cfa5fbd1e2108014c9dfd299c679e5152bea9a55e"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:049fef98d02513c34f5babd07569fc1cf1ed14c0f2fbff18fe72597f977ef3c2"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a85136d0ee18a41c91cc3e2844c683be0e72e6dda4cb58da9e15fcaef3726af7"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:766868f729f3ab84125350f1a0ea2594d8b1628a608a574542a5aff7355b9941"}, + {file = "lxml-5.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:99cad5c912f359e59e921689c04e54662cdd80835d80eeaa931e22612f515df7"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:c90c593aa8dd57d5dab0ef6d7d64af894008971d98e6a41b320fdd75258fbc6e"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8134d5441d1ed6a682e3de3d7a98717a328dce619ee9c4c8b3b91f0cb0eb3e28"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f298ac9149037d6a3d5c74991bded39ac46292520b9c7c182cb102486cc87677"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:894c5f71186b410679aaab5774543fcb9cbabe8893f0b31d11cf28a0740e80be"}, + {file = "lxml-5.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9cd3d6c2c67d4fdcd795e4945e2ba5434909c96640b4cc09453bd0dc7e8e1bac"}, + {file = "lxml-5.0.0.zip", hash = "sha256:2219cbf790e701acf9a21a31ead75f983e73daf0eceb9da6990212e4d20ebefe"}, ] [package.extras] cssselect = ["cssselect (>=0.7)"] html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] -source = ["Cython (>=0.29.35)"] +source = ["Cython (>=3.0.7)"] [[package]] name = "markdown" version = "3.1.1" description = "Python implementation of Markdown." +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -1350,6 +1427,7 @@ testing = ["coverage", "pyyaml"] name = "markupsafe" version = "2.0.1" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1428,6 +1506,7 @@ files = [ name = "marshmallow" version = "3.20.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1448,6 +1527,7 @@ tests = ["pytest", "pytz", "simplejson"] name = "mock" version = "4.0.3" description = "Rolling backport of unittest.mock for all Pythons" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1464,6 +1544,7 @@ test = ["pytest (<5.4)", "pytest-cov"] name = "multidict" version = "6.0.4" description = "multidict implementation" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1547,6 +1628,7 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1558,6 +1640,7 @@ files = [ name = "nest-asyncio" version = "1.5.8" description = "Patch asyncio to allow nested event loops" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1569,6 +1652,7 @@ files = [ name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" +category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -1583,6 +1667,7 @@ setuptools = "*" name = "packaging" version = "23.1" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1592,91 +1677,112 @@ files = [ [[package]] name = "pathspec" -version = "0.11.2" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] name = "pillow" -version = "10.1.0" +version = "10.2.0" description = "Python Imaging Library (Fork)" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "Pillow-10.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106"}, - {file = "Pillow-10.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593"}, - {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db"}, - {file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f"}, - {file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818"}, - {file = "Pillow-10.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57"}, - {file = "Pillow-10.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7"}, - {file = "Pillow-10.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172"}, - {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061"}, - {file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262"}, - {file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992"}, - {file = "Pillow-10.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a"}, - {file = "Pillow-10.1.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b"}, - {file = "Pillow-10.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de"}, - {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651"}, - {file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b"}, - {file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f"}, - {file = "Pillow-10.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996"}, - {file = "Pillow-10.1.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793"}, - {file = "Pillow-10.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01"}, - {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d"}, - {file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80"}, - {file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212"}, - {file = "Pillow-10.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14"}, - {file = "Pillow-10.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099"}, - {file = "Pillow-10.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34"}, - {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd"}, - {file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28"}, - {file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2"}, - {file = "Pillow-10.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4"}, - {file = "Pillow-10.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b"}, - {file = "Pillow-10.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f"}, - {file = "Pillow-10.1.0.tar.gz", hash = "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38"}, + {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"}, + {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0"}, + {file = "pillow-10.2.0-cp310-cp310-win32.whl", hash = "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023"}, + {file = "pillow-10.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72"}, + {file = "pillow-10.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757"}, + {file = "pillow-10.2.0-cp311-cp311-win32.whl", hash = "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068"}, + {file = "pillow-10.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56"}, + {file = "pillow-10.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb"}, + {file = "pillow-10.2.0-cp312-cp312-win32.whl", hash = "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f"}, + {file = "pillow-10.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9"}, + {file = "pillow-10.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe"}, + {file = "pillow-10.2.0-cp38-cp38-win32.whl", hash = "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e"}, + {file = "pillow-10.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591"}, + {file = "pillow-10.2.0-cp39-cp39-win32.whl", hash = "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516"}, + {file = "pillow-10.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8"}, + {file = "pillow-10.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6"}, + {file = "pillow-10.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868"}, + {file = "pillow-10.2.0.tar.gz", hash = "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e"}, ] [package.extras] docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] [[package]] name = "platformdirs" -version = "4.0.0" +version = "4.1.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-4.0.0-py3-none-any.whl", hash = "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b"}, - {file = "platformdirs-4.0.0.tar.gz", hash = "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731"}, + {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, + {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, ] [package.extras] @@ -1687,6 +1793,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.3.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1702,6 +1809,7 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" +category = "main" optional = false python-versions = "*" files = [ @@ -1713,6 +1821,7 @@ files = [ name = "portalocker" version = "2.7.0" description = "Wraps the portalocker recipe for easy usage" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1732,6 +1841,7 @@ tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "p name = "pre-commit" version = "3.3.3" description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1750,8 +1860,9 @@ virtualenv = ">=20.10.0" name = "prompt-toolkit" version = "2.0.10" description = "Library for building powerful interactive command lines in Python" +category = "main" optional = false -python-versions = ">=2.6,<3.0.dev0 || >=3.3.dev0" +python-versions = ">=2.6,<3.0.0 || >=3.3.0" files = [ {file = "prompt_toolkit-2.0.10-py2-none-any.whl", hash = "sha256:e7f8af9e3d70f514373bf41aa51bc33af12a6db3f71461ea47fea985defb2c31"}, {file = "prompt_toolkit-2.0.10-py3-none-any.whl", hash = "sha256:46642344ce457641f28fc9d1c9ca939b63dadf8df128b86f1b9860e59c73a5e4"}, @@ -1766,6 +1877,7 @@ wcwidth = "*" name = "ptvsd" version = "4.3.2" description = "Remote debugging server for Python support in Visual Studio and Visual Studio Code" +category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" files = [ @@ -1800,6 +1912,7 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1811,6 +1924,7 @@ files = [ name = "pydantic" version = "1.10.13" description = "Data validation and settings management using python type hints" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1863,6 +1977,7 @@ email = ["email-validator (>=1.0.3)"] name = "pydevd" version = "1.5.1" description = "PyDev.Debugger (used in PyDev, PyCharm and VSCode Python)" +category = "dev" optional = false python-versions = "*" files = [ @@ -1883,6 +1998,7 @@ files = [ name = "pydevd-pycharm" version = "193.6015.41" description = "PyCharm Debugger (used in PyCharm and PyDev)" +category = "dev" optional = false python-versions = "*" files = [ @@ -1893,6 +2009,7 @@ files = [ name = "pydid" version = "0.4.2" description = "Python library for validating, constructing, and representing DIDs and DID Documents" +category = "main" optional = false python-versions = ">=3.8.0,<4.0.0" files = [ @@ -1909,6 +2026,7 @@ typing-extensions = ">=4.5.0,<5.0.0" name = "pygments" version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1924,6 +2042,7 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pyjwt" version = "2.8.0" description = "JSON Web Token implementation in Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1941,6 +2060,7 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pyld" version = "2.0.3" description = "Python implementation of the JSON-LD API" +category = "main" optional = false python-versions = "*" files = [ @@ -1962,6 +2082,7 @@ requests = ["requests"] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1986,13 +2107,14 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] name = "pytest" -version = "7.4.3" +version = "7.4.4" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] @@ -2010,6 +2132,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.21.1" description = "Pytest support for asyncio" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2028,6 +2151,7 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2046,6 +2170,7 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-ruff" version = "0.1.1" description = "pytest plugin to check ruff requirements." +category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -2060,6 +2185,7 @@ ruff = ">=0.0.242" name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -2074,6 +2200,7 @@ six = ">=1.5" name = "python-json-logger" version = "2.0.7" description = "A python library adding a json log formatter" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2085,6 +2212,7 @@ files = [ name = "python3-indy" version = "1.16.0.post286" description = "This is the official SDK for Hyperledger Indy (https://www.hyperledger.org/projects), which provides a distributed-ledger-based foundation for self-sovereign identity (https://sovrin.org). The major artifact of the SDK is a c-callable library." +category = "main" optional = true python-versions = "*" files = [ @@ -2101,6 +2229,7 @@ test = ["base58", "pytest (<3.7)", "pytest-asyncio (==0.10.0)"] name = "pytz" version = "2021.1" description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" files = [ @@ -2112,6 +2241,7 @@ files = [ name = "pywin32" version = "306" description = "Python for Window Extensions" +category = "main" optional = false python-versions = "*" files = [ @@ -2135,6 +2265,7 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2194,6 +2325,7 @@ files = [ name = "qrcode" version = "6.1" description = "QR Code image generator" +category = "main" optional = false python-versions = "*" files = [ @@ -2216,6 +2348,7 @@ test = ["mock", "pytest", "pytest-cov"] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2237,6 +2370,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rlp" version = "1.2.0" description = "A package for Recursive Length Prefix encoding and decoding" +category = "main" optional = false python-versions = "*" files = [ @@ -2257,6 +2391,7 @@ test = ["hypothesis (==3.56.5)", "pytest (==3.3.2)", "tox (>=2.9.1,<3)"] name = "ruff" version = "0.1.2" description = "An extremely fast Python linter, written in Rust." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2283,6 +2418,7 @@ files = [ name = "sd-jwt" version = "0.10.3" description = "The reference implementation of the IETF SD-JWT specification." +category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -2296,13 +2432,14 @@ pyyaml = ">=5.4" [[package]] name = "setuptools" -version = "69.0.2" +version = "69.0.3" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, - {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, + {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, + {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, ] [package.extras] @@ -2314,6 +2451,7 @@ testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jar name = "simplejson" version = "3.19.2" description = "Simple, fast, extensible JSON encoder/decoder for Python" +category = "main" optional = false python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2421,6 +2559,7 @@ files = [ name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2432,6 +2571,7 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" optional = false python-versions = "*" files = [ @@ -2443,6 +2583,7 @@ files = [ name = "sphinx" version = "1.8.4" description = "Python documentation generator" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2471,25 +2612,44 @@ websupport = ["sqlalchemy (>=0.9)", "whoosh (>=2.0)"] [[package]] name = "sphinx-rtd-theme" -version = "0.5.1" +version = "1.3.0" description = "Read the Docs theme for Sphinx" +category = "dev" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "sphinx_rtd_theme-0.5.1-py2.py3-none-any.whl", hash = "sha256:fa6bebd5ab9a73da8e102509a86f3fcc36dec04a0b52ea80e5a033b2aba00113"}, - {file = "sphinx_rtd_theme-0.5.1.tar.gz", hash = "sha256:eda689eda0c7301a80cf122dad28b1861e5605cbf455558f3775e1e8200e83a5"}, + {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"}, + {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"}, ] [package.dependencies] -sphinx = "*" +docutils = "<0.19" +sphinx = ">=1.6,<8" +sphinxcontrib-jquery = ">=4,<5" [package.extras] -dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"] +dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] + +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +description = "Extension to include jQuery on newer Sphinx releases" +category = "dev" +optional = false +python-versions = ">=2.7" +files = [ + {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, + {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, +] + +[package.dependencies] +Sphinx = ">=1.8" [[package]] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2505,6 +2665,7 @@ test = ["pytest"] name = "sphinxcontrib-websupport" version = "1.2.4" description = "Sphinx API for Web Apps" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -2523,6 +2684,7 @@ test = ["Sphinx", "pytest", "sqlalchemy", "whoosh"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2534,6 +2696,7 @@ files = [ name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2543,19 +2706,21 @@ files = [ [[package]] name = "typing-extensions" -version = "4.8.0" +version = "4.9.0" description = "Backported and Experimental Type Hints for Python 3.8+" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] [[package]] name = "unflatten" version = "0.1.1" description = "Unflatten dict to dict with nested dict/arrays" +category = "main" optional = false python-versions = "*" files = [ @@ -2567,6 +2732,7 @@ files = [ name = "urllib3" version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2583,6 +2749,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "ursa-bbs-signatures" version = "1.0.1" description = "" +category = "main" optional = true python-versions = ">=3.6.3" files = [ @@ -2593,13 +2760,14 @@ files = [ [[package]] name = "virtualenv" -version = "20.24.7" +version = "20.25.0" description = "Virtual Python Environment builder" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.7-py3-none-any.whl", hash = "sha256:a18b3fd0314ca59a2e9f4b556819ed07183b3e9a3702ecfe213f593d44f7b3fd"}, - {file = "virtualenv-20.24.7.tar.gz", hash = "sha256:69050ffb42419c91f6c1284a7b24e0475d793447e35929b488bf6a0aade39353"}, + {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, + {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, ] [package.dependencies] @@ -2615,6 +2783,7 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "wcwidth" version = "0.2.12" description = "Measures the displayed width of unicode strings in a terminal" +category = "main" optional = false python-versions = "*" files = [ @@ -2626,6 +2795,7 @@ files = [ name = "webargs" version = "5.5.3" description = "Declarative parsing and validation of HTTP request objects, with built-in support for popular web frameworks, including Flask, Django, Bottle, Tornado, Pyramid, webapp2, Falcon, and aiohttp." +category = "main" optional = false python-versions = "*" files = [ @@ -2649,6 +2819,7 @@ tests = ["Django (>=1.11.16)", "Flask (>=0.12.2)", "aiohttp (>=3.0.0)", "bottle name = "wrapt" version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2726,101 +2897,102 @@ files = [ [[package]] name = "yarl" -version = "1.9.3" +version = "1.9.4" description = "Yet another URL library" +category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "yarl-1.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32435d134414e01d937cd9d6cc56e8413a8d4741dea36af5840c7750f04d16ab"}, - {file = "yarl-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9a5211de242754b5e612557bca701f39f8b1a9408dff73c6db623f22d20f470e"}, - {file = "yarl-1.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:525cd69eff44833b01f8ef39aa33a9cc53a99ff7f9d76a6ef6a9fb758f54d0ff"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc94441bcf9cb8c59f51f23193316afefbf3ff858460cb47b5758bf66a14d130"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e36021db54b8a0475805acc1d6c4bca5d9f52c3825ad29ae2d398a9d530ddb88"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0f17d1df951336a02afc8270c03c0c6e60d1f9996fcbd43a4ce6be81de0bd9d"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5f3faeb8100a43adf3e7925d556801d14b5816a0ac9e75e22948e787feec642"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aed37db837ecb5962469fad448aaae0f0ee94ffce2062cf2eb9aed13328b5196"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:721ee3fc292f0d069a04016ef2c3a25595d48c5b8ddc6029be46f6158d129c92"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b8bc5b87a65a4e64bc83385c05145ea901b613d0d3a434d434b55511b6ab0067"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:dd952b9c64f3b21aedd09b8fe958e4931864dba69926d8a90c90d36ac4e28c9a"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:c405d482c320a88ab53dcbd98d6d6f32ada074f2d965d6e9bf2d823158fa97de"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9df9a0d4c5624790a0dea2e02e3b1b3c69aed14bcb8650e19606d9df3719e87d"}, - {file = "yarl-1.9.3-cp310-cp310-win32.whl", hash = "sha256:d34c4f80956227f2686ddea5b3585e109c2733e2d4ef12eb1b8b4e84f09a2ab6"}, - {file = "yarl-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:cf7a4e8de7f1092829caef66fd90eaf3710bc5efd322a816d5677b7664893c93"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d61a0ca95503867d4d627517bcfdc28a8468c3f1b0b06c626f30dd759d3999fd"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73cc83f918b69110813a7d95024266072d987b903a623ecae673d1e71579d566"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d81657b23e0edb84b37167e98aefb04ae16cbc5352770057893bd222cdc6e45f"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a1a8443091c7fbc17b84a0d9f38de34b8423b459fb853e6c8cdfab0eacf613"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe34befb8c765b8ce562f0200afda3578f8abb159c76de3ab354c80b72244c41"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c757f64afe53a422e45e3e399e1e3cf82b7a2f244796ce80d8ca53e16a49b9f"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72a57b41a0920b9a220125081c1e191b88a4cdec13bf9d0649e382a822705c65"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:632c7aeb99df718765adf58eacb9acb9cbc555e075da849c1378ef4d18bf536a"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b0b8c06afcf2bac5a50b37f64efbde978b7f9dc88842ce9729c020dc71fae4ce"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1d93461e2cf76c4796355494f15ffcb50a3c198cc2d601ad8d6a96219a10c363"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4003f380dac50328c85e85416aca6985536812c082387255c35292cb4b41707e"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4d6d74a97e898c1c2df80339aa423234ad9ea2052f66366cef1e80448798c13d"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b61e64b06c3640feab73fa4ff9cb64bd8182de52e5dc13038e01cfe674ebc321"}, - {file = "yarl-1.9.3-cp311-cp311-win32.whl", hash = "sha256:29beac86f33d6c7ab1d79bd0213aa7aed2d2f555386856bb3056d5fdd9dab279"}, - {file = "yarl-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:f7271d6bd8838c49ba8ae647fc06469137e1c161a7ef97d778b72904d9b68696"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:dd318e6b75ca80bff0b22b302f83a8ee41c62b8ac662ddb49f67ec97e799885d"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c4b1efb11a8acd13246ffb0bee888dd0e8eb057f8bf30112e3e21e421eb82d4a"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c6f034386e5550b5dc8ded90b5e2ff7db21f0f5c7de37b6efc5dac046eb19c10"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd49a908cb6d387fc26acee8b7d9fcc9bbf8e1aca890c0b2fdfd706057546080"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa4643635f26052401750bd54db911b6342eb1a9ac3e74f0f8b58a25d61dfe41"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e741bd48e6a417bdfbae02e088f60018286d6c141639359fb8df017a3b69415a"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c86d0d0919952d05df880a1889a4f0aeb6868e98961c090e335671dea5c0361"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d5434b34100b504aabae75f0622ebb85defffe7b64ad8f52b8b30ec6ef6e4b9"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79e1df60f7c2b148722fb6cafebffe1acd95fd8b5fd77795f56247edaf326752"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:44e91a669c43f03964f672c5a234ae0d7a4d49c9b85d1baa93dec28afa28ffbd"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3cfa4dbe17b2e6fca1414e9c3bcc216f6930cb18ea7646e7d0d52792ac196808"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:88d2c3cc4b2f46d1ba73d81c51ec0e486f59cc51165ea4f789677f91a303a9a7"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cccdc02e46d2bd7cb5f38f8cc3d9db0d24951abd082b2f242c9e9f59c0ab2af3"}, - {file = "yarl-1.9.3-cp312-cp312-win32.whl", hash = "sha256:96758e56dceb8a70f8a5cff1e452daaeff07d1cc9f11e9b0c951330f0a2396a7"}, - {file = "yarl-1.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:c4472fe53ebf541113e533971bd8c32728debc4c6d8cc177f2bff31d011ec17e"}, - {file = "yarl-1.9.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:126638ab961633f0940a06e1c9d59919003ef212a15869708dcb7305f91a6732"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c99ddaddb2fbe04953b84d1651149a0d85214780e4d0ee824e610ab549d98d92"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dab30b21bd6fb17c3f4684868c7e6a9e8468078db00f599fb1c14e324b10fca"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:828235a2a169160ee73a2fcfb8a000709edf09d7511fccf203465c3d5acc59e4"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc391e3941045fd0987c77484b2799adffd08e4b6735c4ee5f054366a2e1551d"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51382c72dd5377861b573bd55dcf680df54cea84147c8648b15ac507fbef984d"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:28a108cb92ce6cf867690a962372996ca332d8cda0210c5ad487fe996e76b8bb"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8f18a7832ff85dfcd77871fe677b169b1bc60c021978c90c3bb14f727596e0ae"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:7eaf13af79950142ab2bbb8362f8d8d935be9aaf8df1df89c86c3231e4ff238a"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:66a6dbf6ca7d2db03cc61cafe1ee6be838ce0fbc97781881a22a58a7c5efef42"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1a0a4f3aaa18580038cfa52a7183c8ffbbe7d727fe581300817efc1e96d1b0e9"}, - {file = "yarl-1.9.3-cp37-cp37m-win32.whl", hash = "sha256:946db4511b2d815979d733ac6a961f47e20a29c297be0d55b6d4b77ee4b298f6"}, - {file = "yarl-1.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2dad8166d41ebd1f76ce107cf6a31e39801aee3844a54a90af23278b072f1ccf"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bb72d2a94481e7dc7a0c522673db288f31849800d6ce2435317376a345728225"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9a172c3d5447b7da1680a1a2d6ecdf6f87a319d21d52729f45ec938a7006d5d8"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2dc72e891672343b99db6d497024bf8b985537ad6c393359dc5227ef653b2f17"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8d51817cf4b8d545963ec65ff06c1b92e5765aa98831678d0e2240b6e9fd281"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53ec65f7eee8655bebb1f6f1607760d123c3c115a324b443df4f916383482a67"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cfd77e8e5cafba3fb584e0f4b935a59216f352b73d4987be3af51f43a862c403"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e73db54c967eb75037c178a54445c5a4e7461b5203b27c45ef656a81787c0c1b"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09c19e5f4404574fcfb736efecf75844ffe8610606f3fccc35a1515b8b6712c4"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6280353940f7e5e2efaaabd686193e61351e966cc02f401761c4d87f48c89ea4"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c25ec06e4241e162f5d1f57c370f4078797ade95c9208bd0c60f484834f09c96"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7217234b10c64b52cc39a8d82550342ae2e45be34f5bff02b890b8c452eb48d7"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4ce77d289f8d40905c054b63f29851ecbfd026ef4ba5c371a158cfe6f623663e"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5f74b015c99a5eac5ae589de27a1201418a5d9d460e89ccb3366015c6153e60a"}, - {file = "yarl-1.9.3-cp38-cp38-win32.whl", hash = "sha256:8a2538806be846ea25e90c28786136932ec385c7ff3bc1148e45125984783dc6"}, - {file = "yarl-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:6465d36381af057d0fab4e0f24ef0e80ba61f03fe43e6eeccbe0056e74aadc70"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2f3c8822bc8fb4a347a192dd6a28a25d7f0ea3262e826d7d4ef9cc99cd06d07e"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7831566595fe88ba17ea80e4b61c0eb599f84c85acaa14bf04dd90319a45b90"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff34cb09a332832d1cf38acd0f604c068665192c6107a439a92abfd8acf90fe2"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe8080b4f25dfc44a86bedd14bc4f9d469dfc6456e6f3c5d9077e81a5fedfba7"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8535e111a064f3bdd94c0ed443105934d6f005adad68dd13ce50a488a0ad1bf3"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d155a092bf0ebf4a9f6f3b7a650dc5d9a5bbb585ef83a52ed36ba46f55cc39d"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:778df71c8d0c8c9f1b378624b26431ca80041660d7be7c3f724b2c7a6e65d0d6"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9f9cafaf031c34d95c1528c16b2fa07b710e6056b3c4e2e34e9317072da5d1a"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ca6b66f69e30f6e180d52f14d91ac854b8119553b524e0e28d5291a724f0f423"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0e7e83f31e23c5d00ff618045ddc5e916f9e613d33c5a5823bc0b0a0feb522f"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:af52725c7c39b0ee655befbbab5b9a1b209e01bb39128dce0db226a10014aacc"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0ab5baaea8450f4a3e241ef17e3d129b2143e38a685036b075976b9c415ea3eb"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d350388ba1129bc867c6af1cd17da2b197dff0d2801036d2d7d83c2d771a682"}, - {file = "yarl-1.9.3-cp39-cp39-win32.whl", hash = "sha256:e2a16ef5fa2382af83bef4a18c1b3bcb4284c4732906aa69422cf09df9c59f1f"}, - {file = "yarl-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:d92d897cb4b4bf915fbeb5e604c7911021a8456f0964f3b8ebbe7f9188b9eabb"}, - {file = "yarl-1.9.3-py3-none-any.whl", hash = "sha256:271d63396460b6607b588555ea27a1a02b717ca2e3f2cf53bdde4013d7790929"}, - {file = "yarl-1.9.3.tar.gz", hash = "sha256:4a14907b597ec55740f63e52d7fee0e9ee09d5b9d57a4f399a7423268e457b57"}, + {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"}, ] [package.dependencies] @@ -2835,4 +3007,4 @@ indy = ["python3-indy"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "89cdee60bd4fdb74cc9ccc1874649d77f4169e2770d52920657d9573dc395aa5" +content-hash = "2e034e1e6caa070f23d06640f89041567fa676b43f682e83de2f3a90b3c42169" diff --git a/pyproject.toml b/pyproject.toml index a031ebdfc5..f0f4336aae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ ursa-bbs-signatures= { version = "~1.0.1", optional = true } # indy python3-indy= { version = "^1.11.1", optional = true } +did-peer-4 = "^0.1.4" [tool.poetry.group.dev.dependencies] pre-commit="~3.3.3"