Skip to content

Commit

Permalink
DEXA protocol plugin initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: George J Padayatti <[email protected]>
  • Loading branch information
georgepadayatti committed Sep 6, 2022
1 parent a4e7cc0 commit 634c8d2
Show file tree
Hide file tree
Showing 18 changed files with 3,647 additions and 0 deletions.
165 changes: 165 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

.vscode/
samples.ipynb
sample.py
examples/
Binary file added dexa_protocol/.DS_Store
Binary file not shown.
Empty file added dexa_protocol/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions dexa_protocol/definition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Version definitions for this protocol."""

versions = [
{
"major_version": 1,
"minimum_minor_version": 0,
"current_minor_version": 0,
"path": "v1_0",
}
]
Empty file added dexa_protocol/v1_0/__init__.py
Empty file.
Empty file.
62 changes: 62 additions & 0 deletions dexa_protocol/v1_0/handlers/basicmessage_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""Basic message handler."""

from aries_cloudagent.messaging.base_handler import (
BaseHandler,
BaseResponder,
RequestContext,
)

from ..messages.sample_message import SampleMessage


class BasicMessageHandler(BaseHandler):
"""Message handler class for basic messages."""

async def handle(self, context: RequestContext, responder: BaseResponder):
"""
Message handler logic for basic messages.
Args:
context: request context
responder: responder callback
"""
self._logger.debug("BasicMessageHandler called with context %s", context)
assert isinstance(context.message, SampleMessage)

self._logger.info("Received sample message: %s", context.message.content)
self._logger.info("Received message of type: %s", context.message._type)

body = context.message.content
meta = {"content": body}

# For Workshop: mark invitations as copyable
if context.message.content and context.message.content.startswith(
("http:", "https:")
):
meta["copy_invite"] = True

await responder.send_webhook(
"basicmessages",
{
"connection_id": context.connection_record.connection_id,
"message_id": context.message._id,
"content": body,
"state": "received",
},
)

reply = None
if body:
if context.settings.get("debug.auto_respond_messages"):
if "received your message" not in body:
reply = f"{context.default_label} received your message"
elif body.startswith("Reply with: "):
reply = body[12:]

if reply:
reply_msg = SampleMessage(content=reply)
reply_msg.assign_thread_from(context.message)
reply_msg.assign_trace_from(context.message)
if "l10n" in context.message._decorators:
reply_msg._decorators["l10n"] = context.message._decorators["l10n"]
await responder.send_reply(reply_msg)
14 changes: 14 additions & 0 deletions dexa_protocol/v1_0/message_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Message type identifiers for Connections."""

from aries_cloudagent.protocols.didcomm_prefix import DIDCommPrefix

SPEC_URI = "https://github.com/decentralised-dataexchange/data-exchange-agreements"

# Message types
BASIC_MESSAGE = f"sample/1.0/message"

PROTOCOL_PACKAGE = "dexa_sdk.plugin.v1_0"

MESSAGE_TYPES = DIDCommPrefix.qualify_all(
{BASIC_MESSAGE: f"{PROTOCOL_PACKAGE}.messages.sample_message.SampleMessage"}
)
Empty file.
70 changes: 70 additions & 0 deletions dexa_protocol/v1_0/messages/sample_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Basic message."""

from datetime import datetime
from typing import Union

from marshmallow import EXCLUDE, fields

from aries_cloudagent.messaging.agent_message import (
AgentMessage,
AgentMessageSchema
)
from aries_cloudagent.messaging.util import datetime_now, datetime_to_str
from aries_cloudagent.messaging.valid import INDY_ISO8601_DATETIME

from ..message_types import BASIC_MESSAGE, PROTOCOL_PACKAGE

HANDLER_CLASS = f"{PROTOCOL_PACKAGE}.handlers.basicmessage_handler.BasicMessageHandler"


class SampleMessage(AgentMessage):
"""Class defining the structure of a basic message."""

class Meta:
"""Basic message metadata class."""

handler_class = HANDLER_CLASS
message_type = BASIC_MESSAGE
schema_class = "BasicMessageSchema"

def __init__(
self,
*,
sent_time: Union[str, datetime] = None,
content: str = None,
localization: str = None,
**kwargs,
):
"""
Initialize basic message object.
Args:
sent_time: Time message was sent
content: message content
localization: localization
"""
super().__init__(**kwargs)
if not sent_time:
sent_time = datetime_now()
if localization:
self._decorators["l10n"] = localization
self.sent_time = datetime_to_str(sent_time)
self.content = content


class BasicMessageSchema(AgentMessageSchema):
"""Basic message schema class."""

class Meta:
"""Basic message schema metadata."""

model_class = SampleMessage
unknown = EXCLUDE

sent_time = fields.Str(
required=False,
description="Time message was sent, ISO8601 with space date/time separator",
**INDY_ISO8601_DATETIME,
)
content = fields.Str(required=True, description="Message content", example="Hello")
1 change: 1 addition & 0 deletions dexa_protocol/v1_0/routes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .routes import *
40 changes: 40 additions & 0 deletions dexa_protocol/v1_0/routes/dda_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from aiohttp import web
from aiohttp_apispec import docs, request_schema
from marshmallow import EXCLUDE

from dexa_sdk.agreements.dda.v1_0.models import (
DataDisclosureAgreementSchema,
)
from .maps.tag_maps import TAGS_DDA_LABEL


class WrappedDataDisclosureAgreementSchema(DataDisclosureAgreementSchema):
class Meta:
"""OpenAPISchema metadata."""

# Hack to use child classes of BaseModelSchema
# as OpenAPI request schema
model_class = dict

# Exclude unknown fields
unknown = EXCLUDE


@docs(tags=[TAGS_DDA_LABEL], summary="Create a Data Disclosure Agreement")
@request_schema(WrappedDataDisclosureAgreementSchema())
async def create_data_disclosure_agreement_handler(request: web.BaseRequest):
"""
Request handle to create a data disclosure agreement.
Args:
request: aiohttp request object
"""
context = request.app["request_context"]

# Fetch request body
data_agreement = await request.json()

return web.json_response(
{"purposeDescription": data_agreement["purposeDescription"]}
)
Empty file.
10 changes: 10 additions & 0 deletions dexa_protocol/v1_0/routes/maps/route_maps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from aiohttp import web
from ..dda_routes import create_data_disclosure_agreement_handler

# Data Disclosure Agreement routes
ROUTES_DDA = [
web.post(
"/v1/data-disclosure-agreements",
create_data_disclosure_agreement_handler,
)
]
11 changes: 11 additions & 0 deletions dexa_protocol/v1_0/routes/maps/tag_maps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from ...message_types import SPEC_URI

TAGS_DDA_LABEL = "Data Disclosure Agreements"
TAGS_DDA = {
"name": "Data Disclosure Agreements",
"description": "Data Disclosure Agreement - Core Functions",
"externalDocs": {
"description": "Specification",
"url": SPEC_URI,
},
}
Loading

0 comments on commit 634c8d2

Please sign in to comment.