Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor / adapts Avellaneda config map for pydantic #96

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ed33eb4
(refactor) Adapts Avellaneda config map for pydantic.
petioptrv Feb 18, 2022
d39995a
(fix) addresses a potential problem in parsing sub-models.
petioptrv Feb 18, 2022
dca2f69
(cleanup) Edited misleading comment
petioptrv Feb 18, 2022
f2124a7
Merge branch 'development' into refactor/avellaneda_config_map_pydantic
petioptrv Feb 18, 2022
e795c30
Update hummingbot/client/config/config_data_types.py
petioptrv Feb 22, 2022
2913ded
(fix) Addresses @aarmoa's PR comments
petioptrv Feb 22, 2022
7342751
Merge remote-tracking branch 'origin/refactor/avellaneda_config_map_p…
petioptrv Feb 22, 2022
ad111a7
(cleanup) Adds clarification comments to client-specific validations
petioptrv Feb 22, 2022
a15f757
Merge branch 'development' into refactor/avellaneda_config_map_pydantic
petioptrv Feb 22, 2022
f85e949
Update test/hummingbot/strategy/avellaneda_market_making/test_config.yml
petioptrv Feb 23, 2022
65b0bd7
(cleanup) Makes sub-model validators a bit more precise.
petioptrv Feb 23, 2022
344a187
Merge remote-tracking branch 'origin/refactor/avellaneda_config_map_p…
petioptrv Feb 23, 2022
e652242
(cleanup) Adds the last prompt functions as class methods to the conf…
petioptrv Feb 24, 2022
832153c
(refactor) Adapts Avellaneda config map for pydantic.
petioptrv Feb 18, 2022
c2c42e2
(fix) addresses a potential problem in parsing sub-models.
petioptrv Feb 18, 2022
71cf8db
(cleanup) Edited misleading comment
petioptrv Feb 18, 2022
d1314cb
(fix) Addresses @aarmoa's PR comments
petioptrv Feb 22, 2022
8b71afe
Update hummingbot/client/config/config_data_types.py
petioptrv Feb 22, 2022
c5301d1
(cleanup) Adds clarification comments to client-specific validations
petioptrv Feb 22, 2022
9c25a74
(cleanup) Makes sub-model validators a bit more precise.
petioptrv Feb 23, 2022
f71994a
Update test/hummingbot/strategy/avellaneda_market_making/test_config.yml
petioptrv Feb 23, 2022
0e83f33
(cleanup) Adds the last prompt functions as class methods to the conf…
petioptrv Feb 24, 2022
8e7e7ea
Merge remote-tracking branch 'origin/refactor/avellaneda_config_map_p…
petioptrv Mar 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions hummingbot/client/config/config_data_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from dataclasses import dataclass
from enum import Enum
from typing import Any, Callable, Optional

from pydantic import BaseModel
from pydantic.schema import default_ref_template

from hummingbot.client.config.config_helpers import strategy_config_schema_encoder


class ClientConfigEnum(Enum):
def __str__(self):
return self.value


@dataclass()
class ClientFieldData:
prompt: Optional[Callable[['BaseClientModel'], str]] = None
prompt_on_new: bool = False


class BaseClientModel(BaseModel):
"""
Notes on configs:
- In nested models, be weary that pydantic will take the first model that fits
(see https://pydantic-docs.helpmanual.io/usage/model_config/#smart-union).
"""
@classmethod
def schema_json(
cls, *, by_alias: bool = True, ref_template: str = default_ref_template, **dumps_kwargs: Any
) -> str:
# todo: make it ignore `client_data` all together
aarmoa marked this conversation as resolved.
Show resolved Hide resolved
return cls.__config__.json_dumps(
cls.schema(by_alias=by_alias, ref_template=ref_template),
default=strategy_config_schema_encoder,
**dumps_kwargs
)

def get_client_prompt(self, attr_name: str) -> Optional[str]:
prompt = None
client_data = self.get_client_data(attr_name)
if client_data is not None:
prompt = client_data.prompt(self)
return prompt

def get_client_data(self, attr_name: str) -> Optional[ClientFieldData]:
return self.__fields__[attr_name].field_info.extra["client_data"]
54 changes: 28 additions & 26 deletions hummingbot/client/config/config_helpers.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,31 @@
import json
import logging
import shutil
from collections import OrderedDict
from decimal import Decimal
from os import listdir, unlink
from os.path import isfile, join
from typing import Any, Callable, Dict, List, Optional

import ruamel.yaml
from os import (
unlink
)
from os.path import (
join,
isfile
)
from collections import OrderedDict
import json
from typing import (
Any,
Callable,
Dict,
List,
Optional,
)
from os import listdir
import shutil
from eth_account import Account
from pydantic import ValidationError
from pydantic.json import pydantic_encoder

from hummingbot import get_strategy_list
from hummingbot.client.config.config_var import ConfigVar
from hummingbot.client.config.global_config_map import global_config_map
from hummingbot.client.config.fee_overrides_config_map import fee_overrides_config_map
from hummingbot.client.config.global_config_map import global_config_map
from hummingbot.client.config.security import Security
from hummingbot.client.settings import (
GLOBAL_CONFIG_PATH,
TRADE_FEES_CONFIG_PATH,
TEMPLATE_PATH,
AllConnectorSettings,
CONF_FILE_PATH,
CONF_POSTFIX,
CONF_PREFIX,
AllConnectorSettings,
GLOBAL_CONFIG_PATH,
TEMPLATE_PATH,
TRADE_FEES_CONFIG_PATH,
)
from hummingbot.client.config.security import Security
from hummingbot import get_strategy_list
from eth_account import Account

# Use ruamel.yaml to preserve order and comments in .yml file
yaml_parser = ruamel.yaml.YAML()
Expand Down Expand Up @@ -456,3 +447,14 @@ def secondary_market_conversion_rate(strategy) -> Decimal:
else:
return Decimal("1")
return quote_rate / base_rate


def retrieve_validation_error_msg(e: ValidationError) -> str:
return e.errors().pop()["msg"]


def strategy_config_schema_encoder(o):
if callable(o):
return None
else:
return pydantic_encoder(o)
Loading