chore: add mypy

This commit is contained in:
cătălin 2023-12-09 11:29:28 +01:00
commit cd5783b9f0
Signed by: catalin
GPG key ID: 0178DF42F43E5FD2
8 changed files with 128 additions and 82 deletions

View file

@ -25,4 +25,12 @@ repos:
args:
- --fix
- --exit-non-zero-on-fix
- id: ruff-format
- id: ruff-format
- repo: local
hooks:
- id: mypy
name: mypy
entry: pdm run mypy
language: system
types: [ python ]

View file

@ -5,8 +5,8 @@ ENV USERNAME "secretsanta"
ENV APP_HOME "/home/$USERNAME"
ENV APP_PATH "$APP_HOME/src"
ARG uid=1000
ARG gid=1000
ARG uid=10000
ARG gid=10000
# hadolint ignore=DL3001,DL3008
RUN apt-get -y update \

View file

@ -1,7 +1,7 @@
from dataclasses import asdict, dataclass
from typing import Annotated, Literal
from litestar import Controller, Litestar, MediaType, Request, Response, get, put
from litestar import Controller, Litestar, MediaType, Response, get, put
from litestar.params import Parameter
from pydantic import UUID4
@ -35,26 +35,19 @@ class GroupController(Controller):
self.create_group_service = CreateGroupService(self.repo)
self.get_pair_service = GetPairService(self.repo)
@staticmethod
def _group2urls(participants: list[str], url: str) -> list[str]:
return [f"{url}/pair/{participant_name}" for participant_name in participants]
@get("/{group_uuid:uuid}")
async def get_participants(self, request: Request, group_uuid: UUID4) -> list[str]:
participants = await self.get_participants_service.run(group_uuid)
return self._group2urls(participants, request.url)
async def get_participants(self, group_uuid: UUID4) -> list[str]:
return await self.get_participants_service.run(group_uuid)
@put("/{group_uuid:uuid}")
async def create_group(
self,
request: Request,
group_uuid: UUID4,
data: CreateGroup,
) -> list[str]:
group = await self.create_group_service.run(
return await self.create_group_service.run(
Group(uuid=group_uuid, **asdict(data)),
)
return self._group2urls(group.participants, request.url)
@get("/{group_uuid:uuid}/pair/{participant_name:str}")
async def get_pair(

144
pdm.lock generated
View file

@ -2,53 +2,53 @@
# It is not intended for manual editing.
[metadata]
groups = ["default", "litestar", "testing", "dev", "linting", "chalice", "sls"]
groups = ["default", "litestar", "testing", "linting", "chalice", "sls"]
strategy = ["cross_platform"]
lock_version = "4.4"
content_hash = "sha256:ba9863870aa9f5f47435713bc9ae20992b801a13bced3f58aad28f2a5685614d"
content_hash = "sha256:50c4af85a208a58b532c1a92815e06aff9623ea01a5097dccf41d4c86170187f"
[[package]]
name = "aioboto3"
version = "12.0.0"
version = "12.1.0"
requires_python = ">=3.8,<4.0"
summary = "Async boto3 wrapper"
dependencies = [
"aiobotocore[boto3]==2.7.0",
"aiobotocore[boto3]==2.8.0",
]
files = [
{file = "aioboto3-12.0.0-py3-none-any.whl", hash = "sha256:23895e734f83e34827a38d3a08ccc3f4178cc8d4e3a7b7031a0cbf8efc875555"},
{file = "aioboto3-12.0.0.tar.gz", hash = "sha256:c2bbb990b4efd2e474a1e8a42a80291faf6434b2dc8678f163208d338b2dba39"},
{file = "aioboto3-12.1.0-py3-none-any.whl", hash = "sha256:9f9e07261ddf3d6fec04dd8d5f5a55e0cb3250089f4282f7a60054495ad9699b"},
{file = "aioboto3-12.1.0.tar.gz", hash = "sha256:8eae15dd52c9a43845448508ad0f912028a0a176bbd85b78e1377bb5f2a4d450"},
]
[[package]]
name = "aiobotocore"
version = "2.7.0"
version = "2.8.0"
requires_python = ">=3.8"
summary = "Async client for aws services using botocore and aiohttp"
dependencies = [
"aiohttp<4.0.0,>=3.7.4.post0",
"aioitertools<1.0.0,>=0.5.1",
"botocore<1.31.65,>=1.31.16",
"botocore<1.33.2,>=1.32.4",
"wrapt<2.0.0,>=1.10.10",
]
files = [
{file = "aiobotocore-2.7.0-py3-none-any.whl", hash = "sha256:aec605df77ce4635a0479b50fd849aa6b640900f7b295021ecca192e1140e551"},
{file = "aiobotocore-2.7.0.tar.gz", hash = "sha256:506591374cc0aee1bdf0ebe290560424a24af176dfe2ea7057fe1df97c4f0467"},
{file = "aiobotocore-2.8.0-py3-none-any.whl", hash = "sha256:32e632fea387acd45416c2bbc03828ee2c2a66a7dc4bd3a9bcb808dea249c469"},
{file = "aiobotocore-2.8.0.tar.gz", hash = "sha256:f160497cef21cfffc1a8d4219eeb27bb7b243389c2d021a812b9c0e3fb8e2bd1"},
]
[[package]]
name = "aiobotocore"
version = "2.7.0"
version = "2.8.0"
extras = ["boto3"]
requires_python = ">=3.8"
summary = "Async client for aws services using botocore and aiohttp"
dependencies = [
"aiobotocore==2.7.0",
"boto3<1.28.65,>=1.28.16",
"aiobotocore==2.8.0",
"boto3<1.33.2,>=1.29.4",
]
files = [
{file = "aiobotocore-2.7.0-py3-none-any.whl", hash = "sha256:aec605df77ce4635a0479b50fd849aa6b640900f7b295021ecca192e1140e551"},
{file = "aiobotocore-2.7.0.tar.gz", hash = "sha256:506591374cc0aee1bdf0ebe290560424a24af176dfe2ea7057fe1df97c4f0467"},
{file = "aiobotocore-2.8.0-py3-none-any.whl", hash = "sha256:32e632fea387acd45416c2bbc03828ee2c2a66a7dc4bd3a9bcb808dea249c469"},
{file = "aiobotocore-2.8.0.tar.gz", hash = "sha256:f160497cef21cfffc1a8d4219eeb27bb7b243389c2d021a812b9c0e3fb8e2bd1"},
]
[[package]]
@ -180,52 +180,52 @@ files = [
[[package]]
name = "boto3"
version = "1.28.64"
version = "1.33.1"
requires_python = ">= 3.7"
summary = "The AWS SDK for Python"
dependencies = [
"botocore<1.32.0,>=1.31.64",
"botocore<1.34.0,>=1.33.1",
"jmespath<2.0.0,>=0.7.1",
"s3transfer<0.8.0,>=0.7.0",
"s3transfer<0.9.0,>=0.8.0",
]
files = [
{file = "boto3-1.28.64-py3-none-any.whl", hash = "sha256:a99150a30c038c73e89662836820a8cce914afab5ea377942a37c484b85f4438"},
{file = "boto3-1.28.64.tar.gz", hash = "sha256:a5cf93b202568e9d378afdc84be55a6dedf11d30156289fe829e23e6d7dccabb"},
{file = "boto3-1.33.1-py3-none-any.whl", hash = "sha256:fa5aa92d16763cb906fb4a83d6eba887342202a980bea07862af5ba40827aa5a"},
{file = "boto3-1.33.1.tar.gz", hash = "sha256:1fe5fa75ff0f0c29a6f55e818d149d33571731e692a7b785ded7a28ac832cae8"},
]
[[package]]
name = "boto3-stubs"
version = "1.33.10"
version = "1.33.11"
requires_python = ">=3.7"
summary = "Type annotations for boto3 1.33.10 generated with mypy-boto3-builder 7.21.0"
summary = "Type annotations for boto3 1.33.11 generated with mypy-boto3-builder 7.21.0"
dependencies = [
"botocore-stubs",
"types-s3transfer",
"typing-extensions>=4.1.0; python_version < \"3.12\"",
]
files = [
{file = "boto3-stubs-1.33.10.tar.gz", hash = "sha256:9e29024bcb6ac12c220d8ea5bfe79c532c92e0c1d1170c14217165e1a8b09218"},
{file = "boto3_stubs-1.33.10-py3-none-any.whl", hash = "sha256:61d07f445f88d5cca0a66e23dfd83611ff947bac08e01a64908df3605c22aabc"},
{file = "boto3-stubs-1.33.11.tar.gz", hash = "sha256:0860a003b8a8bdea2df0ab182345ced6edea06721c196fb2e2e20b987716c7da"},
{file = "boto3_stubs-1.33.11-py3-none-any.whl", hash = "sha256:5f234c6b4ee10bf233a8b55d9caa66ee1da6418a5a97fc81309583def353f858"},
]
[[package]]
name = "boto3-stubs"
version = "1.33.10"
version = "1.33.11"
extras = ["s3"]
requires_python = ">=3.7"
summary = "Type annotations for boto3 1.33.10 generated with mypy-boto3-builder 7.21.0"
summary = "Type annotations for boto3 1.33.11 generated with mypy-boto3-builder 7.21.0"
dependencies = [
"boto3-stubs==1.33.10",
"boto3-stubs==1.33.11",
"mypy-boto3-s3<1.34.0,>=1.33.0",
]
files = [
{file = "boto3-stubs-1.33.10.tar.gz", hash = "sha256:9e29024bcb6ac12c220d8ea5bfe79c532c92e0c1d1170c14217165e1a8b09218"},
{file = "boto3_stubs-1.33.10-py3-none-any.whl", hash = "sha256:61d07f445f88d5cca0a66e23dfd83611ff947bac08e01a64908df3605c22aabc"},
{file = "boto3-stubs-1.33.11.tar.gz", hash = "sha256:0860a003b8a8bdea2df0ab182345ced6edea06721c196fb2e2e20b987716c7da"},
{file = "boto3_stubs-1.33.11-py3-none-any.whl", hash = "sha256:5f234c6b4ee10bf233a8b55d9caa66ee1da6418a5a97fc81309583def353f858"},
]
[[package]]
name = "botocore"
version = "1.31.64"
version = "1.33.1"
requires_python = ">= 3.7"
summary = "Low-level, data-driven core of boto 3."
dependencies = [
@ -234,21 +234,21 @@ dependencies = [
"urllib3<2.1,>=1.25.4; python_version >= \"3.10\"",
]
files = [
{file = "botocore-1.31.64-py3-none-any.whl", hash = "sha256:7b709310343a5b430ec9025b2e17c0bac6b16c05f1ac1d9521dece3f10c71bac"},
{file = "botocore-1.31.64.tar.gz", hash = "sha256:d8eb4b724ac437343359b318d73de0cfae0fecb24095827e56135b0ad6b44caf"},
{file = "botocore-1.33.1-py3-none-any.whl", hash = "sha256:c744b90980786c610dd9ad9c50cf2cdde3f1c4634b954a33613f6f8a1865a1de"},
{file = "botocore-1.33.1.tar.gz", hash = "sha256:d22d29916905e5f0670b91f07688e92b2c4a2075f9a474d6edbe7d22040d8fbf"},
]
[[package]]
name = "botocore-stubs"
version = "1.33.9"
version = "1.33.11"
requires_python = ">=3.7,<4.0"
summary = "Type annotations and code completion for botocore"
dependencies = [
"types-awscrt",
]
files = [
{file = "botocore_stubs-1.33.9-py3-none-any.whl", hash = "sha256:9d1fef0e22953102239fb3108b18588d980823ea765aef21ab861b65eba37e31"},
{file = "botocore_stubs-1.33.9.tar.gz", hash = "sha256:60e1ace3785ecdfec5ed4bfc7c03161a5a478cd45184a4042a0238ce6f56a18a"},
{file = "botocore_stubs-1.33.11-py3-none-any.whl", hash = "sha256:0ea9cad07310bcde284e59d470ecc06592302fa5599f912300e907e56ac51931"},
{file = "botocore_stubs-1.33.11.tar.gz", hash = "sha256:22530caaa1a0551af6c6c35831c6c666aeb4851196ad224564415baed83b99e3"},
]
[[package]]
@ -694,7 +694,7 @@ files = [
[[package]]
name = "litestar"
version = "2.4.2"
version = "2.4.3"
requires_python = "<4.0,>=3.8"
summary = "Litestar - A production-ready, highly performant, extensible ASGI API Framework"
dependencies = [
@ -710,13 +710,13 @@ dependencies = [
"typing-extensions",
]
files = [
{file = "litestar-2.4.2-py3-none-any.whl", hash = "sha256:562ef5075297694a428e5c162f8ec4073676ef3a4dd82279f85ede7cd88aa5b4"},
{file = "litestar-2.4.2.tar.gz", hash = "sha256:a630ebe6575429d06b8af87dd20f2c27e91f14bcb73b6a9e5dd963e517b4891e"},
{file = "litestar-2.4.3-py3-none-any.whl", hash = "sha256:90f0275c77e560a20adb6e07c6759478293be9545247c009c3da1f967ca4d118"},
{file = "litestar-2.4.3.tar.gz", hash = "sha256:11cad142432636384e6fb125a78c4fc80cf5e404c3b698033c0fae2413534944"},
]
[[package]]
name = "litestar"
version = "2.4.2"
version = "2.4.3"
extras = ["standard"]
requires_python = "<4.0,>=3.8"
summary = "Litestar - A production-ready, highly performant, extensible ASGI API Framework"
@ -724,13 +724,13 @@ dependencies = [
"fast-query-parsers>=1.0.2",
"jinja2",
"jsbeautifier",
"litestar==2.4.2",
"litestar==2.4.3",
"uvicorn[standard]",
"uvloop>=0.18.0; sys_platform != \"win32\"",
]
files = [
{file = "litestar-2.4.2-py3-none-any.whl", hash = "sha256:562ef5075297694a428e5c162f8ec4073676ef3a4dd82279f85ede7cd88aa5b4"},
{file = "litestar-2.4.2.tar.gz", hash = "sha256:a630ebe6575429d06b8af87dd20f2c27e91f14bcb73b6a9e5dd963e517b4891e"},
{file = "litestar-2.4.3-py3-none-any.whl", hash = "sha256:90f0275c77e560a20adb6e07c6759478293be9545247c009c3da1f967ca4d118"},
{file = "litestar-2.4.3.tar.gz", hash = "sha256:11cad142432636384e6fb125a78c4fc80cf5e404c3b698033c0fae2413534944"},
]
[[package]]
@ -869,6 +869,30 @@ files = [
{file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
]
[[package]]
name = "mypy"
version = "1.7.1"
requires_python = ">=3.8"
summary = "Optional static typing for Python"
dependencies = [
"mypy-extensions>=1.0.0",
"typing-extensions>=4.1.0",
]
files = [
{file = "mypy-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b901927f16224d0d143b925ce9a4e6b3a758010673eeded9b748f250cf4e8f7"},
{file = "mypy-1.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2f7f6985d05a4e3ce8255396df363046c28bea790e40617654e91ed580ca7c51"},
{file = "mypy-1.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:944bdc21ebd620eafefc090cdf83158393ec2b1391578359776c00de00e8907a"},
{file = "mypy-1.7.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9c7ac372232c928fff0645d85f273a726970c014749b924ce5710d7d89763a28"},
{file = "mypy-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:f6efc9bd72258f89a3816e3a98c09d36f079c223aa345c659622f056b760ab42"},
{file = "mypy-1.7.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6dbdec441c60699288adf051f51a5d512b0d818526d1dcfff5a41f8cd8b4aaf1"},
{file = "mypy-1.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4fc3d14ee80cd22367caaaf6e014494415bf440980a3045bf5045b525680ac33"},
{file = "mypy-1.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c6e4464ed5f01dc44dc9821caf67b60a4e5c3b04278286a85c067010653a0eb"},
{file = "mypy-1.7.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:d9b338c19fa2412f76e17525c1b4f2c687a55b156320acb588df79f2e6fa9fea"},
{file = "mypy-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:204e0d6de5fd2317394a4eff62065614c4892d5a4d1a7ee55b765d7a3d9e3f82"},
{file = "mypy-1.7.1-py3-none-any.whl", hash = "sha256:f7c5d642db47376a0cc130f0de6d055056e010debdaf0707cd2b0fc7e7ef30ea"},
{file = "mypy-1.7.1.tar.gz", hash = "sha256:fcb6d9afb1b6208b4c712af0dafdc650f518836065df0d4fb1d800f5d6773db2"},
]
[[package]]
name = "mypy-boto3-s3"
version = "1.33.2"
@ -882,6 +906,16 @@ files = [
{file = "mypy_boto3_s3-1.33.2-py3-none-any.whl", hash = "sha256:9d463df6def30de31a467d49ab92ff7795d46709d56eff6f52216a08bac27918"},
]
[[package]]
name = "mypy-extensions"
version = "1.0.0"
requires_python = ">=3.5"
summary = "Type system extensions for programs checked with the mypy type checker."
files = [
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
[[package]]
name = "packaging"
version = "23.2"
@ -1237,15 +1271,15 @@ files = [
[[package]]
name = "s3transfer"
version = "0.7.0"
version = "0.8.0"
requires_python = ">= 3.7"
summary = "An Amazon S3 Transfer Manager"
dependencies = [
"botocore<2.0a.0,>=1.12.36",
"botocore<2.0a.0,>=1.32.7",
]
files = [
{file = "s3transfer-0.7.0-py3-none-any.whl", hash = "sha256:10d6923c6359175f264811ef4bf6161a3156ce8e350e705396a7557d6293c33a"},
{file = "s3transfer-0.7.0.tar.gz", hash = "sha256:fd3889a66f5fe17299fe75b82eae6cf722554edca744ca5d5fe308b104883d2e"},
{file = "s3transfer-0.8.0-py3-none-any.whl", hash = "sha256:baa479dc2e63e5c2ed51611b4d46cdf0295e2070d8d0b86b22f335ee5b954986"},
{file = "s3transfer-0.8.0.tar.gz", hash = "sha256:e8d6bd52ffd99841e3a57b34370a54841f12d3aab072af862cdcc50955288002"},
]
[[package]]
@ -1280,9 +1314,9 @@ files = [
[[package]]
name = "types-aioboto3-lite"
version = "12.0.0"
version = "12.1.0"
requires_python = ">=3.7"
summary = "Type annotations for aioboto3 12.0.0 generated with mypy-boto3-builder 7.19.0"
summary = "Type annotations for aioboto3 12.1.0 generated with mypy-boto3-builder 7.21.0"
dependencies = [
"botocore-stubs",
"types-aiobotocore-lite",
@ -1290,23 +1324,23 @@ dependencies = [
"typing-extensions>=4.1.0; python_version < \"3.12\"",
]
files = [
{file = "types-aioboto3-lite-12.0.0.tar.gz", hash = "sha256:1588120d3facdbbdbe2a755cb6d323a27a7c24b7e908c0228bb9bb42576323bd"},
{file = "types_aioboto3_lite-12.0.0-py3-none-any.whl", hash = "sha256:ea1f76082b96b31f1333a5bce5f6038f2c220ec722fe9b84099f54ce2f4878ca"},
{file = "types-aioboto3-lite-12.1.0.tar.gz", hash = "sha256:3b3f2a3adce6769cd1b598f81b095d69e8508717eee01f552b6add0c9071971d"},
{file = "types_aioboto3_lite-12.1.0-py3-none-any.whl", hash = "sha256:35ce7eff72e85ee7a55b45e03e1baad8a2064c4e3c6c4e83ee2717bd49c6b864"},
]
[[package]]
name = "types-aioboto3-lite"
version = "12.0.0"
version = "12.1.0"
extras = ["s3"]
requires_python = ">=3.7"
summary = "Type annotations for aioboto3 12.0.0 generated with mypy-boto3-builder 7.19.0"
summary = "Type annotations for aioboto3 12.1.0 generated with mypy-boto3-builder 7.21.0"
dependencies = [
"types-aioboto3-lite==12.0.0",
"types-aioboto3-lite==12.1.0",
"types-aiobotocore-s3",
]
files = [
{file = "types-aioboto3-lite-12.0.0.tar.gz", hash = "sha256:1588120d3facdbbdbe2a755cb6d323a27a7c24b7e908c0228bb9bb42576323bd"},
{file = "types_aioboto3_lite-12.0.0-py3-none-any.whl", hash = "sha256:ea1f76082b96b31f1333a5bce5f6038f2c220ec722fe9b84099f54ce2f4878ca"},
{file = "types-aioboto3-lite-12.1.0.tar.gz", hash = "sha256:3b3f2a3adce6769cd1b598f81b095d69e8508717eee01f552b6add0c9071971d"},
{file = "types_aioboto3_lite-12.1.0-py3-none-any.whl", hash = "sha256:35ce7eff72e85ee7a55b45e03e1baad8a2064c4e3c6c4e83ee2717bd49c6b864"},
]
[[package]]

View file

@ -26,6 +26,9 @@ testing = [
]
linting = [
"ruff>=0.1.7",
"mypy>=1.7.1",
"types-aioboto3-lite[s3]>=12.0.0",
"boto3-stubs[s3]>=1.33.10",
]
chalice = [
"chalice>=1.29.0",
@ -39,12 +42,13 @@ sls = [
requires = ["pdm-backend"]
build-backend = "pdm.backend"
[tool.pdm.dev-dependencies]
dev = [
"types-aioboto3-lite[s3]>=12.0.0",
"boto3-stubs[s3]>=1.33.10",
]
[tool.ruff]
extend-select = ["W", "C90", "I", "N", "UP", "S", "BLE", "B", "A", "COM", "C4", "DTZ", "T10", "EM", "ISC", "T20", "PT", "RSE", "RET", "SIM", "PTH", "ERA", "PGH", "PL", "TRY", "RUF"]
extend-ignore = ["S101", "ISC002", "ISC002", "COM812"]
extend-ignore = ["S101", "ISC001", "ISC002", "COM812"]
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
[[tool.mypy.overrides]]
module = ["aioboto3"]

View file

@ -1,6 +1,7 @@
import random
from abc import ABC, abstractmethod
from typing import Any
from uuid import UUID
from pydantic import UUID4, BaseModel
@ -31,7 +32,7 @@ class Group(BaseModel):
class IRepo(ABC):
@abstractmethod
async def get(self, group_uuid: str) -> Group | None:
async def get(self, group_uuid: str | UUID) -> Group | None:
... # pragma: no cover
@abstractmethod
@ -45,5 +46,5 @@ class IService(ABC):
self.config = config or get_config()
@abstractmethod
async def run(self, *args, **kwargs) -> Any:
async def run(self, *args, **kwargs) -> Any | None:
... # pragma: no cover

View file

@ -1,5 +1,6 @@
import json
from contextlib import asynccontextmanager
from uuid import UUID
import aioboto3
from botocore.exceptions import ClientError
@ -26,7 +27,7 @@ class S3Repo(IRepo):
async with self.session.client("s3", **kwargs) as s3:
yield s3
async def get(self, group_uuid: str) -> Group | None:
async def get(self, group_uuid: str | UUID) -> Group | None:
async with self.get_s3() as s3:
try:
s3_obj = await s3.get_object(

View file

@ -3,7 +3,9 @@ from uuid import UUID
from secretsanta.domain import Group, IService
def participants2url(participants: list[str], group_uuid: str | UUID, server_url: str):
def participants2url(
participants: list[str], group_uuid: str | UUID, server_url: str
) -> list[str]:
return [
f"{server_url}/groups/{group_uuid}/pair/{participant}"
for participant in participants
@ -11,7 +13,7 @@ def participants2url(participants: list[str], group_uuid: str | UUID, server_url
class CreateGroupService(IService):
async def run(self, group: Group):
async def run(self, group: Group) -> list[str]:
if existing_group := await self.repo.get(group.uuid):
return participants2url(
participants=existing_group.participants,
@ -42,6 +44,9 @@ class GetGroupParticipantsService(IService):
class GetPairService(IService):
async def run(self, group_uuid: str, participant: str) -> str:
async def run(self, group_uuid: str, participant: str) -> str | None:
group = await self.repo.get(group_uuid)
if not group or not group.pairs:
return None
return group.pairs[participant]