crypticorn 2.0.0__tar.gz → 2.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. {crypticorn-2.0.0 → crypticorn-2.0.1}/PKG-INFO +24 -6
  2. {crypticorn-2.0.0 → crypticorn-2.0.1}/README.md +21 -1
  3. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/common/auth.py +2 -2
  4. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/common/auth_client.py +60 -40
  5. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/common/scopes.py +8 -1
  6. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn.egg-info/PKG-INFO +24 -6
  7. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn.egg-info/SOURCES.txt +2 -1
  8. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn.egg-info/requires.txt +2 -4
  9. {crypticorn-2.0.0 → crypticorn-2.0.1}/pyproject.toml +2 -2
  10. {crypticorn-2.0.0 → crypticorn-2.0.1}/requirements/main.txt +3 -0
  11. crypticorn-2.0.1/requirements/test.txt +3 -0
  12. crypticorn-2.0.1/tests/test_auth_client.py +102 -0
  13. crypticorn-2.0.0/requirements/test.txt +0 -6
  14. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/__init__.py +0 -0
  15. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/__init__.py +0 -0
  16. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/__init__.py +0 -0
  17. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api/__init__.py +0 -0
  18. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api/admin_api.py +0 -0
  19. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api/auth_api.py +0 -0
  20. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api/service_api.py +0 -0
  21. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api/user_api.py +0 -0
  22. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api/wallet_api.py +0 -0
  23. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api_client.py +0 -0
  24. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/api_response.py +0 -0
  25. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/configuration.py +0 -0
  26. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/exceptions.py +0 -0
  27. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/__init__.py +0 -0
  28. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/add_wallet200_response.py +0 -0
  29. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/add_wallet_request.py +0 -0
  30. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/authorize_user200_response.py +0 -0
  31. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/authorize_user200_response_auth.py +0 -0
  32. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/authorize_user_request.py +0 -0
  33. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/create_user_request.py +0 -0
  34. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/list_wallets200_response.py +0 -0
  35. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/list_wallets200_response_balances_inner.py +0 -0
  36. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_sale_round.py +0 -0
  37. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet.py +0 -0
  38. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet_vesting_wallets_inner.py +0 -0
  39. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/list_wallets200_response_data_inner.py +0 -0
  40. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/list_wallets200_response_user_value.py +0 -0
  41. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/logout_default_response.py +0 -0
  42. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/logout_default_response_issues_inner.py +0 -0
  43. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/refresh_token_info200_response.py +0 -0
  44. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/refresh_token_info200_response_user_session.py +0 -0
  45. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/resend_verification_email_request.py +0 -0
  46. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/revoke_user_tokens_request.py +0 -0
  47. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/rotate_tokens200_response.py +0 -0
  48. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/token_info200_response.py +0 -0
  49. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/unlink_wallet_request.py +0 -0
  50. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/update_user_request.py +0 -0
  51. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/user_reset_password_request.py +0 -0
  52. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/user_set_password_request.py +0 -0
  53. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/verify200_response.py +0 -0
  54. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/verify_email200_response.py +0 -0
  55. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/verify_email200_response_auth.py +0 -0
  56. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/verify_email200_response_auth_auth.py +0 -0
  57. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/verify_email_request.py +0 -0
  58. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/verify_wallet_request.py +0 -0
  59. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/wallet_verified200_response.py +0 -0
  60. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/models/whoami200_response.py +0 -0
  61. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/py.typed +0 -0
  62. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/client/rest.py +0 -0
  63. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/auth/main.py +0 -0
  64. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/client.py +0 -0
  65. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/common/__init__.py +0 -0
  66. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/common/errors.py +0 -0
  67. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/common/urls.py +0 -0
  68. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/__init__.py +0 -0
  69. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/__init__.py +0 -0
  70. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/api/__init__.py +0 -0
  71. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/api/data_api.py +0 -0
  72. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/api/models_api.py +0 -0
  73. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/api/status_api.py +0 -0
  74. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/api_client.py +0 -0
  75. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/api_response.py +0 -0
  76. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/configuration.py +0 -0
  77. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/exceptions.py +0 -0
  78. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/__init__.py +0 -0
  79. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/coins.py +0 -0
  80. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/data_download_response.py +0 -0
  81. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/data_info.py +0 -0
  82. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/data_value_value_value_inner.py +0 -0
  83. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/data_version.py +0 -0
  84. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/download_links.py +0 -0
  85. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/evaluation.py +0 -0
  86. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/evaluation_response.py +0 -0
  87. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/feature_size.py +0 -0
  88. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/http_validation_error.py +0 -0
  89. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/model.py +0 -0
  90. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/model_create.py +0 -0
  91. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/model_status.py +0 -0
  92. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/model_update.py +0 -0
  93. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/target.py +0 -0
  94. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/target_type.py +0 -0
  95. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/validation_error.py +0 -0
  96. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/models/validation_error_loc_inner.py +0 -0
  97. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/py.typed +0 -0
  98. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/client/rest.py +0 -0
  99. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/hive/main.py +0 -0
  100. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/__init__.py +0 -0
  101. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/__init__.py +0 -0
  102. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api/__init__.py +0 -0
  103. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api/funding_rates_api.py +0 -0
  104. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api/health_check_api.py +0 -0
  105. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api/ohlcv_data_api.py +0 -0
  106. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api/symbols_api.py +0 -0
  107. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api/udf_api.py +0 -0
  108. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api_client.py +0 -0
  109. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/api_response.py +0 -0
  110. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/configuration.py +0 -0
  111. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/exceptions.py +0 -0
  112. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/__init__.py +0 -0
  113. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/base_response_health_check_response.py +0 -0
  114. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/base_response_list_funding_rate_response.py +0 -0
  115. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/base_response_list_str.py +0 -0
  116. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/base_response_ohlcv_response.py +0 -0
  117. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/error_response.py +0 -0
  118. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/exchange.py +0 -0
  119. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/funding_rate_response.py +0 -0
  120. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/health_check_response.py +0 -0
  121. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/history_error_response.py +0 -0
  122. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/history_no_data_response.py +0 -0
  123. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/history_success_response.py +0 -0
  124. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/http_validation_error.py +0 -0
  125. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/market.py +0 -0
  126. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/ohlcv_response.py +0 -0
  127. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/resolution.py +0 -0
  128. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/response_get_history_udf_history_get.py +0 -0
  129. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/search_symbol_response.py +0 -0
  130. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/sort_direction.py +0 -0
  131. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/symbol_group_response.py +0 -0
  132. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/symbol_info_response.py +0 -0
  133. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/symbol_type.py +0 -0
  134. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/timeframe.py +0 -0
  135. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/udf_config_response.py +0 -0
  136. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/validation_error.py +0 -0
  137. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/models/validation_error_loc_inner.py +0 -0
  138. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/py.typed +0 -0
  139. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/client/rest.py +0 -0
  140. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/klines/main.py +0 -0
  141. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/__init__.py +0 -0
  142. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/__init__.py +0 -0
  143. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/api/__init__.py +0 -0
  144. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/api/now_payments_api.py +0 -0
  145. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/api/payments_api.py +0 -0
  146. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/api/products_api.py +0 -0
  147. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/api/status_api.py +0 -0
  148. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/api_client.py +0 -0
  149. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/api_response.py +0 -0
  150. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/configuration.py +0 -0
  151. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/exceptions.py +0 -0
  152. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/__init__.py +0 -0
  153. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/api_status_res.py +0 -0
  154. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/combined_payment_history.py +0 -0
  155. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/create_invoice_req.py +0 -0
  156. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/create_invoice_res.py +0 -0
  157. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/currency.py +0 -0
  158. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/estimate_price_req.py +0 -0
  159. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/estimate_price_res.py +0 -0
  160. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/get_currencies_res.py +0 -0
  161. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/get_payment_status_res.py +0 -0
  162. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/get_payments_list_res.py +0 -0
  163. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/http_validation_error.py +0 -0
  164. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/min_amount_req.py +0 -0
  165. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/min_amount_res.py +0 -0
  166. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/now_api_status_res.py +0 -0
  167. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/now_create_invoice_req.py +0 -0
  168. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/now_create_invoice_res.py +0 -0
  169. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/now_fee_structure.py +0 -0
  170. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/now_payment_model.py +0 -0
  171. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/now_payment_status.py +0 -0
  172. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/now_webhook_payload.py +0 -0
  173. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/payment.py +0 -0
  174. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/payment_status.py +0 -0
  175. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/product.py +0 -0
  176. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/product_model.py +0 -0
  177. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/product_subs_model.py +0 -0
  178. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/services.py +0 -0
  179. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/unified_payment_model.py +0 -0
  180. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/validation_error.py +0 -0
  181. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/models/validation_error_loc_inner.py +0 -0
  182. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/py.typed +0 -0
  183. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/client/rest.py +0 -0
  184. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/pay/main.py +0 -0
  185. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/__init__.py +0 -0
  186. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/__init__.py +0 -0
  187. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/__init__.py +0 -0
  188. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/api_keys_api.py +0 -0
  189. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/bots_api.py +0 -0
  190. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/exchanges_api.py +0 -0
  191. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/futures_trading_panel_api.py +0 -0
  192. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/notifications_api.py +0 -0
  193. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/orders_api.py +0 -0
  194. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/status_api.py +0 -0
  195. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/strategies_api.py +0 -0
  196. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api/trading_actions_api.py +0 -0
  197. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api_client.py +0 -0
  198. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/api_response.py +0 -0
  199. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/configuration.py +0 -0
  200. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/exceptions.py +0 -0
  201. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/__init__.py +0 -0
  202. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/action_model.py +0 -0
  203. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/api_error_identifier.py +0 -0
  204. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/api_error_level.py +0 -0
  205. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/api_error_type.py +0 -0
  206. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/api_key_model.py +0 -0
  207. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/bot_model.py +0 -0
  208. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/bot_status.py +0 -0
  209. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/exchange.py +0 -0
  210. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/execution_ids.py +0 -0
  211. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/futures_balance.py +0 -0
  212. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/futures_trading_action.py +0 -0
  213. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/http_validation_error.py +0 -0
  214. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/margin_mode.py +0 -0
  215. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/market_type.py +0 -0
  216. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/notification_model.py +0 -0
  217. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/notification_type.py +0 -0
  218. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/order_model.py +0 -0
  219. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/order_status.py +0 -0
  220. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/post_futures_action.py +0 -0
  221. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/strategy_exchange_info.py +0 -0
  222. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/strategy_model.py +0 -0
  223. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/strategy_model_input.py +0 -0
  224. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/strategy_model_output.py +0 -0
  225. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/tpsl.py +0 -0
  226. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/trading_action_type.py +0 -0
  227. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/update_notification.py +0 -0
  228. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/validation_error.py +0 -0
  229. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/models/validation_error_loc_inner.py +0 -0
  230. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/py.typed +0 -0
  231. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/client/rest.py +0 -0
  232. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn/trade/main.py +0 -0
  233. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn.egg-info/dependency_links.txt +0 -0
  234. {crypticorn-2.0.0 → crypticorn-2.0.1}/crypticorn.egg-info/top_level.txt +0 -0
  235. {crypticorn-2.0.0 → crypticorn-2.0.1}/requirements/dev.txt +0 -0
  236. {crypticorn-2.0.0 → crypticorn-2.0.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crypticorn
3
- Version: 2.0.0
3
+ Version: 2.0.1
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
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Typing :: Typed
14
14
  Requires-Python: >=3.10
15
15
  Description-Content-Type: text/markdown
16
+ Requires-Dist: fastapi
16
17
  Requires-Dist: urllib3<3.0.0,>=1.25.3
17
18
  Requires-Dist: python_dateutil>=2.8.2
18
19
  Requires-Dist: aiohttp>=3.8.4
@@ -33,10 +34,7 @@ Requires-Dist: pyflakes; extra == "dev"
33
34
  Provides-Extra: test
34
35
  Requires-Dist: pytest>=7.2.1; extra == "test"
35
36
  Requires-Dist: pytest-cov>=2.8.1; extra == "test"
36
- Requires-Dist: tox>=3.9.0; extra == "test"
37
- Requires-Dist: flake8>=4.0.0; extra == "test"
38
- Requires-Dist: types-python-dateutil>=2.8.19.14; extra == "test"
39
- Requires-Dist: mypy>=1.5; extra == "test"
37
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
40
38
 
41
39
  # What is Crypticorn?
42
40
 
@@ -50,9 +48,28 @@ Crypticorn offers AI-based solutions for both active and passive investors, incl
50
48
  Use this API Client to contribute to the so-called Hive AI, a community driven AI Meta Model for predicting the
51
49
  cryptocurrency market.
52
50
 
51
+ ## Installation
52
+
53
+ You can install the latest stable version from PyPi:
54
+ ```bash
55
+ pip install crypticorn
56
+ ```
57
+
58
+ If you want a specific version, run:
59
+ ```bash
60
+ pip install crypticorn==2.0.0
61
+ ```
62
+
63
+ If you want the latest version, which could be a pre release, run:
64
+ ```bash
65
+ pip install --pre crypticorn
66
+ ```
67
+
53
68
  ## Usage
54
69
 
55
- Within an asynchronous context the session is closed automatically.
70
+ As of know the library is available in async mode only. There are two was of using it.
71
+
72
+ ## With Async Context Protocol
56
73
  ```python
57
74
  async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
58
75
  # json response
@@ -66,6 +83,7 @@ async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
66
83
  print(response)
67
84
  ```
68
85
 
86
+ ## Without Async Context Protocol
69
87
  Without the context you need to close the session manually.
70
88
  ```python
71
89
  client = ApiClient(base_url="http://localhost", jwt=jwt)
@@ -10,9 +10,28 @@ Crypticorn offers AI-based solutions for both active and passive investors, incl
10
10
  Use this API Client to contribute to the so-called Hive AI, a community driven AI Meta Model for predicting the
11
11
  cryptocurrency market.
12
12
 
13
+ ## Installation
14
+
15
+ You can install the latest stable version from PyPi:
16
+ ```bash
17
+ pip install crypticorn
18
+ ```
19
+
20
+ If you want a specific version, run:
21
+ ```bash
22
+ pip install crypticorn==2.0.0
23
+ ```
24
+
25
+ If you want the latest version, which could be a pre release, run:
26
+ ```bash
27
+ pip install --pre crypticorn
28
+ ```
29
+
13
30
  ## Usage
14
31
 
15
- Within an asynchronous context the session is closed automatically.
32
+ As of know the library is available in async mode only. There are two was of using it.
33
+
34
+ ## With Async Context Protocol
16
35
  ```python
17
36
  async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
18
37
  # json response
@@ -26,6 +45,7 @@ async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
26
45
  print(response)
27
46
  ```
28
47
 
48
+ ## Without Async Context Protocol
29
49
  Without the context you need to close the session manually.
30
50
  ```python
31
51
  client = ApiClient(base_url="http://localhost", jwt=jwt)
@@ -5,7 +5,7 @@ from enum import Enum
5
5
  from fastapi import params
6
6
  from fastapi.security import APIKeyHeader, HTTPBearer
7
7
 
8
- from crypticorn.common import ApiScope
8
+ from crypticorn.common import Scope
9
9
 
10
10
 
11
11
  http_bearer = HTTPBearer(
@@ -26,7 +26,7 @@ def Security( # noqa: N802
26
26
  Optional[Callable[..., Any]], Doc("A dependable callable (like a function).")
27
27
  ] = None,
28
28
  scopes: Annotated[
29
- Optional[list[ApiScope]], # Optional[Sequence[Union[str, APIScope]]],
29
+ Optional[list[Scope]], # Optional[Sequence[Union[str, Scope]]],
30
30
  Doc("OAuth2 scopes required for the *path operation*."),
31
31
  ] = None,
32
32
  use_cache: Annotated[
@@ -1,12 +1,13 @@
1
1
  from fastapi import Depends, HTTPException, status
2
2
  from fastapi.security import HTTPAuthorizationCredentials
3
3
  from typing_extensions import Annotated, Doc
4
+ import json
4
5
 
5
6
  from crypticorn.auth import AuthClient, Verify200Response
6
- from crypticorn.auth.client.exceptions import UnauthorizedException
7
+ from crypticorn.auth.client.exceptions import ApiException
7
8
  from crypticorn.common import (
8
9
  ApiError,
9
- ApiScope,
10
+ Scope,
10
11
  ApiVersion,
11
12
  BaseURL,
12
13
  Domain,
@@ -41,29 +42,17 @@ class AuthHandler:
41
42
  self.whitelist = whitelist
42
43
  self.auth_client = AuthClient(base_url=base_url, api_version=api_version)
43
44
 
44
- self.invalid_scopes_exception = HTTPException(
45
- status_code=status.HTTP_403_FORBIDDEN,
46
- detail=ApiError.INSUFFICIENT_SCOPES.identifier,
47
- )
48
45
  self.no_credentials_exception = HTTPException(
49
46
  status_code=status.HTTP_401_UNAUTHORIZED,
50
47
  detail=ApiError.NO_CREDENTIALS.identifier,
51
48
  )
52
- self.invalid_api_key_exception = HTTPException(
53
- status_code=status.HTTP_401_UNAUTHORIZED,
54
- detail=ApiError.INVALID_API_KEY.identifier,
55
- )
56
- self.invalid_bearer_exception = HTTPException(
57
- status_code=status.HTTP_401_UNAUTHORIZED,
58
- detail=ApiError.INVALID_BEARER.identifier,
59
- )
60
49
 
61
50
  async def _verify_api_key(self, api_key: str) -> None:
62
51
  """
63
52
  Verifies the API key.
64
53
  """
65
54
  # TODO: Implement in auth service
66
- return NotImplementedError()
55
+ raise NotImplementedError("API key verification not implemented")
67
56
 
68
57
  async def _verify_bearer(
69
58
  self, bearer: HTTPAuthorizationCredentials
@@ -74,32 +63,66 @@ class AuthHandler:
74
63
  self.auth_client.config.access_token = bearer.credentials
75
64
  return await self.auth_client.login.verify()
76
65
 
77
- async def _check_scopes(
78
- self, api_scopes: list[ApiScope], user_scopes: list[ApiScope]
66
+ async def _validate_scopes(
67
+ self, api_scopes: list[Scope], user_scopes: list[Scope]
79
68
  ) -> bool:
80
69
  """
81
70
  Checks if the user scopes are a subset of the API scopes.
82
71
  """
83
- return set(api_scopes).issubset(user_scopes)
72
+ if not set(api_scopes).issubset(user_scopes):
73
+ raise HTTPException(
74
+ status_code=status.HTTP_403_FORBIDDEN,
75
+ detail=ApiError.INSUFFICIENT_SCOPES.identifier,
76
+ )
84
77
 
78
+ async def _extract_message(self, e: ApiException) -> str:
79
+ '''
80
+ Tries to extract the message from the body of the exception.
81
+ '''
82
+ try:
83
+ load = json.loads(e.body)
84
+ except (json.JSONDecodeError, TypeError):
85
+ return e.body
86
+ else:
87
+ common_keys = ["message"]
88
+ for key in common_keys:
89
+ if key in load:
90
+ return load[key]
91
+ return load
92
+
93
+ async def _handle_exception(self, e: Exception) -> HTTPException:
94
+ '''
95
+ Handles exceptions and returns a HTTPException with the appropriate status code and detail.
96
+ '''
97
+ if isinstance(e, ApiException):
98
+ return HTTPException(
99
+ status_code=e.status,
100
+ detail=await self._extract_message(e),
101
+ )
102
+ elif isinstance(e, HTTPException):
103
+ return e
104
+ else:
105
+ return HTTPException(
106
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
107
+ )
108
+
85
109
  async def api_key_auth(
86
110
  self,
87
111
  api_key: Annotated[str | None, Depends(apikey_header)] = None,
88
- scopes: list[ApiScope] = [],
112
+ scopes: list[Scope] = [],
89
113
  ) -> Verify200Response:
90
114
  """
91
115
  Verifies the API key and checks if the user scopes are a subset of the API scopes.
92
116
  """
93
- if not api_key:
94
- raise self.no_credentials_exception
95
117
  try:
118
+ if not api_key:
119
+ raise self.no_credentials_exception
120
+
96
121
  res = await self._verify_api_key(api_key)
97
- except UnauthorizedException as e:
98
- raise self.invalid_api_key_exception
99
- valid_scopes = await self._check_scopes(scopes, res.scopes)
100
- if not valid_scopes:
101
- raise self.invalid_scopes_exception
102
- return res
122
+ await self._validate_scopes(scopes, [Scope.from_str(scope) for scope in res.scopes])
123
+ return res
124
+ except Exception as e:
125
+ raise await self._handle_exception(e)
103
126
 
104
127
  async def bearer_auth(
105
128
  self,
@@ -107,7 +130,7 @@ class AuthHandler:
107
130
  HTTPAuthorizationCredentials | None,
108
131
  Depends(http_bearer),
109
132
  ] = None,
110
- scopes: list[ApiScope] = [],
133
+ scopes: list[Scope] = [],
111
134
  ) -> Verify200Response:
112
135
  """
113
136
  Verifies the bearer token and checks if the user scopes are a subset of the API scopes.
@@ -117,12 +140,11 @@ class AuthHandler:
117
140
 
118
141
  try:
119
142
  res = await self._verify_bearer(bearer)
120
- except UnauthorizedException as e:
121
- raise self.invalid_bearer_exception
122
- valid_scopes = await self._check_scopes(scopes, res.scopes)
123
- if not valid_scopes:
124
- raise self.invalid_scopes_exception
125
- return res
143
+ await self._validate_scopes(scopes, [Scope.from_str(scope) for scope in res.scopes])
144
+ return res
145
+ except Exception as e:
146
+ raise await self._handle_exception(e)
147
+
126
148
 
127
149
  async def combined_auth(
128
150
  self,
@@ -130,7 +152,7 @@ class AuthHandler:
130
152
  HTTPAuthorizationCredentials | None, Depends(http_bearer)
131
153
  ] = None,
132
154
  api_key: Annotated[str | None, Depends(apikey_header)] = None,
133
- scopes: list[ApiScope] = [],
155
+ scopes: list[Scope] = [],
134
156
  ) -> Verify200Response:
135
157
  """
136
158
  Verifies the bearer token and API key and checks if the user scopes are a subset of the API scopes.
@@ -151,13 +173,11 @@ class AuthHandler:
151
173
  if res is None:
152
174
  continue
153
175
  if scopes:
154
- valid_scopes = await self._check_scopes(scopes, res.scopes)
155
- if not valid_scopes:
156
- raise self.invalid_scopes_exception
176
+ await self._validate_scopes(scopes, [Scope.from_str(scope) for scope in res.scopes])
157
177
  return res
158
178
 
159
- except UnauthorizedException as e:
160
- last_error = e
179
+ except Exception as e:
180
+ last_error = await self._handle_exception(e)
161
181
  continue
162
182
 
163
183
  raise last_error or self.no_credentials_exception
@@ -1,11 +1,15 @@
1
1
  from enum import Enum
2
2
 
3
3
 
4
- class ApiScope(str, Enum):
4
+ class Scope(str, Enum):
5
5
  """
6
6
  The permission scopes for the API.
7
7
  """
8
8
 
9
+ @classmethod
10
+ def from_str(cls, value: str) -> "Scope":
11
+ return cls(value)
12
+
9
13
  # Hive scopes
10
14
  HIVE_MODEL_READ = "hive:model:read"
11
15
  HIVE_DATA_READ = "hive:data:read"
@@ -27,3 +31,6 @@ class ApiScope(str, Enum):
27
31
  TRADE_NOTIFICATIONS_WRITE = "trade:notifications:write"
28
32
  TRADE_STRATEGIES_READ = "trade:strategies:read"
29
33
  TRADE_STRATEGIES_WRITE = "trade:strategies:write"
34
+
35
+ # Read projections
36
+ READ_PREDICTIONS = "read:predictions"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crypticorn
3
- Version: 2.0.0
3
+ Version: 2.0.1
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
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Typing :: Typed
14
14
  Requires-Python: >=3.10
15
15
  Description-Content-Type: text/markdown
16
+ Requires-Dist: fastapi
16
17
  Requires-Dist: urllib3<3.0.0,>=1.25.3
17
18
  Requires-Dist: python_dateutil>=2.8.2
18
19
  Requires-Dist: aiohttp>=3.8.4
@@ -33,10 +34,7 @@ Requires-Dist: pyflakes; extra == "dev"
33
34
  Provides-Extra: test
34
35
  Requires-Dist: pytest>=7.2.1; extra == "test"
35
36
  Requires-Dist: pytest-cov>=2.8.1; extra == "test"
36
- Requires-Dist: tox>=3.9.0; extra == "test"
37
- Requires-Dist: flake8>=4.0.0; extra == "test"
38
- Requires-Dist: types-python-dateutil>=2.8.19.14; extra == "test"
39
- Requires-Dist: mypy>=1.5; extra == "test"
37
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
40
38
 
41
39
  # What is Crypticorn?
42
40
 
@@ -50,9 +48,28 @@ Crypticorn offers AI-based solutions for both active and passive investors, incl
50
48
  Use this API Client to contribute to the so-called Hive AI, a community driven AI Meta Model for predicting the
51
49
  cryptocurrency market.
52
50
 
51
+ ## Installation
52
+
53
+ You can install the latest stable version from PyPi:
54
+ ```bash
55
+ pip install crypticorn
56
+ ```
57
+
58
+ If you want a specific version, run:
59
+ ```bash
60
+ pip install crypticorn==2.0.0
61
+ ```
62
+
63
+ If you want the latest version, which could be a pre release, run:
64
+ ```bash
65
+ pip install --pre crypticorn
66
+ ```
67
+
53
68
  ## Usage
54
69
 
55
- Within an asynchronous context the session is closed automatically.
70
+ As of know the library is available in async mode only. There are two was of using it.
71
+
72
+ ## With Async Context Protocol
56
73
  ```python
57
74
  async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
58
75
  # json response
@@ -66,6 +83,7 @@ async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
66
83
  print(response)
67
84
  ```
68
85
 
86
+ ## Without Async Context Protocol
69
87
  Without the context you need to close the session manually.
70
88
  ```python
71
89
  client = ApiClient(base_url="http://localhost", jwt=jwt)
@@ -229,4 +229,5 @@ crypticorn/trade/client/models/validation_error.py
229
229
  crypticorn/trade/client/models/validation_error_loc_inner.py
230
230
  requirements/dev.txt
231
231
  requirements/main.txt
232
- requirements/test.txt
232
+ requirements/test.txt
233
+ tests/test_auth_client.py
@@ -1,3 +1,4 @@
1
+ fastapi
1
2
  urllib3<3.0.0,>=1.25.3
2
3
  python_dateutil>=2.8.2
3
4
  aiohttp>=3.8.4
@@ -20,7 +21,4 @@ pyflakes
20
21
  [test]
21
22
  pytest>=7.2.1
22
23
  pytest-cov>=2.8.1
23
- tox>=3.9.0
24
- flake8>=4.0.0
25
- types-python-dateutil>=2.8.19.14
26
- mypy>=1.5
24
+ pytest-asyncio>=0.21.0
@@ -4,7 +4,7 @@ description = "Maximise Your Crypto Trading Profits with AI Predictions"
4
4
  readme = "README.md"
5
5
  requires-python = ">=3.10"
6
6
  authors = [{name = "Crypticorn", email = "timon@crypticorn.com"}]
7
- version = "2.0.0"
7
+ version = "2.0.1"
8
8
  keywords = ["machine learning", "data science", "crypto", "modelling"]
9
9
  dynamic = ["dependencies", "optional-dependencies"]
10
10
 
@@ -32,7 +32,7 @@ build_command = "pip install build && python -m build"
32
32
 
33
33
  # https://python-semantic-release.readthedocs.io/en/latest/multibranch_releases.html#multibranch-releases
34
34
  [tool.semantic_release.branches.main]
35
- match = "(main|dev)" # TODO: change this later to only main and uncomment the block below
35
+ match = "(dev)" # TODO: change this later to only main and uncomment the block below
36
36
  prerelease = false
37
37
 
38
38
  #[tool.semantic_release.branches.dev]
@@ -1,3 +1,6 @@
1
+ # crypticorn/common
2
+ fastapi
3
+
1
4
  # crypticorn/trade/requirements.txt
2
5
  urllib3 >= 1.25.3, < 3.0.0
3
6
  python_dateutil >= 2.8.2
@@ -0,0 +1,3 @@
1
+ pytest >= 7.2.1
2
+ pytest-cov >= 2.8.1
3
+ pytest-asyncio >= 0.21.0
@@ -0,0 +1,102 @@
1
+ from crypticorn.common import BaseURL, AuthHandler, Scope, http_bearer
2
+ import asyncio
3
+ from fastapi import HTTPException
4
+ import pytest_asyncio
5
+ import pytest
6
+ from fastapi.security import HTTPAuthorizationCredentials
7
+
8
+ VALID_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYlowNUVqS2ZqWGpXdDBTMDdvOSIsImF1ZCI6ImFwcC5jcnlwdGljb3JuLmNvbSIsImlzcyI6ImFjY291bnRzLmNyeXB0aWNvcm4uY29tIiwianRpIjoiTXY3ZTBpMkt0TlliYmN0TVp2aGYiLCJpYXQiOjE3NDM5NzI4NjgsImV4cCI6MTc0Mzk3NjQ2OCwic2NvcGVzIjpbInJlYWQ6cHJlZGljdGlvbnMiXX0.NkQ6FlmViPFZDqT9SLV0u8bnm2pegLQ0TknxYgutoGk"
9
+ EXPIRED_JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYlowNUVqS2ZqWGpXdDBTMDdvOSIsImF1ZCI6ImFwcC5jcnlwdGljb3JuLmNvbSIsImlzcyI6ImFjY291bnRzLmNyeXB0aWNvcm4uY29tIiwianRpIjoiM3FlU0h5S082VVNvMkZBU1VxMmkiLCJpYXQiOjE3NDM5Njc2MzAsImV4cCI6MTc0Mzk3MTIzMCwic2NvcGVzIjpbInJlYWQ6cHJlZGljdGlvbnMiXX0.d3yfsTGIZaygORyrRQvPPZTZLK0oM2rYz4ijUtpl3xk"
10
+
11
+
12
+ @pytest_asyncio.fixture
13
+ async def auth_handler() -> AuthHandler:
14
+ return AuthHandler(BaseURL.DEV)
15
+
16
+ @pytest.mark.asyncio
17
+ async def test_combined_auth_without_credentials(auth_handler: AuthHandler):
18
+ with pytest.raises(HTTPException) as e:
19
+ await auth_handler.combined_auth(bearer=None, api_key=None)
20
+ assert e.value.status_code == 401
21
+ assert e.value.detail == auth_handler.no_credentials_exception.detail
22
+
23
+ @pytest.mark.asyncio
24
+ async def test_combined_auth_with_invalid_bearer_token(auth_handler: AuthHandler):
25
+ with pytest.raises(HTTPException) as e:
26
+ await auth_handler.combined_auth(
27
+ bearer=HTTPAuthorizationCredentials(scheme="Bearer", credentials="123"),
28
+ api_key=None
29
+ )
30
+ assert e.value.status_code == 401
31
+
32
+ @pytest.mark.asyncio
33
+ async def test_combined_auth_with_expired_bearer_token(auth_handler: AuthHandler):
34
+ with pytest.raises(HTTPException) as e:
35
+ await auth_handler.combined_auth(
36
+ bearer=HTTPAuthorizationCredentials(scheme="Bearer", credentials=EXPIRED_JWT),
37
+ api_key=None
38
+ )
39
+ assert e.value.status_code == 401
40
+ assert e.value.detail == "jwt expired"
41
+
42
+ @pytest.mark.asyncio
43
+ async def test_combined_auth_with_invalid_api_key(auth_handler: AuthHandler):
44
+ with pytest.raises(HTTPException) as e:
45
+ return await auth_handler.combined_auth(bearer=None, api_key="123")
46
+ assert e.value.status_code == 500 # Not implemented
47
+
48
+ @pytest.mark.asyncio
49
+ async def test_combined_auth_with_valid_bearer_token(auth_handler: AuthHandler):
50
+ res = await auth_handler.combined_auth(bearer=HTTPAuthorizationCredentials(scheme="Bearer", credentials=VALID_JWT), api_key=None)
51
+ assert res.scopes == [Scope.READ_PREDICTIONS]
52
+
53
+ @pytest.mark.asyncio
54
+ async def test_combined_auth_with_valid_api_key(auth_handler: AuthHandler):
55
+ # res = await auth_handler.combined_auth(bearer=None, api_key="123")
56
+ # assert res.scopes == [Scope.READ_PREDICTIONS]
57
+ assert True # not implemented
58
+
59
+ @pytest.mark.asyncio
60
+ async def test_api_key_auth_without_api_key(auth_handler: AuthHandler):
61
+ with pytest.raises(HTTPException) as e:
62
+ return await auth_handler.api_key_auth(api_key=None)
63
+ assert e.value.status_code == 401
64
+
65
+ @pytest.mark.asyncio
66
+ async def test_api_key_auth_with_invalid_api_key(auth_handler: AuthHandler):
67
+ with pytest.raises(HTTPException) as e:
68
+ return await auth_handler.api_key_auth(api_key="123")
69
+ assert e.value.status_code == 500 # Not implemented
70
+
71
+ @pytest.mark.asyncio
72
+ async def test_api_key_auth_with_valid_api_key(auth_handler: AuthHandler):
73
+ # res = await auth_handler.api_key_auth(api_key="123")
74
+ # assert res.scopes == [Scope.READ_PREDICTIONS]
75
+ assert True # not implemented
76
+
77
+ @pytest.mark.asyncio
78
+ async def test_bearer_auth_without_bearer(auth_handler: AuthHandler):
79
+ with pytest.raises(HTTPException) as e:
80
+ return await auth_handler.bearer_auth(bearer=None)
81
+ assert e.value.status_code == 401
82
+
83
+ @pytest.mark.asyncio
84
+ async def test_bearer_auth_with_invalid_bearer(auth_handler: AuthHandler):
85
+ with pytest.raises(HTTPException) as e:
86
+ return await auth_handler.bearer_auth(bearer=HTTPAuthorizationCredentials(scheme="Bearer", credentials="123"))
87
+ assert e.value.status_code == 401
88
+
89
+ @pytest.mark.asyncio
90
+ async def test_bearer_auth_with_valid_bearer(auth_handler: AuthHandler):
91
+ res = await auth_handler.bearer_auth(bearer=HTTPAuthorizationCredentials(scheme="Bearer", credentials=VALID_JWT))
92
+ assert res.scopes == [Scope.READ_PREDICTIONS]
93
+
94
+ @pytest.mark.asyncio
95
+ async def test_bearer_auth_with_expired_bearer(auth_handler: AuthHandler):
96
+ with pytest.raises(HTTPException) as e:
97
+ return await auth_handler.bearer_auth(bearer=HTTPAuthorizationCredentials(scheme="Bearer", credentials=EXPIRED_JWT))
98
+ assert e.value.status_code == 401
99
+ assert e.value.detail == "jwt expired"
100
+
101
+
102
+
@@ -1,6 +0,0 @@
1
- pytest >= 7.2.1
2
- pytest-cov >= 2.8.1
3
- tox >= 3.9.0
4
- flake8 >= 4.0.0
5
- types-python-dateutil >= 2.8.19.14
6
- mypy >= 1.5