crypticorn 2.8.0rc7__tar.gz → 2.8.0rc9__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 (275) hide show
  1. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/CHANGELOG.md +35 -0
  2. {crypticorn-2.8.0rc7/crypticorn.egg-info → crypticorn-2.8.0rc9}/PKG-INFO +3 -2
  3. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/__init__.py +5 -1
  4. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/__init__.py +2 -0
  5. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/ansi_colors.py +2 -1
  6. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/auth.py +2 -2
  7. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/enums.py +2 -0
  8. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/errors.py +8 -5
  9. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/exceptions.py +24 -20
  10. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/logging.py +19 -12
  11. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/middleware.py +4 -4
  12. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/mixins.py +10 -3
  13. crypticorn-2.8.0rc9/crypticorn/common/openapi.py +11 -0
  14. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/pagination.py +2 -0
  15. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/router/admin_router.py +3 -3
  16. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/router/status_router.py +9 -2
  17. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/scopes.py +3 -3
  18. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/urls.py +9 -0
  19. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/utils.py +16 -8
  20. crypticorn-2.8.0rc9/crypticorn/common/warnings.py +63 -0
  21. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/utils.py +1 -2
  22. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/__init__.py +11 -0
  23. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/api/__init__.py +2 -0
  24. crypticorn-2.8.0rc9/crypticorn/metrics/client/api/admin_api.py +1452 -0
  25. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/api/exchanges_api.py +51 -40
  26. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/api/indicators_api.py +49 -32
  27. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/api/logs_api.py +7 -7
  28. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/api/marketcap_api.py +28 -25
  29. crypticorn-2.8.0rc9/crypticorn/metrics/client/api/markets_api.py +374 -0
  30. crypticorn-2.8.0rc7/crypticorn/metrics/client/api/tokens_api.py → crypticorn-2.8.0rc9/crypticorn/metrics/client/api/quote_currencies_api.py +43 -40
  31. crypticorn-2.8.0rc9/crypticorn/metrics/client/api/status_api.py +508 -0
  32. crypticorn-2.8.0rc9/crypticorn/metrics/client/api/tokens_api.py +490 -0
  33. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/__init__.py +29 -0
  34. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/api_error_identifier.py +115 -0
  35. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/api_error_level.py +37 -0
  36. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/api_error_type.py +37 -0
  37. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/models/exception_detail.py +6 -3
  38. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/exchange_mapping.py +121 -0
  39. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/internal_exchange.py +39 -0
  40. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/log_level.py +38 -0
  41. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/market_type.py +35 -0
  42. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/marketcap_ranking.py +87 -0
  43. crypticorn-2.8.0rc9/crypticorn/metrics/client/models/ohlcv.py +113 -0
  44. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/main.py +14 -2
  45. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9/crypticorn.egg-info}/PKG-INFO +3 -2
  46. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn.egg-info/SOURCES.txt +13 -0
  47. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/pyproject.toml +3 -2
  48. crypticorn-2.8.0rc7/crypticorn/metrics/client/api/markets_api.py +0 -602
  49. crypticorn-2.8.0rc7/crypticorn/metrics/client/api/status_api.py +0 -735
  50. crypticorn-2.8.0rc7/crypticorn/metrics/client/models/__init__.py +0 -20
  51. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/MANIFEST.in +0 -0
  52. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/README.md +0 -0
  53. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/__init__.py +0 -0
  54. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/__init__.py +0 -0
  55. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api/__init__.py +0 -0
  56. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api/admin_api.py +0 -0
  57. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api/auth_api.py +0 -0
  58. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api/service_api.py +0 -0
  59. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api/user_api.py +0 -0
  60. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api/wallet_api.py +0 -0
  61. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api_client.py +0 -0
  62. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/api_response.py +0 -0
  63. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/configuration.py +0 -0
  64. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/exceptions.py +0 -0
  65. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/__init__.py +0 -0
  66. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/add_wallet200_response.py +0 -0
  67. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/add_wallet_request.py +0 -0
  68. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/authorize_user200_response.py +0 -0
  69. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/authorize_user200_response_auth.py +0 -0
  70. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/authorize_user_request.py +0 -0
  71. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/create_api_key200_response.py +0 -0
  72. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/create_api_key_request.py +0 -0
  73. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/create_user_request.py +0 -0
  74. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/get_api_keys200_response_inner.py +0 -0
  75. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/list_wallets200_response.py +0 -0
  76. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/list_wallets200_response_balances_inner.py +0 -0
  77. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_sale_round.py +0 -0
  78. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet.py +0 -0
  79. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet_vesting_wallets_inner.py +0 -0
  80. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/list_wallets200_response_data_inner.py +0 -0
  81. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/list_wallets200_response_user_value.py +0 -0
  82. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/logout_default_response.py +0 -0
  83. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/logout_default_response_issues_inner.py +0 -0
  84. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/oauth_callback200_response.py +0 -0
  85. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/oauth_callback200_response_user.py +0 -0
  86. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/refresh_token_info200_response.py +0 -0
  87. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/refresh_token_info200_response_user_session.py +0 -0
  88. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/resend_verification_email_request.py +0 -0
  89. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/revoke_user_tokens_request.py +0 -0
  90. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/rotate_tokens200_response.py +0 -0
  91. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/token_info200_response.py +0 -0
  92. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/unlink_wallet_request.py +0 -0
  93. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/update_user_request.py +0 -0
  94. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/user_by_username200_response.py +0 -0
  95. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/user_reset_password_request.py +0 -0
  96. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/user_set_password_request.py +0 -0
  97. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/verify200_response.py +0 -0
  98. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/verify_email200_response.py +0 -0
  99. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/verify_email200_response_auth.py +0 -0
  100. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/verify_email200_response_auth_auth.py +0 -0
  101. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/verify_email_request.py +0 -0
  102. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/verify_wallet_request.py +0 -0
  103. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/wallet_verified200_response.py +0 -0
  104. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/models/whoami200_response.py +0 -0
  105. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/py.typed +0 -0
  106. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/client/rest.py +0 -0
  107. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/auth/main.py +0 -0
  108. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/__init__.py +0 -0
  109. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/__main__.py +0 -0
  110. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/init.py +0 -0
  111. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/templates/Dockerfile +0 -0
  112. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/templates/__init__.py +0 -0
  113. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/templates/auth.py +0 -0
  114. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/templates/dependabot.yml +0 -0
  115. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/cli/templates/ruff.yml +0 -0
  116. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/client.py +0 -0
  117. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/common/decorators.py +0 -0
  118. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/__init__.py +0 -0
  119. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/__init__.py +0 -0
  120. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/api/__init__.py +0 -0
  121. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/api/admin_api.py +0 -0
  122. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/api/data_api.py +0 -0
  123. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/api/models_api.py +0 -0
  124. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/api/status_api.py +0 -0
  125. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/api_client.py +0 -0
  126. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/api_response.py +0 -0
  127. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/configuration.py +0 -0
  128. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/exceptions.py +0 -0
  129. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/__init__.py +0 -0
  130. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/api_error_identifier.py +0 -0
  131. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/api_error_level.py +0 -0
  132. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/api_error_type.py +0 -0
  133. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/coins.py +0 -0
  134. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/data_download_response.py +0 -0
  135. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/data_info.py +0 -0
  136. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/data_options.py +0 -0
  137. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/data_version.py +0 -0
  138. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/data_version_info.py +0 -0
  139. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/download_links.py +0 -0
  140. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/evaluation.py +0 -0
  141. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/evaluation_response.py +0 -0
  142. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/exception_detail.py +0 -0
  143. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/feature_size.py +0 -0
  144. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/log_level.py +0 -0
  145. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/model.py +0 -0
  146. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/model_create.py +0 -0
  147. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/model_status.py +0 -0
  148. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/model_update.py +0 -0
  149. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/target.py +0 -0
  150. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/target_info.py +0 -0
  151. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/models/target_type.py +0 -0
  152. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/py.typed +0 -0
  153. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/client/rest.py +0 -0
  154. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/hive/main.py +0 -0
  155. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/__init__.py +0 -0
  156. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/__init__.py +0 -0
  157. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api/__init__.py +0 -0
  158. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api/change_in_timeframe_api.py +0 -0
  159. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api/funding_rates_api.py +0 -0
  160. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api/ohlcv_data_api.py +0 -0
  161. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api/status_api.py +0 -0
  162. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api/symbols_api.py +0 -0
  163. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api/udf_api.py +0 -0
  164. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api_client.py +0 -0
  165. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/api_response.py +0 -0
  166. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/configuration.py +0 -0
  167. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/exceptions.py +0 -0
  168. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/__init__.py +0 -0
  169. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/change_in_timeframe.py +0 -0
  170. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/exception_detail.py +0 -0
  171. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/funding_rate.py +0 -0
  172. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/ohlcv_history.py +0 -0
  173. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/resolution.py +0 -0
  174. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/search_symbol.py +0 -0
  175. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/sort_direction.py +0 -0
  176. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/symbol_group.py +0 -0
  177. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/symbol_info.py +0 -0
  178. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/symbol_type.py +0 -0
  179. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/timeframe.py +0 -0
  180. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/models/udf_config.py +0 -0
  181. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/py.typed +0 -0
  182. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/client/rest.py +0 -0
  183. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/klines/main.py +0 -0
  184. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/__init__.py +0 -0
  185. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/api_client.py +0 -0
  186. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/api_response.py +0 -0
  187. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/configuration.py +0 -0
  188. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/exceptions.py +0 -0
  189. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/models/severity.py +0 -0
  190. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/models/time_interval.py +0 -0
  191. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/models/trading_status.py +0 -0
  192. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/py.typed +0 -0
  193. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/metrics/client/rest.py +0 -0
  194. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/__init__.py +0 -0
  195. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/__init__.py +0 -0
  196. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api/__init__.py +0 -0
  197. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api/admin_api.py +0 -0
  198. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api/now_payments_api.py +0 -0
  199. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api/payments_api.py +0 -0
  200. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api/products_api.py +0 -0
  201. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api/status_api.py +0 -0
  202. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api_client.py +0 -0
  203. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/api_response.py +0 -0
  204. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/configuration.py +0 -0
  205. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/exceptions.py +0 -0
  206. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/__init__.py +0 -0
  207. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/exception_detail.py +0 -0
  208. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/log_level.py +0 -0
  209. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/now_create_invoice_req.py +0 -0
  210. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/now_create_invoice_res.py +0 -0
  211. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/payment.py +0 -0
  212. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/payment_status.py +0 -0
  213. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/product_create.py +0 -0
  214. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/product_read.py +0 -0
  215. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/product_sub_read.py +0 -0
  216. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/product_update.py +0 -0
  217. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/provider.py +0 -0
  218. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/response_getuptime.py +0 -0
  219. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/models/scope.py +0 -0
  220. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/py.typed +0 -0
  221. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/client/rest.py +0 -0
  222. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/pay/main.py +0 -0
  223. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/__init__.py +0 -0
  224. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/__init__.py +0 -0
  225. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/__init__.py +0 -0
  226. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/api_keys_api.py +0 -0
  227. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/bots_api.py +0 -0
  228. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/exchanges_api.py +0 -0
  229. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/futures_trading_panel_api.py +0 -0
  230. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/notifications_api.py +0 -0
  231. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/orders_api.py +0 -0
  232. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/status_api.py +0 -0
  233. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/strategies_api.py +0 -0
  234. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api/trading_actions_api.py +0 -0
  235. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api_client.py +0 -0
  236. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/api_response.py +0 -0
  237. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/configuration.py +0 -0
  238. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/exceptions.py +0 -0
  239. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/__init__.py +0 -0
  240. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/action_model.py +0 -0
  241. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/bot_model.py +0 -0
  242. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/bot_status.py +0 -0
  243. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/exception_detail.py +0 -0
  244. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/exchange_key_model.py +0 -0
  245. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/execution_ids.py +0 -0
  246. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/futures_balance.py +0 -0
  247. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/futures_trading_action.py +0 -0
  248. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/margin_mode.py +0 -0
  249. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/notification_model.py +0 -0
  250. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/order_model.py +0 -0
  251. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/order_status.py +0 -0
  252. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/post_futures_action.py +0 -0
  253. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/spot_trading_action.py +0 -0
  254. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/strategy_exchange_info.py +0 -0
  255. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/strategy_model_input.py +0 -0
  256. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/strategy_model_output.py +0 -0
  257. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/tpsl.py +0 -0
  258. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/models/trading_action_type.py +0 -0
  259. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/py.typed +0 -0
  260. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/client/rest.py +0 -0
  261. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn/trade/main.py +0 -0
  262. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn.egg-info/dependency_links.txt +0 -0
  263. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn.egg-info/entry_points.txt +0 -0
  264. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn.egg-info/requires.txt +0 -0
  265. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/crypticorn.egg-info/top_level.txt +0 -0
  266. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/requirements/dev.txt +0 -0
  267. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/requirements/extra.txt +0 -0
  268. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/requirements/main.txt +0 -0
  269. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/requirements/test.txt +0 -0
  270. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/setup.cfg +0 -0
  271. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/tests/test_auth_client.py +0 -0
  272. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/tests/test_config.py +0 -0
  273. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/tests/test_enums.py +0 -0
  274. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/tests/test_errors.py +0 -0
  275. {crypticorn-2.8.0rc7 → crypticorn-2.8.0rc9}/tests/test_pagination.py +0 -0
@@ -1,6 +1,41 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v2.8.0-rc.9 (2025-05-08)
5
+
6
+ ### Bug Fixes
7
+
8
+ - Capture and format warnings in logging output
9
+ ([`2c8c87b`](https://github.com/crypticorn-ai/api-client/commit/2c8c87bff5848e488e7350a93f34983a76f904b5))
10
+
11
+ - Fixes wrong response in ping endpoint
12
+ ([`b550576`](https://github.com/crypticorn-ai/api-client/commit/b55057682b28d8b4e1712486002545faa47ddc27))
13
+
14
+ - Use `contextlib.asynccontextmanager` for starlette lifespan
15
+ ([`1dfa46e`](https://github.com/crypticorn-ai/api-client/commit/1dfa46ef66df1d7f623da1da614cf9530aa6b5e3))
16
+
17
+ ### Documentation
18
+
19
+ - Update docstrings and module descriptions
20
+ ([`3113abe`](https://github.com/crypticorn-ai/api-client/commit/3113abe2bf82077b12aac2b91aae2735ba521dfb))
21
+
22
+ ### Features
23
+
24
+ - Add deprecation warnings in call and in-code support
25
+ ([`c92e573`](https://github.com/crypticorn-ai/api-client/commit/c92e5737d83a4058bc7a161bb9aa7bbd1e4ad1ca))
26
+
27
+ - Provide default openapi tags from the status and admin router
28
+ ([`03b603c`](https://github.com/crypticorn-ai/api-client/commit/03b603c296fcb4e51e7572b4f2d5ea93c26b6139))
29
+
30
+
31
+ ## v2.8.0-rc.8 (2025-05-07)
32
+
33
+ ### Bug Fixes
34
+
35
+ - Use root logger of the client with specific child logger as option
36
+ ([`2f8cde2`](https://github.com/crypticorn-ai/api-client/commit/2f8cde2659f22704c5c4310f3ec9a07cbd1d4cef))
37
+
38
+
4
39
  ## v2.8.0-rc.7 (2025-05-07)
5
40
 
6
41
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crypticorn
3
- Version: 2.8.0rc7
3
+ Version: 2.8.0rc9
4
4
  Summary: Maximise Your Crypto Trading Profits with Machine Learning
5
5
  Author-email: Crypticorn <timon@crypticorn.com>
6
6
  License: MIT
@@ -10,8 +10,9 @@ Project-URL: Dashboard, https://app.crypticorn.com
10
10
  Keywords: machine learning,data science,crypto,modelling
11
11
  Classifier: Topic :: Scientific/Engineering
12
12
  Classifier: Development Status :: 4 - Beta
13
- Classifier: Intended Audience :: Science/Research
13
+ Classifier: Intended Audience :: Developers
14
14
  Classifier: Operating System :: OS Independent
15
+ Classifier: License :: OSI Approved :: MIT License
15
16
  Classifier: Programming Language :: Python :: 3.10
16
17
  Classifier: Programming Language :: Python :: 3.11
17
18
  Classifier: Programming Language :: Python :: 3.12
@@ -6,9 +6,13 @@ We adhere to [Semantic Versioning](https://semver.org/).
6
6
  You can find the full Changelog [below](#changelog).
7
7
  """
8
8
 
9
+ import warnings
10
+ import logging
9
11
  from crypticorn.common.logging import configure_logging
10
12
 
11
- configure_logging("crypticorn")
13
+ warnings.filterwarnings("default", "", DeprecationWarning)
14
+ configure_logging()
15
+ logging.captureWarnings(True)
12
16
 
13
17
  from crypticorn.client import ApiClient
14
18
 
@@ -11,5 +11,7 @@ from crypticorn.common.pagination import *
11
11
  from crypticorn.common.logging import *
12
12
  from crypticorn.common.ansi_colors import *
13
13
  from crypticorn.common.middleware import *
14
+ from crypticorn.common.warnings import *
15
+ from crypticorn.common.openapi import *
14
16
  from crypticorn.common.router.status_router import router as status_router
15
17
  from crypticorn.common.router.admin_router import router as admin_router
@@ -1,8 +1,9 @@
1
1
  from enum import StrEnum
2
- from typing import TYPE_CHECKING
3
2
 
4
3
 
5
4
  class AnsiColors(StrEnum):
5
+ """Provides a collection of ANSI color codes for terminal text formatting, including regular, bright, and bold text colors. Useful for creating colorful and readable console output."""
6
+
6
7
  # Regular Text Colors
7
8
  BLACK = "\033[30m" # black
8
9
  RED = "\033[31m" # red
@@ -38,8 +38,8 @@ class AuthHandler:
38
38
  """
39
39
  Middleware for verifying API requests. Verifies the validity of the authentication token, scopes, etc.
40
40
 
41
- @param base_url: The base URL of the API.
42
- @param api_version: The version of the API.
41
+ :param base_url: The base URL of the API.
42
+ :param api_version: The version of the API.
43
43
  """
44
44
 
45
45
  def __init__(
@@ -1,3 +1,5 @@
1
+ """Defines common enumerations used throughout the codebase for type safety and consistency."""
2
+
1
3
  from enum import StrEnum
2
4
  from crypticorn.common.mixins import ValidateEnumMixin, ExcludeEnumMixin
3
5
 
@@ -1,10 +1,12 @@
1
+ """Comprehensive error handling system defining various API error types, HTTP exceptions, and error content structures."""
2
+
1
3
  from enum import Enum, StrEnum
2
4
  from fastapi import status
3
5
  from crypticorn.common.mixins import ExcludeEnumMixin, ApiErrorFallback
4
6
 
5
7
 
6
8
  class ApiErrorType(ExcludeEnumMixin, StrEnum):
7
- """Type of API error"""
9
+ """Type of the API error."""
8
10
 
9
11
  USER_ERROR = "user error"
10
12
  """user error by people using our services"""
@@ -17,7 +19,7 @@ class ApiErrorType(ExcludeEnumMixin, StrEnum):
17
19
 
18
20
 
19
21
  class ApiErrorIdentifier(ExcludeEnumMixin, StrEnum):
20
- """API error identifiers"""
22
+ """Unique identifier of the API error."""
21
23
 
22
24
  ALLOCATION_BELOW_EXPOSURE = "allocation_below_current_exposure"
23
25
  ALLOCATION_BELOW_MINIMUM = "allocation_below_min_amount"
@@ -103,7 +105,7 @@ class ApiErrorIdentifier(ExcludeEnumMixin, StrEnum):
103
105
 
104
106
 
105
107
  class ApiErrorLevel(ExcludeEnumMixin, StrEnum):
106
- """API error levels"""
108
+ """Level of the API error."""
107
109
 
108
110
  ERROR = "error"
109
111
  INFO = "info"
@@ -112,7 +114,8 @@ class ApiErrorLevel(ExcludeEnumMixin, StrEnum):
112
114
 
113
115
 
114
116
  class ApiError(ExcludeEnumMixin, Enum, metaclass=ApiErrorFallback):
115
- """API error codes. Fallback to UNKNOWN_ERROR for error codes not yet published to PyPI."""
117
+ # Fallback to UNKNOWN_ERROR for error codes not yet published to PyPI.
118
+ """Crypticorn API error enumeration."""
116
119
 
117
120
  ALLOCATION_BELOW_EXPOSURE = (
118
121
  ApiErrorIdentifier.ALLOCATION_BELOW_EXPOSURE,
@@ -518,7 +521,7 @@ class ApiError(ExcludeEnumMixin, Enum, metaclass=ApiErrorFallback):
518
521
 
519
522
 
520
523
  class StatusCodeMapper:
521
- """Map API errors to HTTP status codes."""
524
+ """Mapping of API errors to HTTP/Websocket status codes."""
522
525
 
523
526
  _mapping = {
524
527
  # Authentication/Authorization
@@ -1,4 +1,4 @@
1
- from typing import Optional, Dict, Any, Literal
1
+ from typing import Optional, Dict, Any
2
2
  from enum import StrEnum
3
3
  from pydantic import BaseModel, Field
4
4
  from fastapi import HTTPException as FastAPIHTTPException, Request, FastAPI
@@ -6,17 +6,20 @@ from fastapi.exceptions import RequestValidationError, ResponseValidationError
6
6
  from fastapi.responses import JSONResponse
7
7
  from crypticorn.common import ApiError, ApiErrorIdentifier, ApiErrorType, ApiErrorLevel
8
8
  import logging
9
+ import json
9
10
 
10
- logger = logging.getLogger(__name__)
11
+ _logger = logging.getLogger("crypticorn")
11
12
 
12
13
 
13
- class ExceptionType(StrEnum):
14
+ class _ExceptionType(StrEnum):
15
+ """The protocol the exception is called from"""
16
+
14
17
  HTTP = "http"
15
18
  WEBSOCKET = "websocket"
16
19
 
17
20
 
18
21
  class ExceptionDetail(BaseModel):
19
- """This is the detail of the exception. It is used to enrich the exception with additional information by unwrapping the ApiError into its components."""
22
+ """Exception details returned to the client."""
20
23
 
21
24
  message: Optional[str] = Field(None, description="An additional error message")
22
25
  code: ApiErrorIdentifier = Field(..., description="The unique error code")
@@ -27,14 +30,14 @@ class ExceptionDetail(BaseModel):
27
30
 
28
31
 
29
32
  class ExceptionContent(BaseModel):
30
- """This is the detail of the exception. Pass an ApiError to the constructor and an optional human readable message."""
33
+ """Exception content used when raising an exception."""
31
34
 
32
35
  error: ApiError = Field(..., description="The unique error code")
33
36
  message: Optional[str] = Field(None, description="An additional error message")
34
37
  details: Any = Field(None, description="Additional details about the error")
35
38
 
36
39
  def enrich(
37
- self, _type: Optional[ExceptionType] = ExceptionType.HTTP
40
+ self, _type: Optional[_ExceptionType] = _ExceptionType.HTTP
38
41
  ) -> ExceptionDetail:
39
42
  return ExceptionDetail(
40
43
  message=self.message,
@@ -43,7 +46,7 @@ class ExceptionContent(BaseModel):
43
46
  level=self.error.level,
44
47
  status_code=(
45
48
  self.error.http_code
46
- if _type == ExceptionType.HTTP
49
+ if _type == _ExceptionType.HTTP
47
50
  else self.error.websocket_code
48
51
  ),
49
52
  details=self.details,
@@ -53,14 +56,14 @@ class ExceptionContent(BaseModel):
53
56
  class HTTPException(FastAPIHTTPException):
54
57
  """A custom HTTP exception wrapper around FastAPI's HTTPException.
55
58
  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.
56
- 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.
59
+ The ApiError class is the source of truth. If the error is not yet implemented, there are fallbacks in place.
57
60
  """
58
61
 
59
62
  def __init__(
60
63
  self,
61
64
  content: ExceptionContent,
62
65
  headers: Optional[Dict[str, str]] = None,
63
- _type: Optional[ExceptionType] = ExceptionType.HTTP,
66
+ _type: Optional[_ExceptionType] = _ExceptionType.HTTP,
64
67
  ):
65
68
  self.content = content
66
69
  self.headers = headers
@@ -81,11 +84,11 @@ class WebSocketException(HTTPException):
81
84
  def __init__(
82
85
  self, content: ExceptionContent, headers: Optional[Dict[str, str]] = None
83
86
  ):
84
- super().__init__(content, headers, _type=ExceptionType.WEBSOCKET)
87
+ super().__init__(content, headers, _type=_ExceptionType.WEBSOCKET)
85
88
 
86
89
  @classmethod
87
90
  def from_http_exception(cls, http_exception: HTTPException):
88
- """This is a helper method to convert an HTTPException to a WebSocketException."""
91
+ """Helper method to convert an HTTPException to a WebSocketException."""
89
92
  return WebSocketException(
90
93
  content=http_exception.content,
91
94
  headers=http_exception.headers,
@@ -93,46 +96,47 @@ class WebSocketException(HTTPException):
93
96
 
94
97
 
95
98
  async def general_handler(request: Request, exc: Exception) -> JSONResponse:
96
- """This is the default exception handler for all exceptions."""
99
+ """Default exception handler for all exceptions."""
97
100
  body = ExceptionContent(message=str(exc), error=ApiError.UNKNOWN_ERROR)
98
101
  res = JSONResponse(
99
102
  status_code=body.enrich().status_code,
100
103
  content=HTTPException(content=body).detail,
101
104
  )
102
- logger.error(f"Response validation error: {res}")
105
+ _logger.error(f"Response validation error: {json.loads(res.__dict__.get('body'))}")
103
106
  return res
104
107
 
105
108
 
106
109
  async def request_validation_handler(
107
110
  request: Request, exc: RequestValidationError
108
111
  ) -> JSONResponse:
109
- """This is the exception handler for all request validation errors."""
112
+ """Exception handler for all request validation errors."""
110
113
  body = ExceptionContent(message=str(exc), error=ApiError.INVALID_DATA_REQUEST)
111
114
  res = JSONResponse(
112
115
  status_code=body.enrich().status_code,
113
116
  content=HTTPException(content=body).detail,
114
117
  )
115
- logger.error(f"Response validation error: {res}")
118
+ _logger.error(f"Response validation error: {json.loads(res.__dict__.get('body'))}")
116
119
  return res
117
120
 
118
121
 
119
122
  async def response_validation_handler(
120
123
  request: Request, exc: ResponseValidationError
121
124
  ) -> JSONResponse:
122
- """This is the exception handler for all response validation errors."""
125
+ """Exception handler for all response validation errors."""
123
126
  body = ExceptionContent(message=str(exc), error=ApiError.INVALID_DATA_RESPONSE)
124
127
  res = JSONResponse(
125
128
  status_code=body.enrich().status_code,
126
129
  content=HTTPException(content=body).detail,
127
130
  )
128
- logger.error(f"Response validation error: {res}")
131
+ _logger.error(f"Response validation error: {json.loads(res.__dict__.get('body'))}")
129
132
  return res
130
133
 
131
134
 
132
135
  async def http_handler(request: Request, exc: HTTPException) -> JSONResponse:
133
- """This is the exception handler for HTTPExceptions. It unwraps the HTTPException and returns the detail in a flat JSON response."""
134
- logger.error(f"HTTP error: {exc.detail}")
135
- return JSONResponse(status_code=exc.status_code, content=exc.detail)
136
+ """Exception handler for HTTPExceptions. It unwraps the HTTPException and returns the detail in a flat JSON response."""
137
+ res = JSONResponse(status_code=exc.status_code, content=exc.detail)
138
+ _logger.error(f"HTTP error: {json.loads(res.__dict__.get('body'))}")
139
+ return res
136
140
 
137
141
 
138
142
  def register_exception_handlers(app: FastAPI):
@@ -1,12 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- # shared_logger.py
4
3
  import logging
5
4
  import sys
6
- from contextvars import ContextVar
7
- from contextlib import asynccontextmanager
8
- import json
9
- from pydantic import BaseModel
10
5
  from enum import StrEnum
11
6
  from crypticorn.common.mixins import ValidateEnumMixin
12
7
  from crypticorn.common.ansi_colors import AnsiColors as C
@@ -23,6 +18,7 @@ class LogLevel(ValidateEnumMixin, StrEnum):
23
18
 
24
19
  @classmethod
25
20
  def get_color(cls, level: str) -> str:
21
+ """Get the ansi color based on the log level."""
26
22
  if level == cls.DEBUG:
27
23
  return C.GREEN_BRIGHT
28
24
  elif level == cls.INFO:
@@ -38,10 +34,12 @@ class LogLevel(ValidateEnumMixin, StrEnum):
38
34
 
39
35
  @staticmethod
40
36
  def get_level(level: "LogLevel") -> int:
37
+ """Get the integer value from a log level name."""
41
38
  return logging._nameToLevel.get(level, logging.INFO)
42
39
 
43
40
  @staticmethod
44
41
  def get_name(level: int) -> "LogLevel":
42
+ """Get the level name from the integer value of a log level."""
45
43
  return LogLevel(logging._levelToName.get(level, "INFO"))
46
44
 
47
45
 
@@ -51,11 +49,10 @@ _LOGFORMAT = (
51
49
  f"%(levelcolor)s%(levelname)s{C.RESET} - "
52
50
  f"%(message)s"
53
51
  )
54
- _PLAIN_LOGFORMAT = "%(asctime)s - " "%(name)s - " "%(levelname)s - " "%(message)s"
55
52
  _DATEFMT = "%Y-%m-%d %H:%M:%S.%f:"
56
53
 
57
54
 
58
- class CustomFormatter(logging.Formatter):
55
+ class _CustomFormatter(logging.Formatter):
59
56
  def __init__(self, *args, **kwargs):
60
57
  super().__init__(*args, **kwargs)
61
58
 
@@ -71,7 +68,7 @@ class CustomFormatter(logging.Formatter):
71
68
 
72
69
 
73
70
  def configure_logging(
74
- name: str,
71
+ name: str = None,
75
72
  fmt: str = _LOGFORMAT,
76
73
  datefmt: str = _DATEFMT,
77
74
  stdout_level: int = logging.INFO,
@@ -81,9 +78,16 @@ def configure_logging(
81
78
  ) -> None:
82
79
  """Configures the logging for the application.
83
80
  Run this function as early as possible in the application (for example using the `lifespan` parameter in FastAPI).
84
- Then use can use the default `logging.getLogger(__name__)` method to get the logger.
81
+ Then use can use the default `logging.getLogger(__name__)` method to get the logger (or <name> if you set the name parameter).
82
+ :param name: The name of the logger. If not provided, the root logger will be used. Use a name if you use multiple loggers in the same application.
83
+ :param fmt: The format of the log message.
84
+ :param datefmt: The date format of the log message.
85
+ :param stdout_level: The level of the log message to be printed to the console.
86
+ :param file_level: The level of the log message to be written to the file. Only used if `log_file` is provided.
87
+ :param log_file: The file to write the log messages to.
88
+ :param filters: A list of filters to apply to the log handlers.
85
89
  """
86
- logger = logging.getLogger(name)
90
+ logger = logging.getLogger(name) if name else logging.getLogger()
87
91
 
88
92
  if logger.handlers: # clear existing handlers to avoid duplicates
89
93
  logger.handlers.clear()
@@ -93,7 +97,7 @@ def configure_logging(
93
97
  # Configure stdout handler
94
98
  stdout_handler = logging.StreamHandler(sys.stdout)
95
99
  stdout_handler.setLevel(stdout_level)
96
- stdout_handler.setFormatter(CustomFormatter(fmt=fmt, datefmt=datefmt))
100
+ stdout_handler.setFormatter(_CustomFormatter(fmt=fmt, datefmt=datefmt))
97
101
  for filter in filters:
98
102
  stdout_handler.addFilter(filter)
99
103
  logger.addHandler(stdout_handler)
@@ -105,11 +109,14 @@ def configure_logging(
105
109
  log_file, maxBytes=10 * 1024 * 1024, backupCount=5
106
110
  )
107
111
  file_handler.setLevel(file_level)
108
- file_handler.setFormatter(CustomFormatter(fmt=fmt, datefmt=datefmt))
112
+ file_handler.setFormatter(_CustomFormatter(fmt=fmt, datefmt=datefmt))
109
113
  for filter in filters:
110
114
  file_handler.addFilter(filter)
111
115
  logger.addHandler(file_handler)
112
116
 
117
+ if name:
118
+ logger.propagate = False
119
+
113
120
 
114
121
  def disable_logging():
115
122
  """Disable logging for the crypticorn logger."""
@@ -1,7 +1,7 @@
1
1
  from fastapi import FastAPI
2
2
  from fastapi.middleware.cors import CORSMiddleware
3
3
  from crypticorn.common.logging import configure_logging
4
- import logging
4
+ from contextlib import asynccontextmanager
5
5
 
6
6
 
7
7
  def add_cors_middleware(app: "FastAPI"):
@@ -11,18 +11,18 @@ def add_cors_middleware(app: "FastAPI"):
11
11
  "http://localhost:5173", # vite dev server
12
12
  "http://localhost:4173", # vite preview server
13
13
  ],
14
- allow_origin_regex="^https:\/\/([a-zA-Z0-9-]+\.)*crypticorn\.(dev|com)\/?$", # matches (multiple or no) subdomains of crypticorn.dev and crypticorn.com
14
+ allow_origin_regex="^https://([a-zA-Z0-9-]+.)*crypticorn.(dev|com)/?$", # matches (multiple or no) subdomains of crypticorn.dev and crypticorn.com
15
15
  allow_credentials=True,
16
16
  allow_methods=["*"],
17
17
  allow_headers=["*"],
18
18
  )
19
19
 
20
20
 
21
+ @asynccontextmanager
21
22
  async def default_lifespan(app: FastAPI):
22
23
  """Default lifespan for the applications.
23
24
  This is used to configure the logging for the application.
24
25
  To override this, pass a different lifespan to the FastAPI constructor or call this lifespan within a custom lifespan.
25
26
  """
26
- configure_logging(__name__) # for the consuming app
27
- logger = logging.getLogger(__name__)
27
+ configure_logging()
28
28
  yield
@@ -1,7 +1,9 @@
1
1
  from enum import EnumMeta
2
2
  import logging
3
+ import warnings
4
+ from crypticorn.common.warnings import CrypticornDeprecatedSince28
3
5
 
4
- logger = logging.getLogger("uvicorn")
6
+ _logger = logging.getLogger("crypticorn")
5
7
 
6
8
 
7
9
  class ValidateEnumMixin:
@@ -35,7 +37,12 @@ class ValidateEnumMixin:
35
37
 
36
38
  # This Mixin will be removed in a future version. And has no effect from now on
37
39
  class ExcludeEnumMixin:
38
- """Mixin to exclude enum from OpenAPI schema. We use this to avoid duplicating enums when generating client code from the openapi spec."""
40
+ """(deprecated) Mixin to exclude enum from OpenAPI schema. We use this to avoid duplicating enums when generating client code from the openapi spec."""
41
+
42
+ warnings.warn(
43
+ "The `ExcludeEnumMixin` class is deprecated. Should be removed from enums inheriting this class.",
44
+ category=CrypticornDeprecatedSince28,
45
+ )
39
46
 
40
47
  @classmethod
41
48
  def __get_pydantic_json_schema__(cls, core_schema, handler):
@@ -51,7 +58,7 @@ class ApiErrorFallback(EnumMeta):
51
58
  # Let Pydantic/internal stuff pass silently ! fragile
52
59
  if name.startswith("__"):
53
60
  raise AttributeError(name)
54
- logger.warning(
61
+ _logger.warning(
55
62
  f"Unknown enum member '{name}' - update crypticorn package or check for typos"
56
63
  )
57
64
  return cls.UNKNOWN_ERROR
@@ -0,0 +1,11 @@
1
+ default_tags = [
2
+ {
3
+ "name": "Status",
4
+ "description": "These endpoints contain status operations.",
5
+ },
6
+ {
7
+ "name": "Admin",
8
+ "description": "These endpoints contain debugging and monitoring operations. They require admin scopes.",
9
+ }
10
+ ]
11
+
@@ -1,3 +1,5 @@
1
+ """Utilities for handling paginated API responses and cursor-based pagination."""
2
+
1
3
  from typing import Generic, Type, TypeVar, List, Optional, Literal
2
4
  from pydantic import BaseModel, Field, model_validator
3
5
 
@@ -20,10 +20,10 @@ router = APIRouter(tags=["Admin"], prefix="/admin")
20
20
  START_TIME = time.time()
21
21
 
22
22
 
23
- @router.get("/log-level", status_code=200, operation_id="getLogLevel")
23
+ @router.get("/log-level", status_code=200, operation_id="getLogLevel", deprecated=True)
24
24
  async def get_logging_level() -> LogLevel:
25
25
  """
26
- Get the log level of the server logger.
26
+ Get the log level of the server logger. Will be removed in a future release.
27
27
  """
28
28
  return LogLevel.get_name(logging.getLogger().level)
29
29
 
@@ -39,7 +39,7 @@ def get_uptime(type: Literal["seconds", "human"] = "seconds") -> str:
39
39
 
40
40
 
41
41
  @router.get("/memory", operation_id="getMemoryUsage", status_code=200)
42
- def get_memory_usage() -> int:
42
+ def get_memory_usage() -> float:
43
43
  """
44
44
  Resident Set Size (RSS) in MB — the actual memory used by the process in RAM.
45
45
  Represents the physical memory footprint. Important for monitoring real usage.
@@ -1,12 +1,19 @@
1
+ """
2
+ This module contains the status router for the API.
3
+ It provides endpoints for checking the status of the API and get the server's time.
4
+ SHOULD ALLOW ACCESS TO THIS ROUTER WITHOUT.
5
+ >>> app.include_router(status_router)
6
+ """
7
+
1
8
  from datetime import datetime
2
9
  from typing import Literal
3
- from fastapi import APIRouter
10
+ from fastapi import APIRouter, Request
4
11
 
5
12
  router = APIRouter(tags=["Status"], prefix="")
6
13
 
7
14
 
8
15
  @router.get("/", operation_id="ping")
9
- async def ping() -> str:
16
+ async def ping(request: Request) -> dict:
10
17
  """
11
18
  Returns 'OK' if the API is running.
12
19
  """
@@ -54,7 +54,7 @@ class Scope(StrEnum):
54
54
 
55
55
  @classmethod
56
56
  def admin_scopes(cls) -> list["Scope"]:
57
- """Scopes that are only available to admins"""
57
+ """Scopes that are only available to admins."""
58
58
  return [
59
59
  cls.WRITE_TRADE_STRATEGIES,
60
60
  cls.WRITE_PAY_PRODUCTS,
@@ -64,14 +64,14 @@ class Scope(StrEnum):
64
64
 
65
65
  @classmethod
66
66
  def internal_scopes(cls) -> list["Scope"]:
67
- """Scopes that are only available to internal services"""
67
+ """Scopes that are only available to internal services."""
68
68
  return [
69
69
  cls.WRITE_TRADE_ACTIONS,
70
70
  ]
71
71
 
72
72
  @classmethod
73
73
  def purchaseable_scopes(cls) -> list["Scope"]:
74
- """Scopes that can be purchased"""
74
+ """Scopes that can be purchased."""
75
75
  return [
76
76
  cls.READ_PREDICTIONS,
77
77
  ]
@@ -3,6 +3,8 @@ from crypticorn.common.enums import ValidateEnumMixin
3
3
 
4
4
 
5
5
  class ApiEnv(StrEnum):
6
+ """The environment the API is being used with."""
7
+
6
8
  PROD = "prod"
7
9
  DEV = "dev"
8
10
  LOCAL = "local"
@@ -10,6 +12,8 @@ class ApiEnv(StrEnum):
10
12
 
11
13
 
12
14
  class BaseUrl(StrEnum):
15
+ """The base URL to connect to the API."""
16
+
13
17
  PROD = "https://api.crypticorn.com"
14
18
  DEV = "https://api.crypticorn.dev"
15
19
  LOCAL = "http://localhost"
@@ -17,6 +21,7 @@ class BaseUrl(StrEnum):
17
21
 
18
22
  @classmethod
19
23
  def from_env(cls, env: ApiEnv) -> "BaseUrl":
24
+ """Load the base URL from the API environment."""
20
25
  if env == ApiEnv.PROD:
21
26
  return cls.PROD
22
27
  elif env == ApiEnv.DEV:
@@ -28,10 +33,14 @@ class BaseUrl(StrEnum):
28
33
 
29
34
 
30
35
  class ApiVersion(StrEnum):
36
+ """Versions to use for the microservice APIs."""
37
+
31
38
  V1 = "v1"
32
39
 
33
40
 
34
41
  class Service(ValidateEnumMixin, StrEnum):
42
+ """The microservices available to connect to through the API"""
43
+
35
44
  HIVE = "hive"
36
45
  KLINES = "klines"
37
46
  PAY = "pay"
@@ -1,11 +1,14 @@
1
- from typing import Any, Union
1
+ """General utility functions and helper methods used across the codebase."""
2
+
3
+ from typing import Any
2
4
  from decimal import Decimal
3
5
  import string
4
6
  import random
5
- from fastapi import status
6
- from typing_extensions import deprecated
7
+ import typing_extensions
8
+ import warnings
7
9
 
8
- from crypticorn.common import ApiError, HTTPException, ExceptionContent
10
+ from crypticorn.common.exceptions import ApiError, HTTPException, ExceptionContent
11
+ from crypticorn.common.warnings import CrypticornDeprecatedSince25
9
12
 
10
13
 
11
14
  def throw_if_none(
@@ -33,7 +36,9 @@ def gen_random_id(length: int = 20) -> str:
33
36
  return "".join(random.choice(charset) for _ in range(length))
34
37
 
35
38
 
36
- @deprecated("Use math.isclose instead. Will be removed in a future version.")
39
+ @typing_extensions.deprecated(
40
+ "The `is_equal` method is deprecated; use `math.is_close` instead.", category=None
41
+ )
37
42
  def is_equal(
38
43
  a: float | Decimal,
39
44
  b: float | Decimal,
@@ -43,6 +48,10 @@ def is_equal(
43
48
  """
44
49
  Compare two Decimal numbers for approximate equality.
45
50
  """
51
+ warnings.warn(
52
+ "The `is_equal` method is deprecated; use `math.is_close` instead.",
53
+ category=CrypticornDeprecatedSince25,
54
+ )
46
55
  if not isinstance(a, Decimal):
47
56
  a = Decimal(str(a))
48
57
  if not isinstance(b, Decimal):
@@ -56,13 +65,12 @@ def is_equal(
56
65
 
57
66
  def optional_import(module_name: str, extra_name: str) -> Any:
58
67
  """
59
- Import a module optionally.
68
+ Tries to import a module. Raises `ImportError` if not found with a message to install the extra dependency.
60
69
  """
61
70
  try:
62
71
  return __import__(module_name)
63
72
  except ImportError as e:
64
- extra = f"[{extra_name}]"
65
73
  raise ImportError(
66
74
  f"Optional dependency '{module_name}' is required for this feature. "
67
- f"Install it with: pip install crypticorn{extra}"
75
+ f"Install it with: pip install crypticorn[{extra_name}]"
68
76
  ) from e