crypticorn 2.5.0rc5__tar.gz → 2.5.2__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 (320) hide show
  1. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/PKG-INFO +7 -5
  2. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/README.md +5 -4
  3. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/main.py +2 -0
  4. crypticorn-2.5.2/crypticorn/client.py +122 -0
  5. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/common/__init__.py +3 -1
  6. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/common/auth.py +38 -20
  7. crypticorn-2.5.2/crypticorn/common/enums.py +29 -0
  8. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/common/errors.py +72 -17
  9. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/common/exceptions.py +29 -15
  10. crypticorn-2.5.0rc5/crypticorn/common/enums.py → crypticorn-2.5.2/crypticorn/common/mixins.py +8 -27
  11. crypticorn-2.5.2/crypticorn/common/status_router.py +42 -0
  12. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/common/urls.py +2 -1
  13. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/common/utils.py +9 -14
  14. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/main.py +2 -0
  15. crypticorn-2.5.2/crypticorn/klines/client/__init__.py +50 -0
  16. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api/__init__.py +1 -1
  17. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api/change_in_timeframe_api.py +16 -31
  18. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api/funding_rates_api.py +8 -22
  19. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api/ohlcv_data_api.py +17 -38
  20. crypticorn-2.5.2/crypticorn/klines/client/api/status_api.py +260 -0
  21. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api/symbols_api.py +18 -34
  22. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api/udf_api.py +48 -59
  23. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api_client.py +1 -1
  24. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/configuration.py +1 -1
  25. crypticorn-2.5.2/crypticorn/klines/client/exceptions.py +220 -0
  26. crypticorn-2.5.2/crypticorn/klines/client/models/__init__.py +28 -0
  27. crypticorn-2.5.0rc5/crypticorn/klines/client/models/change_in_timeframe_response.py → crypticorn-2.5.2/crypticorn/klines/client/models/change_in_timeframe.py +5 -5
  28. crypticorn-2.5.0rc5/crypticorn/klines/client/models/error_response.py → crypticorn-2.5.2/crypticorn/klines/client/models/exception_detail.py +25 -20
  29. crypticorn-2.5.0rc5/crypticorn/klines/client/models/funding_rate_response.py → crypticorn-2.5.2/crypticorn/klines/client/models/funding_rate.py +5 -5
  30. crypticorn-2.5.0rc5/crypticorn/klines/client/models/ohlcv_response.py → crypticorn-2.5.2/crypticorn/klines/client/models/ohlcv_history.py +14 -14
  31. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/models/resolution.py +1 -1
  32. crypticorn-2.5.2/crypticorn/klines/client/models/search_symbol.py +95 -0
  33. crypticorn-2.5.2/crypticorn/klines/client/models/sort_direction.py +35 -0
  34. crypticorn-2.5.0rc5/crypticorn/klines/client/models/symbol_group_response.py → crypticorn-2.5.2/crypticorn/klines/client/models/symbol_group.py +5 -5
  35. crypticorn-2.5.0rc5/crypticorn/klines/client/models/symbol_info_response.py → crypticorn-2.5.2/crypticorn/klines/client/models/symbol_info.py +5 -5
  36. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/models/symbol_type.py +1 -1
  37. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/models/timeframe.py +1 -1
  38. crypticorn-2.5.0rc5/crypticorn/klines/client/models/udf_config_response.py → crypticorn-2.5.2/crypticorn/klines/client/models/udf_config.py +7 -19
  39. crypticorn-2.5.2/crypticorn/klines/client/rest.py +198 -0
  40. crypticorn-2.5.2/crypticorn/klines/main.py +91 -0
  41. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/__init__.py +3 -22
  42. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api/__init__.py +1 -1
  43. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api/exchanges_api.py +53 -97
  44. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api/indicators_api.py +26 -52
  45. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api/logs_api.py +8 -23
  46. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api/marketcap_api.py +36 -88
  47. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api/markets_api.py +26 -55
  48. crypticorn-2.5.2/crypticorn/metrics/client/api/status_api.py +260 -0
  49. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api/tokens_api.py +7 -21
  50. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api_client.py +1 -1
  51. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/configuration.py +1 -1
  52. crypticorn-2.5.2/crypticorn/metrics/client/exceptions.py +220 -0
  53. crypticorn-2.5.2/crypticorn/metrics/client/models/__init__.py +20 -0
  54. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/error_response.py → crypticorn-2.5.2/crypticorn/metrics/client/models/exception_detail.py +25 -20
  55. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/models/severity.py +1 -1
  56. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/models/time_interval.py +1 -1
  57. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/models/trading_status.py +1 -1
  58. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/rest.py +1 -1
  59. crypticorn-2.5.2/crypticorn/metrics/main.py +113 -0
  60. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/main.py +2 -0
  61. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/__init__.py +1 -5
  62. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/exchanges_api.py +6 -6
  63. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/trading_actions_api.py +16 -15
  64. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/__init__.py +1 -5
  65. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/action_model.py +1 -2
  66. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/bot_model.py +3 -7
  67. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/exchange_key_model.py +2 -11
  68. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/execution_ids.py +1 -1
  69. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/futures_trading_action.py +1 -2
  70. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/notification_model.py +3 -12
  71. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/order_model.py +7 -21
  72. crypticorn-2.5.2/crypticorn/trade/client/models/spot_trading_action.py +230 -0
  73. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/strategy_exchange_info.py +2 -3
  74. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/strategy_model_input.py +1 -2
  75. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/strategy_model_output.py +1 -2
  76. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/tpsl.py +3 -1
  77. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/main.py +2 -0
  78. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn.egg-info/PKG-INFO +7 -5
  79. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn.egg-info/SOURCES.txt +15 -75
  80. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn.egg-info/requires.txt +1 -0
  81. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/pyproject.toml +1 -1
  82. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/requirements/test.txt +1 -0
  83. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/tests/test_auth_client.py +14 -23
  84. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/tests/test_config.py +2 -2
  85. crypticorn-2.5.2/tests/test_errors.py +54 -0
  86. crypticorn-2.5.0rc5/crypticorn/client.py +0 -131
  87. crypticorn-2.5.0rc5/crypticorn/common/sorter.py +0 -40
  88. crypticorn-2.5.0rc5/crypticorn/klines/client/__init__.py +0 -83
  89. crypticorn-2.5.0rc5/crypticorn/klines/client/api/health_check_api.py +0 -265
  90. crypticorn-2.5.0rc5/crypticorn/klines/client/exceptions.py +0 -220
  91. crypticorn-2.5.0rc5/crypticorn/klines/client/models/__init__.py +0 -61
  92. crypticorn-2.5.0rc5/crypticorn/klines/client/models/base_response_health_check_response.py +0 -114
  93. crypticorn-2.5.0rc5/crypticorn/klines/client/models/base_response_list_change_in_timeframe_response.py +0 -123
  94. crypticorn-2.5.0rc5/crypticorn/klines/client/models/base_response_list_funding_rate_response.py +0 -118
  95. crypticorn-2.5.0rc5/crypticorn/klines/client/models/base_response_list_str.py +0 -106
  96. crypticorn-2.5.0rc5/crypticorn/klines/client/models/base_response_ohlcv_response.py +0 -114
  97. crypticorn-2.5.0rc5/crypticorn/klines/client/models/exchange.py +0 -91
  98. crypticorn-2.5.0rc5/crypticorn/klines/client/models/health_check_response.py +0 -91
  99. crypticorn-2.5.0rc5/crypticorn/klines/client/models/history_error_response.py +0 -89
  100. crypticorn-2.5.0rc5/crypticorn/klines/client/models/history_no_data_response.py +0 -99
  101. crypticorn-2.5.0rc5/crypticorn/klines/client/models/history_success_response.py +0 -99
  102. crypticorn-2.5.0rc5/crypticorn/klines/client/models/http_validation_error.py +0 -99
  103. crypticorn-2.5.0rc5/crypticorn/klines/client/models/market.py +0 -35
  104. crypticorn-2.5.0rc5/crypticorn/klines/client/models/market_type.py +0 -35
  105. crypticorn-2.5.0rc5/crypticorn/klines/client/models/response_get_history_udf_history_get.py +0 -198
  106. crypticorn-2.5.0rc5/crypticorn/klines/client/models/response_get_udf_history.py +0 -198
  107. crypticorn-2.5.0rc5/crypticorn/klines/client/models/search_symbol_response.py +0 -104
  108. crypticorn-2.5.0rc5/crypticorn/klines/client/models/sort_direction.py +0 -35
  109. crypticorn-2.5.0rc5/crypticorn/klines/client/models/validation_error.py +0 -105
  110. crypticorn-2.5.0rc5/crypticorn/klines/client/models/validation_error_loc_inner.py +0 -159
  111. crypticorn-2.5.0rc5/crypticorn/klines/client/rest.py +0 -198
  112. crypticorn-2.5.0rc5/crypticorn/klines/main.py +0 -74
  113. crypticorn-2.5.0rc5/crypticorn/metrics/client/api/health_check_api.py +0 -265
  114. crypticorn-2.5.0rc5/crypticorn/metrics/client/exceptions.py +0 -220
  115. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/__init__.py +0 -39
  116. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/base_response_dict.py +0 -106
  117. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/base_response_health_check_response.py +0 -114
  118. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/base_response_list_dict.py +0 -106
  119. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/base_response_list_exchange_mapping.py +0 -118
  120. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/base_response_list_str.py +0 -106
  121. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/exchange_mapping.py +0 -134
  122. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/health_check_response.py +0 -91
  123. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/http_validation_error.py +0 -99
  124. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/market.py +0 -35
  125. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/market_type.py +0 -35
  126. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/validation_error.py +0 -105
  127. crypticorn-2.5.0rc5/crypticorn/metrics/client/models/validation_error_loc_inner.py +0 -159
  128. crypticorn-2.5.0rc5/crypticorn/metrics/main.py +0 -105
  129. crypticorn-2.5.0rc5/crypticorn/pay/client/models/api_status_res.py +0 -83
  130. crypticorn-2.5.0rc5/crypticorn/pay/client/models/body_create_now_invoice.py +0 -98
  131. crypticorn-2.5.0rc5/crypticorn/pay/client/models/body_create_product.py +0 -98
  132. crypticorn-2.5.0rc5/crypticorn/pay/client/models/body_get_products.py +0 -87
  133. crypticorn-2.5.0rc5/crypticorn/pay/client/models/body_handle_now_webhook.py +0 -98
  134. crypticorn-2.5.0rc5/crypticorn/pay/client/models/body_update_product.py +0 -98
  135. crypticorn-2.5.0rc5/crypticorn/pay/client/models/combined_payment_history.py +0 -101
  136. crypticorn-2.5.0rc5/crypticorn/pay/client/models/create_invoice_req.py +0 -188
  137. crypticorn-2.5.0rc5/crypticorn/pay/client/models/create_invoice_res.py +0 -188
  138. crypticorn-2.5.0rc5/crypticorn/pay/client/models/currency.py +0 -165
  139. crypticorn-2.5.0rc5/crypticorn/pay/client/models/estimate_price_req.py +0 -91
  140. crypticorn-2.5.0rc5/crypticorn/pay/client/models/estimate_price_res.py +0 -102
  141. crypticorn-2.5.0rc5/crypticorn/pay/client/models/get_currencies_res.py +0 -99
  142. crypticorn-2.5.0rc5/crypticorn/pay/client/models/get_payment_status_res.py +0 -222
  143. crypticorn-2.5.0rc5/crypticorn/pay/client/models/get_payments_list_res.py +0 -109
  144. crypticorn-2.5.0rc5/crypticorn/pay/client/models/min_amount_req.py +0 -124
  145. crypticorn-2.5.0rc5/crypticorn/pay/client/models/min_amount_res.py +0 -105
  146. crypticorn-2.5.0rc5/crypticorn/pay/client/models/now_fee_structure.py +0 -104
  147. crypticorn-2.5.0rc5/crypticorn/pay/client/models/now_payment_model.py +0 -124
  148. crypticorn-2.5.0rc5/crypticorn/pay/client/models/now_payment_status.py +0 -42
  149. crypticorn-2.5.0rc5/crypticorn/pay/client/models/now_webhook_payload.py +0 -181
  150. crypticorn-2.5.0rc5/crypticorn/pay/client/models/partial_product_update_model.py +0 -150
  151. crypticorn-2.5.0rc5/crypticorn/pay/client/models/product.py +0 -87
  152. crypticorn-2.5.0rc5/crypticorn/pay/client/models/product_model.py +0 -128
  153. crypticorn-2.5.0rc5/crypticorn/pay/client/models/product_subs_model.py +0 -108
  154. crypticorn-2.5.0rc5/crypticorn/pay/client/models/product_update_model.py +0 -150
  155. crypticorn-2.5.0rc5/crypticorn/pay/client/models/unified_payment_model.py +0 -112
  156. crypticorn-2.5.0rc5/crypticorn/trade/client/models/api_error_identifier.py +0 -104
  157. crypticorn-2.5.0rc5/crypticorn/trade/client/models/api_error_level.py +0 -37
  158. crypticorn-2.5.0rc5/crypticorn/trade/client/models/api_error_type.py +0 -37
  159. crypticorn-2.5.0rc5/crypticorn/trade/client/models/api_key_model.py +0 -156
  160. crypticorn-2.5.0rc5/crypticorn/trade/client/models/exchange.py +0 -35
  161. crypticorn-2.5.0rc5/crypticorn/trade/client/models/market_type.py +0 -35
  162. crypticorn-2.5.0rc5/tests/test_errors.py +0 -39
  163. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/__init__.py +0 -0
  164. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/__init__.py +0 -0
  165. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/__init__.py +0 -0
  166. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api/__init__.py +0 -0
  167. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api/admin_api.py +0 -0
  168. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api/auth_api.py +0 -0
  169. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api/service_api.py +0 -0
  170. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api/user_api.py +0 -0
  171. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api/wallet_api.py +0 -0
  172. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api_client.py +0 -0
  173. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/api_response.py +0 -0
  174. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/configuration.py +0 -0
  175. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/exceptions.py +0 -0
  176. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/__init__.py +0 -0
  177. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/add_wallet200_response.py +0 -0
  178. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/add_wallet_request.py +0 -0
  179. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/authorize_user200_response.py +0 -0
  180. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/authorize_user200_response_auth.py +0 -0
  181. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/authorize_user_request.py +0 -0
  182. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/create_api_key200_response.py +0 -0
  183. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/create_api_key_request.py +0 -0
  184. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/create_user_request.py +0 -0
  185. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/get_api_keys200_response_inner.py +0 -0
  186. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/list_wallets200_response.py +0 -0
  187. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/list_wallets200_response_balances_inner.py +0 -0
  188. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_sale_round.py +0 -0
  189. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet.py +0 -0
  190. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet_vesting_wallets_inner.py +0 -0
  191. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/list_wallets200_response_data_inner.py +0 -0
  192. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/list_wallets200_response_user_value.py +0 -0
  193. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/logout_default_response.py +0 -0
  194. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/logout_default_response_issues_inner.py +0 -0
  195. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/oauth_callback200_response.py +0 -0
  196. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/oauth_callback200_response_user.py +0 -0
  197. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/refresh_token_info200_response.py +0 -0
  198. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/refresh_token_info200_response_user_session.py +0 -0
  199. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/resend_verification_email_request.py +0 -0
  200. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/revoke_user_tokens_request.py +0 -0
  201. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/rotate_tokens200_response.py +0 -0
  202. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/token_info200_response.py +0 -0
  203. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/unlink_wallet_request.py +0 -0
  204. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/update_user_request.py +0 -0
  205. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/user_reset_password_request.py +0 -0
  206. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/user_set_password_request.py +0 -0
  207. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/verify200_response.py +0 -0
  208. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/verify_email200_response.py +0 -0
  209. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/verify_email200_response_auth.py +0 -0
  210. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/verify_email200_response_auth_auth.py +0 -0
  211. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/verify_email_request.py +0 -0
  212. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/verify_wallet_request.py +0 -0
  213. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/wallet_verified200_response.py +0 -0
  214. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/models/whoami200_response.py +0 -0
  215. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/py.typed +0 -0
  216. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/auth/client/rest.py +0 -0
  217. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/cli/__init__.py +0 -0
  218. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/cli/__main__.py +0 -0
  219. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/cli/init.py +0 -0
  220. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/cli/templates/__init__.py +0 -0
  221. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/cli/templates/auth.py +0 -0
  222. /crypticorn-2.5.0rc5/crypticorn/common/pydantic.py → /crypticorn-2.5.2/crypticorn/common/decorators.py +0 -0
  223. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/common/scopes.py +0 -0
  224. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/__init__.py +0 -0
  225. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/__init__.py +0 -0
  226. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/api/__init__.py +0 -0
  227. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/api/data_api.py +0 -0
  228. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/api/models_api.py +0 -0
  229. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/api/status_api.py +0 -0
  230. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/api_client.py +0 -0
  231. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/api_response.py +0 -0
  232. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/configuration.py +0 -0
  233. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/exceptions.py +0 -0
  234. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/__init__.py +0 -0
  235. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/coins.py +0 -0
  236. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/data_download_response.py +0 -0
  237. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/data_info.py +0 -0
  238. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/data_value_value_value_inner.py +0 -0
  239. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/data_version.py +0 -0
  240. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/download_links.py +0 -0
  241. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/evaluation.py +0 -0
  242. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/evaluation_response.py +0 -0
  243. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/feature_size.py +0 -0
  244. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/http_validation_error.py +0 -0
  245. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/model.py +0 -0
  246. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/model_create.py +0 -0
  247. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/model_status.py +0 -0
  248. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/model_update.py +0 -0
  249. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/target.py +0 -0
  250. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/target_type.py +0 -0
  251. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/validation_error.py +0 -0
  252. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/models/validation_error_loc_inner.py +0 -0
  253. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/py.typed +0 -0
  254. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/hive/client/rest.py +0 -0
  255. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/__init__.py +0 -0
  256. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/api_response.py +0 -0
  257. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/klines/client/py.typed +0 -0
  258. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/__init__.py +0 -0
  259. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/api_response.py +0 -0
  260. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/metrics/client/py.typed +0 -0
  261. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/__init__.py +0 -0
  262. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/__init__.py +0 -0
  263. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/api/__init__.py +0 -0
  264. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/api/now_payments_api.py +0 -0
  265. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/api/payments_api.py +0 -0
  266. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/api/products_api.py +0 -0
  267. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/api/status_api.py +0 -0
  268. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/api_client.py +0 -0
  269. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/api_response.py +0 -0
  270. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/configuration.py +0 -0
  271. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/exceptions.py +0 -0
  272. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/__init__.py +0 -0
  273. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/http_validation_error.py +0 -0
  274. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/now_api_status_res.py +0 -0
  275. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/now_create_invoice_req.py +0 -0
  276. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/now_create_invoice_res.py +0 -0
  277. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/payment.py +0 -0
  278. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/payment_status.py +0 -0
  279. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/product_create.py +0 -0
  280. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/product_read.py +0 -0
  281. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/product_sub_read.py +0 -0
  282. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/product_update.py +0 -0
  283. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/scope.py +0 -0
  284. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/services.py +0 -0
  285. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/validation_error.py +0 -0
  286. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/models/validation_error_loc_inner.py +0 -0
  287. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/py.typed +0 -0
  288. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/pay/client/rest.py +0 -0
  289. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/__init__.py +0 -0
  290. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/__init__.py +0 -0
  291. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/api_keys_api.py +0 -0
  292. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/bots_api.py +0 -0
  293. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/futures_trading_panel_api.py +0 -0
  294. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/notifications_api.py +0 -0
  295. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/orders_api.py +0 -0
  296. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/status_api.py +0 -0
  297. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api/strategies_api.py +0 -0
  298. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api_client.py +0 -0
  299. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/api_response.py +0 -0
  300. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/configuration.py +0 -0
  301. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/exceptions.py +0 -0
  302. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/bot_status.py +0 -0
  303. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/futures_balance.py +0 -0
  304. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/http_validation_error.py +0 -0
  305. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/margin_mode.py +0 -0
  306. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/order_status.py +0 -0
  307. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/post_futures_action.py +0 -0
  308. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/trading_action_type.py +0 -0
  309. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/validation_error.py +0 -0
  310. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/models/validation_error_loc_inner.py +0 -0
  311. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/py.typed +0 -0
  312. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn/trade/client/rest.py +0 -0
  313. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn.egg-info/dependency_links.txt +0 -0
  314. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn.egg-info/entry_points.txt +0 -0
  315. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/crypticorn.egg-info/top_level.txt +0 -0
  316. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/requirements/dev.txt +0 -0
  317. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/requirements/extra.txt +0 -0
  318. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/requirements/main.txt +0 -0
  319. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/setup.cfg +0 -0
  320. {crypticorn-2.5.0rc5 → crypticorn-2.5.2}/tests/test_enums.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crypticorn
3
- Version: 2.5.0rc5
3
+ Version: 2.5.2
4
4
  Summary: Maximise Your Crypto Trading Profits with AI Predictions
5
5
  Author-email: Crypticorn <timon@crypticorn.com>
6
6
  Project-URL: Homepage, https://crypticorn.com
@@ -36,6 +36,7 @@ Requires-Dist: pytest==8.3.5; extra == "test"
36
36
  Requires-Dist: pytest-asyncio==0.26.0; extra == "test"
37
37
  Requires-Dist: pytest-cov==6.1.1; extra == "test"
38
38
  Requires-Dist: python-dotenv==1.0.1; extra == "test"
39
+ Requires-Dist: PyJWT==2.10.0; extra == "test"
39
40
  Provides-Extra: extra
40
41
  Requires-Dist: pandas<3.0.0,>=2.2.0; extra == "extra"
41
42
 
@@ -86,7 +87,7 @@ The `common` submodule contains shared classes not bound to a specific API.
86
87
  from crypticorn.common import Scope, Exchange
87
88
  ```
88
89
 
89
- ## Usage
90
+ ## Basic Usage
90
91
 
91
92
  ### With Async Context Protocol
92
93
  ```python
@@ -107,6 +108,7 @@ async def main():
107
108
 
108
109
  asyncio.run(main())
109
110
  asyncio.run(client.close())
111
+
110
112
  ## Response Types
111
113
 
112
114
  There are three different available output formats you can choose from:
@@ -155,12 +157,12 @@ The output would look like this:
155
157
 
156
158
  ## Advanced Usage
157
159
 
158
- You can override some configuration for specific sub clients. If you just want to use the API as is, you don't need to configure anything.
160
+ You can override some configuration for specific services. If you just want to use the API as is, you don't need to configure anything.
159
161
  This might be of use if you are testing a specific API locally.
160
162
 
161
- To override e.g. the host for the Hive client to connect to http://localhost:8000 instead of the default caddy proxy, you would do:
163
+ To override e.g. the host for the Hive client to connect to http://localhost:8000 instead of the default proxy, you would do:
162
164
  ```python
163
165
  from crypticorn.hive import Configuration as Hiveconfig
164
166
  async with ApiClient(base_url=BaseUrl.DEV) as client:
165
- client.configure(config=HiveConfig(host="http://localhost:8000"), sub_client=client.hive)
167
+ client.configure(config=HiveConfig(host="http://localhost:8000"), client=client.hive)
166
168
  ```
@@ -45,7 +45,7 @@ The `common` submodule contains shared classes not bound to a specific API.
45
45
  from crypticorn.common import Scope, Exchange
46
46
  ```
47
47
 
48
- ## Usage
48
+ ## Basic Usage
49
49
 
50
50
  ### With Async Context Protocol
51
51
  ```python
@@ -66,6 +66,7 @@ async def main():
66
66
 
67
67
  asyncio.run(main())
68
68
  asyncio.run(client.close())
69
+
69
70
  ## Response Types
70
71
 
71
72
  There are three different available output formats you can choose from:
@@ -114,12 +115,12 @@ The output would look like this:
114
115
 
115
116
  ## Advanced Usage
116
117
 
117
- You can override some configuration for specific sub clients. If you just want to use the API as is, you don't need to configure anything.
118
+ You can override some configuration for specific services. If you just want to use the API as is, you don't need to configure anything.
118
119
  This might be of use if you are testing a specific API locally.
119
120
 
120
- To override e.g. the host for the Hive client to connect to http://localhost:8000 instead of the default caddy proxy, you would do:
121
+ To override e.g. the host for the Hive client to connect to http://localhost:8000 instead of the default proxy, you would do:
121
122
  ```python
122
123
  from crypticorn.hive import Configuration as Hiveconfig
123
124
  async with ApiClient(base_url=BaseUrl.DEV) as client:
124
- client.configure(config=HiveConfig(host="http://localhost:8000"), sub_client=client.hive)
125
+ client.configure(config=HiveConfig(host="http://localhost:8000"), client=client.hive)
125
126
  ```
@@ -14,6 +14,8 @@ class AuthClient:
14
14
  A client for interacting with the Crypticorn Auth API.
15
15
  """
16
16
 
17
+ config_class = Configuration
18
+
17
19
  def __init__(
18
20
  self,
19
21
  config: Configuration,
@@ -0,0 +1,122 @@
1
+ from typing import TypeVar
2
+ from crypticorn.hive import HiveClient
3
+ from crypticorn.klines import KlinesClient
4
+ from crypticorn.pay import PayClient
5
+ from crypticorn.trade import TradeClient
6
+ from crypticorn.metrics import MetricsClient
7
+ from crypticorn.auth import AuthClient
8
+ from crypticorn.common import BaseUrl, ApiVersion, Service, apikey_header as aph
9
+
10
+ ConfigT = TypeVar("ConfigT")
11
+ SubClient = TypeVar("SubClient")
12
+
13
+
14
+ class ApiClient:
15
+ """
16
+ The official client for interacting with the Crypticorn API.
17
+
18
+ It is consisting of multiple microservices covering the whole stack of the Crypticorn project.
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ api_key: str = None,
24
+ jwt: str = None,
25
+ base_url: BaseUrl = BaseUrl.PROD,
26
+ ):
27
+ self.base_url = base_url
28
+ """The base URL the client will use to connect to the API."""
29
+ self.api_key = api_key
30
+ """The API key to use for authentication."""
31
+ self.jwt = jwt
32
+ """The JWT to use for authentication."""
33
+
34
+ self.service_classes: dict[Service, type[SubClient]] = {
35
+ Service.HIVE: HiveClient,
36
+ Service.TRADE: TradeClient,
37
+ Service.KLINES: KlinesClient,
38
+ Service.PAY: PayClient,
39
+ Service.METRICS: MetricsClient,
40
+ Service.AUTH: AuthClient,
41
+ }
42
+
43
+ self.services: dict[Service, SubClient] = {
44
+ service: client_class(self._get_default_config(service))
45
+ for service, client_class in self.service_classes.items()
46
+ }
47
+
48
+ @property
49
+ def hive(self) -> HiveClient:
50
+ return self.services[Service.HIVE]
51
+
52
+ @property
53
+ def trade(self) -> TradeClient:
54
+ return self.services[Service.TRADE]
55
+
56
+ @property
57
+ def klines(self) -> KlinesClient:
58
+ return self.services[Service.KLINES]
59
+
60
+ @property
61
+ def metrics(self) -> MetricsClient:
62
+ return self.services[Service.METRICS]
63
+
64
+ @property
65
+ def pay(self) -> PayClient:
66
+ return self.services[Service.PAY]
67
+
68
+ @property
69
+ def auth(self) -> AuthClient:
70
+ return self.services[Service.AUTH]
71
+
72
+ async def close(self):
73
+ """Close all client sessions."""
74
+ for service in self.services.values():
75
+ if hasattr(service.base_client, "close"):
76
+ await service.base_client.close()
77
+
78
+ def _get_default_config(
79
+ self, service: Service, version: ApiVersion = ApiVersion.V1
80
+ ):
81
+ """
82
+ Get the default configuration for a given service.
83
+ """
84
+ config_class = self.service_classes[service].config_class
85
+ return config_class(
86
+ host=f"{self.base_url}/{version}/{service}",
87
+ access_token=self.jwt,
88
+ api_key={aph.scheme_name: self.api_key} if self.api_key else None,
89
+ )
90
+
91
+ def configure(
92
+ self,
93
+ config: ConfigT,
94
+ service: Service,
95
+ ):
96
+ """
97
+ Update a sub-client's configuration by overriding with the values set in the new config.
98
+ Useful for testing a specific service against a local server instead of the default proxy.
99
+
100
+ :param config: The new configuration to use for the sub-client.
101
+ :param service: The service to configure.
102
+
103
+ Example:
104
+ >>> async with ApiClient(base_url=BaseUrl.DEV, jwt=jwt) as client:
105
+ >>> client.configure(config=HiveConfig(host="http://localhost:8000"), client=client.hive)
106
+ """
107
+ assert Service.validate(service), f"Invalid service: {service}"
108
+ client = self.services[service]
109
+ new_config = client.config
110
+
111
+ for attr in vars(config):
112
+ new_value = getattr(config, attr)
113
+ if new_value:
114
+ setattr(new_config, attr, new_value)
115
+
116
+ self.services[service] = type(client)(new_config)
117
+
118
+ async def __aenter__(self):
119
+ return self
120
+
121
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
122
+ await self.close()
@@ -1,8 +1,10 @@
1
1
  from crypticorn.common.errors import *
2
2
  from crypticorn.common.scopes import *
3
3
  from crypticorn.common.urls import *
4
- from crypticorn.common.pydantic import *
4
+ from crypticorn.common.decorators import *
5
+ from crypticorn.common.mixins import *
5
6
  from crypticorn.common.auth import *
6
7
  from crypticorn.common.enums import *
7
8
  from crypticorn.common.utils import *
8
9
  from crypticorn.common.exceptions import *
10
+ from crypticorn.common.status_router import router as status_router
@@ -2,14 +2,10 @@ import json
2
2
 
3
3
  from crypticorn.auth import Verify200Response, AuthClient, Configuration
4
4
  from crypticorn.auth.client.exceptions import ApiException
5
- from crypticorn.common import (
6
- ApiError,
7
- ApiVersion,
8
- BaseUrl,
9
- Scope,
10
- Service,
11
- )
12
- from fastapi import Depends, HTTPException, Query, status, WebSocketException
5
+ from crypticorn.common.scopes import Scope
6
+ from crypticorn.common.exceptions import ApiError, HTTPException, ExceptionContent
7
+ from crypticorn.common.urls import BaseUrl, Service, ApiVersion
8
+ from fastapi import Depends, Query, status, WebSocketException
13
9
  from fastapi.security import (
14
10
  HTTPAuthorizationCredentials,
15
11
  SecurityScopes,
@@ -48,11 +44,6 @@ class AuthHandler:
48
44
  self.url = f"{base_url}/{ApiVersion.V1}/{Service.AUTH}"
49
45
  self.client = AuthClient(Configuration(host=self.url))
50
46
 
51
- self.no_credentials_exception = HTTPException(
52
- status_code=status.HTTP_401_UNAUTHORIZED,
53
- detail=ApiError.NO_CREDENTIALS.identifier,
54
- )
55
-
56
47
  async def _verify_api_key(self, api_key: str) -> Verify200Response:
57
48
  """
58
49
  Verifies the API key.
@@ -76,8 +67,10 @@ class AuthHandler:
76
67
  """
77
68
  if not set(api_scopes).issubset(user_scopes):
78
69
  raise HTTPException(
79
- status_code=status.HTTP_403_FORBIDDEN,
80
- detail=ApiError.INSUFFICIENT_SCOPES.identifier,
70
+ content=ExceptionContent(
71
+ error=ApiError.INSUFFICIENT_SCOPES,
72
+ message="Insufficient scopes to access this resource",
73
+ ),
81
74
  )
82
75
 
83
76
  async def _extract_message(self, e: ApiException) -> str:
@@ -100,16 +93,33 @@ class AuthHandler:
100
93
  Handles exceptions and returns a HTTPException with the appropriate status code and detail.
101
94
  """
102
95
  if isinstance(e, ApiException):
96
+ # handle the TRPC Zod errors from auth-service
97
+ # Unfortunately, we cannot share the error messages defined in python/crypticorn/common/errors.py with the typescript client
98
+ message = await self._extract_message(e)
99
+ if message == "Invalid API key":
100
+ error = ApiError.INVALID_API_KEY
101
+ elif message == "API key expired":
102
+ error = ApiError.EXPIRED_API_KEY
103
+ elif message == "jwt expired":
104
+ error = ApiError.EXPIRED_BEARER
105
+ else:
106
+ error = (
107
+ ApiError.INVALID_BEARER
108
+ ) # jwt malformed, jwt not active (https://www.npmjs.com/package/jsonwebtoken#errors--codes)
103
109
  return HTTPException(
104
- status_code=e.status,
105
- detail=await self._extract_message(e),
110
+ content=ExceptionContent(
111
+ error=error,
112
+ message=message,
113
+ ),
106
114
  )
107
115
  elif isinstance(e, HTTPException):
108
116
  return e
109
117
  else:
110
118
  return HTTPException(
111
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
112
- detail=str(e),
119
+ content=ExceptionContent(
120
+ error=ApiError.UNKNOWN_ERROR,
121
+ message=str(e),
122
+ ),
113
123
  )
114
124
 
115
125
  async def api_key_auth(
@@ -172,7 +182,15 @@ class AuthHandler:
172
182
  last_error = await self._handle_exception(e)
173
183
  continue
174
184
 
175
- raise last_error or self.no_credentials_exception
185
+ if last_error:
186
+ raise last_error
187
+ else:
188
+ raise HTTPException(
189
+ content=ExceptionContent(
190
+ error=ApiError.NO_CREDENTIALS,
191
+ message="No credentials provided",
192
+ ),
193
+ )
176
194
 
177
195
  async def ws_api_key_auth(
178
196
  self,
@@ -0,0 +1,29 @@
1
+ from enum import StrEnum
2
+ from crypticorn.common.mixins import ValidateEnumMixin, ExcludeEnumMixin
3
+
4
+
5
+ class Exchange(ValidateEnumMixin, ExcludeEnumMixin, StrEnum):
6
+ """Supported exchanges for trading"""
7
+
8
+ KUCOIN = "kucoin"
9
+ BINGX = "bingx"
10
+
11
+
12
+ class InternalExchange(ValidateEnumMixin, ExcludeEnumMixin, StrEnum):
13
+ """All exchanges we are using, including public (Exchange)"""
14
+
15
+ KUCOIN = "kucoin"
16
+ BINGX = "bingx"
17
+ BINANCE = "binance"
18
+ BYBIT = "bybit"
19
+ HYPERLIQUID = "hyperliquid"
20
+ BITGET = "bitget"
21
+
22
+
23
+ class MarketType(ValidateEnumMixin, ExcludeEnumMixin, StrEnum):
24
+ """
25
+ Market types
26
+ """
27
+
28
+ SPOT = "spot"
29
+ FUTURES = "futures"
@@ -1,6 +1,7 @@
1
1
  from enum import Enum, EnumMeta, StrEnum
2
2
  import logging
3
3
  from fastapi import status
4
+ from crypticorn.common.mixins import ExcludeEnumMixin
4
5
 
5
6
  logger = logging.getLogger(__name__)
6
7
 
@@ -18,7 +19,7 @@ class Fallback(EnumMeta):
18
19
  return cls.UNKNOWN_ERROR
19
20
 
20
21
 
21
- class ApiErrorType(StrEnum):
22
+ class ApiErrorType(ExcludeEnumMixin, StrEnum):
22
23
  """Type of API error"""
23
24
 
24
25
  USER_ERROR = "user error"
@@ -31,15 +32,17 @@ class ApiErrorType(StrEnum):
31
32
  """error that does not need to be handled or does not affect the program or is a placeholder."""
32
33
 
33
34
 
34
- class ApiErrorIdentifier(StrEnum):
35
+ class ApiErrorIdentifier(ExcludeEnumMixin, StrEnum):
35
36
  """API error identifiers"""
36
37
 
37
38
  ALLOCATION_BELOW_EXPOSURE = "allocation_below_current_exposure"
38
39
  ALLOCATION_BELOW_MINIMUM = "allocation_below_min_amount"
40
+ ALPHANUMERIC_CHARACTERS_ONLY = "alphanumeric_characters_only"
39
41
  BLACK_SWAN = "black_swan"
40
42
  BOT_ALREADY_DELETED = "bot_already_deleted"
41
43
  BOT_DISABLED = "bot_disabled"
42
44
  BOT_STOPPING_COMPLETED = "bot_stopping_completed"
45
+ BOT_STOPPING_STARTED = "bot_stopping_started"
43
46
  CLIENT_ORDER_ID_REPEATED = "client_order_id_already_exists"
44
47
  CONTENT_TYPE_ERROR = "invalid_content_type"
45
48
  DELETE_BOT_ERROR = "delete_bot_error"
@@ -56,6 +59,9 @@ class ApiErrorIdentifier(StrEnum):
56
59
  EXCHANGE_SYSTEM_CONFIG_ERROR = "exchange_system_configuration_error"
57
60
  EXCHANGE_SYSTEM_ERROR = "exchange_internal_system_error"
58
61
  EXCHANGE_USER_FROZEN = "exchange_user_account_is_frozen"
62
+ EXPIRED_API_KEY = "api_key_expired"
63
+ EXPIRED_BEARER = "bearer_token_expired"
64
+ FORBIDDEN = "forbidden"
59
65
  HEDGE_MODE_NOT_ACTIVE = "hedge_mode_not_active"
60
66
  HTTP_ERROR = "http_request_error"
61
67
  INSUFFICIENT_BALANCE = "insufficient_balance"
@@ -68,13 +74,15 @@ class ApiErrorIdentifier(StrEnum):
68
74
  INVALID_EXCHANGE_KEY = "invalid_exchange_key"
69
75
  INVALID_MARGIN_MODE = "invalid_margin_mode"
70
76
  INVALID_PARAMETER = "invalid_parameter_provided"
71
- JWT_EXPIRED = "jwt_expired"
72
77
  LEVERAGE_EXCEEDED = "leverage_limit_exceeded"
73
78
  LIQUIDATION_PRICE_VIOLATION = "order_violates_liquidation_price_constraints"
74
79
  NO_CREDENTIALS = "no_credentials"
75
80
  NOW_API_DOWN = "now_api_down"
76
- OBJECT_NOT_FOUND = "object_not_found"
77
81
  OBJECT_ALREADY_EXISTS = "object_already_exists"
82
+ OBJECT_CREATED = "object_created"
83
+ OBJECT_DELETED = "object_deleted"
84
+ OBJECT_NOT_FOUND = "object_not_found"
85
+ OBJECT_UPDATED = "object_updated"
78
86
  ORDER_ALREADY_FILLED = "order_is_already_filled"
79
87
  ORDER_IN_PROCESS = "order_is_being_processed"
80
88
  ORDER_LIMIT_EXCEEDED = "order_quantity_limit_exceeded"
@@ -90,6 +98,7 @@ class ApiErrorIdentifier(StrEnum):
90
98
  RISK_LIMIT_EXCEEDED = "risk_limit_exceeded"
91
99
  RPC_TIMEOUT = "rpc_timeout"
92
100
  SETTLEMENT_IN_PROGRESS = "system_settlement_in_process"
101
+ STRATEGY_ALREADY_EXISTS = "strategy_already_exists"
93
102
  STRATEGY_DISABLED = "strategy_disabled"
94
103
  STRATEGY_LEVERAGE_MISMATCH = "strategy_leverage_mismatch"
95
104
  STRATEGY_NOT_SUPPORTING_EXCHANGE = "strategy_not_supporting_exchange"
@@ -108,7 +117,7 @@ class ApiErrorIdentifier(StrEnum):
108
117
  return ApiError[self.value]
109
118
 
110
119
 
111
- class ApiErrorLevel(StrEnum):
120
+ class ApiErrorLevel(ExcludeEnumMixin, StrEnum):
112
121
  """API error levels"""
113
122
 
114
123
  ERROR = "error"
@@ -117,7 +126,7 @@ class ApiErrorLevel(StrEnum):
117
126
  WARNING = "warning"
118
127
 
119
128
 
120
- class ApiError(Enum, metaclass=Fallback):
129
+ class ApiError(ExcludeEnumMixin, Enum, metaclass=Fallback):
121
130
  """API error codes. Fallback to UNKNOWN_ERROR for error codes not yet published to PyPI."""
122
131
 
123
132
  ALLOCATION_BELOW_EXPOSURE = (
@@ -130,6 +139,11 @@ class ApiError(Enum, metaclass=Fallback):
130
139
  ApiErrorType.USER_ERROR,
131
140
  ApiErrorLevel.ERROR,
132
141
  )
142
+ ALPHANUMERIC_CHARACTERS_ONLY = (
143
+ ApiErrorIdentifier.ALPHANUMERIC_CHARACTERS_ONLY,
144
+ ApiErrorType.USER_ERROR,
145
+ ApiErrorLevel.ERROR,
146
+ )
133
147
  BLACK_SWAN = (
134
148
  ApiErrorIdentifier.BLACK_SWAN,
135
149
  ApiErrorType.USER_ERROR,
@@ -150,6 +164,11 @@ class ApiError(Enum, metaclass=Fallback):
150
164
  ApiErrorType.NO_ERROR,
151
165
  ApiErrorLevel.INFO,
152
166
  )
167
+ BOT_STOPPING_STARTED = (
168
+ ApiErrorIdentifier.BOT_STOPPING_STARTED,
169
+ ApiErrorType.NO_ERROR,
170
+ ApiErrorLevel.INFO,
171
+ )
153
172
  CLIENT_ORDER_ID_REPEATED = (
154
173
  ApiErrorIdentifier.CLIENT_ORDER_ID_REPEATED,
155
174
  ApiErrorType.SERVER_ERROR,
@@ -230,6 +249,21 @@ class ApiError(Enum, metaclass=Fallback):
230
249
  ApiErrorType.USER_ERROR,
231
250
  ApiErrorLevel.ERROR,
232
251
  )
252
+ EXPIRED_API_KEY = (
253
+ ApiErrorIdentifier.EXPIRED_API_KEY,
254
+ ApiErrorType.USER_ERROR,
255
+ ApiErrorLevel.ERROR,
256
+ )
257
+ EXPIRED_BEARER = (
258
+ ApiErrorIdentifier.EXPIRED_BEARER,
259
+ ApiErrorType.USER_ERROR,
260
+ ApiErrorLevel.ERROR,
261
+ )
262
+ FORBIDDEN = (
263
+ ApiErrorIdentifier.FORBIDDEN,
264
+ ApiErrorType.USER_ERROR,
265
+ ApiErrorLevel.ERROR,
266
+ )
233
267
  HEDGE_MODE_NOT_ACTIVE = (
234
268
  ApiErrorIdentifier.HEDGE_MODE_NOT_ACTIVE,
235
269
  ApiErrorType.USER_ERROR,
@@ -290,11 +324,6 @@ class ApiError(Enum, metaclass=Fallback):
290
324
  ApiErrorType.SERVER_ERROR,
291
325
  ApiErrorLevel.ERROR,
292
326
  )
293
- JWT_EXPIRED = (
294
- ApiErrorIdentifier.JWT_EXPIRED,
295
- ApiErrorType.SERVER_ERROR,
296
- ApiErrorLevel.ERROR,
297
- )
298
327
  LEVERAGE_EXCEEDED = (
299
328
  ApiErrorIdentifier.LEVERAGE_EXCEEDED,
300
329
  ApiErrorType.SERVER_ERROR,
@@ -315,15 +344,30 @@ class ApiError(Enum, metaclass=Fallback):
315
344
  ApiErrorType.SERVER_ERROR,
316
345
  ApiErrorLevel.ERROR,
317
346
  )
347
+ OBJECT_ALREADY_EXISTS = (
348
+ ApiErrorIdentifier.OBJECT_ALREADY_EXISTS,
349
+ ApiErrorType.SERVER_ERROR,
350
+ ApiErrorLevel.ERROR,
351
+ )
352
+ OBJECT_CREATED = (
353
+ ApiErrorIdentifier.OBJECT_CREATED,
354
+ ApiErrorType.SERVER_ERROR,
355
+ ApiErrorLevel.INFO,
356
+ )
357
+ OBJECT_DELETED = (
358
+ ApiErrorIdentifier.OBJECT_DELETED,
359
+ ApiErrorType.SERVER_ERROR,
360
+ ApiErrorLevel.INFO,
361
+ )
318
362
  OBJECT_NOT_FOUND = (
319
363
  ApiErrorIdentifier.OBJECT_NOT_FOUND,
320
364
  ApiErrorType.SERVER_ERROR,
321
365
  ApiErrorLevel.ERROR,
322
366
  )
323
- OBJECT_ALREADY_EXISTS = (
324
- ApiErrorIdentifier.OBJECT_ALREADY_EXISTS,
367
+ OBJECT_UPDATED = (
368
+ ApiErrorIdentifier.OBJECT_UPDATED,
325
369
  ApiErrorType.SERVER_ERROR,
326
- ApiErrorLevel.ERROR,
370
+ ApiErrorLevel.INFO,
327
371
  )
328
372
  ORDER_ALREADY_FILLED = (
329
373
  ApiErrorIdentifier.ORDER_ALREADY_FILLED,
@@ -400,6 +444,11 @@ class ApiError(Enum, metaclass=Fallback):
400
444
  ApiErrorType.EXCHANGE_ERROR,
401
445
  ApiErrorLevel.ERROR,
402
446
  )
447
+ STRATEGY_ALREADY_EXISTS = (
448
+ ApiErrorIdentifier.STRATEGY_ALREADY_EXISTS,
449
+ ApiErrorType.USER_ERROR,
450
+ ApiErrorLevel.ERROR,
451
+ )
403
452
  STRATEGY_DISABLED = (
404
453
  ApiErrorIdentifier.STRATEGY_DISABLED,
405
454
  ApiErrorType.USER_ERROR,
@@ -476,18 +525,18 @@ class ApiError(Enum, metaclass=Fallback):
476
525
  class HttpStatusMapper:
477
526
  """Map API errors to HTTP status codes."""
478
527
 
479
- # TODO: decide if we need all of these mappings, since most errors are not exposed to the client via HTTP
480
- # in case we remove some, update the pytest length check
481
528
  _mapping = {
482
529
  # Authentication/Authorization
483
- ApiError.JWT_EXPIRED: status.HTTP_401_UNAUTHORIZED,
530
+ ApiError.EXPIRED_BEARER: status.HTTP_401_UNAUTHORIZED,
484
531
  ApiError.INVALID_BEARER: status.HTTP_401_UNAUTHORIZED,
532
+ ApiError.EXPIRED_API_KEY: status.HTTP_401_UNAUTHORIZED,
485
533
  ApiError.INVALID_API_KEY: status.HTTP_401_UNAUTHORIZED,
486
534
  ApiError.NO_CREDENTIALS: status.HTTP_401_UNAUTHORIZED,
487
535
  ApiError.INSUFFICIENT_SCOPES: status.HTTP_403_FORBIDDEN,
488
536
  ApiError.EXCHANGE_PERMISSION_DENIED: status.HTTP_403_FORBIDDEN,
489
537
  ApiError.EXCHANGE_USER_FROZEN: status.HTTP_403_FORBIDDEN,
490
538
  ApiError.TRADING_LOCKED: status.HTTP_403_FORBIDDEN,
539
+ ApiError.FORBIDDEN: status.HTTP_403_FORBIDDEN,
491
540
  # Not Found
492
541
  ApiError.URL_NOT_FOUND: status.HTTP_404_NOT_FOUND,
493
542
  ApiError.OBJECT_NOT_FOUND: status.HTTP_404_NOT_FOUND,
@@ -499,6 +548,7 @@ class HttpStatusMapper:
499
548
  ApiError.OBJECT_ALREADY_EXISTS: status.HTTP_409_CONFLICT,
500
549
  ApiError.EXCHANGE_KEY_ALREADY_EXISTS: status.HTTP_409_CONFLICT,
501
550
  ApiError.BOT_ALREADY_DELETED: status.HTTP_409_CONFLICT,
551
+ ApiError.STRATEGY_ALREADY_EXISTS: status.HTTP_409_CONFLICT,
502
552
  # Invalid Content
503
553
  ApiError.CONTENT_TYPE_ERROR: status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
504
554
  ApiError.INVALID_DATA_REQUEST: status.HTTP_422_UNPROCESSABLE_ENTITY,
@@ -519,6 +569,7 @@ class HttpStatusMapper:
519
569
  ApiError.POSITION_SUSPENDED: status.HTTP_503_SERVICE_UNAVAILABLE,
520
570
  ApiError.TRADING_SUSPENDED: status.HTTP_503_SERVICE_UNAVAILABLE,
521
571
  # Bad Requests (400) - Invalid parameters or states
572
+ ApiError.ALPHANUMERIC_CHARACTERS_ONLY: status.HTTP_400_BAD_REQUEST,
522
573
  ApiError.ALLOCATION_BELOW_EXPOSURE: status.HTTP_400_BAD_REQUEST,
523
574
  ApiError.ALLOCATION_BELOW_MINIMUM: status.HTTP_400_BAD_REQUEST,
524
575
  ApiError.BLACK_SWAN: status.HTTP_400_BAD_REQUEST,
@@ -555,6 +606,10 @@ class HttpStatusMapper:
555
606
  # Success cases
556
607
  ApiError.SUCCESS: status.HTTP_200_OK,
557
608
  ApiError.BOT_STOPPING_COMPLETED: status.HTTP_200_OK,
609
+ ApiError.BOT_STOPPING_STARTED: status.HTTP_200_OK,
610
+ ApiError.OBJECT_CREATED: status.HTTP_201_CREATED,
611
+ ApiError.OBJECT_UPDATED: status.HTTP_200_OK,
612
+ ApiError.OBJECT_DELETED: status.HTTP_204_NO_CONTENT,
558
613
  }
559
614
 
560
615
  @classmethod