communex._common
1import random 2import re 3import warnings 4from collections import defaultdict 5from enum import Enum 6from typing import Any, Callable, Mapping, TypeVar 7 8from pydantic import SecretStr 9from pydantic_settings import BaseSettings, SettingsConfigDict 10 11from communex.balance import from_nano 12from communex.types import Ss58Address 13 14IPFS_REGEX = re.compile(r"^Qm[1-9A-HJ-NP-Za-km-z]{44}$") 15 16 17def deprecated(func: Callable[..., Any]) -> Callable[..., Any]: 18 def wrapper(*args: Any, **kwargs: Any) -> Any: 19 warnings.warn( 20 f"The function {func.__name__} is deprecated and may be removed in a future version.", 21 DeprecationWarning, 22 ) 23 return func(*args, **kwargs) 24 25 return wrapper 26 27 28class ComxSettings(BaseSettings): 29 model_config = SettingsConfigDict(env_prefix="COMX_") 30 # TODO: improve node lists 31 NODE_URLS: list[str] = [ 32 "wss://api.communeai.net", 33 ] 34 TESTNET_NODE_URLS: list[str] = ["wss://testnet.api.communeai.net"] 35 UNIVERSAL_PASSWORD: SecretStr | None = None 36 KEY_PASSWORDS: dict[str, SecretStr] | None = None 37 38 39def get_node_url( 40 comx_settings: ComxSettings | None = None, *, use_testnet: bool = False 41) -> str: 42 comx_settings = comx_settings or ComxSettings() 43 match use_testnet: 44 case True: 45 node_url = random.choice(comx_settings.TESTNET_NODE_URLS) 46 case False: 47 node_url = random.choice(comx_settings.NODE_URLS) 48 return node_url 49 50 51def get_available_nodes( 52 comx_settings: ComxSettings | None = None, *, use_testnet: bool = False 53) -> list[str]: 54 comx_settings = comx_settings or ComxSettings() 55 56 match use_testnet: 57 case True: 58 node_urls = comx_settings.TESTNET_NODE_URLS 59 case False: 60 node_urls = comx_settings.NODE_URLS 61 return node_urls 62 63 64class BalanceUnit(str, Enum): 65 joule = "joule" 66 j = "j" 67 nano = "nano" 68 n = "n" 69 70 71def format_balance(balance: int, unit: BalanceUnit = BalanceUnit.nano) -> str: 72 """ 73 Formats a balance. 74 """ 75 76 match unit: 77 case BalanceUnit.nano | BalanceUnit.n: 78 return f"{balance}" 79 case BalanceUnit.joule | BalanceUnit.j: 80 in_joules = from_nano(balance) 81 round_joules = round(in_joules, 4) 82 return f"{round_joules:,} COMAI" 83 84 85K = TypeVar("K") 86V = TypeVar("V") 87Z = TypeVar("Z") 88 89 90def intersection_update( 91 base: dict[K, V], update: dict[K, Z] 92) -> Mapping[K, V | Z]: 93 """ 94 Update a dictionary with another dictionary, but only with keys that are already present. 95 """ 96 updated = {k: update[k] for k in base if k in update} 97 return updated 98 99 100def transform_stake_dmap( 101 stake_storage: dict[tuple[Ss58Address, Ss58Address], int], 102) -> dict[Ss58Address, list[tuple[Ss58Address, int]]]: 103 """ 104 Transforms either the StakeTo or StakeFrom storage into the stake legacy data type. 105 """ 106 transformed: dict[Ss58Address, list[tuple[Ss58Address, int]]] = defaultdict( 107 list 108 ) 109 [transformed[k1].append((k2, v)) for (k1, k2), v in stake_storage.items()] 110 111 return dict(transformed)
18def deprecated(func: Callable[..., Any]) -> Callable[..., Any]: 19 def wrapper(*args: Any, **kwargs: Any) -> Any: 20 warnings.warn( 21 f"The function {func.__name__} is deprecated and may be removed in a future version.", 22 DeprecationWarning, 23 ) 24 return func(*args, **kwargs) 25 26 return wrapper
29class ComxSettings(BaseSettings): 30 model_config = SettingsConfigDict(env_prefix="COMX_") 31 # TODO: improve node lists 32 NODE_URLS: list[str] = [ 33 "wss://api.communeai.net", 34 ] 35 TESTNET_NODE_URLS: list[str] = ["wss://testnet.api.communeai.net"] 36 UNIVERSAL_PASSWORD: SecretStr | None = None 37 KEY_PASSWORDS: dict[str, SecretStr] | None = None
Base class for settings, allowing values to be overridden by environment variables.
This is useful in production for secrets you do not wish to save in code, it plays nicely with docker(-compose), Heroku and any 12 factor app design.
All the below attributes can be set via model_config
.
Arguments:
- _case_sensitive: Whether environment variables names should be read with case-sensitivity. Defaults to
None
. - _env_prefix: Prefix for all environment variables. Defaults to
None
. - _env_file: The env file(s) to load settings values from. Defaults to
Path('')
, which means that the value frommodel_config['env_file']
should be used. You can also passNone
to indicate that environment variables should not be loaded from an env file. - _env_file_encoding: The env file encoding, e.g.
'latin-1'
. Defaults toNone
. - _env_ignore_empty: Ignore environment variables where the value is an empty string. Default to
False
. - _env_nested_delimiter: The nested env values delimiter. Defaults to
None
. - _env_parse_none_str: The env string value that should be parsed (e.g. "null", "void", "None", etc.)
into
None
type(None). Defaults toNone
type(None), which means no parsing should occur. - _env_parse_enums: Parse enum field names to values. Defaults to
None.
, which means no parsing should occur. - _cli_prog_name: The CLI program name to display in help text. Defaults to
None
if _cli_parse_args isNone
. Otherwse, defaults to sys.argv[0]. - _cli_parse_args: The list of CLI arguments to parse. Defaults to None.
If set to
True
, defaults to sys.argv[1:]. - _cli_settings_source: Override the default CLI settings source with a user defined instance. Defaults to None.
- _cli_parse_none_str: The CLI string value that should be parsed (e.g. "null", "void", "None", etc.) into
None
type(None). Defaults to _env_parse_none_str value if set. Otherwise, defaults to "null" if _cli_avoid_json isFalse
, and "None" if _cli_avoid_json isTrue
. - _cli_hide_none_type: Hide
None
values in CLI help text. Defaults toFalse
. - _cli_avoid_json: Avoid complex JSON objects in CLI help text. Defaults to
False
. - _cli_enforce_required: Enforce required fields at the CLI. Defaults to
False
. - _cli_use_class_docs_for_groups: Use class docstrings in CLI group help text instead of field descriptions.
Defaults to
False
. - _cli_prefix: The root parser command line arguments prefix. Defaults to "".
- _secrets_dir: The secret files directory. Defaults to
None
.
Inherited Members
- pydantic_settings.main.BaseSettings
- BaseSettings
- settings_customise_sources
- pydantic.main.BaseModel
- model_extra
- model_fields_set
- model_construct
- model_copy
- model_dump
- model_dump_json
- model_json_schema
- model_parametrized_name
- model_post_init
- model_rebuild
- model_validate
- model_validate_json
- model_validate_strings
- dict
- json
- parse_obj
- parse_raw
- parse_file
- from_orm
- construct
- copy
- schema
- schema_json
- validate
- update_forward_refs
40def get_node_url( 41 comx_settings: ComxSettings | None = None, *, use_testnet: bool = False 42) -> str: 43 comx_settings = comx_settings or ComxSettings() 44 match use_testnet: 45 case True: 46 node_url = random.choice(comx_settings.TESTNET_NODE_URLS) 47 case False: 48 node_url = random.choice(comx_settings.NODE_URLS) 49 return node_url
52def get_available_nodes( 53 comx_settings: ComxSettings | None = None, *, use_testnet: bool = False 54) -> list[str]: 55 comx_settings = comx_settings or ComxSettings() 56 57 match use_testnet: 58 case True: 59 node_urls = comx_settings.TESTNET_NODE_URLS 60 case False: 61 node_urls = comx_settings.NODE_URLS 62 return node_urls
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- removeprefix
- removesuffix
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
72def format_balance(balance: int, unit: BalanceUnit = BalanceUnit.nano) -> str: 73 """ 74 Formats a balance. 75 """ 76 77 match unit: 78 case BalanceUnit.nano | BalanceUnit.n: 79 return f"{balance}" 80 case BalanceUnit.joule | BalanceUnit.j: 81 in_joules = from_nano(balance) 82 round_joules = round(in_joules, 4) 83 return f"{round_joules:,} COMAI"
Formats a balance.
91def intersection_update( 92 base: dict[K, V], update: dict[K, Z] 93) -> Mapping[K, V | Z]: 94 """ 95 Update a dictionary with another dictionary, but only with keys that are already present. 96 """ 97 updated = {k: update[k] for k in base if k in update} 98 return updated
Update a dictionary with another dictionary, but only with keys that are already present.
101def transform_stake_dmap( 102 stake_storage: dict[tuple[Ss58Address, Ss58Address], int], 103) -> dict[Ss58Address, list[tuple[Ss58Address, int]]]: 104 """ 105 Transforms either the StakeTo or StakeFrom storage into the stake legacy data type. 106 """ 107 transformed: dict[Ss58Address, list[tuple[Ss58Address, int]]] = defaultdict( 108 list 109 ) 110 [transformed[k1].append((k2, v)) for (k1, k2), v in stake_storage.items()] 111 112 return dict(transformed)
Transforms either the StakeTo or StakeFrom storage into the stake legacy data type.