crypticorn 2.4.6__tar.gz → 2.5.0__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 (307) hide show
  1. {crypticorn-2.4.6 → crypticorn-2.5.0}/PKG-INFO +8 -2
  2. {crypticorn-2.4.6 → crypticorn-2.5.0}/README.md +2 -0
  3. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/cli/init.py +7 -4
  4. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/__init__.py +1 -0
  5. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/auth.py +11 -9
  6. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/errors.py +26 -0
  7. crypticorn-2.5.0/crypticorn/common/exceptions.py +83 -0
  8. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/utils.py +23 -6
  9. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/__init__.py +10 -3
  10. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api/__init__.py +1 -0
  11. crypticorn-2.5.0/crypticorn/klines/client/api/change_in_timeframe_api.py +331 -0
  12. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api/funding_rates_api.py +13 -13
  13. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api/health_check_api.py +8 -8
  14. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api/ohlcv_data_api.py +38 -26
  15. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api/symbols_api.py +26 -20
  16. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api/udf_api.py +229 -229
  17. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api_client.py +8 -5
  18. crypticorn-2.5.0/crypticorn/klines/client/configuration.py +620 -0
  19. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/__init__.py +9 -3
  20. crypticorn-2.5.0/crypticorn/klines/client/models/base_response_list_change_in_timeframe_response.py +123 -0
  21. crypticorn-2.5.0/crypticorn/klines/client/models/change_in_timeframe_response.py +86 -0
  22. crypticorn-2.5.0/crypticorn/klines/client/models/market_type.py +35 -0
  23. crypticorn-2.5.0/crypticorn/klines/client/models/response_get_udf_history.py +198 -0
  24. crypticorn-2.5.0/crypticorn/klines/client/rest.py +198 -0
  25. crypticorn-2.5.0/crypticorn/klines/main.py +84 -0
  26. crypticorn-2.5.0/crypticorn/metrics/main.py +103 -0
  27. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/__init__.py +0 -3
  28. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/api/now_payments_api.py +1 -53
  29. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/__init__.py +0 -3
  30. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/payment.py +3 -3
  31. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/scope.py +6 -1
  32. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/exchange_key_model.py +2 -1
  33. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn.egg-info/PKG-INFO +8 -2
  34. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn.egg-info/SOURCES.txt +8 -0
  35. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn.egg-info/requires.txt +6 -1
  36. {crypticorn-2.4.6 → crypticorn-2.5.0}/pyproject.toml +7 -6
  37. {crypticorn-2.4.6 → crypticorn-2.5.0}/requirements/dev.txt +3 -0
  38. crypticorn-2.5.0/requirements/extra.txt +2 -0
  39. {crypticorn-2.4.6 → crypticorn-2.5.0}/requirements/main.txt +0 -1
  40. {crypticorn-2.4.6 → crypticorn-2.5.0}/tests/test_auth_client.py +1 -13
  41. crypticorn-2.5.0/tests/test_config.py +21 -0
  42. crypticorn-2.4.6/crypticorn/klines/client/configuration.py +0 -577
  43. crypticorn-2.4.6/crypticorn/klines/client/rest.py +0 -246
  44. crypticorn-2.4.6/crypticorn/klines/main.py +0 -69
  45. crypticorn-2.4.6/crypticorn/metrics/main.py +0 -103
  46. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/__init__.py +0 -0
  47. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/__init__.py +0 -0
  48. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/__init__.py +0 -0
  49. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api/__init__.py +0 -0
  50. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api/admin_api.py +0 -0
  51. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api/auth_api.py +0 -0
  52. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api/service_api.py +0 -0
  53. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api/user_api.py +0 -0
  54. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api/wallet_api.py +0 -0
  55. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api_client.py +0 -0
  56. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/api_response.py +0 -0
  57. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/configuration.py +0 -0
  58. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/exceptions.py +0 -0
  59. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/__init__.py +0 -0
  60. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/add_wallet200_response.py +0 -0
  61. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/add_wallet_request.py +0 -0
  62. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/authorize_user200_response.py +0 -0
  63. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/authorize_user200_response_auth.py +0 -0
  64. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/authorize_user_request.py +0 -0
  65. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/create_api_key200_response.py +0 -0
  66. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/create_api_key_request.py +0 -0
  67. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/create_user_request.py +0 -0
  68. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/get_api_keys200_response_inner.py +0 -0
  69. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/list_wallets200_response.py +0 -0
  70. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner.py +0 -0
  71. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_sale_round.py +0 -0
  72. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet.py +0 -0
  73. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet_vesting_wallets_inner.py +0 -0
  74. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/list_wallets200_response_data_inner.py +0 -0
  75. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/list_wallets200_response_user_value.py +0 -0
  76. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/logout_default_response.py +0 -0
  77. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/logout_default_response_issues_inner.py +0 -0
  78. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/oauth_callback200_response.py +0 -0
  79. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/oauth_callback200_response_user.py +0 -0
  80. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/refresh_token_info200_response.py +0 -0
  81. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/refresh_token_info200_response_user_session.py +0 -0
  82. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/resend_verification_email_request.py +0 -0
  83. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/revoke_user_tokens_request.py +0 -0
  84. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/rotate_tokens200_response.py +0 -0
  85. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/token_info200_response.py +0 -0
  86. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/unlink_wallet_request.py +0 -0
  87. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/update_user_request.py +0 -0
  88. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/user_reset_password_request.py +0 -0
  89. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/user_set_password_request.py +0 -0
  90. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/verify200_response.py +0 -0
  91. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/verify_email200_response.py +0 -0
  92. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/verify_email200_response_auth.py +0 -0
  93. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/verify_email200_response_auth_auth.py +0 -0
  94. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/verify_email_request.py +0 -0
  95. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/verify_wallet_request.py +0 -0
  96. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/wallet_verified200_response.py +0 -0
  97. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/models/whoami200_response.py +0 -0
  98. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/py.typed +0 -0
  99. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/client/rest.py +0 -0
  100. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/auth/main.py +0 -0
  101. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/cli/__init__.py +0 -0
  102. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/cli/__main__.py +0 -0
  103. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/cli/templates/__init__.py +0 -0
  104. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/cli/templates/auth.py +0 -0
  105. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/client.py +0 -0
  106. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/enums.py +0 -0
  107. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/pydantic.py +0 -0
  108. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/scopes.py +0 -0
  109. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/sorter.py +0 -0
  110. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/common/urls.py +0 -0
  111. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/__init__.py +0 -0
  112. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/__init__.py +0 -0
  113. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/api/__init__.py +0 -0
  114. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/api/data_api.py +0 -0
  115. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/api/models_api.py +0 -0
  116. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/api/status_api.py +0 -0
  117. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/api_client.py +0 -0
  118. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/api_response.py +0 -0
  119. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/configuration.py +0 -0
  120. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/exceptions.py +0 -0
  121. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/__init__.py +0 -0
  122. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/coins.py +0 -0
  123. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/data_download_response.py +0 -0
  124. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/data_info.py +0 -0
  125. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/data_value_value_value_inner.py +0 -0
  126. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/data_version.py +0 -0
  127. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/download_links.py +0 -0
  128. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/evaluation.py +0 -0
  129. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/evaluation_response.py +0 -0
  130. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/feature_size.py +0 -0
  131. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/http_validation_error.py +0 -0
  132. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/model.py +0 -0
  133. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/model_create.py +0 -0
  134. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/model_status.py +0 -0
  135. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/model_update.py +0 -0
  136. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/target.py +0 -0
  137. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/target_type.py +0 -0
  138. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/validation_error.py +0 -0
  139. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/models/validation_error_loc_inner.py +0 -0
  140. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/py.typed +0 -0
  141. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/client/rest.py +0 -0
  142. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/hive/main.py +0 -0
  143. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/__init__.py +0 -0
  144. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/api_response.py +0 -0
  145. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/exceptions.py +0 -0
  146. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/base_response_health_check_response.py +0 -0
  147. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/base_response_list_funding_rate_response.py +0 -0
  148. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/base_response_list_str.py +0 -0
  149. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/base_response_ohlcv_response.py +0 -0
  150. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/error_response.py +0 -0
  151. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/exchange.py +0 -0
  152. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/funding_rate_response.py +0 -0
  153. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/health_check_response.py +0 -0
  154. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/history_error_response.py +0 -0
  155. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/history_no_data_response.py +0 -0
  156. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/history_success_response.py +0 -0
  157. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/http_validation_error.py +0 -0
  158. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/market.py +0 -0
  159. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/ohlcv_response.py +0 -0
  160. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/resolution.py +0 -0
  161. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/response_get_history_udf_history_get.py +0 -0
  162. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/search_symbol_response.py +0 -0
  163. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/sort_direction.py +0 -0
  164. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/symbol_group_response.py +0 -0
  165. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/symbol_info_response.py +0 -0
  166. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/symbol_type.py +0 -0
  167. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/timeframe.py +0 -0
  168. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/udf_config_response.py +0 -0
  169. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/validation_error.py +0 -0
  170. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/models/validation_error_loc_inner.py +0 -0
  171. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/klines/client/py.typed +0 -0
  172. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/__init__.py +0 -0
  173. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/__init__.py +0 -0
  174. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/__init__.py +0 -0
  175. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/exchanges_api.py +0 -0
  176. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/health_check_api.py +0 -0
  177. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/indicators_api.py +0 -0
  178. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/logs_api.py +0 -0
  179. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/marketcap_api.py +0 -0
  180. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/markets_api.py +0 -0
  181. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api/tokens_api.py +0 -0
  182. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api_client.py +0 -0
  183. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/api_response.py +0 -0
  184. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/configuration.py +0 -0
  185. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/exceptions.py +0 -0
  186. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/__init__.py +0 -0
  187. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/base_response_dict.py +0 -0
  188. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/base_response_health_check_response.py +0 -0
  189. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/base_response_list_dict.py +0 -0
  190. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/base_response_list_exchange_mapping.py +0 -0
  191. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/base_response_list_str.py +0 -0
  192. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/error_response.py +0 -0
  193. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/exchange_mapping.py +0 -0
  194. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/health_check_response.py +0 -0
  195. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/http_validation_error.py +0 -0
  196. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/market.py +0 -0
  197. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/market_type.py +0 -0
  198. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/severity.py +0 -0
  199. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/time_interval.py +0 -0
  200. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/trading_status.py +0 -0
  201. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/validation_error.py +0 -0
  202. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/models/validation_error_loc_inner.py +0 -0
  203. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/py.typed +0 -0
  204. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/metrics/client/rest.py +0 -0
  205. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/__init__.py +0 -0
  206. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/api/__init__.py +0 -0
  207. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/api/payments_api.py +0 -0
  208. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/api/products_api.py +0 -0
  209. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/api/status_api.py +0 -0
  210. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/api_client.py +0 -0
  211. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/api_response.py +0 -0
  212. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/configuration.py +0 -0
  213. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/exceptions.py +0 -0
  214. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/api_status_res.py +0 -0
  215. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/body_create_now_invoice.py +0 -0
  216. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/body_create_product.py +0 -0
  217. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/body_get_products.py +0 -0
  218. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/body_handle_now_webhook.py +0 -0
  219. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/body_update_product.py +0 -0
  220. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/combined_payment_history.py +0 -0
  221. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/create_invoice_req.py +0 -0
  222. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/create_invoice_res.py +0 -0
  223. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/currency.py +0 -0
  224. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/estimate_price_req.py +0 -0
  225. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/estimate_price_res.py +0 -0
  226. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/get_currencies_res.py +0 -0
  227. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/get_payment_status_res.py +0 -0
  228. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/get_payments_list_res.py +0 -0
  229. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/http_validation_error.py +0 -0
  230. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/min_amount_req.py +0 -0
  231. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/min_amount_res.py +0 -0
  232. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/now_api_status_res.py +0 -0
  233. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/now_create_invoice_req.py +0 -0
  234. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/now_create_invoice_res.py +0 -0
  235. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/now_fee_structure.py +0 -0
  236. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/now_payment_model.py +0 -0
  237. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/now_payment_status.py +0 -0
  238. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/now_webhook_payload.py +0 -0
  239. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/partial_product_update_model.py +0 -0
  240. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/payment_status.py +0 -0
  241. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product.py +0 -0
  242. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product_create.py +0 -0
  243. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product_model.py +0 -0
  244. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product_read.py +0 -0
  245. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product_sub_read.py +0 -0
  246. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product_subs_model.py +0 -0
  247. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product_update.py +0 -0
  248. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/product_update_model.py +0 -0
  249. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/services.py +0 -0
  250. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/unified_payment_model.py +0 -0
  251. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/validation_error.py +0 -0
  252. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/models/validation_error_loc_inner.py +0 -0
  253. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/py.typed +0 -0
  254. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/client/rest.py +0 -0
  255. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/pay/main.py +0 -0
  256. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/__init__.py +0 -0
  257. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/__init__.py +0 -0
  258. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/__init__.py +0 -0
  259. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/api_keys_api.py +0 -0
  260. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/bots_api.py +0 -0
  261. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/exchanges_api.py +0 -0
  262. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/futures_trading_panel_api.py +0 -0
  263. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/notifications_api.py +0 -0
  264. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/orders_api.py +0 -0
  265. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/status_api.py +0 -0
  266. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/strategies_api.py +0 -0
  267. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api/trading_actions_api.py +0 -0
  268. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api_client.py +0 -0
  269. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/api_response.py +0 -0
  270. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/configuration.py +0 -0
  271. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/exceptions.py +0 -0
  272. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/__init__.py +0 -0
  273. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/action_model.py +0 -0
  274. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/api_error_identifier.py +0 -0
  275. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/api_error_level.py +0 -0
  276. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/api_error_type.py +0 -0
  277. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/api_key_model.py +0 -0
  278. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/bot_model.py +0 -0
  279. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/bot_status.py +0 -0
  280. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/exchange.py +0 -0
  281. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/execution_ids.py +0 -0
  282. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/futures_balance.py +0 -0
  283. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/futures_trading_action.py +0 -0
  284. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/http_validation_error.py +0 -0
  285. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/margin_mode.py +0 -0
  286. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/market_type.py +0 -0
  287. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/notification_model.py +0 -0
  288. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/order_model.py +0 -0
  289. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/order_status.py +0 -0
  290. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/post_futures_action.py +0 -0
  291. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/strategy_exchange_info.py +0 -0
  292. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/strategy_model_input.py +0 -0
  293. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/strategy_model_output.py +0 -0
  294. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/tpsl.py +0 -0
  295. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/trading_action_type.py +0 -0
  296. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/validation_error.py +0 -0
  297. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/models/validation_error_loc_inner.py +0 -0
  298. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/py.typed +0 -0
  299. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/client/rest.py +0 -0
  300. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn/trade/main.py +0 -0
  301. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn.egg-info/dependency_links.txt +0 -0
  302. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn.egg-info/entry_points.txt +0 -0
  303. {crypticorn-2.4.6 → crypticorn-2.5.0}/crypticorn.egg-info/top_level.txt +0 -0
  304. {crypticorn-2.4.6 → crypticorn-2.5.0}/requirements/test.txt +0 -0
  305. {crypticorn-2.4.6 → crypticorn-2.5.0}/setup.cfg +0 -0
  306. {crypticorn-2.4.6 → crypticorn-2.5.0}/tests/test_enums.py +0 -0
  307. {crypticorn-2.4.6 → crypticorn-2.5.0}/tests/test_errors.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crypticorn
3
- Version: 2.4.6
3
+ Version: 2.5.0
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
@@ -21,19 +21,23 @@ Requires-Dist: aiohttp<4.0.0,>=3.8.4
21
21
  Requires-Dist: aiohttp-retry<3.0.0,>=2.8.3
22
22
  Requires-Dist: pydantic<3.0.0,>=2.0.0
23
23
  Requires-Dist: typing-extensions<5.0.0,>=4.7.1
24
- Requires-Dist: pandas<3.0.0,>=2.2.0
25
24
  Requires-Dist: requests<3.0.0,>=2.32.0
26
25
  Requires-Dist: tqdm<5.0.0,>=4.67.0
27
26
  Provides-Extra: dev
28
27
  Requires-Dist: streamlit; extra == "dev"
29
28
  Requires-Dist: httpx; extra == "dev"
30
29
  Requires-Dist: black; extra == "dev"
30
+ Requires-Dist: ruff; extra == "dev"
31
+ Requires-Dist: isort; extra == "dev"
32
+ Requires-Dist: mypy; extra == "dev"
31
33
  Requires-Dist: openapi-generator-cli<8.0.0,>=7.12.0; extra == "dev"
32
34
  Provides-Extra: test
33
35
  Requires-Dist: pytest==8.3.5; extra == "test"
34
36
  Requires-Dist: pytest-asyncio==0.26.0; extra == "test"
35
37
  Requires-Dist: pytest-cov==6.1.1; extra == "test"
36
38
  Requires-Dist: python-dotenv==1.0.1; extra == "test"
39
+ Provides-Extra: extra
40
+ Requires-Dist: pandas<3.0.0,>=2.2.0; extra == "extra"
37
41
 
38
42
  # What is Crypticorn?
39
43
 
@@ -49,6 +53,8 @@ cryptocurrency market.
49
53
 
50
54
  ## Installation
51
55
 
56
+ >Python 3.10+ required
57
+
52
58
  You can install the latest stable version from PyPi:
53
59
  ```bash
54
60
  pip install crypticorn
@@ -12,6 +12,8 @@ cryptocurrency market.
12
12
 
13
13
  ## Installation
14
14
 
15
+ >Python 3.10+ required
16
+
15
17
  You can install the latest stable version from PyPi:
16
18
  ```bash
17
19
  pip install crypticorn
@@ -57,7 +57,10 @@ def init_ruff(force):
57
57
  def init_docker(output, force):
58
58
  """Add Dockerfile"""
59
59
  root = get_git_root()
60
- target = Path(output) if output else root / "Dockerfile"
60
+ if output and Path(output).is_file():
61
+ click.secho("Output path is a file, please provide a directory path", fg="red")
62
+ return
63
+ target = (Path(output) if output else root) / "Dockerfile"
61
64
  if target.exists() and not force:
62
65
  click.secho("File already exists, use --force / -f to overwrite", fg="red")
63
66
  return
@@ -73,10 +76,10 @@ def init_docker(output, force):
73
76
  def init_auth(output, force):
74
77
  """Add auth.py with auth handler. Everything you need to start using the auth service."""
75
78
  root = get_git_root()
76
- if Path(output).is_dir():
77
- click.secho("Output path is a directory, please provide a file path", fg="red")
79
+ if output and Path(output).is_file():
80
+ click.secho("Output path is a file, please provide a directory path", fg="red")
78
81
  return
79
- target = Path(output) if output else root / "src/auth.py"
82
+ target = (Path(output) if output else root) / "auth.py"
80
83
  if target.exists() and not force:
81
84
  click.secho("File already exists, use --force / -f to overwrite", fg="red")
82
85
  return
@@ -5,3 +5,4 @@ from crypticorn.common.pydantic import *
5
5
  from crypticorn.common.auth import *
6
6
  from crypticorn.common.enums import *
7
7
  from crypticorn.common.utils import *
8
+ from crypticorn.common.exceptions import *
@@ -9,7 +9,7 @@ from crypticorn.common import (
9
9
  Scope,
10
10
  Service,
11
11
  )
12
- from fastapi import Depends, HTTPException, Query, status
12
+ from fastapi import Depends, HTTPException, Query, status, WebSocketException
13
13
  from fastapi.security import (
14
14
  HTTPAuthorizationCredentials,
15
15
  SecurityScopes,
@@ -183,7 +183,7 @@ class AuthHandler:
183
183
  Verifies the API key and checks if the user scopes are a subset of the API scopes.
184
184
  Use this function if you only want to allow access via the API key.
185
185
  """
186
- return await self.api_key_auth(api_key=api_key, sec=sec)
186
+ return await self.ws_combined_auth(bearer=None, api_key=api_key, sec=sec)
187
187
 
188
188
  async def ws_bearer_auth(
189
189
  self,
@@ -194,12 +194,7 @@ class AuthHandler:
194
194
  Verifies the bearer token and checks if the user scopes are a subset of the API scopes.
195
195
  Use this function if you only want to allow access via the bearer token.
196
196
  """
197
- credentials = (
198
- HTTPAuthorizationCredentials(scheme="Bearer", credentials=bearer)
199
- if bearer
200
- else None
201
- )
202
- return await self.bearer_auth(bearer=credentials, sec=sec)
197
+ return await self.ws_combined_auth(bearer=bearer, api_key=None, sec=sec)
203
198
 
204
199
  async def ws_combined_auth(
205
200
  self,
@@ -216,4 +211,11 @@ class AuthHandler:
216
211
  if bearer
217
212
  else None
218
213
  )
219
- return await self.combined_auth(bearer=credentials, api_key=api_key, sec=sec)
214
+ response = await self.combined_auth(
215
+ bearer=credentials, api_key=api_key, sec=sec
216
+ )
217
+ if isinstance(response, HTTPException):
218
+ raise WebSocketException(
219
+ code=status.WS_1008_POLICY_VIOLATION, reason=response.detail
220
+ )
221
+ return response
@@ -36,6 +36,7 @@ class ApiErrorIdentifier(StrEnum):
36
36
 
37
37
  ALLOCATION_BELOW_EXPOSURE = "allocation_below_current_exposure"
38
38
  ALLOCATION_BELOW_MINIMUM = "allocation_below_min_amount"
39
+ ALPHANUMERIC_CHARACTERS_ONLY = "alphanumeric_characters_only"
39
40
  BLACK_SWAN = "black_swan"
40
41
  BOT_ALREADY_DELETED = "bot_already_deleted"
41
42
  BOT_DISABLED = "bot_disabled"
@@ -56,6 +57,7 @@ class ApiErrorIdentifier(StrEnum):
56
57
  EXCHANGE_SYSTEM_CONFIG_ERROR = "exchange_system_configuration_error"
57
58
  EXCHANGE_SYSTEM_ERROR = "exchange_internal_system_error"
58
59
  EXCHANGE_USER_FROZEN = "exchange_user_account_is_frozen"
60
+ FORBIDDEN = "forbidden"
59
61
  HEDGE_MODE_NOT_ACTIVE = "hedge_mode_not_active"
60
62
  HTTP_ERROR = "http_request_error"
61
63
  INSUFFICIENT_BALANCE = "insufficient_balance"
@@ -63,6 +65,8 @@ class ApiErrorIdentifier(StrEnum):
63
65
  INSUFFICIENT_SCOPES = "insufficient_scopes"
64
66
  INVALID_API_KEY = "invalid_api_key"
65
67
  INVALID_BEARER = "invalid_bearer"
68
+ INVALID_DATA_REQUEST = "invalid_data"
69
+ INVALID_DATA_RESPONSE = "invalid_data_response"
66
70
  INVALID_EXCHANGE_KEY = "invalid_exchange_key"
67
71
  INVALID_MARGIN_MODE = "invalid_margin_mode"
68
72
  INVALID_PARAMETER = "invalid_parameter_provided"
@@ -100,6 +104,11 @@ class ApiErrorIdentifier(StrEnum):
100
104
  UNKNOWN_ERROR = "unknown_error_occurred"
101
105
  URL_NOT_FOUND = "requested_resource_not_found"
102
106
 
107
+ @property
108
+ def get_error_code(self) -> str:
109
+ """Get the corresponding ApiError."""
110
+ return ApiError[self.value]
111
+
103
112
 
104
113
  class ApiErrorLevel(StrEnum):
105
114
  """API error levels"""
@@ -123,6 +132,11 @@ class ApiError(Enum, metaclass=Fallback):
123
132
  ApiErrorType.USER_ERROR,
124
133
  ApiErrorLevel.ERROR,
125
134
  )
135
+ ALPHANUMERIC_CHARACTERS_ONLY = (
136
+ ApiErrorIdentifier.ALPHANUMERIC_CHARACTERS_ONLY,
137
+ ApiErrorType.USER_ERROR,
138
+ ApiErrorLevel.ERROR,
139
+ )
126
140
  BLACK_SWAN = (
127
141
  ApiErrorIdentifier.BLACK_SWAN,
128
142
  ApiErrorType.USER_ERROR,
@@ -258,6 +272,16 @@ class ApiError(Enum, metaclass=Fallback):
258
272
  ApiErrorType.USER_ERROR,
259
273
  ApiErrorLevel.ERROR,
260
274
  )
275
+ INVALID_DATA_REQUEST = (
276
+ ApiErrorIdentifier.INVALID_DATA_REQUEST,
277
+ ApiErrorType.USER_ERROR,
278
+ ApiErrorLevel.ERROR,
279
+ )
280
+ INVALID_DATA_RESPONSE = (
281
+ ApiErrorIdentifier.INVALID_DATA_RESPONSE,
282
+ ApiErrorType.USER_ERROR,
283
+ ApiErrorLevel.ERROR,
284
+ )
261
285
  INVALID_EXCHANGE_KEY = (
262
286
  ApiErrorIdentifier.INVALID_EXCHANGE_KEY,
263
287
  ApiErrorType.SERVER_ERROR,
@@ -484,6 +508,8 @@ class HttpStatusMapper:
484
508
  ApiError.BOT_ALREADY_DELETED: status.HTTP_409_CONFLICT,
485
509
  # Invalid Content
486
510
  ApiError.CONTENT_TYPE_ERROR: status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
511
+ ApiError.INVALID_DATA_REQUEST: status.HTTP_422_UNPROCESSABLE_ENTITY,
512
+ ApiError.INVALID_DATA_RESPONSE: status.HTTP_422_UNPROCESSABLE_ENTITY,
487
513
  # Rate Limits
488
514
  ApiError.EXCHANGE_RATE_LIMIT: status.HTTP_429_TOO_MANY_REQUESTS,
489
515
  ApiError.REQUEST_SCOPE_EXCEEDED: status.HTTP_429_TOO_MANY_REQUESTS,
@@ -0,0 +1,83 @@
1
+ from enum import Enum
2
+ from typing import Optional, Dict, Type, Any
3
+ from pydantic import BaseModel, Field
4
+ from fastapi import HTTPException as FastAPIHTTPException, Request, FastAPI
5
+ from fastapi.exceptions import RequestValidationError, ResponseValidationError
6
+ from fastapi.openapi.utils import get_openapi
7
+ from fastapi.responses import JSONResponse
8
+ from crypticorn.common import ApiError, ApiErrorIdentifier, ApiErrorType, ApiErrorLevel
9
+
10
+ class ExceptionDetail(BaseModel):
11
+ '''This is the detail of the exception. It is used to enrich the exception with additional information by unwrapping the ApiError into its components.'''
12
+ message: Optional[str] = Field(None, description="An additional error message")
13
+ code: ApiErrorIdentifier = Field(..., description="The unique error code")
14
+ type: ApiErrorType = Field(..., description="The type of error")
15
+ level: ApiErrorLevel = Field(..., description="The level of the error")
16
+ status_code: int = Field(..., description="The HTTP status code")
17
+ details: Any = Field(None, description="Additional details about the error")
18
+
19
+
20
+ class ExceptionContent(BaseModel):
21
+ '''This is the detail of the exception. Pass an ApiError to the constructor and an optional human readable message.'''
22
+ error: ApiError = Field(..., description="The unique error code")
23
+ message: Optional[str] = Field(None, description="An additional error message")
24
+ details: Any = Field(None, description="Additional details about the error")
25
+
26
+ def enrich(self) -> ExceptionDetail:
27
+ return ExceptionDetail(
28
+ message=self.message,
29
+ code=self.error.identifier,
30
+ type=self.error.type,
31
+ level=self.error.level,
32
+ status_code=self.error.status_code,
33
+ details=self.details,
34
+ )
35
+
36
+ class HTTPException(FastAPIHTTPException):
37
+ """A custom HTTP exception wrapper around FastAPI's HTTPException.
38
+ It allows for a more structured way to handle errors, with a message and an error code. The status code is being derived from the detail's error.
39
+ The ApiError class is the source of truth for everything. If the error is not yet implemented, there are fallbacks to avoid errors while testing.
40
+ """
41
+
42
+ def __init__(
43
+ self,
44
+ content: ExceptionContent,
45
+ headers: Optional[Dict[str, str]] = None,
46
+ ):
47
+ assert isinstance(content, ExceptionContent)
48
+ body = content.enrich()
49
+ super().__init__(
50
+ status_code=body.status_code,
51
+ detail=body.model_dump(mode="json"),
52
+ headers=headers,
53
+ )
54
+
55
+ async def general_handler(request: Request, exc: Exception):
56
+ '''This is the default exception handler for all exceptions.'''
57
+ body = ExceptionContent(message=str(exc), error=ApiError.UNKNOWN_ERROR)
58
+ return JSONResponse(status_code=body.error.status_code, content=HTTPException(content=body).detail)
59
+
60
+ async def request_validation_handler(request: Request, exc: RequestValidationError):
61
+ '''This is the exception handler for all request validation errors.'''
62
+ body = ExceptionContent(message=str(exc), error=ApiError.INVALID_DATA_REQUEST)
63
+ return JSONResponse(status_code=body.error.status_code, content=HTTPException(content=body).detail)
64
+
65
+ async def response_validation_handler(request: Request, exc: ResponseValidationError):
66
+ '''This is the exception handler for all response validation errors.'''
67
+ body = ExceptionContent(message=str(exc), error=ApiError.INVALID_DATA_RESPONSE)
68
+ return JSONResponse(status_code=body.error.status_code, content=HTTPException(content=body).detail)
69
+
70
+ async def http_handler(request: Request, exc: HTTPException):
71
+ '''This is the exception handler for HTTPExceptions. It unwraps the HTTPException and returns the detail in a flat JSON response.'''
72
+ return JSONResponse(status_code=exc.status_code, content=exc.detail)
73
+
74
+ def register_exception_handlers(app: FastAPI):
75
+ '''Utility to register serveral exception handlers in one go. Catches Exception, HTTPException and Data Validation errors and responds with a unified json body.'''
76
+ app.add_exception_handler(Exception, general_handler)
77
+ app.add_exception_handler(FastAPIHTTPException, http_handler)
78
+ app.add_exception_handler(RequestValidationError, request_validation_handler)
79
+ app.add_exception_handler(ResponseValidationError, response_validation_handler)
80
+
81
+ exception_response = {
82
+ "default": {"model": ExceptionDetail, "description": "Error response"}
83
+ }
@@ -1,27 +1,29 @@
1
- from typing import Any
1
+ from typing import Any, Union
2
2
  from decimal import Decimal
3
3
  import string
4
4
  import random
5
-
6
5
  from fastapi import HTTPException
7
6
  from fastapi import status
7
+ from typing_extensions import deprecated
8
8
 
9
9
  from crypticorn.common import ApiError
10
10
 
11
11
 
12
- def throw_if_none(value: Any, message: ApiError) -> None:
12
+ def throw_if_none(value: Any, message: Union[ApiError, str]) -> None:
13
13
  """Throws an FastAPI HTTPException if the value is None."""
14
14
  if value is None:
15
15
  raise HTTPException(
16
- status_code=status.HTTP_404_NOT_FOUND, detail=message.identifier
16
+ status_code=status.HTTP_404_NOT_FOUND,
17
+ detail=message.identifier if isinstance(message, ApiError) else message,
17
18
  )
18
19
 
19
20
 
20
- def throw_if_falsy(value: Any, message: ApiError) -> None:
21
+ def throw_if_falsy(value: Any, message: Union[ApiError, str]) -> None:
21
22
  """Throws an FastAPI HTTPException if the value is False."""
22
23
  if not value:
23
24
  raise HTTPException(
24
- status_code=status.HTTP_400_BAD_REQUEST, detail=message.identifier
25
+ status_code=status.HTTP_400_BAD_REQUEST,
26
+ detail=message.identifier if isinstance(message, ApiError) else message,
25
27
  )
26
28
 
27
29
 
@@ -32,6 +34,7 @@ def gen_random_id(length: int = 20) -> str:
32
34
  return "".join(random.choice(charset) for _ in range(length))
33
35
 
34
36
 
37
+ @deprecated("Use math.isclose instead. Will be removed in a future version.")
35
38
  def is_equal(
36
39
  a: float | Decimal,
37
40
  b: float | Decimal,
@@ -50,3 +53,17 @@ def is_equal(
50
53
  return Decimal(abs(a - b)) <= max(
51
54
  Decimal(str(rel_tol)) * max(abs(a), abs(b)), Decimal(str(abs_tol))
52
55
  )
56
+
57
+
58
+ def optional_import(module_name: str, extra_name: str) -> Any:
59
+ """
60
+ Import a module optionally.
61
+ """
62
+ try:
63
+ return __import__(module_name)
64
+ except ImportError as e:
65
+ extra = f"[{extra_name}]"
66
+ raise ImportError(
67
+ f"Optional dependency '{module_name}' is required for this feature. "
68
+ f"Install it with: pip install crypticorn{extra}"
69
+ ) from e
@@ -17,6 +17,7 @@ Do not edit the class manually.
17
17
  __version__ = "1.0.0"
18
18
 
19
19
  # import apis into sdk package
20
+ from crypticorn.klines.client.api.change_in_timeframe_api import ChangeInTimeframeApi
20
21
  from crypticorn.klines.client.api.funding_rates_api import FundingRatesApi
21
22
  from crypticorn.klines.client.api.health_check_api import HealthCheckApi
22
23
  from crypticorn.klines.client.api.ohlcv_data_api import OHLCVDataApi
@@ -38,6 +39,9 @@ from crypticorn.klines.client.exceptions import ApiException
38
39
  from crypticorn.klines.client.models.base_response_health_check_response import (
39
40
  BaseResponseHealthCheckResponse,
40
41
  )
42
+ from crypticorn.klines.client.models.base_response_list_change_in_timeframe_response import (
43
+ BaseResponseListChangeInTimeframeResponse,
44
+ )
41
45
  from crypticorn.klines.client.models.base_response_list_funding_rate_response import (
42
46
  BaseResponseListFundingRateResponse,
43
47
  )
@@ -45,6 +49,9 @@ from crypticorn.klines.client.models.base_response_list_str import BaseResponseL
45
49
  from crypticorn.klines.client.models.base_response_ohlcv_response import (
46
50
  BaseResponseOHLCVResponse,
47
51
  )
52
+ from crypticorn.klines.client.models.change_in_timeframe_response import (
53
+ ChangeInTimeframeResponse,
54
+ )
48
55
  from crypticorn.klines.client.models.error_response import ErrorResponse
49
56
  from crypticorn.klines.client.models.exchange import Exchange
50
57
  from crypticorn.klines.client.models.funding_rate_response import FundingRateResponse
@@ -57,11 +64,11 @@ from crypticorn.klines.client.models.history_no_data_response import (
57
64
  from crypticorn.klines.client.models.history_success_response import (
58
65
  HistorySuccessResponse,
59
66
  )
60
- from crypticorn.klines.client.models.market import Market
67
+ from crypticorn.klines.client.models.market_type import MarketType
61
68
  from crypticorn.klines.client.models.ohlcv_response import OHLCVResponse
62
69
  from crypticorn.klines.client.models.resolution import Resolution
63
- from crypticorn.klines.client.models.response_get_history_udf_history_get import (
64
- ResponseGetHistoryUdfHistoryGet,
70
+ from crypticorn.klines.client.models.response_get_udf_history import (
71
+ ResponseGetUdfHistory,
65
72
  )
66
73
  from crypticorn.klines.client.models.search_symbol_response import SearchSymbolResponse
67
74
  from crypticorn.klines.client.models.sort_direction import SortDirection
@@ -1,6 +1,7 @@
1
1
  # flake8: noqa
2
2
 
3
3
  # import apis into api package
4
+ from crypticorn.klines.client.api.change_in_timeframe_api import ChangeInTimeframeApi
4
5
  from crypticorn.klines.client.api.funding_rates_api import FundingRatesApi
5
6
  from crypticorn.klines.client.api.health_check_api import HealthCheckApi
6
7
  from crypticorn.klines.client.api.ohlcv_data_api import OHLCVDataApi