trd-utils 0.0.41__py3-none-any.whl → 0.0.42__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of trd-utils might be problematic. Click here for more details.

trd_utils/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
 
2
- __version__ = "0.0.41"
2
+ __version__ = "0.0.42"
3
3
 
@@ -323,6 +323,8 @@ class BlofinClient(ExchangeBase):
323
323
  async def get_unified_trader_positions(
324
324
  self,
325
325
  uid: int | str,
326
+ no_warn: bool = False,
327
+ min_margin: Decimal = 0,
326
328
  ) -> UnifiedTraderPositions:
327
329
  result = await self.get_copy_trader_all_order_list(
328
330
  uid=uid,
@@ -343,6 +345,12 @@ class BlofinClient(ExchangeBase):
343
345
  unified_pos.open_price = position.avg_open_price
344
346
  unified_pos.open_price_unit = position.symbol.split("-")[-1]
345
347
  unified_pos.initial_margin = position.get_initial_margin()
348
+ if min_margin and (
349
+ not unified_pos.initial_margin
350
+ or unified_pos.initial_margin < min_margin
351
+ ):
352
+ continue
353
+
346
354
  unified_result.positions.append(unified_pos)
347
355
 
348
356
  return unified_result
@@ -920,6 +920,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
920
920
  uid: int | str,
921
921
  api_identity: int | str | None = None,
922
922
  no_warn: bool = False,
923
+ min_margin: Decimal = 0,
923
924
  ) -> UnifiedTraderPositions:
924
925
  perp_positions = []
925
926
  std_positions = []
@@ -930,26 +931,38 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
930
931
  result = await self.get_unified_trader_positions_perp(
931
932
  uid=uid,
932
933
  api_identity=api_identity,
934
+ min_margin=min_margin,
933
935
  )
934
936
  perp_positions = result.positions
935
937
  except Exception as ex:
938
+ err_str = f"{ex}"
939
+ if err_str.find("as the client has been closed") != -1:
940
+ raise ex
941
+
936
942
  if not no_warn:
937
- perp_ex = f"{ex}"
943
+ logger.warning(f"Failed to fetch perp positions of {uid}: {ex}")
944
+ perp_ex = ex
938
945
 
939
946
  try:
940
947
  result = await self.get_unified_trader_positions_std(
941
948
  uid=uid,
949
+ min_margin=min_margin,
942
950
  )
943
951
  std_positions = result.positions
944
952
  except Exception as ex:
953
+ err_str = f"{ex}"
954
+ if err_str.find("as the client has been closed") != -1:
955
+ raise ex
956
+
945
957
  if not no_warn:
946
- std_ex = f"{ex}"
958
+ logger.warning(f"Failed to fetch std positions of {uid}: {ex}")
959
+ std_ex = ex
947
960
 
948
961
  if not perp_positions and not std_positions:
949
- if perp_ex:
950
- logger.warning(f"Failed to fetch perp positions of {uid}: {perp_ex}")
951
- if std_ex:
952
- logger.warning(f"Failed to fetch std positions of {uid}: {std_ex}")
962
+ if perp_ex or std_ex:
963
+ raise RuntimeError(
964
+ f"Failed to fetch both std and perp positions: perp: {perp_ex}; std: {std_ex}"
965
+ )
953
966
 
954
967
  unified_result = UnifiedTraderPositions()
955
968
  unified_result.positions = perp_positions + std_positions
@@ -960,6 +973,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
960
973
  uid: int | str,
961
974
  api_identity: int | str | None = None,
962
975
  sub_account_filter: str = "futures",
976
+ min_margin: Decimal = 0,
963
977
  ) -> UnifiedTraderPositions:
964
978
  if not api_identity:
965
979
  api_identity = await self.get_trader_api_identity(
@@ -988,6 +1002,9 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
988
1002
  unified_result = UnifiedTraderPositions()
989
1003
  unified_result.positions = []
990
1004
  for position in result.data.positions:
1005
+ if min_margin and (not position.margin or position.margin < min_margin):
1006
+ continue
1007
+
991
1008
  unified_pos = UnifiedPositionInfo()
992
1009
  unified_pos.position_id = position.position_no
993
1010
  unified_pos.position_pnl = position.unrealized_pnl
@@ -1019,6 +1036,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
1019
1036
  page_offset: int = 0,
1020
1037
  page_size: int = 50,
1021
1038
  delay_amount: float = 1,
1039
+ min_margin: Decimal = 0,
1022
1040
  ) -> UnifiedTraderPositions:
1023
1041
  unified_result = UnifiedTraderPositions()
1024
1042
  unified_result.positions = []
@@ -1041,6 +1059,9 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
1041
1059
  )
1042
1060
 
1043
1061
  for position in result.data.positions:
1062
+ if min_margin and (not position.margin or position.margin < min_margin):
1063
+ continue
1064
+
1044
1065
  unified_pos = UnifiedPositionInfo()
1045
1066
  unified_pos.position_id = position.order_no
1046
1067
  unified_pos.position_pnl = (
@@ -16,14 +16,15 @@ from trd_utils.types_helper.base_model import BaseModel
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
19
- class JWTManager():
19
+
20
+ class JWTManager:
20
21
  _jwt_string: str = None
21
22
 
22
23
  def __init__(self, jwt_string: str):
23
24
  self._jwt_string = jwt_string
24
25
  try:
25
- payload_b64 = self._jwt_string.split('.')[1]
26
- payload_bytes = base64.urlsafe_b64decode(payload_b64 + '==')
26
+ payload_b64 = self._jwt_string.split(".")[1]
27
+ payload_bytes = base64.urlsafe_b64decode(payload_b64 + "==")
27
28
  self.payload = json.loads(payload_bytes)
28
29
  except Exception:
29
30
  self.payload = {}
@@ -31,9 +32,10 @@ class JWTManager():
31
32
  def is_expired(self):
32
33
  if "exp" not in self.payload:
33
34
  return False
34
-
35
+
35
36
  return time.time() > self.payload["exp"]
36
37
 
38
+
37
39
  class ExchangeBase(ABC):
38
40
  ###########################################################
39
41
  # region client parameters
@@ -82,6 +84,8 @@ class ExchangeBase(ABC):
82
84
  async def get_unified_trader_positions(
83
85
  self,
84
86
  uid: int | str,
87
+ no_warn: bool = False,
88
+ min_margin: Decimal = 0,
85
89
  ) -> UnifiedTraderPositions:
86
90
  """
87
91
  Returns the unified version of all currently open positions of the specific
@@ -1,4 +1,3 @@
1
-
2
1
  from datetime import datetime
3
2
  from decimal import Decimal
4
3
  import json
@@ -11,9 +10,15 @@ import pytz
11
10
 
12
11
  from trd_utils.cipher import AESCipher
13
12
  from trd_utils.common_utils.wallet_utils import shorten_wallet_address
14
- from trd_utils.exchanges.base_types import UnifiedPositionInfo, UnifiedTraderInfo, UnifiedTraderPositions
13
+ from trd_utils.exchanges.base_types import (
14
+ UnifiedPositionInfo,
15
+ UnifiedTraderInfo,
16
+ UnifiedTraderPositions,
17
+ )
15
18
  from trd_utils.exchanges.exchange_base import ExchangeBase
16
- from trd_utils.exchanges.hyperliquid.hyperliquid_types import TraderPositionsInfoResponse
19
+ from trd_utils.exchanges.hyperliquid.hyperliquid_types import (
20
+ TraderPositionsInfoResponse,
21
+ )
17
22
 
18
23
  logger = logging.getLogger(__name__)
19
24
 
@@ -75,7 +80,7 @@ class HyperLiquidClient(ExchangeBase):
75
80
  model_type=TraderPositionsInfoResponse,
76
81
  )
77
82
 
78
- #endregion
83
+ # endregion
79
84
  ###########################################################
80
85
  # region another-thing
81
86
  # async def get_another_thing_info(self, uid: int) -> AnotherThingInfoResponse:
@@ -151,6 +156,8 @@ class HyperLiquidClient(ExchangeBase):
151
156
  async def get_unified_trader_positions(
152
157
  self,
153
158
  uid: int | str,
159
+ no_warn: bool = False,
160
+ min_margin: Decimal = 0,
154
161
  ) -> UnifiedTraderPositions:
155
162
  result = await self.get_trader_positions_info(
156
163
  uid=uid,
@@ -159,6 +166,11 @@ class HyperLiquidClient(ExchangeBase):
159
166
  unified_result.positions = []
160
167
  for position_container in result.asset_positions:
161
168
  position = position_container.position
169
+ if min_margin and (
170
+ not position.margin_used or position.margin_used < min_margin
171
+ ):
172
+ continue
173
+
162
174
  unified_pos = UnifiedPositionInfo()
163
175
  unified_pos.position_id = position.get_position_id()
164
176
  unified_pos.position_pnl = round(position.unrealized_pnl, 3)
@@ -166,7 +178,9 @@ class HyperLiquidClient(ExchangeBase):
166
178
  unified_pos.margin_mode = position.leverage.type
167
179
  unified_pos.position_leverage = Decimal(position.leverage.value)
168
180
  unified_pos.position_pair = f"{position.coin}/USDT"
169
- unified_pos.open_time = datetime.now(pytz.UTC) # hyperliquid doesn't provide this...
181
+ unified_pos.open_time = datetime.now(
182
+ pytz.UTC
183
+ ) # hyperliquid doesn't provide this...
170
184
  unified_pos.open_price = position.entry_px
171
185
  unified_pos.open_price_unit = "USDT"
172
186
  unified_pos.initial_margin = position.margin_used
@@ -1,6 +1,11 @@
1
+
2
+ from .ultra_list import UltraList
1
3
  from .base_model import BaseModel
4
+ from .decorators import ignore_json_fields
2
5
 
3
6
 
4
7
  __all__ = [
8
+ "UltraList",
5
9
  "BaseModel",
10
+ "ignore_json_fields",
6
11
  ]
@@ -3,7 +3,6 @@ from decimal import Decimal
3
3
  import json
4
4
  from typing import (
5
5
  Union,
6
- get_type_hints,
7
6
  Any,
8
7
  get_args as get_type_args,
9
8
  )
@@ -12,6 +11,9 @@ import dateutil.parser
12
11
 
13
12
  from trd_utils.date_utils.datetime_helpers import dt_from_ts, dt_to_ts
14
13
  from trd_utils.html_utils.html_formats import camel_to_snake
14
+ from trd_utils.types_helper.model_config import ModelConfig
15
+ from trd_utils.types_helper.ultra_list import convert_to_ultra_list
16
+ from trd_utils.types_helper.utils import AbstractModel, get_my_field_types
15
17
 
16
18
  # Whether to use ultra-list instead of normal python list or not.
17
19
  # This might be convenient in some cases, but it is not recommended
@@ -24,27 +26,11 @@ ULTRA_LIST_ENABLED: bool = False
24
26
  # attribute names are converted to snake_case.
25
27
  SET_CAMEL_ATTR_NAMES = False
26
28
 
27
-
28
- def get_my_field_types(cls):
29
- type_hints = {}
30
- for current_cls in cls.__class__.__mro__:
31
- if current_cls is object or current_cls is BaseModel:
32
- break
33
- type_hints.update(get_type_hints(current_cls))
34
- return type_hints
35
-
36
-
37
- def get_real_attr(cls, attr_name):
38
- if cls is None:
39
- return None
40
-
41
- if isinstance(cls, dict):
42
- return cls.get(attr_name, None)
43
-
44
- if hasattr(cls, attr_name):
45
- return getattr(cls, attr_name)
46
-
47
- return None
29
+ # The _model_config is a special field which cannot get serialized
30
+ # nor can it get deserialized.
31
+ SPECIAL_FIELDS = [
32
+ "_model_config",
33
+ ]
48
34
 
49
35
 
50
36
  def is_base_model_type(expected_type: type) -> bool:
@@ -176,41 +162,13 @@ def generic_obj_to_value(
176
162
  raise TypeError(f"unsupported type: {type(value)}")
177
163
 
178
164
 
179
- class UltraList(list):
180
- def __getattr__(self, attr):
181
- if len(self) == 0:
182
- return None
183
- return UltraList([get_real_attr(item, attr) for item in self])
165
+ class BaseModel(AbstractModel):
166
+ _model_config: ModelConfig = None
184
167
 
185
-
186
- def convert_to_ultra_list(value: Any) -> UltraList:
187
- if not value:
188
- return UltraList()
189
-
190
- # Go through all fields of the value and convert them to
191
- # UltraList if they are lists
192
-
193
- try:
194
- if isinstance(value, list):
195
- return UltraList([convert_to_ultra_list(item) for item in value])
196
- elif isinstance(value, dict):
197
- return {k: convert_to_ultra_list(v) for k, v in value.items()}
198
- elif isinstance(value, tuple):
199
- return tuple(convert_to_ultra_list(v) for v in value)
200
- elif isinstance(value, set):
201
- return {convert_to_ultra_list(v) for v in value}
202
-
203
- for attr, attr_value in get_my_field_types(value).items():
204
- if isinstance(attr_value, list):
205
- setattr(value, attr, convert_to_ultra_list(getattr(value, attr)))
206
-
207
- return value
208
- except Exception:
209
- return value
210
-
211
-
212
- class BaseModel:
213
168
  def __init__(self, **kwargs):
169
+ if not self._model_config:
170
+ self._model_config = ModelConfig()
171
+
214
172
  annotations = get_my_field_types(self)
215
173
  for key, value in kwargs.items():
216
174
  corrected_key = key
@@ -222,6 +180,12 @@ class BaseModel:
222
180
  annotations[key] = Any
223
181
  annotations[corrected_key] = Any
224
182
 
183
+ if corrected_key in SPECIAL_FIELDS or (
184
+ self._model_config.ignored_fields
185
+ and corrected_key in self._model_config.ignored_fields
186
+ ):
187
+ continue
188
+
225
189
  expected_type = annotations[corrected_key]
226
190
  if hasattr(self, "_get_" + corrected_key + "_type"):
227
191
  try:
@@ -344,13 +308,19 @@ class BaseModel:
344
308
  annotations = get_my_field_types(self)
345
309
  result_dict = {}
346
310
  for key, _ in annotations.items():
347
- if not isinstance(key, str):
311
+ if not isinstance(key, str) or key in SPECIAL_FIELDS:
348
312
  continue
349
313
 
350
314
  if key.startswith("__") or key.startswith(f"_{self.__class__.__name__}__"):
351
315
  # ignore private attributes
352
316
  continue
353
317
 
318
+ if (
319
+ self._model_config.ignored_fields
320
+ and key in self._model_config.ignored_fields
321
+ ):
322
+ continue
323
+
354
324
  normalized_value = value_to_normal_obj(
355
325
  value=getattr(self, key),
356
326
  omit_none=omit_none,
@@ -0,0 +1,20 @@
1
+
2
+ from typing import Type, TypeVar
3
+
4
+ from trd_utils.types_helper.model_config import ModelConfig
5
+ from trd_utils.types_helper.utils import AbstractModel
6
+
7
+
8
+ T = TypeVar('T', bound=AbstractModel)
9
+
10
+ def ignore_json_fields(fields: list[str]):
11
+ def wrapper(cls: Type[T]) -> Type[T]:
12
+ config = getattr(cls, "_model_config", None)
13
+ if not config:
14
+ config = ModelConfig()
15
+
16
+ config.ignored_fields = fields.copy()
17
+ setattr(cls, "_model_config", config)
18
+ return cls
19
+ return wrapper
20
+
@@ -0,0 +1,6 @@
1
+
2
+
3
+ class ModelConfig:
4
+ ignored_fields: list[str] = None
5
+
6
+
@@ -0,0 +1,40 @@
1
+
2
+
3
+ from typing import Any
4
+ from trd_utils.types_helper.utils import get_my_field_types, get_real_attr
5
+
6
+
7
+ class UltraList(list):
8
+ def __getattr__(self, attr):
9
+ if len(self) == 0:
10
+ return None
11
+ return UltraList([get_real_attr(item, attr) for item in self])
12
+
13
+
14
+ def convert_to_ultra_list(value: Any) -> UltraList:
15
+ if not value:
16
+ return UltraList()
17
+
18
+ # Go through all fields of the value and convert them to
19
+ # UltraList if they are lists
20
+
21
+ try:
22
+ if isinstance(value, list):
23
+ return UltraList([convert_to_ultra_list(item) for item in value])
24
+ elif isinstance(value, dict):
25
+ return {k: convert_to_ultra_list(v) for k, v in value.items()}
26
+ elif isinstance(value, tuple):
27
+ return tuple(convert_to_ultra_list(v) for v in value)
28
+ elif isinstance(value, set):
29
+ return {convert_to_ultra_list(v) for v in value}
30
+
31
+ for attr, attr_value in get_my_field_types(value).items():
32
+ if isinstance(attr_value, list):
33
+ setattr(value, attr, convert_to_ultra_list(getattr(value, attr)))
34
+
35
+ return value
36
+ except Exception:
37
+ return value
38
+
39
+
40
+
@@ -0,0 +1,28 @@
1
+ from typing import (
2
+ get_type_hints,
3
+ )
4
+
5
+ class AbstractModel:
6
+ pass
7
+
8
+ def get_real_attr(cls, attr_name):
9
+ if cls is None:
10
+ return None
11
+
12
+ if isinstance(cls, dict):
13
+ return cls.get(attr_name, None)
14
+
15
+ if hasattr(cls, attr_name):
16
+ return getattr(cls, attr_name)
17
+
18
+ return None
19
+
20
+ def get_my_field_types(cls):
21
+ type_hints = {}
22
+ for current_cls in cls.__class__.__mro__:
23
+ if current_cls is object or current_cls is AbstractModel:
24
+ break
25
+ type_hints.update(get_type_hints(current_cls))
26
+ return type_hints
27
+
28
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: trd_utils
3
- Version: 0.0.41
3
+ Version: 0.0.42
4
4
  Summary: Common Basic Utils for Python3. By ALiwoto.
5
5
  Keywords: utils,trd_utils,basic-utils,common-utils
6
6
  Author: ALiwoto
@@ -1,4 +1,4 @@
1
- trd_utils/__init__.py,sha256=opeJdyFbAssqryQZxqUaYkJDAEZ8cuVWBwxBnzfUbDk,25
1
+ trd_utils/__init__.py,sha256=FTqI9urUdadYKumV6MlrQz3u1hDU-E2PPZzSEvKr-Wg,25
2
2
  trd_utils/cipher/__init__.py,sha256=V05KNuzQwCic-ihMVHlC8sENaJGc3I8MCb4pg4849X8,1765
3
3
  trd_utils/common_utils/float_utils.py,sha256=aYPwJ005LmrRhXAngojwvdDdtRgeb1FfR6hKeQ5ndMU,470
4
4
  trd_utils/common_utils/wallet_utils.py,sha256=OX9q2fymP0VfIWTRIRBP8W33cfyjLXimxMgPOsZe-3g,727
@@ -8,17 +8,17 @@ trd_utils/exchanges/README.md,sha256=8egE4IPUQ3_UtiGP6GaCg50xq_dp43aGY_X1lKcO6ok
8
8
  trd_utils/exchanges/__init__.py,sha256=sZRyp24q0KyMYASshAfsP-AfvsCADTYqqefxiRulPKE,484
9
9
  trd_utils/exchanges/base_types.py,sha256=MVZvmxmYWgYh4URGVYaalNgY57l0VJX1GC8U18tB0rE,4964
10
10
  trd_utils/exchanges/blofin/__init__.py,sha256=X4r9o4Nyjla4UeOBG8lrgtnGYO2aErFMKaJ7yQrFasE,76
11
- trd_utils/exchanges/blofin/blofin_client.py,sha256=LAAbwXbA7nDxJZFwbXtaNsIZCayEyX3SwfwYdRr3uQs,13079
11
+ trd_utils/exchanges/blofin/blofin_client.py,sha256=JVimaxGHRVviQHZbPY1gek8ICPl8-yS2AM-PRMa4_RA,13322
12
12
  trd_utils/exchanges/blofin/blofin_types.py,sha256=bQx0opCgHwcuC-5TxiVA4VQr17A1x7u7QIMdcIrROAg,4315
13
13
  trd_utils/exchanges/bx_ultra/__init__.py,sha256=8Ssy-eOemQR32Nv1-FoPHm87nRqRO4Fm2PU5GHEFKfQ,80
14
14
  trd_utils/exchanges/bx_ultra/bx_types.py,sha256=7Ga6IYHQNRDbhWXmS1J0NxpcR9HUJ8ZwQGh-1EvNRqM,36687
15
- trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=aWnJjK0KXn_250lOfm3tUk8KZbr3wq9lsRIqcuOLAJk,40196
15
+ trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=TVTdgebRLjbqo_FEz-id35ModqRRaoQvsed_52Z3ou8,40972
16
16
  trd_utils/exchanges/bx_ultra/bx_utils.py,sha256=PwapomwDW33arVmKIDj6cL-aP0ptu4BYy_lOCqSAPOo,1392
17
17
  trd_utils/exchanges/errors.py,sha256=P_NTuc389XL7rFegomP59BydWmHv8ckiGyNU-_l5qNQ,167
18
- trd_utils/exchanges/exchange_base.py,sha256=Zn5y4bymK53ENVLjYnQadS61SZKs8BGoZ4jfsY4GOcE,7835
18
+ trd_utils/exchanges/exchange_base.py,sha256=eAORzCci78b2-IrslkQnMIbzVJGb6YYzNzniCUHG-jg,7891
19
19
  trd_utils/exchanges/hyperliquid/README.md,sha256=-qaxmDt_9NTus2xRuzyFGkKgYDWgWk7ufHVTSkyn3t4,105
20
20
  trd_utils/exchanges/hyperliquid/__init__.py,sha256=QhwGRcneGFHREM-MMdYpbcx-aWdsWsu2WznHzx7LaUM,92
21
- trd_utils/exchanges/hyperliquid/hyperliquid_client.py,sha256=JC9hp-INt7oSFshsa402dsFmzEOHjnrg6NlGTxIesp8,6998
21
+ trd_utils/exchanges/hyperliquid/hyperliquid_client.py,sha256=J1NjslRkyuAiqg9xvD8Mn7n0qxHtzDWibYU-mYgeG2s,7270
22
22
  trd_utils/exchanges/hyperliquid/hyperliquid_types.py,sha256=MiGG5fRU7wHqOMtCzQXD1fwwbeUK1HEcQwW5rl-9D4c,2678
23
23
  trd_utils/exchanges/okx/__init__.py,sha256=OjVpvcwB9mrCTofLt14JRHV2-fMAzGz9-YkJAMwl6dM,67
24
24
  trd_utils/exchanges/okx/okx_client.py,sha256=3gvpF0xAGNNpYGfMeOy81yo8O2Eo-CM1BUqMibKkga8,7238
@@ -29,9 +29,13 @@ trd_utils/html_utils/html_formats.py,sha256=unKsvOiiDmYTTaM0DYZEUNLEUzWQKKrqASJX
29
29
  trd_utils/tradingview/__init__.py,sha256=H0QYb-O5qvy7qC3yswtlcSWLmeBnaS6oJ3JtjvmaV_Y,154
30
30
  trd_utils/tradingview/tradingview_client.py,sha256=g_eWYaCRQAL8Kvd-r6AnAdbH7Jha6C_GAyCuxh-RQUU,3917
31
31
  trd_utils/tradingview/tradingview_types.py,sha256=z21MXPVdWHAduEl3gSeMIRhxtBN9yK-jPYHfZSMIbSA,6144
32
- trd_utils/types_helper/__init__.py,sha256=lLbUiW1jUV1gjzTMFLthwkvF0hwauH-F_J2JZq--1U0,67
33
- trd_utils/types_helper/base_model.py,sha256=dknzoq6iAUOb0n_yhI5mU3So-F_8d5ykGk3EbrERLnM,11763
34
- trd_utils-0.0.41.dist-info/LICENSE,sha256=J1EP2xt87RjjmsTV1jTjHDQMLIM9FjdwEftTpw8hyv4,1067
35
- trd_utils-0.0.41.dist-info/METADATA,sha256=VfqukF_Pe-4dpdr8SDsCaYHHcWVdUVq50LOhH943Dgw,1179
36
- trd_utils-0.0.41.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
37
- trd_utils-0.0.41.dist-info/RECORD,,
32
+ trd_utils/types_helper/__init__.py,sha256=cVm7Pbvuow4zS9vvH4cI9TQjRjPf_d1JE15zXb6dG40,188
33
+ trd_utils/types_helper/base_model.py,sha256=5y_QHYiNu57IxYtyFpPUNA3HI9Jywryl8cyxbM5jQcI,11066
34
+ trd_utils/types_helper/decorators.py,sha256=ziQGDKV0RnhMG6gBPAz244Ug3j6ayr0iKXeucAdnXB8,527
35
+ trd_utils/types_helper/model_config.py,sha256=uvyhdGHQZ1A_I5RUbCgzlDk6MxWL6RLV8r0cdVi6nBk,60
36
+ trd_utils/types_helper/ultra_list.py,sha256=01WQSkx0G7lD9O9XcXccexniNwyuQ9LwVOeixxr4tWQ,1178
37
+ trd_utils/types_helper/utils.py,sha256=Xq4SZG4NkkGzJyOBs9huAvzl2YcCZ7ZRjfOHol3o-Kc,569
38
+ trd_utils-0.0.42.dist-info/LICENSE,sha256=J1EP2xt87RjjmsTV1jTjHDQMLIM9FjdwEftTpw8hyv4,1067
39
+ trd_utils-0.0.42.dist-info/METADATA,sha256=MdFK7xoEWa1ft1BpEwzRkyGrJNiyb-6Aw4lvYkiRzoQ,1179
40
+ trd_utils-0.0.42.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
41
+ trd_utils-0.0.42.dist-info/RECORD,,