Skip to content
Snippets Groups Projects
Commit ba7982e3 authored by Krzysztof Mochocki's avatar Krzysztof Mochocki
Browse files

Fix legacy serialization

parent 3633b66b
No related branches found
No related tags found
No related merge requests found
Pipeline #86774 passed
......@@ -5,6 +5,7 @@ import re
from abc import ABC
from collections import defaultdict
from datetime import datetime
from enum import IntEnum
from functools import partial, wraps
from typing import (
TYPE_CHECKING,
......@@ -38,6 +39,12 @@ HandleT = TypeVar("HandleT", bound=SyncHandleT | AsyncHandleT)
RegisteredApisT = defaultdict[bool, defaultdict[str, set[str]]]
class ApiArgumentSerialization(IntEnum):
OBJECT = 0
ARRAY = 1
DOUBLE_ARRAY = 2
def _convert_pascal_case_to_sneak_case(pascal_case_input: str) -> str:
return re.sub(r"(?<!^)(?=[A-Z])", "_", pascal_case_input).lower()
......@@ -68,16 +75,18 @@ class AbstractApi(ABC, Generic[HandleT]):
def _serialize_params(self, args: Any, kwargs: dict[str, Any]) -> str:
"""Return serialized given params. Can be overloaded."""
if not self.is_keyword_only():
return AbstractApi.json_dumps()([args])
json_dumps = AbstractApi.json_dumps()
if self.argument_serialization() == ApiArgumentSerialization.ARRAY:
return json_dumps(args)
if self.argument_serialization() == ApiArgumentSerialization.DOUBLE_ARRAY:
return json_dumps([args])
prepared_kwargs = {}
for key, value in kwargs.items():
if value is not None:
prepared_kwargs[key.strip("_")] = value
return AbstractApi.json_dumps()(prepared_kwargs)
prepared_kwargs[key.strip("_")] = value
return json_dumps(prepared_kwargs)
def _verify_positional_keyword_args(self, args: Any, kwargs: dict[str, Any]) -> None:
if self.is_keyword_only():
if self.argument_serialization() == ApiArgumentSerialization.OBJECT:
assert len(args) == 0, "This api allows only keyword arguments; Ex.: foo(a=1, b=2, c=3)"
else:
assert len(kwargs) == 0, "This api allows only positional arguments; Ex.: foo(1, 2, 3)"
......@@ -105,8 +114,8 @@ class AbstractApi(ABC, Generic[HandleT]):
return pytest_is_running.is_running()
def is_keyword_only(self) -> bool:
return True
def argument_serialization(self) -> ApiArgumentSerialization:
return ApiArgumentSerialization.OBJECT
def __init__(self, owner: HandleT) -> None:
self._owner = owner
......
......@@ -145,39 +145,35 @@ def _retry_on_unable_to_acquire_database_lock( # noqa: C901
def __workaround_communication_problem_with_node( # noqa: C901
send_request: _SyncCall | _AsyncCall,
) -> Callable[..., JSONRPCResult[Any]]:
def __handle_exception(this: AbstractHandle, exception: RequestError | CommunicationError, count: int) -> int:
def __handle_exception(this: AbstractHandle, exception: RequestError | CommunicationError) -> None:
ignored_messages = [
"Unable to acquire database lock",
"Unable to acquire forkdb lock",
]
message = f"{exception}" + str(exception)
message = exception.error if isinstance(exception, RequestError) else str(exception.args)
for imsg in ignored_messages:
if imsg in message:
logger.debug(f"Ignored '{imsg}'")
if count <= this._communicator.settings.max_retries:
return count + 1
break
logger.debug(f"Ignored for {this.http_endpoint}: '{imsg}'")
return
raise exception
def sync_impl(this: AbstractHandle, *args: Any, **kwargs: Any) -> JSONRPCResult[Any]:
i = 0
while True:
try:
return send_request(*[this, *args], **kwargs) # type: ignore[return-value]
except CommunicationError as exception:
i = __handle_exception(this, exception, i)
__handle_exception(this, exception)
except RequestError as exception:
i = __handle_exception(this, exception, i)
__handle_exception(this, exception)
async def async_impl(this: AbstractHandle, *args: Any, **kwargs: Any) -> JSONRPCResult[Any]:
i = 0
while True:
try:
return await send_request(*[this, *args], **kwargs) # type: ignore[no-any-return, misc]
except CommunicationError as exception:
i = __handle_exception(this, exception, i)
__handle_exception(this, exception)
except RequestError as exception:
i = __handle_exception(this, exception, i)
__handle_exception(this, exception)
return async_impl if async_version else sync_impl # type: ignore[return-value]
......
......@@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import datetime # noqa: TCH003
from helpy._handles.abc.api import AbstractAsyncApi
from helpy._handles.abc.api import AbstractAsyncApi, ApiArgumentSerialization
from helpy._handles.hived.api.condenser_api.common import CondenserApiCommons
from schemas.apis import condenser_api # noqa: TCH001
from schemas.transaction import TransactionLegacy # noqa: TCH001
......@@ -11,8 +11,8 @@ from schemas.transaction import TransactionLegacy # noqa: TCH001
class CondenserApi(AbstractAsyncApi, CondenserApiCommons):
api = AbstractAsyncApi._endpoint
def is_keyword_only(self) -> bool:
return False
def argument_serialization(self) -> ApiArgumentSerialization:
return ApiArgumentSerialization.ARRAY
@api
async def get_version(self) -> condenser_api.GetVersion:
......
from __future__ import annotations
from typing import Any, ClassVar, Literal, TypeAlias
from typing import ClassVar, Literal, TypeAlias
from helpy._handles.abc.api import AbstractApi
from helpy._handles.hived.api.database_api.common import DatabaseApiCommons
......@@ -11,7 +10,3 @@ class CondenserApiCommons:
SORT_DIRECTION: ClassVar[TypeAlias] = DatabaseApiCommons.SORT_DIRECTION
PROPOSAL_STATUS: ClassVar[TypeAlias] = DatabaseApiCommons.PROPOSAL_STATUS
WITHDRAW_ROUTE_TYPES = Literal["incoming", "outgoing", "all"]
@classmethod
def _legacy_serialization(cls, args: list[Any]) -> str:
return AbstractApi.json_dumps()(args)
......@@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import datetime # noqa: TCH003
from helpy._handles.abc.api import AbstractSyncApi
from helpy._handles.abc.api import AbstractSyncApi, ApiArgumentSerialization
from helpy._handles.hived.api.condenser_api.common import CondenserApiCommons
from schemas.apis import condenser_api # noqa: TCH001
from schemas.transaction import TransactionLegacy # noqa: TCH001
......@@ -11,8 +11,8 @@ from schemas.transaction import TransactionLegacy # noqa: TCH001
class CondenserApi(AbstractSyncApi, CondenserApiCommons):
api = AbstractSyncApi._endpoint
def is_keyword_only(self) -> bool:
return False
def argument_serialization(self) -> ApiArgumentSerialization:
return ApiArgumentSerialization.ARRAY
@api
def get_version(self) -> condenser_api.GetVersion:
......
......@@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import datetime # noqa: TCH003
from helpy._handles.abc.api import AbstractAsyncApi
from helpy._handles.abc.api import AbstractAsyncApi, ApiArgumentSerialization
from helpy._handles.hived.api.wallet_bridge_api.common import WalletBridgeApiCommons
from helpy._interfaces.asset.asset import Hf26Asset # noqa: TCH001
from schemas.apis import wallet_bridge_api # noqa: TCH001
......@@ -12,8 +12,8 @@ from schemas.transaction import Transaction # noqa: TCH001
class WalletBridgeApi(AbstractAsyncApi, WalletBridgeApiCommons):
api = AbstractAsyncApi._endpoint
def is_keyword_only(self) -> bool:
return False
def argument_serialization(self) -> ApiArgumentSerialization:
return ApiArgumentSerialization.DOUBLE_ARRAY
@api
async def get_version(self) -> wallet_bridge_api.GetVersion:
......
from __future__ import annotations
from typing import Any, ClassVar, TypeAlias
from typing import ClassVar, TypeAlias
from helpy._handles.abc.api import AbstractApi
from helpy._handles.hived.api.condenser_api.common import CondenserApiCommons
from helpy._handles.hived.api.database_api.common import DatabaseApiCommons
......@@ -12,7 +11,3 @@ class WalletBridgeApiCommons:
SORT_DIRECTION: ClassVar[TypeAlias] = DatabaseApiCommons.SORT_DIRECTION
PROPOSAL_STATUS: ClassVar[TypeAlias] = DatabaseApiCommons.PROPOSAL_STATUS
WITHDRAW_ROUTE_TYPES: ClassVar[TypeAlias] = CondenserApiCommons.WITHDRAW_ROUTE_TYPES
@classmethod
def _legacy_serialization(cls, args: list[Any]) -> str:
return AbstractApi.json_dumps()([args])
......@@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import datetime # noqa: TCH003
from helpy._handles.abc.api import AbstractSyncApi
from helpy._handles.abc.api import AbstractSyncApi, ApiArgumentSerialization
from helpy._handles.hived.api.wallet_bridge_api.common import WalletBridgeApiCommons
from helpy._interfaces.asset.asset import Hf26Asset # noqa: TCH001
from schemas.apis import wallet_bridge_api # noqa: TCH001
......@@ -12,8 +12,8 @@ from schemas.transaction import Transaction # noqa: TCH001
class WalletBridgeApi(AbstractSyncApi, WalletBridgeApiCommons):
api = AbstractSyncApi._endpoint
def is_keyword_only(self) -> bool:
return False
def argument_serialization(self) -> ApiArgumentSerialization:
return ApiArgumentSerialization.DOUBLE_ARRAY
@api
def get_version(self) -> wallet_bridge_api.GetVersion:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment