Source code for aries_cloudagent.protocols.issue_credential.v2_0.messages.cred_format
"""Issue-credential protocol message attachment format."""
from collections import namedtuple
from enum import Enum
from typing import TYPE_CHECKING, Mapping, Sequence, Type, Union
from uuid import uuid4
from marshmallow import EXCLUDE, fields
from .....messaging.decorators.attach_decorator import AttachDecorator
from .....messaging.models.base import BaseModel, BaseModelSchema
from .....messaging.valid import UUID4_EXAMPLE
from .....utils.classloader import DeferLoad
from ..models.detail.indy import V20CredExRecordIndy
from ..models.detail.ld_proof import V20CredExRecordLDProof
if TYPE_CHECKING:
from ..formats.handler import V20CredFormatHandler
FormatSpec = namedtuple("FormatSpec", "aries detail handler")
[docs]class V20CredFormat(BaseModel):
"""Issue-credential protocol message attachment format."""
[docs] class Meta:
"""Issue-credential protocol message attachment format metadata."""
schema_class = "V20CredFormatSchema"
[docs] class Format(Enum):
"""Attachment format."""
INDY = FormatSpec(
"hlindy/",
V20CredExRecordIndy,
DeferLoad(
"aries_cloudagent.protocols.issue_credential.v2_0"
".formats.indy.handler.IndyCredFormatHandler"
),
)
"""
Once we switch to anoncreds this will replace the above INDY definition.
In the meantime there are some hardcoded references in the
"...formats.indy.handler.IndyCredFormatHandler" class.
INDY = FormatSpec(
"hlindy/",
V20CredExRecordIndy,
DeferLoad(
"aries_cloudagent.protocols.issue_credential.v2_0"
".formats.anoncreds.handler.AnonCredsCredFormatHandler"
),
)
"""
LD_PROOF = FormatSpec(
"aries/",
V20CredExRecordLDProof,
DeferLoad(
"aries_cloudagent.protocols.issue_credential.v2_0"
".formats.ld_proof.handler.LDProofCredFormatHandler"
),
)
[docs] @classmethod
def get(cls, label: Union[str, "V20CredFormat.Format"]):
"""Get format enum for label."""
if isinstance(label, str):
for fmt in V20CredFormat.Format:
if label.startswith(fmt.aries) or label == fmt.api:
return fmt
elif isinstance(label, V20CredFormat.Format):
return label
return None
@property
def api(self) -> str:
"""Admin API specifier."""
return self.name.lower()
@property
def aries(self) -> str:
"""Aries specifier prefix."""
return self.value.aries
@property
def detail(self) -> Union[V20CredExRecordIndy, V20CredExRecordLDProof]:
"""Accessor for credential exchange detail class."""
return self.value.detail
@property
def handler(self) -> Type["V20CredFormatHandler"]:
"""Accessor for credential exchange format handler."""
return self.value.handler.resolved
[docs] def validate_fields(self, message_type: str, attachment_data: Mapping):
"""Raise ValidationError for invalid attachment formats."""
self.handler.validate_fields(message_type, attachment_data)
[docs] def get_attachment_data(
self,
formats: Sequence["V20CredFormat"],
attachments: Sequence[AttachDecorator],
):
"""Find attachment of current format, decode and return its content."""
for fmt in formats:
if V20CredFormat.Format.get(fmt.format) is self:
attach_id = fmt.attach_id
break
else:
return None
for atch in attachments:
if atch.ident == attach_id:
return atch.content
return None
def __init__(
self,
*,
attach_id: str = None,
format_: str = None,
):
"""Initialize issue-credential protocol message attachment format."""
self.attach_id = attach_id or uuid4()
self.format_ = format_
@property
def format(self) -> str:
"""Return format."""
return self.format_
[docs]class V20CredFormatSchema(BaseModelSchema):
"""Issue-credential protocol message attachment format schema."""
[docs] class Meta:
"""Issue-credential protocol message attachment format schema metadata."""
model_class = V20CredFormat
unknown = EXCLUDE
attach_id = fields.Str(
required=True,
allow_none=False,
metadata={"description": "Attachment identifier", "example": UUID4_EXAMPLE},
)
format_ = fields.Str(
required=True,
allow_none=False,
data_key="format",
metadata={
"description": "Attachment format specifier",
"example": "aries/ld-proof-vc-detail@v1.0",
},
)