Skip to content

Commit

Permalink
Merge pull request #10 from Indicio-tech/feature/routing-keys
Browse files Browse the repository at this point in the history
feat: support for specifying routing keys
  • Loading branch information
dbluhm authored Aug 9, 2022
2 parents 42988a5 + 78d8290 commit ac45b8b
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 852 deletions.
24 changes: 9 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
FROM python:3.7-alpine AS base
FROM python:3.10-slim-buster AS base
WORKDIR /usr/src/app
RUN apk update && \
apk add \
build-base \
curl \
git \
libffi-dev \
openssh-client \
postgresql-dev
RUN apt-get update && apt-get install -y curl git && apt-get clean

ENV POETRY_HOME=/opt/poetry \
VENV=/usr/src/app/.venv
ENV PATH="$POETRY_HOME/bin:$VENV/bin:$PATH"
# Install and configure poetry
ENV POETRY_VERSION=1.1.11
ENV POETRY_HOME=/opt/poetry
RUN curl -sSL https://install.python-poetry.org | python -

RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -
RUN poetry config virtualenvs.create true; poetry config virtualenvs.in-project true
ENV PATH="/opt/poetry/bin:$PATH"
RUN poetry config virtualenvs.in-project true

COPY ./pyproject.toml ./poetry.lock ./
RUN mkdir echo_agent && touch echo_agent/__init__.py
RUN poetry install --no-dev -E server
RUN poetry run pip install uvicorn

FROM python:3.7-alpine as main
FROM python:3.10-slim-buster AS main
WORKDIR /usr/src/app
COPY --from=base /usr/src/app /usr/src/app
ENV PATH="/usr/src/app/.venv/bin:$PATH"
Expand Down
66 changes: 48 additions & 18 deletions echo_agent/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,34 @@
Target,
crypto,
)
from aries_staticagent.utils import ensure_key_b58
from fastapi import Body, FastAPI, HTTPException, Request
from pydantic import dataclasses

from pydantic.dataclasses import dataclass

from .webhook_queue import Queue

from .session import Session, SessionMessage
from .models import (
NewConnection,
ConnectionInfo as ConnectionInfoDataclass,
ConnectionInfo as ConnectionInfoModel,
SessionInfo,
Webhook as WebhookDataclass,
Webhook as WebhookModel,
)

# Dataclass to Pydantic conversion
ConnectionInfo = dataclasses.dataclass(ConnectionInfoDataclass)
Webhook = dataclasses.dataclass(WebhookDataclass)

# Convert dataclasses to pydantic dataclasses
# See this issue for why this is necessary:
# https://github.com/tiangolo/fastapi/issues/5138
@dataclass
class ConnectionInfo(ConnectionInfoModel):
pass


@dataclass
class Webhook(WebhookModel):
pass


# Logging
LOGGER = logging.getLogger("uvicorn.error." + __name__)
Expand All @@ -66,13 +78,22 @@ async def new_connection(new_connection: NewConnection):
"""Create a new static connection."""
LOGGER.debug("Creating new connection from request: %s", new_connection)
dispatcher = QueueDispatcher()
conn = Connection.from_seed(
seed=new_connection.seed.encode("ascii"),
target=Target(
endpoint=new_connection.endpoint, their_vk=new_connection.their_vk
),
dispatcher=dispatcher,
)
try:
conn = Connection.from_seed(
seed=new_connection.seed.encode("ascii"),
target=Target(
endpoint=new_connection.endpoint,
recipients=new_connection.recipient_keys,
routing_keys=new_connection.routing_keys,
),
dispatcher=dispatcher,
)
except ValueError as error:
raise HTTPException(status_code=400, detail=str(error))

# Type narrowing
assert conn.target.recipients
assert conn.target.endpoint

# Store state
connection_id = str(uuid4())
Expand All @@ -85,8 +106,11 @@ async def new_connection(new_connection: NewConnection):
connection_id=connection_id,
did=conn.did,
verkey=conn.verkey_b58,
their_vk=new_connection.their_vk,
endpoint=new_connection.endpoint,
endpoint=conn.target.endpoint,
recipient_keys=[ensure_key_b58(recip) for recip in conn.target.recipients],
routing_keys=[
ensure_key_b58(route) for route in conn.target.routing_keys or []
],
)
LOGGER.debug("Returning new connection: %s", result)
return result
Expand Down Expand Up @@ -117,11 +141,17 @@ async def get_connections() -> List[ConnectionInfo]:
connection_id=connection_id,
did=conn.did,
verkey=conn.verkey_b58,
their_vk=crypto.bytes_to_b58(conn.target.recipients[0]),
endpoint=conn.target.endpoint,
endpoint=conn.target.endpoint or "",
recipient_keys=[
crypto.bytes_to_b58(key_bytes)
for key_bytes in conn.target.recipients or []
],
routing_keys=[
crypto.bytes_to_b58(key_bytes)
for key_bytes in conn.target.routing_keys or []
],
)
for connection_id, conn in connections.items()
if conn.target and conn.target.recipients
]


Expand Down
17 changes: 14 additions & 3 deletions echo_agent/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Client to Echo Agent."""
from contextlib import AbstractAsyncContextManager, asynccontextmanager
from dataclasses import asdict
from typing import Any, Dict, List, Mapping, Optional, Union
from typing import Any, Dict, List, Mapping, Optional, Sequence, Union

from httpx import AsyncClient

Expand Down Expand Up @@ -37,7 +37,11 @@ async def __aexit__(self, exc_type, exc_value, traceback):
await self.client.__aexit__(exc_type, exc_value, traceback)

async def new_connection(
self, seed: str, endpoint: str, their_vk: str
self,
seed: str,
endpoint: str,
recipient_keys: Optional[Sequence[str]] = None,
routing_keys: Optional[Sequence[str]] = None,
) -> ConnectionInfo:
if not self.client:
raise NoOpenClient(
Expand All @@ -46,7 +50,14 @@ async def new_connection(

response = await self.client.post(
"/connection",
json=asdict(NewConnection(seed=seed, endpoint=endpoint, their_vk=their_vk)),
json=asdict(
NewConnection(
seed=seed,
endpoint=endpoint,
recipient_keys=recipient_keys or [],
routing_keys=routing_keys or [],
)
),
)

if response.is_error:
Expand Down
8 changes: 5 additions & 3 deletions echo_agent/models.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
from dataclasses import dataclass, field
from typing import Any, Dict
from typing import Any, Dict, Sequence


@dataclass
class NewConnection:
seed: str = field(metadata={"example": "00000000000000000000000000000000"})
endpoint: str
their_vk: str
recipient_keys: Sequence[str] = field(default_factory=list)
routing_keys: Sequence[str] = field(default_factory=list)


@dataclass
class ConnectionInfo:
connection_id: str
did: str
verkey: str
their_vk: str
endpoint: str
recipient_keys: Sequence[str] = field(default_factory=list)
routing_keys: Sequence[str] = field(default_factory=list)


@dataclass
Expand Down
Loading

0 comments on commit ac45b8b

Please sign in to comment.