compass_api_sdk 1.1.1__py3-none-any.whl → 2.0.21rc1__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.
Files changed (248) hide show
  1. compass_api_sdk/_hooks/sdkhooks.py +4 -4
  2. compass_api_sdk/_hooks/types.py +1 -2
  3. compass_api_sdk/_version.py +3 -3
  4. compass_api_sdk/aave_v3.py +386 -114
  5. compass_api_sdk/aerodrome_slipstream.py +104 -54
  6. compass_api_sdk/basesdk.py +6 -0
  7. compass_api_sdk/bridge.py +536 -0
  8. compass_api_sdk/earn.py +1780 -0
  9. compass_api_sdk/erc_4626_vaults.py +28 -10
  10. compass_api_sdk/errors/__init__.py +8 -0
  11. compass_api_sdk/errors/apierror.py +1 -1
  12. compass_api_sdk/errors/compassapierror.py +1 -1
  13. compass_api_sdk/errors/httpvalidationerror.py +1 -1
  14. compass_api_sdk/errors/mintpreparenotfoundresponse_error.py +49 -0
  15. compass_api_sdk/errors/no_response_error.py +1 -1
  16. compass_api_sdk/errors/responsevalidationerror.py +1 -1
  17. compass_api_sdk/ethena.py +36 -10
  18. compass_api_sdk/gas_sponsorship.py +446 -0
  19. compass_api_sdk/httpclient.py +0 -1
  20. compass_api_sdk/models/__init__.py +764 -392
  21. compass_api_sdk/models/aaveborrowparams.py +4 -13
  22. compass_api_sdk/models/aaveborrowrequest.py +10 -14
  23. compass_api_sdk/models/aavehistoricaltransactionsresponse.py +3 -3
  24. compass_api_sdk/models/aavelooprequest.py +32 -28
  25. compass_api_sdk/models/aaveposition.py +49 -0
  26. compass_api_sdk/models/aaverepayparams.py +4 -13
  27. compass_api_sdk/models/aaverepayrequest.py +10 -14
  28. compass_api_sdk/models/aavesetuseremodeparams.py +28 -0
  29. compass_api_sdk/models/aavesetuseremoderequest.py +48 -0
  30. compass_api_sdk/models/aavesupplyparams.py +4 -13
  31. compass_api_sdk/models/aavesupplyrequest.py +10 -14
  32. compass_api_sdk/models/aavevenue.py +27 -0
  33. compass_api_sdk/models/aavewithdrawparams.py +4 -13
  34. compass_api_sdk/models/aavewithdrawrequest.py +10 -14
  35. compass_api_sdk/models/aerodromeenrichedposition.py +109 -0
  36. compass_api_sdk/models/aerodromelppositionsresponse.py +10 -7
  37. compass_api_sdk/models/aerodromeslipstreambuyexactlyparams.py +8 -25
  38. compass_api_sdk/models/aerodromeslipstreambuyexactlyrequest.py +14 -26
  39. compass_api_sdk/models/aerodromeslipstreamincreaseliquidityprovisionrequest.py +6 -1
  40. compass_api_sdk/models/aerodromeslipstreammintliquidityprovisionparams.py +8 -25
  41. compass_api_sdk/models/aerodromeslipstreammintliquidityprovisionrequest.py +14 -26
  42. compass_api_sdk/models/aerodromeslipstreampoolpriceresponse.py +8 -25
  43. compass_api_sdk/models/aerodromeslipstreamsellexactlyparams.py +8 -25
  44. compass_api_sdk/models/aerodromeslipstreamsellexactlyrequest.py +13 -25
  45. compass_api_sdk/models/aerodromeslipstreamwithdrawliquidityprovisionrequest.py +6 -1
  46. compass_api_sdk/models/approvetransferrequest.py +32 -0
  47. compass_api_sdk/models/approvetransferresponse.py +52 -0
  48. compass_api_sdk/models/batchedsafeoperationsresponse_input.py +52 -0
  49. compass_api_sdk/models/batchedsafeoperationsresponse_output.py +52 -0
  50. compass_api_sdk/models/batcheduseroperationsrequest.py +15 -4
  51. compass_api_sdk/models/chainmarketinfo.py +29 -0
  52. compass_api_sdk/models/{compass_api_backend_models_generic_read_response_portfolio_tokenbalance.py → compass_api_backend_v1_models_generic_read_response_portfolio_tokenbalance.py} +6 -15
  53. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_check_user_position_apydata.py → compass_api_backend_v1_models_morpho_read_response_check_user_position_apydata.py} +2 -2
  54. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_check_user_position_asset.py → compass_api_backend_v1_models_morpho_read_response_check_user_position_asset.py} +2 -2
  55. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_check_user_position_marketstate.py → compass_api_backend_v1_models_morpho_read_response_check_user_position_marketstate.py} +4 -2
  56. compass_api_sdk/models/compass_api_backend_v1_models_morpho_read_response_check_user_position_vaultposition.py +30 -0
  57. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_check_user_position_vaultstate.py → compass_api_backend_v1_models_morpho_read_response_check_user_position_vaultstate.py} +2 -2
  58. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_get_market_apydata.py → compass_api_backend_v1_models_morpho_read_response_get_market_apydata.py} +2 -2
  59. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_get_market_asset.py → compass_api_backend_v1_models_morpho_read_response_get_market_asset.py} +5 -5
  60. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_get_market_marketstate.py → compass_api_backend_v1_models_morpho_read_response_get_market_marketstate.py} +4 -2
  61. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_get_markets_asset.py → compass_api_backend_v1_models_morpho_read_response_get_markets_asset.py} +2 -2
  62. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_get_markets_marketstate.py → compass_api_backend_v1_models_morpho_read_response_get_markets_marketstate.py} +2 -2
  63. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_get_vaults_asset.py → compass_api_backend_v1_models_morpho_read_response_get_vaults_asset.py} +2 -2
  64. compass_api_sdk/models/{compass_api_backend_models_morpho_read_response_get_vaults_vaultstate.py → compass_api_backend_v1_models_morpho_read_response_get_vaults_vaultstate.py} +4 -2
  65. compass_api_sdk/models/{compass_api_backend_models_pendle_read_response_market_userposition.py → compass_api_backend_v1_models_pendle_read_response_market_userposition.py} +2 -2
  66. compass_api_sdk/models/{compass_api_backend_models_pendle_read_response_positions_tokenbalance.py → compass_api_backend_v1_models_pendle_read_response_positions_tokenbalance.py} +2 -2
  67. compass_api_sdk/models/{compass_api_backend_models_vaults_read_response_vault_userposition.py → compass_api_backend_v1_models_vaults_read_response_vault_userposition.py} +2 -2
  68. compass_api_sdk/models/compass_api_backend_v1_models_wildcat_read_response_market_userposition.py +22 -0
  69. compass_api_sdk/models/compass_api_backend_v2_models_earn_read_response_positions_vaultposition.py +49 -0
  70. compass_api_sdk/models/compass_api_backend_v2_models_gas_sponsorship_permit_2_typed_data_eip712domain.py +36 -0
  71. compass_api_sdk/models/compass_api_backend_v2_models_gas_sponsorship_permit_2_typed_data_eip712types.py +36 -0
  72. compass_api_sdk/models/compass_api_backend_v2_models_gas_sponsorship_permit_typed_data_eip712domain.py +37 -0
  73. compass_api_sdk/models/compass_api_backend_v2_models_gas_sponsorship_permit_typed_data_eip712types.py +32 -0
  74. compass_api_sdk/models/compass_api_backend_v2_models_safe_transact_response_batched_safe_operations_eip712domain.py +29 -0
  75. compass_api_sdk/models/compass_api_backend_v2_models_safe_transact_response_batched_safe_operations_eip712types.py +34 -0
  76. compass_api_sdk/models/createaccountrequest.py +40 -0
  77. compass_api_sdk/models/createaccountresponse.py +56 -0
  78. compass_api_sdk/models/depositforburnrequest.py +77 -0
  79. compass_api_sdk/models/depositforburnresponse.py +100 -0
  80. compass_api_sdk/models/earnmanageparams.py +74 -0
  81. compass_api_sdk/models/earnmanagerequest.py +130 -0
  82. compass_api_sdk/models/earnmanageresponse.py +52 -0
  83. compass_api_sdk/models/earnpositionsresponse.py +39 -0
  84. compass_api_sdk/models/earnswapparams.py +74 -0
  85. compass_api_sdk/models/earnswaprequest.py +90 -0
  86. compass_api_sdk/models/earnswapresponse.py +55 -0
  87. compass_api_sdk/models/earntransferrequest.py +104 -0
  88. compass_api_sdk/models/earntransferresponse.py +71 -0
  89. compass_api_sdk/models/eip712domainfield.py +20 -0
  90. compass_api_sdk/models/eip712field.py +20 -0
  91. compass_api_sdk/models/ethenadepositrequest.py +6 -1
  92. compass_api_sdk/models/ethenagetvaultresponse.py +5 -5
  93. compass_api_sdk/models/ethenarequesttowithdrawrequest.py +6 -1
  94. compass_api_sdk/models/ethenaunstakerequest.py +6 -1
  95. compass_api_sdk/models/fee.py +42 -0
  96. compass_api_sdk/models/listaavemarketsresponse.py +21 -0
  97. compass_api_sdk/models/marketposition.py +5 -5
  98. compass_api_sdk/models/maxsupplyapyinfo.py +34 -0
  99. compass_api_sdk/models/mintpreparecompletedresponse.py +46 -0
  100. compass_api_sdk/models/mintpreparependingresponse.py +65 -0
  101. compass_api_sdk/models/mintpreparereadyresponse.py +43 -0
  102. compass_api_sdk/models/mintpreparerequest.py +25 -0
  103. compass_api_sdk/models/morphoborrowrequest.py +6 -1
  104. compass_api_sdk/models/morphocheckuserpositionresponse.py +9 -3
  105. compass_api_sdk/models/morphodepositrequest.py +6 -1
  106. compass_api_sdk/models/morphogetmarketresponse.py +72 -31
  107. compass_api_sdk/models/morphomarket.py +26 -20
  108. compass_api_sdk/models/morphorepayrequest.py +11 -1
  109. compass_api_sdk/models/morphosupplycollateralrequest.py +11 -1
  110. compass_api_sdk/models/morphovault.py +10 -10
  111. compass_api_sdk/models/morphowithdrawcollateralrequest.py +6 -1
  112. compass_api_sdk/models/morphowithdrawrequest.py +6 -1
  113. compass_api_sdk/models/multicallexecuterequest.py +7 -2
  114. compass_api_sdk/models/odosswapparams.py +9 -30
  115. compass_api_sdk/models/odosswaprequest.py +15 -33
  116. compass_api_sdk/models/oneinchswapparams.py +59 -0
  117. compass_api_sdk/models/openposition.py +7 -7
  118. compass_api_sdk/models/operationtype.py +11 -0
  119. compass_api_sdk/models/pendlegetmarketresponse.py +5 -5
  120. compass_api_sdk/models/pendlemanageliquidityparams.py +2 -15
  121. compass_api_sdk/models/pendlemanageliquidityrequest.py +8 -16
  122. compass_api_sdk/models/pendleredeemyieldrequest.py +6 -1
  123. compass_api_sdk/models/pendletradeptparams.py +2 -15
  124. compass_api_sdk/models/pendletradeptrequest.py +8 -16
  125. compass_api_sdk/models/pendletradeytparams.py +2 -15
  126. compass_api_sdk/models/pendletradeytrequest.py +8 -16
  127. compass_api_sdk/models/permit2typeddata_input.py +46 -0
  128. compass_api_sdk/models/permit2typeddata_output.py +46 -0
  129. compass_api_sdk/models/permitfield.py +20 -0
  130. compass_api_sdk/models/permitmessage.py +39 -0
  131. compass_api_sdk/models/permittransferfrommessage.py +29 -0
  132. compass_api_sdk/models/permittypeddataresponse_input.py +50 -0
  133. compass_api_sdk/models/permittypeddataresponse_output.py +50 -0
  134. compass_api_sdk/models/portfolio.py +5 -5
  135. compass_api_sdk/models/reserve.py +6 -15
  136. compass_api_sdk/models/safetransactionparams.py +78 -0
  137. compass_api_sdk/models/safetransactionresponse.py +28 -0
  138. compass_api_sdk/models/safetxfield.py +20 -0
  139. compass_api_sdk/models/safetxmessage.py +66 -0
  140. compass_api_sdk/models/setallowanceparams.py +3 -16
  141. compass_api_sdk/models/setallowancerequest.py +9 -17
  142. compass_api_sdk/models/skybuyrequest.py +6 -1
  143. compass_api_sdk/models/skydepositrequest.py +7 -2
  144. compass_api_sdk/models/skysellrequest.py +7 -2
  145. compass_api_sdk/models/skywithdrawrequest.py +7 -2
  146. compass_api_sdk/models/sponsorgasrequest.py +71 -0
  147. compass_api_sdk/models/sponsorgasresponse.py +14 -0
  148. compass_api_sdk/models/tokenbalanceresponse.py +5 -15
  149. compass_api_sdk/models/tokenconfig.py +30 -0
  150. compass_api_sdk/models/tokenlistresponse.py +21 -0
  151. compass_api_sdk/models/tokenmarketdata.py +27 -0
  152. compass_api_sdk/models/tokenpermissions.py +20 -0
  153. compass_api_sdk/models/tokentransferparams.py +2 -15
  154. compass_api_sdk/models/tokentransferrequest.py +8 -16
  155. compass_api_sdk/models/uniswapbuyexactlyparams.py +8 -33
  156. compass_api_sdk/models/uniswapbuyexactlyrequest.py +14 -34
  157. compass_api_sdk/models/uniswapincreaseliquidityprovisionrequest.py +6 -1
  158. compass_api_sdk/models/uniswapmintliquidityprovisionparams.py +8 -25
  159. compass_api_sdk/models/uniswapmintliquidityprovisionrequest.py +14 -26
  160. compass_api_sdk/models/uniswappoolpriceresponse.py +8 -25
  161. compass_api_sdk/models/uniswapsellexactlyparams.py +4 -29
  162. compass_api_sdk/models/uniswapsellexactlyrequest.py +10 -30
  163. compass_api_sdk/models/uniswapwithdrawliquidityprovisionrequest.py +6 -1
  164. compass_api_sdk/models/unsignedmulticalltransaction.py +34 -3
  165. compass_api_sdk/models/unsignedtransaction.py +34 -3
  166. compass_api_sdk/models/unwrapwethrequest.py +6 -1
  167. compass_api_sdk/models/useroperation.py +33 -24
  168. compass_api_sdk/models/v1_aave_aave_supported_tokensop.py +1 -1
  169. compass_api_sdk/models/v1_aave_avg_rateop.py +15 -93
  170. compass_api_sdk/models/v1_aave_historical_transactionsop.py +15 -15
  171. compass_api_sdk/models/v1_aave_liquidity_changeop.py +8 -86
  172. compass_api_sdk/models/v1_aave_rateop.py +8 -86
  173. compass_api_sdk/models/v1_aave_reserve_overviewop.py +8 -86
  174. compass_api_sdk/models/v1_aave_std_rateop.py +15 -93
  175. compass_api_sdk/models/v1_aave_token_priceop.py +8 -86
  176. compass_api_sdk/models/v1_aave_user_position_per_tokenop.py +14 -92
  177. compass_api_sdk/models/v1_aave_user_position_summaryop.py +8 -8
  178. compass_api_sdk/models/v1_aerodrome_slipstream_liquidity_provision_positionsop.py +48 -3
  179. compass_api_sdk/models/v1_aerodrome_slipstream_pool_priceop.py +12 -168
  180. compass_api_sdk/models/v1_ethena_vaultop.py +1 -1
  181. compass_api_sdk/models/v1_generic_allowanceop.py +12 -26
  182. compass_api_sdk/models/v1_generic_ensop.py +2 -2
  183. compass_api_sdk/models/v1_generic_portfolioop.py +2 -2
  184. compass_api_sdk/models/v1_morpho_market_positionop.py +3 -3
  185. compass_api_sdk/models/v1_morpho_marketop.py +2 -2
  186. compass_api_sdk/models/v1_morpho_marketsop.py +10 -30
  187. compass_api_sdk/models/v1_morpho_user_positionop.py +2 -2
  188. compass_api_sdk/models/v1_morpho_vaultop.py +8 -8
  189. compass_api_sdk/models/v1_morpho_vaultsop.py +6 -16
  190. compass_api_sdk/models/v1_pendle_marketop.py +8 -8
  191. compass_api_sdk/models/v1_pendle_marketsop.py +1 -1
  192. compass_api_sdk/models/v1_pendle_positionsop.py +2 -2
  193. compass_api_sdk/models/v1_sky_positionop.py +5 -6
  194. compass_api_sdk/models/v1_token_balanceop.py +12 -25
  195. compass_api_sdk/models/{v1_generic_supported_tokensop.py → v1_token_listop.py} +6 -6
  196. compass_api_sdk/models/v1_token_priceop.py +8 -9
  197. compass_api_sdk/models/v1_transaction_bundler_aave_loopop.py +6 -6
  198. compass_api_sdk/models/v1_uniswap_liquidity_provision_in_rangeop.py +2 -2
  199. compass_api_sdk/models/v1_uniswap_liquidity_provision_positionsop.py +2 -2
  200. compass_api_sdk/models/v1_uniswap_pool_priceop.py +12 -168
  201. compass_api_sdk/models/v1_uniswap_quote_buy_exactlyop.py +20 -176
  202. compass_api_sdk/models/v1_uniswap_quote_sell_exactlyop.py +20 -176
  203. compass_api_sdk/models/v1_vaults_vaultop.py +8 -8
  204. compass_api_sdk/models/v1_wildcat_marketop.py +82 -0
  205. compass_api_sdk/models/v2_cctp_mintop.py +47 -0
  206. compass_api_sdk/models/v2_earn_aave_marketsop.py +57 -0
  207. compass_api_sdk/models/v2_earn_positionsop.py +56 -0
  208. compass_api_sdk/models/v2_earn_vaultsop.py +105 -0
  209. compass_api_sdk/models/v2bundlerequest.py +33 -0
  210. compass_api_sdk/models/v2bundleresponse.py +67 -0
  211. compass_api_sdk/models/v2useroperation.py +37 -0
  212. compass_api_sdk/models/vault.py +14 -14
  213. compass_api_sdk/models/vaultdepositrequest.py +6 -1
  214. compass_api_sdk/models/vaultgetvaultresponse.py +5 -5
  215. compass_api_sdk/models/vaultinfo.py +129 -0
  216. compass_api_sdk/models/vaultsresponse.py +30 -0
  217. compass_api_sdk/models/vaultvenue.py +27 -0
  218. compass_api_sdk/models/vaultwithdrawrequest.py +6 -1
  219. compass_api_sdk/models/wildcatgetmarketresponse.py +151 -0
  220. compass_api_sdk/models/{redeemunderlying.py → withdraw.py} +2 -2
  221. compass_api_sdk/models/wrapethrequest.py +6 -1
  222. compass_api_sdk/morpho.py +126 -78
  223. compass_api_sdk/pendle.py +68 -44
  224. compass_api_sdk/sdk.py +18 -11
  225. compass_api_sdk/sky.py +62 -38
  226. compass_api_sdk/smart_account.py +10 -2
  227. compass_api_sdk/swap.py +22 -22
  228. compass_api_sdk/{token_sdk.py → token.py} +511 -103
  229. compass_api_sdk/transaction_bundler.py +46 -16
  230. compass_api_sdk/uniswap_v3.py +152 -114
  231. compass_api_sdk/universal.py +44 -606
  232. compass_api_sdk/utils/annotations.py +32 -8
  233. compass_api_sdk/utils/forms.py +21 -10
  234. compass_api_sdk/utils/queryparams.py +14 -2
  235. compass_api_sdk/utils/retries.py +69 -5
  236. compass_api_sdk/utils/unmarshal_json_response.py +15 -1
  237. compass_api_sdk/wildcat.py +208 -0
  238. compass_api_sdk-2.0.21rc1.dist-info/METADATA +623 -0
  239. compass_api_sdk-2.0.21rc1.dist-info/RECORD +346 -0
  240. {compass_api_sdk-1.1.1.dist-info → compass_api_sdk-2.0.21rc1.dist-info}/WHEEL +1 -1
  241. compass_api_sdk/models/aerodromeposition.py +0 -70
  242. compass_api_sdk/models/token_enum.py +0 -81
  243. compass_api_sdk/models/tokenaddressresponse.py +0 -15
  244. compass_api_sdk/models/tokeninfo.py +0 -17
  245. compass_api_sdk/models/v1_token_addressop.py +0 -109
  246. compass_api_sdk/models/vaultposition.py +0 -24
  247. compass_api_sdk-1.1.1.dist-info/METADATA +0 -592
  248. compass_api_sdk-1.1.1.dist-info/RECORD +0 -275
@@ -3,6 +3,7 @@
3
3
  from enum import Enum
4
4
  from typing import Any, Optional
5
5
 
6
+
6
7
  def get_discriminator(model: Any, fieldname: str, key: str) -> str:
7
8
  """
8
9
  Recursively search for the discriminator attribute in a model.
@@ -25,31 +26,54 @@ def get_discriminator(model: Any, fieldname: str, key: str) -> str:
25
26
 
26
27
  if isinstance(field, dict):
27
28
  if key in field:
28
- return f'{field[key]}'
29
+ return f"{field[key]}"
29
30
 
30
31
  if hasattr(field, fieldname):
31
32
  attr = getattr(field, fieldname)
32
33
  if isinstance(attr, Enum):
33
- return f'{attr.value}'
34
- return f'{attr}'
34
+ return f"{attr.value}"
35
+ return f"{attr}"
35
36
 
36
37
  if hasattr(field, upper_fieldname):
37
38
  attr = getattr(field, upper_fieldname)
38
39
  if isinstance(attr, Enum):
39
- return f'{attr.value}'
40
- return f'{attr}'
40
+ return f"{attr.value}"
41
+ return f"{attr}"
41
42
 
42
43
  return None
43
44
 
45
+ def search_nested_discriminator(obj: Any) -> Optional[str]:
46
+ """Recursively search for discriminator in nested structures."""
47
+ # First try direct field lookup
48
+ discriminator = get_field_discriminator(obj)
49
+ if discriminator is not None:
50
+ return discriminator
51
+
52
+ # If it's a dict, search in nested values
53
+ if isinstance(obj, dict):
54
+ for value in obj.values():
55
+ if isinstance(value, list):
56
+ # Search in list items
57
+ for item in value:
58
+ nested_discriminator = search_nested_discriminator(item)
59
+ if nested_discriminator is not None:
60
+ return nested_discriminator
61
+ elif isinstance(value, dict):
62
+ # Search in nested dict
63
+ nested_discriminator = search_nested_discriminator(value)
64
+ if nested_discriminator is not None:
65
+ return nested_discriminator
66
+
67
+ return None
44
68
 
45
69
  if isinstance(model, list):
46
70
  for field in model:
47
- discriminator = get_field_discriminator(field)
71
+ discriminator = search_nested_discriminator(field)
48
72
  if discriminator is not None:
49
73
  return discriminator
50
74
 
51
- discriminator = get_field_discriminator(model)
75
+ discriminator = search_nested_discriminator(model)
52
76
  if discriminator is not None:
53
77
  return discriminator
54
78
 
55
- raise ValueError(f'Could not find discriminator field {fieldname} in {model}')
79
+ raise ValueError(f"Could not find discriminator field {fieldname} in {model}")
@@ -142,16 +142,21 @@ def serialize_multipart_form(
142
142
  if field_metadata.file:
143
143
  if isinstance(val, List):
144
144
  # Handle array of files
145
+ array_field_name = f_name + "[]"
145
146
  for file_obj in val:
146
147
  if not _is_set(file_obj):
147
148
  continue
148
-
149
- file_name, content, content_type = _extract_file_properties(file_obj)
149
+
150
+ file_name, content, content_type = _extract_file_properties(
151
+ file_obj
152
+ )
150
153
 
151
154
  if content_type is not None:
152
- files.append((f_name + "[]", (file_name, content, content_type)))
155
+ files.append(
156
+ (array_field_name, (file_name, content, content_type))
157
+ )
153
158
  else:
154
- files.append((f_name + "[]", (file_name, content)))
159
+ files.append((array_field_name, (file_name, content)))
155
160
  else:
156
161
  # Handle single file
157
162
  file_name, content, content_type = _extract_file_properties(val)
@@ -161,11 +166,16 @@ def serialize_multipart_form(
161
166
  else:
162
167
  files.append((f_name, (file_name, content)))
163
168
  elif field_metadata.json:
164
- files.append((f_name, (
165
- None,
166
- marshal_json(val, request_field_types[name]),
167
- "application/json",
168
- )))
169
+ files.append(
170
+ (
171
+ f_name,
172
+ (
173
+ None,
174
+ marshal_json(val, request_field_types[name]),
175
+ "application/json",
176
+ ),
177
+ )
178
+ )
169
179
  else:
170
180
  if isinstance(val, List):
171
181
  values = []
@@ -175,7 +185,8 @@ def serialize_multipart_form(
175
185
  continue
176
186
  values.append(_val_to_string(value))
177
187
 
178
- form[f_name + "[]"] = values
188
+ array_field_name = f_name + "[]"
189
+ form[array_field_name] = values
179
190
  else:
180
191
  form[f_name] = _val_to_string(val)
181
192
  return media_type, form, files
@@ -27,12 +27,13 @@ from .forms import _populate_form
27
27
  def get_query_params(
28
28
  query_params: Any,
29
29
  gbls: Optional[Any] = None,
30
+ allow_empty_value: Optional[List[str]] = None,
30
31
  ) -> Dict[str, List[str]]:
31
32
  params: Dict[str, List[str]] = {}
32
33
 
33
- globals_already_populated = _populate_query_params(query_params, gbls, params, [])
34
+ globals_already_populated = _populate_query_params(query_params, gbls, params, [], allow_empty_value)
34
35
  if _is_set(gbls):
35
- _populate_query_params(gbls, None, params, globals_already_populated)
36
+ _populate_query_params(gbls, None, params, globals_already_populated, allow_empty_value)
36
37
 
37
38
  return params
38
39
 
@@ -42,6 +43,7 @@ def _populate_query_params(
42
43
  gbls: Any,
43
44
  query_param_values: Dict[str, List[str]],
44
45
  skip_fields: List[str],
46
+ allow_empty_value: Optional[List[str]] = None,
45
47
  ) -> List[str]:
46
48
  globals_already_populated: List[str] = []
47
49
 
@@ -69,6 +71,16 @@ def _populate_query_params(
69
71
  globals_already_populated.append(name)
70
72
 
71
73
  f_name = field.alias if field.alias is not None else name
74
+
75
+ allow_empty_set = set(allow_empty_value or [])
76
+ should_include_empty = f_name in allow_empty_set and (
77
+ value is None or value == [] or value == ""
78
+ )
79
+
80
+ if should_include_empty:
81
+ query_param_values[f_name] = [""]
82
+ continue
83
+
72
84
  serialization = metadata.serialization
73
85
  if serialization is not None:
74
86
  serialized_parms = _get_serialized_params(
@@ -3,7 +3,9 @@
3
3
  import asyncio
4
4
  import random
5
5
  import time
6
- from typing import List
6
+ from datetime import datetime
7
+ from email.utils import parsedate_to_datetime
8
+ from typing import List, Optional
7
9
 
8
10
  import httpx
9
11
 
@@ -51,9 +53,11 @@ class Retries:
51
53
 
52
54
  class TemporaryError(Exception):
53
55
  response: httpx.Response
56
+ retry_after: Optional[int]
54
57
 
55
58
  def __init__(self, response: httpx.Response):
56
59
  self.response = response
60
+ self.retry_after = _parse_retry_after_header(response)
57
61
 
58
62
 
59
63
  class PermanentError(Exception):
@@ -63,6 +67,62 @@ class PermanentError(Exception):
63
67
  self.inner = inner
64
68
 
65
69
 
70
+ def _parse_retry_after_header(response: httpx.Response) -> Optional[int]:
71
+ """Parse Retry-After header from response.
72
+
73
+ Returns:
74
+ Retry interval in milliseconds, or None if header is missing or invalid.
75
+ """
76
+ retry_after_header = response.headers.get("retry-after")
77
+ if not retry_after_header:
78
+ return None
79
+
80
+ try:
81
+ seconds = float(retry_after_header)
82
+ return round(seconds * 1000)
83
+ except ValueError:
84
+ pass
85
+
86
+ try:
87
+ retry_date = parsedate_to_datetime(retry_after_header)
88
+ delta = (retry_date - datetime.now(retry_date.tzinfo)).total_seconds()
89
+ return round(max(0, delta) * 1000)
90
+ except (ValueError, TypeError):
91
+ pass
92
+
93
+ return None
94
+
95
+
96
+ def _get_sleep_interval(
97
+ exception: Exception,
98
+ initial_interval: int,
99
+ max_interval: int,
100
+ exponent: float,
101
+ retries: int,
102
+ ) -> float:
103
+ """Get sleep interval for retry with exponential backoff.
104
+
105
+ Args:
106
+ exception: The exception that triggered the retry.
107
+ initial_interval: Initial retry interval in milliseconds.
108
+ max_interval: Maximum retry interval in milliseconds.
109
+ exponent: Base for exponential backoff calculation.
110
+ retries: Current retry attempt count.
111
+
112
+ Returns:
113
+ Sleep interval in seconds.
114
+ """
115
+ if (
116
+ isinstance(exception, TemporaryError)
117
+ and exception.retry_after is not None
118
+ and exception.retry_after > 0
119
+ ):
120
+ return exception.retry_after / 1000
121
+
122
+ sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1)
123
+ return min(sleep, max_interval / 1000)
124
+
125
+
66
126
  def retry(func, retries: Retries):
67
127
  if retries.config.strategy == "backoff":
68
128
 
@@ -183,8 +243,10 @@ def retry_with_backoff(
183
243
  return exception.response
184
244
 
185
245
  raise
186
- sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1)
187
- sleep = min(sleep, max_interval / 1000)
246
+
247
+ sleep = _get_sleep_interval(
248
+ exception, initial_interval, max_interval, exponent, retries
249
+ )
188
250
  time.sleep(sleep)
189
251
  retries += 1
190
252
 
@@ -211,7 +273,9 @@ async def retry_with_backoff_async(
211
273
  return exception.response
212
274
 
213
275
  raise
214
- sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1)
215
- sleep = min(sleep, max_interval / 1000)
276
+
277
+ sleep = _get_sleep_interval(
278
+ exception, initial_interval, max_interval, exponent, retries
279
+ )
216
280
  await asyncio.sleep(sleep)
217
281
  retries += 1
@@ -1,12 +1,26 @@
1
1
  """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
2
 
3
- from typing import Any, Optional
3
+ from typing import Any, Optional, Type, TypeVar, overload
4
4
 
5
5
  import httpx
6
6
 
7
7
  from .serializers import unmarshal_json
8
8
  from compass_api_sdk import errors
9
9
 
10
+ T = TypeVar("T")
11
+
12
+
13
+ @overload
14
+ def unmarshal_json_response(
15
+ typ: Type[T], http_res: httpx.Response, body: Optional[str] = None
16
+ ) -> T: ...
17
+
18
+
19
+ @overload
20
+ def unmarshal_json_response(
21
+ typ: Any, http_res: httpx.Response, body: Optional[str] = None
22
+ ) -> Any: ...
23
+
10
24
 
11
25
  def unmarshal_json_response(
12
26
  typ: Any, http_res: httpx.Response, body: Optional[str] = None
@@ -0,0 +1,208 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from .basesdk import BaseSDK
4
+ from compass_api_sdk import errors, models, utils
5
+ from compass_api_sdk._hooks import HookContext
6
+ from compass_api_sdk.types import OptionalNullable, UNSET
7
+ from compass_api_sdk.utils.unmarshal_json_response import unmarshal_json_response
8
+ from typing import Any, Mapping, Optional
9
+
10
+
11
+ class Wildcat(BaseSDK):
12
+ def wildcat_market(
13
+ self,
14
+ *,
15
+ chain: models.V1WildcatMarketChain,
16
+ market_address: str,
17
+ block: OptionalNullable[int] = UNSET,
18
+ user_address: OptionalNullable[str] = UNSET,
19
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
20
+ server_url: Optional[str] = None,
21
+ timeout_ms: Optional[int] = None,
22
+ http_headers: Optional[Mapping[str, str]] = None,
23
+ ) -> models.WildcatGetMarketResponse:
24
+ r"""Get Market & User Position
25
+
26
+ Get Wildcat Market data & user position.
27
+
28
+ The user position is only included if 'user_address' parameter is included.
29
+
30
+ :param chain:
31
+ :param market_address: The market address of the desired market data.
32
+ :param block: Optional block number (defaults to latest).
33
+ :param user_address: The user address of the desired market position. Only include if you would like the user position included in the response. Defaults to `None`.
34
+ :param retries: Override the default retry configuration for this method
35
+ :param server_url: Override the default server URL for this method
36
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
37
+ :param http_headers: Additional headers to set or replace on requests.
38
+ """
39
+ base_url = None
40
+ url_variables = None
41
+ if timeout_ms is None:
42
+ timeout_ms = self.sdk_configuration.timeout_ms
43
+
44
+ if server_url is not None:
45
+ base_url = server_url
46
+ else:
47
+ base_url = self._get_url(base_url, url_variables)
48
+
49
+ request = models.V1WildcatMarketRequest(
50
+ chain=chain,
51
+ block=block,
52
+ market_address=market_address,
53
+ user_address=user_address,
54
+ )
55
+
56
+ req = self._build_request(
57
+ method="GET",
58
+ path="/v1/wildcat/market",
59
+ base_url=base_url,
60
+ url_variables=url_variables,
61
+ request=request,
62
+ request_body_required=False,
63
+ request_has_path_params=False,
64
+ request_has_query_params=True,
65
+ user_agent_header="user-agent",
66
+ accept_header_value="application/json",
67
+ http_headers=http_headers,
68
+ security=self.sdk_configuration.security,
69
+ allow_empty_value=None,
70
+ timeout_ms=timeout_ms,
71
+ )
72
+
73
+ if retries == UNSET:
74
+ if self.sdk_configuration.retry_config is not UNSET:
75
+ retries = self.sdk_configuration.retry_config
76
+
77
+ retry_config = None
78
+ if isinstance(retries, utils.RetryConfig):
79
+ retry_config = (retries, ["429", "500", "502", "503", "504"])
80
+
81
+ http_res = self.do_request(
82
+ hook_ctx=HookContext(
83
+ config=self.sdk_configuration,
84
+ base_url=base_url or "",
85
+ operation_id="v1_wildcat_market",
86
+ oauth2_scopes=None,
87
+ security_source=self.sdk_configuration.security,
88
+ ),
89
+ request=req,
90
+ error_status_codes=["422", "4XX", "5XX"],
91
+ retry_config=retry_config,
92
+ )
93
+
94
+ response_data: Any = None
95
+ if utils.match_response(http_res, "200", "application/json"):
96
+ return unmarshal_json_response(models.WildcatGetMarketResponse, http_res)
97
+ if utils.match_response(http_res, "422", "application/json"):
98
+ response_data = unmarshal_json_response(
99
+ errors.HTTPValidationErrorData, http_res
100
+ )
101
+ raise errors.HTTPValidationError(response_data, http_res)
102
+ if utils.match_response(http_res, "4XX", "*"):
103
+ http_res_text = utils.stream_to_text(http_res)
104
+ raise errors.APIError("API error occurred", http_res, http_res_text)
105
+ if utils.match_response(http_res, "5XX", "*"):
106
+ http_res_text = utils.stream_to_text(http_res)
107
+ raise errors.APIError("API error occurred", http_res, http_res_text)
108
+
109
+ raise errors.APIError("Unexpected response received", http_res)
110
+
111
+ async def wildcat_market_async(
112
+ self,
113
+ *,
114
+ chain: models.V1WildcatMarketChain,
115
+ market_address: str,
116
+ block: OptionalNullable[int] = UNSET,
117
+ user_address: OptionalNullable[str] = UNSET,
118
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
119
+ server_url: Optional[str] = None,
120
+ timeout_ms: Optional[int] = None,
121
+ http_headers: Optional[Mapping[str, str]] = None,
122
+ ) -> models.WildcatGetMarketResponse:
123
+ r"""Get Market & User Position
124
+
125
+ Get Wildcat Market data & user position.
126
+
127
+ The user position is only included if 'user_address' parameter is included.
128
+
129
+ :param chain:
130
+ :param market_address: The market address of the desired market data.
131
+ :param block: Optional block number (defaults to latest).
132
+ :param user_address: The user address of the desired market position. Only include if you would like the user position included in the response. Defaults to `None`.
133
+ :param retries: Override the default retry configuration for this method
134
+ :param server_url: Override the default server URL for this method
135
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
136
+ :param http_headers: Additional headers to set or replace on requests.
137
+ """
138
+ base_url = None
139
+ url_variables = None
140
+ if timeout_ms is None:
141
+ timeout_ms = self.sdk_configuration.timeout_ms
142
+
143
+ if server_url is not None:
144
+ base_url = server_url
145
+ else:
146
+ base_url = self._get_url(base_url, url_variables)
147
+
148
+ request = models.V1WildcatMarketRequest(
149
+ chain=chain,
150
+ block=block,
151
+ market_address=market_address,
152
+ user_address=user_address,
153
+ )
154
+
155
+ req = self._build_request_async(
156
+ method="GET",
157
+ path="/v1/wildcat/market",
158
+ base_url=base_url,
159
+ url_variables=url_variables,
160
+ request=request,
161
+ request_body_required=False,
162
+ request_has_path_params=False,
163
+ request_has_query_params=True,
164
+ user_agent_header="user-agent",
165
+ accept_header_value="application/json",
166
+ http_headers=http_headers,
167
+ security=self.sdk_configuration.security,
168
+ allow_empty_value=None,
169
+ timeout_ms=timeout_ms,
170
+ )
171
+
172
+ if retries == UNSET:
173
+ if self.sdk_configuration.retry_config is not UNSET:
174
+ retries = self.sdk_configuration.retry_config
175
+
176
+ retry_config = None
177
+ if isinstance(retries, utils.RetryConfig):
178
+ retry_config = (retries, ["429", "500", "502", "503", "504"])
179
+
180
+ http_res = await self.do_request_async(
181
+ hook_ctx=HookContext(
182
+ config=self.sdk_configuration,
183
+ base_url=base_url or "",
184
+ operation_id="v1_wildcat_market",
185
+ oauth2_scopes=None,
186
+ security_source=self.sdk_configuration.security,
187
+ ),
188
+ request=req,
189
+ error_status_codes=["422", "4XX", "5XX"],
190
+ retry_config=retry_config,
191
+ )
192
+
193
+ response_data: Any = None
194
+ if utils.match_response(http_res, "200", "application/json"):
195
+ return unmarshal_json_response(models.WildcatGetMarketResponse, http_res)
196
+ if utils.match_response(http_res, "422", "application/json"):
197
+ response_data = unmarshal_json_response(
198
+ errors.HTTPValidationErrorData, http_res
199
+ )
200
+ raise errors.HTTPValidationError(response_data, http_res)
201
+ if utils.match_response(http_res, "4XX", "*"):
202
+ http_res_text = await utils.stream_to_text_async(http_res)
203
+ raise errors.APIError("API error occurred", http_res, http_res_text)
204
+ if utils.match_response(http_res, "5XX", "*"):
205
+ http_res_text = await utils.stream_to_text_async(http_res)
206
+ raise errors.APIError("API error occurred", http_res, http_res_text)
207
+
208
+ raise errors.APIError("Unexpected response received", http_res)