crypticorn 2.13.2__tar.gz → 2.14.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {crypticorn-2.13.2 → crypticorn-2.14.0}/CHANGELOG.md +26 -0
- {crypticorn-2.13.2/crypticorn.egg-info → crypticorn-2.14.0}/PKG-INFO +17 -9
- {crypticorn-2.13.2 → crypticorn-2.14.0}/README.md +16 -8
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/client.py +25 -8
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/errors.py +1 -1
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/logging.py +2 -1
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/main.py +1 -1
- {crypticorn-2.13.2 → crypticorn-2.14.0/crypticorn.egg-info}/PKG-INFO +17 -9
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn.egg-info/SOURCES.txt +2 -3
- {crypticorn-2.13.2 → crypticorn-2.14.0}/pyproject.toml +1 -1
- crypticorn-2.14.0/tests/test_custom_session.py +113 -0
- crypticorn-2.13.2/tests/test_basic_client.py +0 -41
- crypticorn-2.13.2/tests/test_shared_aiohttp_client.py +0 -29
- {crypticorn-2.13.2 → crypticorn-2.14.0}/LICENSE +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/MANIFEST.in +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api/admin_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api/auth_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api/service_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api/user_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api/wallet_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api_client.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/api_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/configuration.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/exceptions.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/add_wallet200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/add_wallet_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/authorize_user200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/authorize_user200_response_auth.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/authorize_user_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/create_api_key200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/create_api_key_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/create_user_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/get_api_keys200_response_inner.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_sale_round.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet_vesting_wallets_inner.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response_data_inner.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response_user_value.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/logout_default_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/logout_default_response_issues_inner.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/oauth_callback200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/oauth_callback200_response_user.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/refresh_token_info200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/refresh_token_info200_response_user_session.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/resend_verification_email_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/revoke_user_tokens_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/rotate_tokens200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/token_info200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/unlink_wallet_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/update_user_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/user_by_username200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/user_reset_password_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/user_set_password_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_email200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_email200_response_auth.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_email200_response_auth_auth.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_email_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_wallet_request.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/wallet_verified200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/whoami200_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/py.typed +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/rest.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/main.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/__main__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/init.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/templates/Dockerfile +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/templates/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/templates/auth.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/templates/dependabot.yml +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/templates/merge-env.sh +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/templates/ruff.yml +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/cli/version.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/ansi_colors.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/auth.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/decorators.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/enums.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/exceptions.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/middleware.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/mixins.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/openapi.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/pagination.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/router/admin_router.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/router/status_router.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/scopes.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/urls.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/utils.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/common/warnings.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/api/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/api/admin_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/api/data_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/api/models_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/api/status_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/api_client.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/api_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/configuration.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/exceptions.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/api_error_identifier.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/api_error_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/api_error_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/coin_info.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/coins.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/data_download_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/data_info.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/data_options.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/data_version.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/data_version_info.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/download_links.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/evaluation.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/evaluation_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/exception_detail.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/feature_size.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/log_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/model_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/model_read.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/model_status.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/model_update.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/target.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/target_info.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/models/target_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/py.typed +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/client/rest.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/main.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/hive/utils.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/admin_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/change_in_timeframe_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/funding_rates_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/ohlcv_data_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/status_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/symbols_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api/udf_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api_client.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/api_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/configuration.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/exceptions.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/api_error_identifier.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/api_error_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/api_error_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/change_in_timeframe.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/exception_detail.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/funding_rate.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/funding_rate_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/internal_exchange.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/log_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/market_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/ohlcv.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/resolution.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/search_symbol.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/sort_direction.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/symbol_group.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/symbol_info.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/symbol_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/timeframe.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/models/udf_config.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/py.typed +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/client/rest.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/klines/main.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/admin_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/exchanges_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/indicators_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/logs_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/marketcap_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/markets_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/quote_currencies_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/status_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api/tokens_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api_client.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/api_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/configuration.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/exceptions.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/api_error_identifier.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/api_error_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/api_error_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/exception_detail.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/exchange_availability.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/exchange_mapping.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/internal_exchange.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/log_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/market_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/marketcap_ranking.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/marketcap_symbol_ranking.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/ohlcv.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/severity.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/time_interval.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/models/trading_status.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/py.typed +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/client/rest.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/metrics/main.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api/admin_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api/now_payments_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api/payments_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api/products_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api/status_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api_client.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/api_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/configuration.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/exceptions.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/api_error_identifier.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/api_error_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/api_error_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/exception_detail.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/log_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/now_create_invoice_req.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/now_create_invoice_res.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/payment.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/payment_status.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/product.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/product_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/product_update.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/provider.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/scope.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/models/subscription.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/py.typed +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/client/rest.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/pay/main.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/admin_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/api_keys_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/bots_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/exchanges_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/futures_trading_panel_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/notifications_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/orders_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/status_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/strategies_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api/trading_actions_api.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api_client.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/api_response.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/configuration.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/exceptions.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/__init__.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/api_error_identifier.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/api_error_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/api_error_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/bot.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/bot_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/bot_status.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/bot_update.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/exception_detail.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/exchange.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/exchange_key.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/exchange_key_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/exchange_key_update.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/execution_ids.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/futures_balance.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/futures_trading_action.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/futures_trading_action_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/log_level.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/margin_mode.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/market_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/notification.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/notification_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/notification_update.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/order.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/order_status.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/post_futures_action.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/spot_trading_action_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/strategy.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/strategy_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/strategy_exchange_info.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/strategy_update.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/tpsl.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/tpsl_create.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/models/trading_action_type.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/py.typed +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/trade/client/rest.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn.egg-info/dependency_links.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn.egg-info/entry_points.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn.egg-info/requires.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn.egg-info/top_level.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/requirements/dev.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/requirements/extra.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/requirements/main.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/requirements/test.txt +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/setup.cfg +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/static/favicon.svg +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/static/logo.svg +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/static/pip-structure.drawio +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/static/pip-structure.svg +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/tests/test_auth_client.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/tests/test_config.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/tests/test_enums.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/tests/test_errors.py +0 -0
- {crypticorn-2.13.2 → crypticorn-2.14.0}/tests/test_pagination.py +0 -0
@@ -1,6 +1,32 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
3
|
|
4
|
+
## v2.14.0 (2025-05-26)
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
- Fixes error code value
|
9
|
+
([`182d4d7`](https://github.com/crypticorn-ai/api-client/commit/182d4d7a92289b66914816a90e707739dba4af1c))
|
10
|
+
|
11
|
+
### Continuous Integration
|
12
|
+
|
13
|
+
- Cleanup on failure in release step
|
14
|
+
([`dff5ee4`](https://github.com/crypticorn-ai/api-client/commit/dff5ee4b25832ed8b6944213325e7a6d658a2491))
|
15
|
+
|
16
|
+
### Features
|
17
|
+
|
18
|
+
- Allow custom http client injection
|
19
|
+
([`1a4cd0c`](https://github.com/crypticorn-ai/api-client/commit/1a4cd0cdd68d39a950f547d22721409e022c896a))
|
20
|
+
|
21
|
+
|
22
|
+
## v2.13.3 (2025-05-26)
|
23
|
+
|
24
|
+
### Bug Fixes
|
25
|
+
|
26
|
+
- Fixes logging import error
|
27
|
+
([`5df42ef`](https://github.com/crypticorn-ai/api-client/commit/5df42ef9835a397ed6162dcb1c1ad4ab67badd4e))
|
28
|
+
|
29
|
+
|
4
30
|
## v2.13.2 (2025-05-26)
|
5
31
|
|
6
32
|
### Bug Fixes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: crypticorn
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.14.0
|
4
4
|
Summary: Maximise Your Crypto Trading Profits with Machine Learning
|
5
5
|
Author-email: Crypticorn <timon@crypticorn.com>
|
6
6
|
License-Expression: MIT
|
@@ -207,19 +207,27 @@ async with ApiClient() as client:
|
|
207
207
|
|
208
208
|
### Session Management
|
209
209
|
|
210
|
-
By default `ApiClient` manages a single shared `aiohttp.ClientSession` for all service wrappers.
|
210
|
+
By default, `ApiClient` manages a single shared `aiohttp.ClientSession` for all service wrappers.
|
211
|
+
However, you can pass your own pre-configured `aiohttp.ClientSession` if you need advanced control — for example, to add retries, custom headers, logging, or mocking behavior.
|
212
|
+
|
213
|
+
When you inject a custom session, you are responsible for managing its lifecycle, including closing when you're done.
|
211
214
|
|
212
215
|
```python
|
213
216
|
import aiohttp
|
214
217
|
from crypticorn import ApiClient
|
215
218
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
219
|
+
async def main():
|
220
|
+
custom_session = aiohttp.ClientSession()
|
221
|
+
async with ApiClient(api_key="your-key", http_client=custom_session) as client:
|
222
|
+
await client.trade.status.ping()
|
223
|
+
await custom_session.close()
|
224
|
+
# or
|
225
|
+
custom_session = aiohttp.ClientSession()
|
226
|
+
client = ApiClient(api_key="your-key", http_client=custom_session)
|
227
|
+
await client.trade.status.ping()
|
228
|
+
await custom_session.close()
|
229
|
+
```
|
230
|
+
If you don’t pass a session, `ApiClient` will create and manage one internally. In that case, it will be automatically closed when using `async with` or when calling `await client.close()` manually.
|
223
231
|
|
224
232
|
### Disable Logging
|
225
233
|
|
@@ -152,19 +152,27 @@ async with ApiClient() as client:
|
|
152
152
|
|
153
153
|
### Session Management
|
154
154
|
|
155
|
-
By default `ApiClient` manages a single shared `aiohttp.ClientSession` for all service wrappers.
|
155
|
+
By default, `ApiClient` manages a single shared `aiohttp.ClientSession` for all service wrappers.
|
156
|
+
However, you can pass your own pre-configured `aiohttp.ClientSession` if you need advanced control — for example, to add retries, custom headers, logging, or mocking behavior.
|
157
|
+
|
158
|
+
When you inject a custom session, you are responsible for managing its lifecycle, including closing when you're done.
|
156
159
|
|
157
160
|
```python
|
158
161
|
import aiohttp
|
159
162
|
from crypticorn import ApiClient
|
160
163
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
164
|
+
async def main():
|
165
|
+
custom_session = aiohttp.ClientSession()
|
166
|
+
async with ApiClient(api_key="your-key", http_client=custom_session) as client:
|
167
|
+
await client.trade.status.ping()
|
168
|
+
await custom_session.close()
|
169
|
+
# or
|
170
|
+
custom_session = aiohttp.ClientSession()
|
171
|
+
client = ApiClient(api_key="your-key", http_client=custom_session)
|
172
|
+
await client.trade.status.ping()
|
173
|
+
await custom_session.close()
|
174
|
+
```
|
175
|
+
If you don’t pass a session, `ApiClient` will create and manage one internally. In that case, it will be automatically closed when using `async with` or when calling `await client.close()` manually.
|
168
176
|
|
169
177
|
### Disable Logging
|
170
178
|
|
@@ -24,6 +24,8 @@ class ApiClient:
|
|
24
24
|
api_key: Optional[str] = None,
|
25
25
|
jwt: Optional[str] = None,
|
26
26
|
base_url: BaseUrl = BaseUrl.PROD,
|
27
|
+
*,
|
28
|
+
http_client: Optional[ClientSession] = None,
|
27
29
|
):
|
28
30
|
self.base_url = base_url
|
29
31
|
"""The base URL the client will use to connect to the API."""
|
@@ -34,13 +36,8 @@ class ApiClient:
|
|
34
36
|
self.version = version("crypticorn")
|
35
37
|
"""The version of the client."""
|
36
38
|
|
37
|
-
|
38
|
-
#
|
39
|
-
# connector=TCPConnector(limit=100, limit_per_host=20),
|
40
|
-
# headers={"User-Agent": f"crypticorn/python/{self.version}"},
|
41
|
-
# )
|
42
|
-
self._http_client = None # temporary fix for the issue with the event loop
|
43
|
-
|
39
|
+
self._http_client = http_client
|
40
|
+
self._owns_http_client = http_client is None # whether we own the http client
|
44
41
|
self._service_classes: dict[Service, type[SubClient]] = {
|
45
42
|
Service.HIVE: HiveClient,
|
46
43
|
Service.TRADE: TradeClient,
|
@@ -99,9 +96,28 @@ class ApiClient:
|
|
99
96
|
return self._services[Service.AUTH]
|
100
97
|
|
101
98
|
async def close(self):
|
99
|
+
# close each in sync
|
102
100
|
for service in self._services.values():
|
103
|
-
if hasattr(service.base_client, "close"):
|
101
|
+
if hasattr(service.base_client, "close") and self._owns_http_client:
|
104
102
|
await service.base_client.close()
|
103
|
+
# close shared in async
|
104
|
+
if self._http_client and self._owns_http_client:
|
105
|
+
await self._http_client.close()
|
106
|
+
self._http_client = None
|
107
|
+
|
108
|
+
async def _ensure_session(self) -> None:
|
109
|
+
"""
|
110
|
+
Lazily create the shared HTTP client when first needed and pass it to all subclients.
|
111
|
+
"""
|
112
|
+
if self._http_client is None:
|
113
|
+
self._http_client = ClientSession(
|
114
|
+
timeout=ClientTimeout(total=30.0),
|
115
|
+
connector=TCPConnector(limit=100, limit_per_host=20),
|
116
|
+
headers={"User-Agent": f"crypticorn/python/{self.version}"},
|
117
|
+
)
|
118
|
+
for service in self._services.values():
|
119
|
+
if hasattr(service, 'base_client') and hasattr(service.base_client, 'rest_client'):
|
120
|
+
service.base_client.rest_client.pool_manager = self._http_client
|
105
121
|
|
106
122
|
def _get_default_config(self, service, version=None):
|
107
123
|
if version is None:
|
@@ -137,6 +153,7 @@ class ApiClient:
|
|
137
153
|
)
|
138
154
|
|
139
155
|
async def __aenter__(self):
|
156
|
+
await self._ensure_session()
|
140
157
|
return self
|
141
158
|
|
142
159
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
@@ -63,7 +63,7 @@ class ApiErrorIdentifier(StrEnum):
|
|
63
63
|
EXCHANGE_USER_FROZEN = "exchange_user_account_is_frozen"
|
64
64
|
EXPIRED_API_KEY = "api_key_expired"
|
65
65
|
EXPIRED_BEARER = "bearer_token_expired"
|
66
|
-
FAILED_OPEN_ORDER = "
|
66
|
+
FAILED_OPEN_ORDER = "failed_open_order"
|
67
67
|
FORBIDDEN = "forbidden"
|
68
68
|
HEDGE_MODE_NOT_ACTIVE = "hedge_mode_not_active"
|
69
69
|
INSUFFICIENT_BALANCE = "insufficient_balance"
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import logging
|
4
|
+
from logging.handlers import RotatingFileHandler
|
4
5
|
import sys
|
5
6
|
from crypticorn.common.mixins import ValidateEnumMixin
|
6
7
|
from crypticorn.common.ansi_colors import AnsiColors as C
|
@@ -109,7 +110,7 @@ def configure_logging(
|
|
109
110
|
# Configure file handler
|
110
111
|
if log_file:
|
111
112
|
os.makedirs(os.path.dirname(log_file), exist_ok=True)
|
112
|
-
file_handler =
|
113
|
+
file_handler = RotatingFileHandler(
|
113
114
|
log_file, maxBytes=10 * 1024 * 1024, backupCount=5
|
114
115
|
)
|
115
116
|
file_handler.setLevel(file_level)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: crypticorn
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.14.0
|
4
4
|
Summary: Maximise Your Crypto Trading Profits with Machine Learning
|
5
5
|
Author-email: Crypticorn <timon@crypticorn.com>
|
6
6
|
License-Expression: MIT
|
@@ -207,19 +207,27 @@ async with ApiClient() as client:
|
|
207
207
|
|
208
208
|
### Session Management
|
209
209
|
|
210
|
-
By default `ApiClient` manages a single shared `aiohttp.ClientSession` for all service wrappers.
|
210
|
+
By default, `ApiClient` manages a single shared `aiohttp.ClientSession` for all service wrappers.
|
211
|
+
However, you can pass your own pre-configured `aiohttp.ClientSession` if you need advanced control — for example, to add retries, custom headers, logging, or mocking behavior.
|
212
|
+
|
213
|
+
When you inject a custom session, you are responsible for managing its lifecycle, including closing when you're done.
|
211
214
|
|
212
215
|
```python
|
213
216
|
import aiohttp
|
214
217
|
from crypticorn import ApiClient
|
215
218
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
219
|
+
async def main():
|
220
|
+
custom_session = aiohttp.ClientSession()
|
221
|
+
async with ApiClient(api_key="your-key", http_client=custom_session) as client:
|
222
|
+
await client.trade.status.ping()
|
223
|
+
await custom_session.close()
|
224
|
+
# or
|
225
|
+
custom_session = aiohttp.ClientSession()
|
226
|
+
client = ApiClient(api_key="your-key", http_client=custom_session)
|
227
|
+
await client.trade.status.ping()
|
228
|
+
await custom_session.close()
|
229
|
+
```
|
230
|
+
If you don’t pass a session, `ApiClient` will create and manage one internally. In that case, it will be automatically closed when using `async with` or when calling `await client.close()` manually.
|
223
231
|
|
224
232
|
### Disable Logging
|
225
233
|
|
@@ -299,9 +299,8 @@ static/logo.svg
|
|
299
299
|
static/pip-structure.drawio
|
300
300
|
static/pip-structure.svg
|
301
301
|
tests/test_auth_client.py
|
302
|
-
tests/test_basic_client.py
|
303
302
|
tests/test_config.py
|
303
|
+
tests/test_custom_session.py
|
304
304
|
tests/test_enums.py
|
305
305
|
tests/test_errors.py
|
306
|
-
tests/test_pagination.py
|
307
|
-
tests/test_shared_aiohttp_client.py
|
306
|
+
tests/test_pagination.py
|
@@ -5,7 +5,7 @@ readme = "README.md"
|
|
5
5
|
license = "MIT"
|
6
6
|
requires-python = ">=3.9"
|
7
7
|
authors = [{name = "Crypticorn", email = "timon@crypticorn.com"}]
|
8
|
-
version = "2.
|
8
|
+
version = "2.14.0"
|
9
9
|
keywords = ["machine learning", "data science", "crypto", "modelling"]
|
10
10
|
dynamic = ["dependencies", "optional-dependencies"]
|
11
11
|
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import gc
|
2
|
+
import warnings
|
3
|
+
import pytest
|
4
|
+
import asyncio
|
5
|
+
from aiohttp import ClientSession
|
6
|
+
from crypticorn.client import ApiClient, Service # Adjust import to your path
|
7
|
+
|
8
|
+
|
9
|
+
@pytest.mark.asyncio
|
10
|
+
async def test_custom_http_client_injection():
|
11
|
+
custom_session = ClientSession()
|
12
|
+
|
13
|
+
client = ApiClient(http_client=custom_session)
|
14
|
+
|
15
|
+
# Subclients should have received the custom session immediately (sync context)
|
16
|
+
for service in Service:
|
17
|
+
subclient = client._services[service]
|
18
|
+
assert subclient.base_client.rest_client.pool_manager is custom_session
|
19
|
+
|
20
|
+
await client.close()
|
21
|
+
assert not custom_session.closed # Client did not own it
|
22
|
+
|
23
|
+
await custom_session.close()
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.mark.asyncio
|
27
|
+
async def test_lazy_http_client_creation():
|
28
|
+
client = ApiClient()
|
29
|
+
assert client._http_client is None
|
30
|
+
|
31
|
+
await client._ensure_session()
|
32
|
+
|
33
|
+
assert isinstance(client._http_client, ClientSession)
|
34
|
+
for service in Service:
|
35
|
+
subclient = client._services[service]
|
36
|
+
assert subclient.base_client.rest_client.pool_manager is client._http_client
|
37
|
+
|
38
|
+
await client.close()
|
39
|
+
assert client._http_client is None # It should have been closed
|
40
|
+
|
41
|
+
|
42
|
+
@pytest.mark.asyncio
|
43
|
+
async def test_close_custom_http_client_not_owned():
|
44
|
+
custom_session = ClientSession()
|
45
|
+
client = ApiClient(http_client=custom_session)
|
46
|
+
|
47
|
+
await client.close()
|
48
|
+
assert not custom_session.closed # Still open since it wasn't owned by us
|
49
|
+
|
50
|
+
await custom_session.close()
|
51
|
+
|
52
|
+
|
53
|
+
@pytest.mark.asyncio
|
54
|
+
async def test_close_owned_http_client():
|
55
|
+
client = ApiClient()
|
56
|
+
await client._ensure_session()
|
57
|
+
session = client._http_client
|
58
|
+
|
59
|
+
await client.close()
|
60
|
+
assert session.closed # session should be closed since we own it
|
61
|
+
|
62
|
+
@pytest.mark.asyncio
|
63
|
+
async def test_unclosed_owned_session_warns():
|
64
|
+
with warnings.catch_warnings(record=True) as w:
|
65
|
+
warnings.simplefilter("always") # Catch all warnings
|
66
|
+
|
67
|
+
client = ApiClient()
|
68
|
+
await client.trade.status.ping()
|
69
|
+
|
70
|
+
# Intentionally forget to close
|
71
|
+
del client
|
72
|
+
await asyncio.sleep(0.1) # Let __del__ run
|
73
|
+
|
74
|
+
# Look for aiohttp's unclosed session warning
|
75
|
+
unclosed_warnings = [
|
76
|
+
warn for warn in w if "Unclosed client session" in str(warn.message)
|
77
|
+
]
|
78
|
+
assert unclosed_warnings, "Expected unclosed client session warning"
|
79
|
+
|
80
|
+
@pytest.mark.asyncio
|
81
|
+
async def test_custom_session_not_closed_by_client():
|
82
|
+
with warnings.catch_warnings(record=True) as w:
|
83
|
+
warnings.simplefilter("always")
|
84
|
+
custom_session = ClientSession()
|
85
|
+
client = ApiClient(http_client=custom_session)
|
86
|
+
await client.trade.status.ping()
|
87
|
+
|
88
|
+
# Don't close the custom session
|
89
|
+
del client
|
90
|
+
del custom_session
|
91
|
+
|
92
|
+
# Force cleanup (otherwise it's unpredicatable when the warning will be raised)
|
93
|
+
await asyncio.sleep(0.1)
|
94
|
+
gc.collect()
|
95
|
+
await asyncio.sleep(0.1)
|
96
|
+
|
97
|
+
unclosed_warnings = [
|
98
|
+
warn for warn in w
|
99
|
+
if "Unclosed client session" in str(warn.message) or
|
100
|
+
"Unclosed connector" in str(warn.message)
|
101
|
+
]
|
102
|
+
assert unclosed_warnings, "Expected unclosed client session warning"
|
103
|
+
|
104
|
+
@pytest.mark.asyncio
|
105
|
+
async def test_context_manager_usage():
|
106
|
+
async with ApiClient() as client:
|
107
|
+
assert isinstance(client._http_client, ClientSession)
|
108
|
+
for service in Service:
|
109
|
+
subclient = client._services[service]
|
110
|
+
assert subclient.base_client.rest_client.pool_manager is client._http_client
|
111
|
+
|
112
|
+
# Confirm session is closed after context manager
|
113
|
+
assert client._http_client is None
|
@@ -1,41 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
import aiohttp
|
3
|
-
from crypticorn import ApiClient
|
4
|
-
|
5
|
-
|
6
|
-
@pytest.mark.asyncio
|
7
|
-
@pytest.mark.skip(reason="temporary fix for the issue with the event loop")
|
8
|
-
async def test_api_client_creation():
|
9
|
-
api = ApiClient(api_key="test", jwt="test", base_url="http://localhost:8000")
|
10
|
-
|
11
|
-
assert isinstance(api._http_client, aiohttp.ClientSession)
|
12
|
-
|
13
|
-
for service_name, service in api._services.items():
|
14
|
-
assert hasattr(service, "base_client")
|
15
|
-
assert hasattr(service.base_client, "rest_client")
|
16
|
-
assert service.base_client.rest_client.pool_manager is api._http_client
|
17
|
-
|
18
|
-
await api.close()
|
19
|
-
|
20
|
-
|
21
|
-
@pytest.mark.asyncio
|
22
|
-
@pytest.mark.skip(reason="temporary fix for the issue with the event loop")
|
23
|
-
async def test_custom_http_client():
|
24
|
-
custom_session = aiohttp.ClientSession()
|
25
|
-
custom_session.is_custom = True # Add a marker
|
26
|
-
|
27
|
-
api = ApiClient(api_key="test", jwt="test", base_url="http://localhost:8000")
|
28
|
-
api._http_client = custom_session
|
29
|
-
|
30
|
-
for service_name, service in api._services.items():
|
31
|
-
service.base_client.rest_client.pool_manager = custom_session
|
32
|
-
|
33
|
-
assert api._http_client is custom_session
|
34
|
-
assert hasattr(api._http_client, "is_custom")
|
35
|
-
|
36
|
-
for service_name, service in api._services.items():
|
37
|
-
assert service.base_client.rest_client.pool_manager is custom_session
|
38
|
-
assert hasattr(service.base_client.rest_client.pool_manager, "is_custom")
|
39
|
-
|
40
|
-
await api.close()
|
41
|
-
await custom_session.close()
|
@@ -1,29 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
import aiohttp
|
3
|
-
from crypticorn import ApiClient
|
4
|
-
from crypticorn.common import Service
|
5
|
-
|
6
|
-
|
7
|
-
class DummyClientSession(aiohttp.ClientSession):
|
8
|
-
def __init__(self, *args, **kwargs):
|
9
|
-
super().__init__(*args, **kwargs)
|
10
|
-
self.is_dummy = True
|
11
|
-
|
12
|
-
|
13
|
-
@pytest.mark.skip(reason="temporary fix for the issue with the event loop")
|
14
|
-
@pytest.mark.asyncio
|
15
|
-
async def test_shared_aiohttp_client_across_services():
|
16
|
-
dummy_client = DummyClientSession()
|
17
|
-
api = ApiClient(api_key="test", jwt="test", base_url="http://localhost:8000")
|
18
|
-
api._http_client = dummy_client
|
19
|
-
for service in api._services.values():
|
20
|
-
service.base_client.rest_client.pool_manager = dummy_client
|
21
|
-
assert api._http_client is dummy_client
|
22
|
-
assert api.hive.base_client.rest_client.pool_manager is dummy_client
|
23
|
-
assert api.trade.base_client.rest_client.pool_manager is dummy_client
|
24
|
-
assert api.klines.base_client.rest_client.pool_manager is dummy_client
|
25
|
-
assert api.pay.base_client.rest_client.pool_manager is dummy_client
|
26
|
-
assert api.metrics.base_client.rest_client.pool_manager is dummy_client
|
27
|
-
assert api.auth.base_client.rest_client.pool_manager is dummy_client
|
28
|
-
await api.close()
|
29
|
-
await dummy_client.close()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/add_wallet200_response.py
RENAMED
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/authorize_user200_response.py
RENAMED
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/authorize_user_request.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/create_api_key200_response.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/create_api_key_request.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/create_user_request.py
RENAMED
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/list_wallets200_response.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/logout_default_response.py
RENAMED
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/oauth_callback200_response.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/revoke_user_tokens_request.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/rotate_tokens200_response.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/token_info200_response.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/unlink_wallet_request.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/update_user_request.py
RENAMED
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/user_reset_password_request.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/user_set_password_request.py
RENAMED
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_email200_response.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_email_request.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/verify_wallet_request.py
RENAMED
File without changes
|
{crypticorn-2.13.2 → crypticorn-2.14.0}/crypticorn/auth/client/models/wallet_verified200_response.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|