diff --git a/.dockerignore b/.dockerignore index 1d929dc..e228b05 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,4 +7,3 @@ ./test ./.git ./.gitignore -./.gitignore diff --git a/.github/workflows/before-merge.yml b/.github/workflows/before-merge.yml index bff983c..4e1a4de 100644 --- a/.github/workflows/before-merge.yml +++ b/.github/workflows/before-merge.yml @@ -23,5 +23,6 @@ jobs: python -m pip install --upgrade pip pip install pipenv pipenv sync --system --dev + - run: pylint ./src ./test - run: mypy ./src ./test - run: pytest -v --cov=src.use_case --cov-report term-missing --cov-report term:skip-covered test diff --git a/Pipfile b/Pipfile index 339dd4e..30e5677 100644 --- a/Pipfile +++ b/Pipfile @@ -17,6 +17,8 @@ debugpy = "*" pytest = "*" pytest-cov = "*" mypy = "*" +pylint = "*" +isort = "*" [requires] python_version = "3.12" diff --git a/Pipfile.lock b/Pipfile.lock index 688cd37..dedbc60 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "ed4c801d8fffab4cd350edac6dc9afc6e37677beddb516e754940007c67e1fa6" + "sha256": "420f23e8e4598628812cf9b71731912743ace09996700d10d9d31ec9003c0cc0" }, "pipfile-spec": 6, "requires": { @@ -520,11 +520,11 @@ }, "idna": { "hashes": [ - "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", - "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" + "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac", + "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603" ], - "markers": "python_version >= '3.5'", - "version": "==3.7" + "markers": "python_version >= '3.6'", + "version": "==3.8" }, "itsdangerous": { "hashes": [ @@ -1270,6 +1270,14 @@ } }, "develop": { + "astroid": { + "hashes": [ + "sha256:0e14202810b30da1b735827f78f5157be2bbd4a7a59b7707ca0bfc2fb4c0063a", + "sha256:413658a61eeca6202a59231abb473f932038fbcbf1666587f66d482083413a25" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==3.2.4" + }, "asttokens": { "hashes": [ "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24", @@ -1395,6 +1403,14 @@ "markers": "python_version >= '3.5'", "version": "==5.1.1" }, + "dill": { + "hashes": [ + "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca", + "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" + ], + "markers": "python_version >= '3.11'", + "version": "==0.3.8" + }, "executing": { "hashes": [ "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147", @@ -1420,6 +1436,15 @@ "markers": "python_version >= '3.10'", "version": "==8.26.0" }, + "isort": { + "hashes": [ + "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", + "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" + ], + "index": "pypi", + "markers": "python_full_version >= '3.8.0'", + "version": "==5.13.2" + }, "jedi": { "hashes": [ "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", @@ -1436,39 +1461,47 @@ "markers": "python_version >= '3.8'", "version": "==0.1.7" }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, "mypy": { "hashes": [ - "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54", - "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a", - "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72", - "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69", - "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b", - "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe", - "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4", - "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd", - "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0", - "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525", - "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2", - "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c", - "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5", - "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de", - "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74", - "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c", - "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e", - "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58", - "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b", - "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417", - "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411", - "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb", - "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03", - "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca", - "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8", - "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08", - "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809" + "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36", + "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce", + "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6", + "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b", + "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca", + "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24", + "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383", + "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7", + "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86", + "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d", + "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4", + "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8", + "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987", + "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385", + "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79", + "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef", + "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6", + "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70", + "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca", + "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70", + "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12", + "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104", + "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a", + "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318", + "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1", + "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b", + "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.11.1" + "version": "==1.11.2" }, "mypy-extensions": { "hashes": [ @@ -1502,6 +1535,14 @@ "markers": "sys_platform != 'win32' and sys_platform != 'emscripten'", "version": "==4.9.0" }, + "platformdirs": { + "hashes": [ + "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", + "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3" + ], + "markers": "python_version >= '3.8'", + "version": "==4.2.2" + }, "pluggy": { "hashes": [ "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", @@ -1540,6 +1581,15 @@ "markers": "python_version >= '3.8'", "version": "==2.18.0" }, + "pylint": { + "hashes": [ + "sha256:03c8e3baa1d9fb995b12c1dbe00aa6c4bcef210c2a2634374aedeb22fb4a8f8f", + "sha256:a5d01678349454806cff6d886fb072294f56a58c4761278c97fb557d708e1eb3" + ], + "index": "pypi", + "markers": "python_full_version >= '3.8.0'", + "version": "==3.2.6" + }, "pytest": { "hashes": [ "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", @@ -1573,6 +1623,14 @@ ], "version": "==0.6.3" }, + "tomlkit": { + "hashes": [ + "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", + "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79" + ], + "markers": "python_version >= '3.8'", + "version": "==0.13.2" + }, "traitlets": { "hashes": [ "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", diff --git a/pyproject.toml b/pyproject.toml index b347735..c36dff8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,3 +16,19 @@ disallow_untyped_defs = true init_forbid_extra = true init_typed = true warn_required_dynamic_aliases = true + +[tool.pylint.imports] +max-line-length = 120 +disable = [ + "missing-module-docstring", + "missing-class-docstring", + "missing-function-docstring", + "too-few-public-methods", + "too-many-arguments", + "duplicate-code" +] +ignore = ["wireup.py", "settings.py"] + +[tool.isort] +line_length = 90 # Specify your desired max line length +profile = "black" # Optional: if you're using Black's formatting style \ No newline at end of file diff --git a/src/abc/infra/inode_client.py b/src/abc/infra/inode_client.py index c15b168..201e01a 100644 --- a/src/abc/infra/inode_client.py +++ b/src/abc/infra/inode_client.py @@ -1,7 +1,12 @@ from abc import ABC, abstractmethod -from src.type.internal import EndPoint, NodeIdentifier, PeerCredentials, UniversalPeerIdentifier from src.type.entity import Message, Node, Peer +from src.type.internal import ( + EndPoint, + NodeIdentifier, + PeerCredentials, + UniversalPeerIdentifier, +) class INodeClient(ABC): diff --git a/src/abc/infra/ipeer_repo.py b/src/abc/infra/ipeer_repo.py index e4104c5..9d73cc5 100644 --- a/src/abc/infra/ipeer_repo.py +++ b/src/abc/infra/ipeer_repo.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from src.type.entity import Peer -from src.type.internal import PeerIdentifier, Keyring +from src.type.internal import Keyring, PeerIdentifier class IPeerRepo(ABC): diff --git a/src/abc/use_case/add_peer_use_case.py b/src/abc/use_case/add_peer_use_case.py index 527f01a..f216d9f 100644 --- a/src/abc/use_case/add_peer_use_case.py +++ b/src/abc/use_case/add_peer_use_case.py @@ -1,6 +1,6 @@ from abc import ABC, abstractmethod -from src.type.internal import PeerIdentifier, Keyring +from src.type.internal import Keyring, PeerIdentifier class AddPeerUseCase(ABC): diff --git a/src/abc/use_case/get_related_messages_use_case.py b/src/abc/use_case/get_related_messages_use_case.py index 4c56292..fc46d7e 100644 --- a/src/abc/use_case/get_related_messages_use_case.py +++ b/src/abc/use_case/get_related_messages_use_case.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod -from src.type.internal import PeerCredentials, UniversalPeerIdentifier from src.type.entity import Message +from src.type.internal import PeerCredentials, UniversalPeerIdentifier class GetRelatedMessagesUseCase(ABC): diff --git a/src/api/auth.py b/src/api/auth.py index 758ff66..0efd587 100644 --- a/src/api/auth.py +++ b/src/api/auth.py @@ -27,11 +27,14 @@ def __init__(self, app: Application) -> None: self.app = app @property - def _find_peer_use_case(self) -> FindPeerUseCase: return self.app.services.resolve(FindPeerUseCase) + def _find_peer_use_case(self) -> FindPeerUseCase: + return self.app.services.resolve(FindPeerUseCase) @property - def _settings(self) -> AuthenticationSettings: return self.app.services.resolve(AuthenticationSettings) + def _settings(self) -> AuthenticationSettings: + return self.app.services.resolve(AuthenticationSettings) + # pylint: disable=invalid-overridden-method async def authenticate(self, context: Request) -> Identity | None: # type: ignore context.identity = None @@ -46,8 +49,9 @@ async def authenticate(self, context: Request) -> Identity | None: # type: ignor now, window_range = datetime.now(), timedelta(seconds=self._settings.TIME_WINDOW) start, end = now - window_range, now + window_range given = datetime.fromtimestamp(signed_timestamp) - if given > start and given < end: + if start < given < end: context.identity = Identity({'id': universal_identifier}, 'authenticated') + # pylint: disable=broad-exception-caught except Exception: pass diff --git a/src/api/controller/node_controller.py b/src/api/controller/node_controller.py index 93fc65b..4a4262e 100644 --- a/src/api/controller/node_controller.py +++ b/src/api/controller/node_controller.py @@ -1,6 +1,6 @@ -from blacksheep import FromJSON, FromRoute, FromQuery, Response +from blacksheep import FromJSON, FromQuery, FromRoute, Response from blacksheep.server.authorization import allow_anonymous -from blacksheep.server.controllers import post, get +from blacksheep.server.controllers import get, post from blacksheep.server.openapi.common import ContentInfo, ResponseInfo from src.abc.use_case.connect_node_use_case import ConnectNodeUseCase diff --git a/src/api/controller/peer_controller.py b/src/api/controller/peer_controller.py index eb3a771..89876e0 100644 --- a/src/api/controller/peer_controller.py +++ b/src/api/controller/peer_controller.py @@ -3,8 +3,8 @@ from blacksheep.server.controllers import post from src.abc.use_case.add_peer_use_case import AddPeerUseCase -from src.api.docs import docs, unsecure_handler from src.api.controller.base_controller import BaseController +from src.api.docs import docs, unsecure_handler from src.api.io_type.peer_io import PeerCreationRequest diff --git a/src/api/controller/related_message_controller.py b/src/api/controller/related_message_controller.py index 78f8c3b..e4f4993 100644 --- a/src/api/controller/related_message_controller.py +++ b/src/api/controller/related_message_controller.py @@ -6,7 +6,7 @@ from src.api.controller.base_controller import BaseController from src.api.docs import docs from src.api.io_type.message_io import MessageTransferRequest -from src.type.internal import UniversalPeerIdentifier +from src.type.internal import PeerCredentials, UniversalPeerIdentifier class RelatedMessageController(BaseController): diff --git a/src/api/controller/related_peer_controller.py b/src/api/controller/related_peer_controller.py index 08a28a0..339c62d 100644 --- a/src/api/controller/related_peer_controller.py +++ b/src/api/controller/related_peer_controller.py @@ -5,8 +5,8 @@ from src.abc.use_case.add_peer_use_case import AddPeerUseCase from src.abc.use_case.find_peer_use_case import FindPeerUseCase -from src.api.docs import docs, unsecure_handler from src.api.controller.base_controller import BaseController +from src.api.docs import docs, unsecure_handler from src.api.io_type.peer_io import PeerModel from src.type.internal import UniversalPeerIdentifier diff --git a/src/api/docs.py b/src/api/docs.py index 774029e..13feb59 100644 --- a/src/api/docs.py +++ b/src/api/docs.py @@ -1,15 +1,25 @@ from blacksheep.server.openapi.v3 import OpenAPIHandler -from openapidocs.v3 import Info, Response, Operation, OpenAPI, HTTPSecurity, Security, SecurityRequirement +from openapidocs.v3 import ( + HTTPSecurity, + Info, + OpenAPI, + Operation, + Response, + Security, + SecurityRequirement, +) +# pylint: disable=unused-argument def unsecure_handler(self: OpenAPIHandler, operation: Operation) -> None: - operation.security = list() + operation.security = [] class SecuredOpenAPIHandler(OpenAPIHandler): + # pylint: disable=redefined-outer-name def on_docs_generated(self, docs: OpenAPI) -> None: docs.components.security_schemes = {'Basic authentication': HTTPSecurity(scheme='Basic')} # type: ignore - docs.security = Security(requirements=[SecurityRequirement(name='Basic authentication', value=list())]) + docs.security = Security(requirements=[SecurityRequirement(name='Basic authentication', value=[])]) super().on_docs_generated(docs) docs = SecuredOpenAPIHandler(info=Info(title='WCYD', version='0')) diff --git a/src/api/entrypoint.py b/src/api/entrypoint.py index b96fb96..7a261cc 100644 --- a/src/api/entrypoint.py +++ b/src/api/entrypoint.py @@ -3,9 +3,12 @@ from guardpost.common import AuthenticatedRequirement from src.api.auth import DecentralizedAuthenticationHandler -from src.api.wireup import inject_dependencies, register_controllers, register_exception_handlers from src.api.docs import docs - +from src.api.wireup import ( + inject_dependencies, + register_controllers, + register_exception_handlers, +) app = Application(show_error_details=False) diff --git a/src/api/io_type/message_io.py b/src/api/io_type/message_io.py index 4d9efa4..dd289a2 100644 --- a/src/api/io_type/message_io.py +++ b/src/api/io_type/message_io.py @@ -1,4 +1,5 @@ from uuid import UUID + from pydantic.dataclasses import dataclass from src.type.internal import UniversalPeerIdentifier diff --git a/src/api/io_type/peer_io.py b/src/api/io_type/peer_io.py index 33379e2..685cb76 100644 --- a/src/api/io_type/peer_io.py +++ b/src/api/io_type/peer_io.py @@ -1,6 +1,6 @@ from pydantic.dataclasses import dataclass -from src.type.internal import PeerIdentifier, Keyring, UniversalPeerIdentifier +from src.type.internal import Keyring, PeerIdentifier, UniversalPeerIdentifier @dataclass(kw_only=True) diff --git a/src/api/wireup.py b/src/api/wireup.py index 04e75ef..187db16 100644 --- a/src/api/wireup.py +++ b/src/api/wireup.py @@ -1,10 +1,10 @@ from typing import Type + from blacksheep import Application, Request, Response, not_found from redis.asyncio import Redis from src.settings import read_settings - SETTINGS = read_settings() @@ -24,6 +24,7 @@ async def inject_dependencies(app: Application) -> None: from src.infra.node_client import NodeClient from src.infra.node_repo import NodeRepo from src.infra.peer_repo import PeerRepo + from src.settings import AuthenticationSettings, NodeSettings from src.use_case.add_peer import AddPeer from src.use_case.connect_node import ConnectNode from src.use_case.find_node import FindNode @@ -31,7 +32,6 @@ async def inject_dependencies(app: Application) -> None: from src.use_case.get_related_messages import GetRelatedMessages from src.use_case.remove_peer import RemovePeer from src.use_case.send_message import SendMessage - from src.settings import AuthenticationSettings, NodeSettings app.services.add_instance(Redis.from_url(str(SETTINGS.REDIS.DSN), decode_responses=True)) # type: ignore app.services.add_singleton(INodeRepo, NodeRepo) # type: ignore @@ -53,8 +53,8 @@ async def register_controllers(app: Application) -> None: from src.api.controller.message_controller import MessageController from src.api.controller.node_controller import NodeController from src.api.controller.peer_controller import PeerController - from src.api.controller.related_peer_controller import RelatedPeerController from src.api.controller.related_message_controller import RelatedMessageController + from src.api.controller.related_peer_controller import RelatedPeerController async def register_exception_handlers(app: Application) -> None: diff --git a/src/infra/message_repo.py b/src/infra/message_repo.py index 58400bf..2a4d53d 100644 --- a/src/infra/message_repo.py +++ b/src/infra/message_repo.py @@ -31,7 +31,7 @@ async def create(self, source: UniversalPeerIdentifier, target: PeerIdentifier, ) async def relative_to_target(self, identifier: PeerIdentifier) -> list[Message]: - message_list: list[Message] = list() + message_list: list[Message] = [] for key in await self._connection.keys( self._REDIS_KEY_NAMESPACE_.format(identifier='*', target_identifier=identifier) diff --git a/src/infra/node_client.py b/src/infra/node_client.py index c6cc65a..8b0c566 100644 --- a/src/infra/node_client.py +++ b/src/infra/node_client.py @@ -5,9 +5,21 @@ from pydantic import AnyUrl from src.abc.infra.inode_client import INodeClient -from src.type.internal import EndPoint, NodeIdentifier, Keyring, PeerCredentials, UniversalPeerIdentifier from src.type.entity import Message, Node, Peer -from src.type.exception import AlreadyAnswered, AlreadyExists, DoesNotExist, UnAuthenticated +from src.type.exception import ( + AlreadyAnswered, + AlreadyExists, + DoesNotExist, + UnAuthenticated, + UnexpectedNodeResponse, +) +from src.type.internal import ( + EndPoint, + Keyring, + NodeIdentifier, + PeerCredentials, + UniversalPeerIdentifier, +) from src.utils import AuthUtils @@ -56,7 +68,7 @@ async def connect_node(self, host: Node, identifier: NodeIdentifier, endpoint: E case 409: raise AlreadyExists case _: - raise Exception + raise UnexpectedNodeResponse async def find_node(self, host: Node, questioners: set[NodeIdentifier], identifier: NodeIdentifier) -> Node: async with self._session as sess: @@ -73,7 +85,7 @@ async def find_node(self, host: Node, questioners: set[NodeIdentifier], identifi case 409: raise AlreadyAnswered case _: - raise Exception + raise UnexpectedNodeResponse async def find_peer(self, host: Node, identifier: UniversalPeerIdentifier) -> Peer: async with self._session as sess: @@ -94,7 +106,7 @@ async def find_peer(self, host: Node, identifier: UniversalPeerIdentifier) -> Pe case 404: raise DoesNotExist case _: - raise Exception + raise UnexpectedNodeResponse async def send_message( self, @@ -118,7 +130,7 @@ async def send_message( case 404: raise DoesNotExist case _: - raise Exception + raise UnexpectedNodeResponse async def get_related_messages(self, host: Node, credentials: PeerCredentials) -> list[Message]: async with self._session as sess: @@ -143,5 +155,4 @@ async def get_related_messages(self, host: Node, credentials: PeerCredentials) - case 401: raise UnAuthenticated case _: - raise Exception - + raise UnexpectedNodeResponse diff --git a/src/infra/node_repo.py b/src/infra/node_repo.py index 650a47b..c39dc66 100644 --- a/src/infra/node_repo.py +++ b/src/infra/node_repo.py @@ -3,9 +3,9 @@ from redis.asyncio import Redis from src.abc.infra.inode_repo import INodeRepo -from src.type.internal import EndPoint, NodeIdentifier from src.type.entity import Node from src.type.exception import AlreadyExists, DoesNotExist +from src.type.internal import EndPoint, NodeIdentifier class RedisRepoNodeObjectModel(TypedDict): @@ -20,7 +20,11 @@ def __init__(self, connection: Redis) -> None: self._connection = connection async def get(self, identifier: NodeIdentifier) -> Node: - if bool(obj := await self._connection.hgetall(self._REDIS_KEY_NAMESPACE_.format(identifier=identifier))): # type: ignore + if bool( + obj := await self._connection.hgetall( + self._REDIS_KEY_NAMESPACE_.format(identifier=identifier) + ) # type: ignore + ): return Node(identifier=identifier, **obj) raise DoesNotExist diff --git a/src/infra/peer_repo.py b/src/infra/peer_repo.py index 9052f11..2d89feb 100644 --- a/src/infra/peer_repo.py +++ b/src/infra/peer_repo.py @@ -6,7 +6,7 @@ from src.settings import NodeSettings from src.type.entity import Peer from src.type.exception import AlreadyExists, DoesNotExist -from src.type.internal import PeerIdentifier, Keyring, UniversalPeerIdentifier +from src.type.internal import Keyring, PeerIdentifier, UniversalPeerIdentifier class RedisRepoPeerObjectModel(TypedDict): @@ -53,4 +53,4 @@ async def delete(self, identifier: PeerIdentifier) -> None: if not await self.exists(identifier): raise DoesNotExist - await self._connection.delete(self._REDIS_KEY_NAMESPACE_.format(identifier=identifier)) + await self._connection.delete(self._REDIS_KEY_NAMESPACE_.format(identifier=identifier)) diff --git a/src/settings.py b/src/settings.py index ef75977..e238610 100644 --- a/src/settings.py +++ b/src/settings.py @@ -1,7 +1,7 @@ from json import loads -from pydantic.dataclasses import dataclass from pydantic import AnyUrl, Field, RedisDsn +from pydantic.dataclasses import dataclass @dataclass(kw_only=True) diff --git a/src/type/entity.py b/src/type/entity.py index 55125dc..cae4cad 100644 --- a/src/type/entity.py +++ b/src/type/entity.py @@ -2,7 +2,7 @@ from pydantic.dataclasses import dataclass -from src.type.internal import NodeIdentifier, EndPoint, Keyring, UniversalPeerIdentifier +from src.type.internal import EndPoint, Keyring, NodeIdentifier, UniversalPeerIdentifier @dataclass(kw_only=True) diff --git a/src/type/exception.py b/src/type/exception.py index e47e302..0c99b51 100644 --- a/src/type/exception.py +++ b/src/type/exception.py @@ -8,3 +8,6 @@ class DoesNotExist(Exception): ... class UnAuthenticated(Exception): ... + + +class UnexpectedNodeResponse(Exception): ... diff --git a/src/type/internal.py b/src/type/internal.py index f00b68e..114f6a8 100644 --- a/src/type/internal.py +++ b/src/type/internal.py @@ -1,4 +1,4 @@ -from typing import TypeAlias, Self +from typing import Self, TypeAlias from nacl.encoding import Base64Encoder from nacl.public import PublicKey as NACLPublicKey @@ -6,8 +6,6 @@ from pydantic import AnyUrl, model_validator from pydantic.dataclasses import dataclass - -# TODO: use the new syntax when mypy releases THE FUCKING SUPPORT NodeIdentifier: TypeAlias = str PeerIdentifier: TypeAlias = str PeerCredentials: TypeAlias = str diff --git a/src/use_case/add_peer.py b/src/use_case/add_peer.py index dce60e4..7ec82eb 100644 --- a/src/use_case/add_peer.py +++ b/src/use_case/add_peer.py @@ -1,6 +1,6 @@ from src.abc.infra.ipeer_repo import IPeerRepo from src.abc.use_case.add_peer_use_case import AddPeerUseCase -from src.type.internal import PeerIdentifier, Keyring +from src.type.internal import Keyring, PeerIdentifier class AddPeer(AddPeerUseCase): diff --git a/src/use_case/find_peer.py b/src/use_case/find_peer.py index 5656ba3..7888be4 100644 --- a/src/use_case/find_peer.py +++ b/src/use_case/find_peer.py @@ -1,7 +1,7 @@ from src.abc.infra.inode_client import INodeClient from src.abc.infra.ipeer_repo import IPeerRepo -from src.abc.use_case.find_peer_use_case import FindPeerUseCase from src.abc.use_case.find_node_use_case import FindNodeUseCase +from src.abc.use_case.find_peer_use_case import FindPeerUseCase from src.settings import NodeSettings from src.type.entity import Peer from src.type.internal import UniversalPeerIdentifier diff --git a/src/utils.py b/src/utils.py index b2eb2ac..623aed6 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,7 +1,8 @@ from base64 import b64decode from nacl.encoding import Base64Encoder -from nacl.signing import VerifyKey as NACLVerifyKey, SigningKey as NACLSigningKey +from nacl.signing import SigningKey as NACLSigningKey +from nacl.signing import VerifyKey as NACLVerifyKey from src.type.internal import PeerCredentials, UniversalPeerIdentifier @@ -16,7 +17,8 @@ def sign(message: str, signing_key: str) -> str: return NACLSigningKey(signing_key.encode(), Base64Encoder).sign(bytes(message.encode())).hex() @staticmethod - def decrypt_base64(encrypted_message: str) -> str: return b64decode(encrypted_message).decode() + def decrypt_base64(encrypted_message: str) -> str: + return b64decode(encrypted_message).decode() class AuthUtils: diff --git a/test/unit/mock/infra/mock_message_repo.py b/test/unit/mock/infra/mock_message_repo.py index 83df995..2c30b87 100644 --- a/test/unit/mock/infra/mock_message_repo.py +++ b/test/unit/mock/infra/mock_message_repo.py @@ -16,14 +16,14 @@ class MockRepoMessageObjectModel(TypedDict): class MockMessageRepo(IMessageRepo): def __init__(self, node_settings: NodeSettings) -> None: - self._mem_storage: dict[PeerIdentifier, list[MockRepoMessageObjectModel]] = dict() + self._mem_storage: dict[PeerIdentifier, list[MockRepoMessageObjectModel]] = {} self._settings = node_settings async def create(self, source: UniversalPeerIdentifier, target: PeerIdentifier, content: str) -> None: try: messages = self._mem_storage[target] except KeyError: - self._mem_storage[target] = list() + self._mem_storage[target] = [] messages = self._mem_storage[target] messages.append( @@ -46,4 +46,4 @@ async def relative_to_target(self, identifier: PeerIdentifier) -> list[Message]: ) for obj in self._mem_storage[identifier] ] except KeyError: - return list() + return [] diff --git a/test/unit/mock/infra/mock_node_client.py b/test/unit/mock/infra/mock_node_client.py index c0a14a7..de3c043 100644 --- a/test/unit/mock/infra/mock_node_client.py +++ b/test/unit/mock/infra/mock_node_client.py @@ -1,12 +1,19 @@ from typing import TypedDict -from uuid import uuid4, UUID +from uuid import UUID, uuid4 from pydantic.networks import AnyUrl from src.abc.infra.inode_client import INodeClient -from src.type.internal import EndPoint, NodeIdentifier, PeerCredentials, PeerIdentifier, Keyring, UniversalPeerIdentifier -from src.type.entity import Node, Peer, Message +from src.type.entity import Message, Node, Peer from src.type.exception import AlreadyAnswered, AlreadyExists, DoesNotExist +from src.type.internal import ( + EndPoint, + Keyring, + NodeIdentifier, + PeerCredentials, + PeerIdentifier, + UniversalPeerIdentifier, +) from src.utils import AuthUtils @@ -35,7 +42,7 @@ class DirectNeighborMemStorage(TypedDict): class MockNodeClient(INodeClient): def __init__(self) -> None: - self._mem_storage: dict[NodeIdentifier, DirectNeighborMemStorage] = dict() + self._mem_storage: dict[NodeIdentifier, DirectNeighborMemStorage] = {} async def connect_node(self, host: Node, identifier: NodeIdentifier, endpoint: EndPoint) -> None: if host.identifier in self._mem_storage and identifier in self._mem_storage[host.identifier]['nodes']: @@ -43,8 +50,8 @@ async def connect_node(self, host: Node, identifier: NodeIdentifier, endpoint: E self._mem_storage[host.identifier] = { 'nodes': {identifier: {'endpoint': str(endpoint)}}, - 'peers': dict(), - 'messages': dict() + 'peers': {}, + 'messages': {} } async def find_node(self, host: Node, questioners: set[NodeIdentifier], identifier: NodeIdentifier) -> Node: @@ -79,7 +86,7 @@ async def send_message( raise DoesNotExist if (messages := self._mem_storage[target.node]['messages'].get(target.peer)) is None: - self._mem_storage[target.node]['messages'][target.peer] = list() + self._mem_storage[target.node]['messages'][target.peer] = [] messages = self._mem_storage[target.node]['messages'][target.peer] source = AuthUtils.extract_identifier(credentials) @@ -99,7 +106,7 @@ async def get_related_messages(self, host: Node, credentials: PeerCredentials) - raise DoesNotExist if (messages := self._mem_storage[target.node]['messages'].get(target.peer)) is None: - return list() + return [] return [ Message( diff --git a/test/unit/mock/infra/mock_node_repo.py b/test/unit/mock/infra/mock_node_repo.py index 975be0f..bd34c1a 100644 --- a/test/unit/mock/infra/mock_node_repo.py +++ b/test/unit/mock/infra/mock_node_repo.py @@ -3,9 +3,9 @@ from pydantic.networks import AnyUrl from src.abc.infra.inode_repo import INodeRepo -from src.type.internal import EndPoint, NodeIdentifier from src.type.entity import Node from src.type.exception import AlreadyExists, DoesNotExist +from src.type.internal import EndPoint, NodeIdentifier class MockRepoNodeObjectModel(TypedDict): @@ -15,7 +15,7 @@ class MockRepoNodeObjectModel(TypedDict): class MockNodeRepo(INodeRepo): def __init__(self) -> None: - self._mem_storage: dict[NodeIdentifier, MockRepoNodeObjectModel] = dict() + self._mem_storage: dict[NodeIdentifier, MockRepoNodeObjectModel] = {} async def get(self, identifier: NodeIdentifier) -> Node: if (obj := self._mem_storage.get(identifier)) is not None: diff --git a/test/unit/mock/infra/mock_peer_repo.py b/test/unit/mock/infra/mock_peer_repo.py index 6d94a77..0101ee0 100644 --- a/test/unit/mock/infra/mock_peer_repo.py +++ b/test/unit/mock/infra/mock_peer_repo.py @@ -1,9 +1,10 @@ from typing import TypedDict + from src.abc.infra.ipeer_repo import IPeerRepo from src.settings import NodeSettings from src.type.entity import Peer from src.type.exception import AlreadyExists, DoesNotExist -from src.type.internal import PeerIdentifier, Keyring, UniversalPeerIdentifier +from src.type.internal import Keyring, PeerIdentifier, UniversalPeerIdentifier class MockRepoPeerObjectModel(TypedDict): @@ -13,7 +14,7 @@ class MockRepoPeerObjectModel(TypedDict): class MockPeerRepo(IPeerRepo): def __init__(self, node_settings: NodeSettings) -> None: - self._mem_storage: dict[PeerIdentifier, MockRepoPeerObjectModel] = dict() + self._mem_storage: dict[PeerIdentifier, MockRepoPeerObjectModel] = {} self._settings = node_settings async def get(self, identifier: PeerIdentifier) -> Peer: @@ -26,8 +27,8 @@ async def get(self, identifier: PeerIdentifier) -> Peer: encryption=obj['encryption_key'] ) ) - except KeyError: - raise DoesNotExist + except KeyError as e: + raise DoesNotExist from e async def exists(self, identifier: PeerIdentifier) -> bool: return identifier in self._mem_storage @@ -41,5 +42,5 @@ async def create(self, identifier: PeerIdentifier, keyring: Keyring) -> None: async def delete(self, identifier: PeerIdentifier) -> None: try: self._mem_storage.pop(identifier) - except KeyError: - raise DoesNotExist + except KeyError as e: + raise DoesNotExist from e diff --git a/test/unit/use_case/test_add_peer_use_case.py b/test/unit/use_case/test_add_peer_use_case.py index be9b07a..ef43ce0 100644 --- a/test/unit/use_case/test_add_peer_use_case.py +++ b/test/unit/use_case/test_add_peer_use_case.py @@ -1,3 +1,5 @@ +from test.unit.mock.infra.mock_peer_repo import MockPeerRepo +from test.unit.utils import get_internal_peer from unittest import IsolatedAsyncioTestCase from pydantic import AnyUrl @@ -6,8 +8,6 @@ from src.type.exception import AlreadyExists from src.type.internal import Keyring from src.use_case.add_peer import AddPeer -from test.unit.mock.infra.mock_peer_repo import MockPeerRepo -from test.unit.utils import get_internal_peer class TestAddPeerUseCase(IsolatedAsyncioTestCase): diff --git a/test/unit/use_case/test_connect_node_use_case.py b/test/unit/use_case/test_connect_node_use_case.py index d74cd0e..45c3169 100644 --- a/test/unit/use_case/test_connect_node_use_case.py +++ b/test/unit/use_case/test_connect_node_use_case.py @@ -1,3 +1,6 @@ +from test.unit.mock.infra.mock_node_client import MockNodeClient +from test.unit.mock.infra.mock_node_repo import MockNodeRepo +from test.unit.utils import add_external_neighbor, get_internal_neighbor from unittest import IsolatedAsyncioTestCase from pydantic import AnyUrl @@ -5,9 +8,6 @@ from src.settings import NodeSettings from src.type.exception import AlreadyExists from src.use_case.connect_node import ConnectNode -from test.unit.mock.infra.mock_node_client import MockNodeClient -from test.unit.mock.infra.mock_node_repo import MockNodeRepo -from test.unit.utils import get_internal_neighbor, add_external_neighbor class TestConnectNodeUseCase(IsolatedAsyncioTestCase): @@ -32,7 +32,12 @@ async def test_internal_duplicated_identifier(self) -> None: async def test_external_duplicated_identifier(self) -> None: external_existing_neighbor_identifier = 'external-existing-neighbor-identifier' endpoint = AnyUrl('http://external-existing-neighbor:80') - add_external_neighbor(self._mock_node_client, external_existing_neighbor_identifier, self._settings.IDENTIFIER, self._settings.ENDPOINT) + add_external_neighbor( + self._mock_node_client, + external_existing_neighbor_identifier, + self._settings.IDENTIFIER, + self._settings.ENDPOINT + ) await self._use_case.execute(external_existing_neighbor_identifier, endpoint) async def test_normal(self) -> None: diff --git a/test/unit/use_case/test_find_node_use_case.py b/test/unit/use_case/test_find_node_use_case.py index a4557cb..522c7b1 100644 --- a/test/unit/use_case/test_find_node_use_case.py +++ b/test/unit/use_case/test_find_node_use_case.py @@ -1,3 +1,6 @@ +from test.unit.mock.infra.mock_node_client import MockNodeClient +from test.unit.mock.infra.mock_node_repo import MockNodeRepo +from test.unit.utils import add_external_neighbor, add_internal_neighbor from unittest import IsolatedAsyncioTestCase from pydantic import AnyUrl @@ -5,9 +8,6 @@ from src.settings import NodeSettings from src.type.exception import AlreadyAnswered, DoesNotExist from src.use_case.find_node import FindNode -from test.unit.mock.infra.mock_node_client import MockNodeClient -from test.unit.mock.infra.mock_node_repo import MockNodeRepo -from test.unit.utils import add_internal_neighbor, add_external_neighbor class TestFindNodeUseCase(IsolatedAsyncioTestCase): diff --git a/test/unit/use_case/test_find_peer_use_case.py b/test/unit/use_case/test_find_peer_use_case.py index 2a56a58..9284192 100644 --- a/test/unit/use_case/test_find_peer_use_case.py +++ b/test/unit/use_case/test_find_peer_use_case.py @@ -1,3 +1,7 @@ +from test.unit.mock.infra.mock_node_client import MockNodeClient +from test.unit.mock.infra.mock_node_repo import MockNodeRepo +from test.unit.mock.infra.mock_peer_repo import MockPeerRepo +from test.unit.utils import add_external_peer, add_internal_neighbor, add_internal_peer from unittest import IsolatedAsyncioTestCase from pydantic import AnyUrl @@ -6,10 +10,6 @@ from src.type.internal import Keyring, UniversalPeerIdentifier from src.use_case.find_node import FindNode from src.use_case.find_peer import FindPeer -from test.unit.mock.infra.mock_node_client import MockNodeClient -from test.unit.mock.infra.mock_node_repo import MockNodeRepo -from test.unit.mock.infra.mock_peer_repo import MockPeerRepo -from test.unit.utils import add_external_peer, add_internal_peer, add_internal_neighbor class TestFindPeerUseCase(IsolatedAsyncioTestCase): diff --git a/test/unit/use_case/test_get_related_messages.py b/test/unit/use_case/test_get_related_messages.py index 4d3db49..46678cf 100644 --- a/test/unit/use_case/test_get_related_messages.py +++ b/test/unit/use_case/test_get_related_messages.py @@ -1,11 +1,3 @@ -from unittest import IsolatedAsyncioTestCase - -from pydantic import AnyUrl - -from src.settings import NodeSettings -from src.type.internal import Keyring, UniversalPeerIdentifier -from src.use_case.find_node import FindNode -from src.use_case.get_related_messages import GetRelatedMessages from test.unit.mock.infra.mock_message_repo import MockMessageRepo from test.unit.mock.infra.mock_node_client import MockNodeClient from test.unit.mock.infra.mock_node_repo import MockNodeRepo @@ -16,8 +8,16 @@ add_internal_message, add_internal_neighbor, add_internal_peer, - make_auth_credentials + make_auth_credentials, ) +from unittest import IsolatedAsyncioTestCase + +from pydantic import AnyUrl + +from src.settings import NodeSettings +from src.type.internal import Keyring, UniversalPeerIdentifier +from src.use_case.find_node import FindNode +from src.use_case.get_related_messages import GetRelatedMessages class TestSendMessageUseCase(IsolatedAsyncioTestCase): diff --git a/test/unit/use_case/test_remove_peer_use_case.py b/test/unit/use_case/test_remove_peer_use_case.py index 3986565..e85a9ae 100644 --- a/test/unit/use_case/test_remove_peer_use_case.py +++ b/test/unit/use_case/test_remove_peer_use_case.py @@ -1,3 +1,5 @@ +from test.unit.mock.infra.mock_peer_repo import MockPeerRepo +from test.unit.utils import add_internal_peer from unittest import IsolatedAsyncioTestCase from pydantic import AnyUrl @@ -6,8 +8,6 @@ from src.type.exception import DoesNotExist from src.type.internal import Keyring from src.use_case.remove_peer import RemovePeer -from test.unit.mock.infra.mock_peer_repo import MockPeerRepo -from test.unit.utils import add_internal_peer class TestRemovePeerUseCase(IsolatedAsyncioTestCase): diff --git a/test/unit/use_case/test_send_message_use_case.py b/test/unit/use_case/test_send_message_use_case.py index a52c637..1bcb7d5 100644 --- a/test/unit/use_case/test_send_message_use_case.py +++ b/test/unit/use_case/test_send_message_use_case.py @@ -1,12 +1,3 @@ -from unittest import IsolatedAsyncioTestCase - -from pydantic import AnyUrl - -from src.settings import NodeSettings -from src.type.exception import DoesNotExist -from src.type.internal import Keyring, UniversalPeerIdentifier -from src.use_case.find_node import FindNode -from src.use_case.send_message import SendMessage from test.unit.mock.infra.mock_message_repo import MockMessageRepo from test.unit.mock.infra.mock_node_client import MockNodeClient from test.unit.mock.infra.mock_node_repo import MockNodeRepo @@ -17,8 +8,17 @@ add_internal_peer, get_external_relative_messages, get_internal_relative_messages, - make_auth_credentials + make_auth_credentials, ) +from unittest import IsolatedAsyncioTestCase + +from pydantic import AnyUrl + +from src.settings import NodeSettings +from src.type.exception import DoesNotExist +from src.type.internal import Keyring, UniversalPeerIdentifier +from src.use_case.find_node import FindNode +from src.use_case.send_message import SendMessage class TestSendMessageUseCase(IsolatedAsyncioTestCase): diff --git a/test/unit/utils.py b/test/unit/utils.py index fc22181..78c2486 100644 --- a/test/unit/utils.py +++ b/test/unit/utils.py @@ -1,17 +1,25 @@ from base64 import b64encode -from uuid import UUID, uuid4 -from src.type.entity import Message, Node, Peer -from src.type.internal import EndPoint, NodeIdentifier, PeerIdentifier, Keyring, UniversalPeerIdentifier from test.unit.mock.infra.mock_message_repo import MockMessageRepo from test.unit.mock.infra.mock_node_client import MockNodeClient from test.unit.mock.infra.mock_node_repo import MockNodeRepo from test.unit.mock.infra.mock_peer_repo import MockPeerRepo +from uuid import UUID, uuid4 + +from src.type.entity import Message, Node, Peer +from src.type.internal import ( + EndPoint, + Keyring, + NodeIdentifier, + PeerIdentifier, + UniversalPeerIdentifier, +) def make_auth_credentials(identifier: UniversalPeerIdentifier) -> str: return b64encode(bytes(f'Basic {identifier.peer}@{identifier.node}:cant-be-tested'.encode())).decode() +# pylint: disable=protected-access def add_external_neighbor( client: MockNodeClient, direct_neighbor: NodeIdentifier, @@ -23,11 +31,12 @@ def add_external_neighbor( else: client._mem_storage[direct_neighbor] = { 'nodes': {far_neighbor: {'endpoint': str(endpoint)}}, - 'peers': dict(), - 'messages': dict() + 'peers': {}, + 'messages': {} } +# pylint: disable=protected-access def add_external_peer( client: MockNodeClient, direct_neighbor: NodeIdentifier, @@ -41,41 +50,47 @@ def add_external_peer( else: client._mem_storage[direct_neighbor] = { 'peers': {peer: {'signing_key': keyring.signing, 'encryption_key': keyring.encryption}}, - 'nodes': dict(), - 'messages': dict() + 'nodes': {}, + 'messages': {} } +# pylint: disable=protected-access async def get_internal_peer(repo: MockPeerRepo, peer_identifier: PeerIdentifier) -> Peer: assert peer_identifier in repo._mem_storage, 'peer does not exist' return await repo.get(peer_identifier) +# pylint: disable=protected-access def add_internal_peer(repo: MockPeerRepo, peer_identifier: PeerIdentifier, public_key: Keyring) -> None: assert peer_identifier not in repo._mem_storage, 'peer already exists' repo._mem_storage[peer_identifier] = {'signing_key': public_key.signing, 'encryption_key': public_key.encryption} +# pylint: disable=protected-access async def get_internal_neighbor(repo: MockNodeRepo, identifier: NodeIdentifier) -> Node: assert identifier in repo._mem_storage, 'node does not exist' return await repo.get(identifier) +# pylint: disable=protected-access def add_internal_neighbor(repo: MockNodeRepo, identifier: NodeIdentifier, endpoint: EndPoint) -> None: assert identifier not in repo._mem_storage, 'node already exists' repo._mem_storage[identifier] = {'endpoint': str(endpoint)} +# pylint: disable=protected-access async def get_internal_relative_messages(repo: MockMessageRepo, identifier: PeerIdentifier) -> list[Message]: assert identifier in repo._mem_storage, 'peer does not exist' return await repo.relative_to_target(identifier) +# pylint: disable=protected-access def get_external_relative_messages(client: MockNodeClient, identifier: UniversalPeerIdentifier) -> list[Message]: assert identifier.node in client._mem_storage, 'node does not exist' assert identifier.peer in client._mem_storage[identifier.node]['peers'], 'peer does not exist' @@ -90,7 +105,7 @@ def get_external_relative_messages(client: MockNodeClient, identifier: Universal ) for obj in client._mem_storage[identifier.node]['messages'][identifier.peer] ] except KeyError: - return list() + return [] async def add_internal_message( @@ -102,6 +117,7 @@ async def add_internal_message( await repo.create(source, target, content) +# pylint: disable=protected-access def add_external_message( client: MockNodeClient, source: UniversalPeerIdentifier, @@ -112,7 +128,7 @@ def add_external_message( assert target.peer in client._mem_storage[target.node]['peers'], 'peer does not exist' if (messages := client._mem_storage[target.node]['messages'].get(target.peer)) is None: - client._mem_storage[target.node]['messages'][target.peer] = list() + client._mem_storage[target.node]['messages'][target.peer] = [] messages = client._mem_storage[target.node]['messages'][target.peer] messages.append(