tpluspy 0.2.0__tar.gz → 0.2.1__tar.gz

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.
Files changed (128) hide show
  1. {tpluspy-0.2.0 → tpluspy-0.2.1}/PKG-INFO +1 -1
  2. {tpluspy-0.2.0 → tpluspy-0.2.1}/setup.py +1 -1
  3. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/clearingengine/admin.py +13 -0
  4. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/orderbook.py +10 -4
  5. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/order.py +17 -0
  6. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/trades.py +13 -2
  7. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/user_margin.py +10 -0
  8. {tpluspy-0.2.0 → tpluspy-0.2.1}/tpluspy.egg-info/PKG-INFO +1 -1
  9. {tpluspy-0.2.0 → tpluspy-0.2.1}/README.md +0 -0
  10. {tpluspy-0.2.0 → tpluspy-0.2.1}/pyproject.toml +0 -0
  11. {tpluspy-0.2.0 → tpluspy-0.2.1}/setup.cfg +0 -0
  12. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/__init__.py +0 -0
  13. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/__init__.py +0 -0
  14. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/__main__.py +0 -0
  15. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/_context.py +0 -0
  16. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/accounts.py +0 -0
  17. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/assets.py +0 -0
  18. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/balance.py +0 -0
  19. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/debug.py +0 -0
  20. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/decimals.py +0 -0
  21. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/deposit.py +0 -0
  22. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/env.py +0 -0
  23. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/markets.py +0 -0
  24. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/orders.py +0 -0
  25. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/params.py +0 -0
  26. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/settle.py +0 -0
  27. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/sign.py +0 -0
  28. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/stream.py +0 -0
  29. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/trades.py +0 -0
  30. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/vaults.py +0 -0
  31. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/withdraw.py +0 -0
  32. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/_cli/withdrawal.py +0 -0
  33. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/cli_tools/__init__.py +0 -0
  34. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/cli_tools/options.py +0 -0
  35. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/cli_tools/output.py +0 -0
  36. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/__init__.py +0 -0
  37. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/auth.py +0 -0
  38. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/base.py +0 -0
  39. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/clearingengine/__init__.py +0 -0
  40. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/clearingengine/admin_settlement.py +0 -0
  41. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/clearingengine/assetregistry.py +0 -0
  42. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/clearingengine/base.py +0 -0
  43. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/clearingengine/decimal.py +0 -0
  44. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/clearingengine/vault.py +0 -0
  45. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/market_data.py +0 -0
  46. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/oms/__init__.py +0 -0
  47. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/oms/assetregistry.py +0 -0
  48. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/oms/oms_admin.py +0 -0
  49. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/client/withdrawal.py +0 -0
  50. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/constants.py +0 -0
  51. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/__init__.py +0 -0
  52. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/abi.py +0 -0
  53. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/address.py +0 -0
  54. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/constants.py +0 -0
  55. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/contracts.py +0 -0
  56. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/dev/__init__.py +0 -0
  57. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/dev/contracts.py +0 -0
  58. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/dev/env.py +0 -0
  59. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/dev/token.py +0 -0
  60. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/exceptions.py +0 -0
  61. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/__init__.py +0 -0
  62. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/chaindata.py +0 -0
  63. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/credential_manager.py +0 -0
  64. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/deposit.py +0 -0
  65. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/evm.py +0 -0
  66. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/registry.py +0 -0
  67. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/settle.py +0 -0
  68. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/vault.py +0 -0
  69. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/managers/withdraw.py +0 -0
  70. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/evm/utils.py +0 -0
  71. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/exceptions.py +0 -0
  72. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/logger.py +0 -0
  73. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/managers/__init__.py +0 -0
  74. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/managers/base.py +0 -0
  75. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/__init__.py +0 -0
  76. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/approval.py +0 -0
  77. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/asset_identifier.py +0 -0
  78. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/batch_order.py +0 -0
  79. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/cancel_order.py +0 -0
  80. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/chain_address.py +0 -0
  81. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/close_all_positions_preview.py +0 -0
  82. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/config.py +0 -0
  83. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/interest_rates.py +0 -0
  84. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/klines.py +0 -0
  85. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/limit_order.py +0 -0
  86. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/market.py +0 -0
  87. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/market_order.py +0 -0
  88. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/multisig.py +0 -0
  89. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/order_trigger.py +0 -0
  90. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/orderbook.py +0 -0
  91. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/position.py +0 -0
  92. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/replace_order.py +0 -0
  93. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/risk_parameters.py +0 -0
  94. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/settlement.py +0 -0
  95. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/signed_message.py +0 -0
  96. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/types.py +0 -0
  97. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/user_event.py +0 -0
  98. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/user_inventory.py +0 -0
  99. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/user_solvency.py +0 -0
  100. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/model/withdrawal.py +0 -0
  101. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/py.typed +0 -0
  102. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/types.py +0 -0
  103. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/__init__.py +0 -0
  104. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/address.py +0 -0
  105. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/amount.py +0 -0
  106. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/bytes32.py +0 -0
  107. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/decimals.py +0 -0
  108. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/domain.py +0 -0
  109. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/hex.py +0 -0
  110. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/limit_order.py +0 -0
  111. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/market_order.py +0 -0
  112. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/replace_order.py +0 -0
  113. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/serializers.py +0 -0
  114. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/signing.py +0 -0
  115. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/timeout.py +0 -0
  116. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/user/__init__.py +0 -0
  117. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/user/decrypt.py +0 -0
  118. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/user/ed_keyfile.py +0 -0
  119. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/user/manager.py +0 -0
  120. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/user/model.py +0 -0
  121. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/user/token_cache.py +0 -0
  122. {tpluspy-0.2.0 → tpluspy-0.2.1}/tplus/utils/user/validate.py +0 -0
  123. {tpluspy-0.2.0 → tpluspy-0.2.1}/tpluspy.egg-info/SOURCES.txt +0 -0
  124. {tpluspy-0.2.0 → tpluspy-0.2.1}/tpluspy.egg-info/dependency_links.txt +0 -0
  125. {tpluspy-0.2.0 → tpluspy-0.2.1}/tpluspy.egg-info/entry_points.txt +0 -0
  126. {tpluspy-0.2.0 → tpluspy-0.2.1}/tpluspy.egg-info/not-zip-safe +0 -0
  127. {tpluspy-0.2.0 → tpluspy-0.2.1}/tpluspy.egg-info/requires.txt +0 -0
  128. {tpluspy-0.2.0 → tpluspy-0.2.1}/tpluspy.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tpluspy
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: tpluspy: Client utilities for interacting with tplus
5
5
  Home-page: https://github.com/tpluslabs/tpluspy
6
6
  Author: TPlus Labs
@@ -8,7 +8,7 @@ long_description = (here / "README.md").read_text(encoding="utf-8")
8
8
 
9
9
  setup(
10
10
  name="tpluspy",
11
- version="0.2.0",
11
+ version="0.2.1",
12
12
  description="""tpluspy: Client utilities for interacting with tplus""",
13
13
  long_description=long_description,
14
14
  long_description_content_type="text/markdown",
@@ -275,6 +275,19 @@ class AdminClient(BaseClearingEngineClient):
275
275
  json_data={"fee_account": user},
276
276
  )
277
277
 
278
+ async def set_avs_backstop_target(
279
+ self, user: UserPublicKey | None, account_index: int | None = None
280
+ ):
281
+ """Configure the AVS backstop target, or clear it (disabling the
282
+ post-liquidation transfer) when ``user`` is ``None``."""
283
+ await self._post(
284
+ "admin/avs-backstop-target/modify",
285
+ json_data={"user": user, "account_index": account_index},
286
+ )
287
+
288
+ async def clear_avs_backstop_target(self):
289
+ await self.set_avs_backstop_target(None)
290
+
278
291
  async def reset_users(self):
279
292
  await self._post(
280
293
  "admin/users/reset",
@@ -184,6 +184,7 @@ class OrderBookClient(AuthenticatedClient):
184
184
  quote_quantity: int | None = None,
185
185
  fill_or_kill: bool = False,
186
186
  asset_id: AssetIdentifier | None = None,
187
+ order_id: str | None = None,
187
188
  target: TradeTarget | None = None,
188
189
  max_trading_fees_rate: int | None = None,
189
190
  trigger: OrderTrigger | None = None,
@@ -202,6 +203,8 @@ class OrderBookClient(AuthenticatedClient):
202
203
  quote_quantity: Quantity expressed in quote-asset units.
203
204
  fill_or_kill: If True, the entire order must fill or be cancelled.
204
205
  asset_id: Asset to trade.
206
+ order_id: Optional caller-supplied order id. When omitted, tpluspy
207
+ preserves its legacy generated id behavior.
205
208
  target: Optional sub-account / collateral target for the trade.
206
209
  max_trading_fees_rate: Optional maximum trading fee rate the
207
210
  caller is willing to pay (basis points; book-specific).
@@ -210,7 +213,6 @@ class OrderBookClient(AuthenticatedClient):
210
213
  ``base_quantity``.
211
214
  max_sellable_quantity: Slippage cap on base sold. Pairs with
212
215
  ``quote_quantity``.
213
-
214
216
  Returns:
215
217
  The :class:`OrderOperationResponse` from the OMS.
216
218
 
@@ -228,7 +230,7 @@ class OrderBookClient(AuthenticatedClient):
228
230
  if max_sellable_quantity is not None and quote_quantity is None:
229
231
  raise ValueError("max_sellable_quantity requires quote_quantity")
230
232
 
231
- order_id = str(base64.b64encode(uuid.uuid4().bytes).decode("ascii"))
233
+ order_id = order_id or str(base64.b64encode(uuid.uuid4().bytes).decode("ascii"))
232
234
  market = await self.get_market(asset_id_unwrapped)
233
235
  base_qty_model = (
234
236
  MarketBaseQuantity(quantity=base_quantity, max_sellable_amount=max_sellable_amount)
@@ -276,6 +278,7 @@ class OrderBookClient(AuthenticatedClient):
276
278
  side: str,
277
279
  time_in_force: GTC | GTD | IOC | None = None,
278
280
  asset_id: AssetIdentifier | None = None,
281
+ order_id: str | None = None,
279
282
  target: TradeTarget | None = None,
280
283
  max_trading_fees_rate: int | None = None,
281
284
  trigger: OrderTrigger | None = None,
@@ -290,11 +293,12 @@ class OrderBookClient(AuthenticatedClient):
290
293
  time_in_force: One of :class:`GTC`, :class:`IOC`, or :class:`GTD`.
291
294
  Defaults to GTC if omitted.
292
295
  asset_id: Asset to trade.
296
+ order_id: Optional caller-supplied order id. When omitted, tpluspy
297
+ preserves its legacy generated id behavior.
293
298
  target: Optional sub-account / collateral target for the trade.
294
299
  max_trading_fees_rate: Optional maximum trading fee rate the
295
300
  caller is willing to pay.
296
301
  trigger: Optional :class:`OrderTrigger` for conditional activation.
297
-
298
302
  Returns:
299
303
  The :class:`OrderOperationResponse` from the OMS.
300
304
 
@@ -312,6 +316,7 @@ class OrderBookClient(AuthenticatedClient):
312
316
  side,
313
317
  target,
314
318
  time_in_force,
319
+ order_id=order_id,
315
320
  max_trading_fees_rate=max_trading_fees_rate,
316
321
  trigger=trigger,
317
322
  user=user,
@@ -337,11 +342,12 @@ class OrderBookClient(AuthenticatedClient):
337
342
  time_in_force,
338
343
  max_trading_fees_rate: int | None = None,
339
344
  trigger: OrderTrigger | None = None,
345
+ order_id: str | None = None,
340
346
  user: "User | None" = None,
341
347
  ):
342
348
  user = self._resolve_user(user=user)
343
349
  asset_id_unwrapped: AssetIdentifier = asset_id # type: ignore
344
- order_id = str(base64.b64encode(uuid.uuid4().bytes).decode("ascii"))
350
+ order_id = order_id or str(base64.b64encode(uuid.uuid4().bytes).decode("ascii"))
345
351
  market = await self.get_market(asset_id_unwrapped)
346
352
  signed_message = create_limit_order_ob_request_payload(
347
353
  quantity=quantity,
@@ -170,6 +170,21 @@ class OrderCancelledEvent(BaseOrderEvent):
170
170
  reason: str | None = None
171
171
 
172
172
 
173
+ class OrderRemovedEvent(BaseOrderEvent):
174
+ event_type: Literal["REMOVED"]
175
+ order_id: str
176
+ asset_id: AssetIdentifier
177
+ user_id: str
178
+ timestamp_ns: int
179
+ operator_pubkey: str | None = None
180
+ reason: str
181
+ filled_quantity: int = 0
182
+ confirmed_quantity: int = 0
183
+ filled_amount: int = 0
184
+ confirmed_amount: int = 0
185
+ book_quantity_decimals: int = 0
186
+
187
+
173
188
  class OrderReplacedEvent(BaseOrderEvent):
174
189
  event_type: Literal["REPLACED"]
175
190
  order_id: str
@@ -204,6 +219,7 @@ OrderEvent = (
204
219
  OrderCreatedEvent
205
220
  | OrderUpdatedEvent
206
221
  | OrderCancelledEvent
222
+ | OrderRemovedEvent
207
223
  | OrderReplacedEvent
208
224
  | OrderCreateFailedEvent
209
225
  | OrderReplaceFailedEvent
@@ -215,6 +231,7 @@ _EVENT_TYPE_MODEL_MAP: dict[str, type[BaseOrderEvent]] = {
215
231
  "CREATED": OrderCreatedEvent,
216
232
  "UPDATED": OrderUpdatedEvent,
217
233
  "CANCELED": OrderCancelledEvent,
234
+ "REMOVED": OrderRemovedEvent,
218
235
  "REPLACED": OrderReplacedEvent,
219
236
  "CREATEFAILED": OrderCreateFailedEvent,
220
237
  "REPLACEFAILED": OrderReplaceFailedEvent,
@@ -29,7 +29,15 @@ class UserTrade(BaseModel):
29
29
  is_maker: bool = Field(..., description="True if this user was the maker")
30
30
  is_buyer: bool = Field(..., description="True if this user was the buyer")
31
31
  status: Literal["Pending", "Confirmed", "Rollbacked"]
32
- rollback_reason: str | None
32
+ rollback_reason: str | None = None
33
+ is_liquidation: bool = False
34
+ sub_account: int = Field(
35
+ default=0, description="Sub-account index (0=main/spot, 1=default margin)"
36
+ )
37
+ trading_fee: Decimal = Field(
38
+ default=Decimal(0),
39
+ description="Trading fee in USD; positive=paid, negative=rebate",
40
+ )
33
41
 
34
42
  @property
35
43
  def buyer_is_maker(self) -> bool:
@@ -134,7 +142,10 @@ def parse_single_user_trade(item: dict[str, Any]) -> UserTrade:
134
142
  is_maker=bool(item["is_maker"]),
135
143
  is_buyer=bool(item["is_buyer"]),
136
144
  status=item["status"],
137
- rollback_reason=item["rollback_reason"],
145
+ rollback_reason=item.get("rollback_reason"),
146
+ is_liquidation=bool(item.get("is_liquidation", False)),
147
+ sub_account=int(item.get("sub_account", 0)),
148
+ trading_fee=Decimal(str(item.get("trading_fee", 0))),
138
149
  )
139
150
  except (KeyError, ValueError, TypeError) as e:
140
151
  raise ValueError(f"Invalid user trade data: {item}") from e
@@ -25,6 +25,16 @@ class PositionSide(str, Enum):
25
25
  LONG = "Long"
26
26
  SHORT = "Short"
27
27
 
28
+ @classmethod
29
+ def _missing_(cls, value: object) -> "PositionSide | None":
30
+ # Accept lowercase values from margin read responses.
31
+ if isinstance(value, str):
32
+ folded = value.strip().lower()
33
+ for member in cls:
34
+ if member.value.lower() == folded:
35
+ return member
36
+ return None
37
+
28
38
 
29
39
  class PositionMarginInfo(BaseModel):
30
40
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tpluspy
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: tpluspy: Client utilities for interacting with tplus
5
5
  Home-page: https://github.com/tpluslabs/tpluspy
6
6
  Author: TPlus Labs
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes