crypticorn 2.5.2__py3-none-any.whl → 2.6.0__py3-none-any.whl

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 (102) hide show
  1. crypticorn/auth/client/__init__.py +9 -0
  2. crypticorn/auth/client/api/auth_api.py +8 -5
  3. crypticorn/auth/client/api/user_api.py +247 -0
  4. crypticorn/auth/client/models/__init__.py +9 -0
  5. crypticorn/auth/client/models/create_api_key_request.py +2 -1
  6. crypticorn/auth/client/models/get_api_keys200_response_inner.py +2 -1
  7. crypticorn/{hive/client/models/http_validation_error.py → auth/client/models/user_by_username200_response.py} +14 -22
  8. crypticorn/auth/client/models/verify200_response.py +14 -1
  9. crypticorn/auth/client/models/verify_email200_response_auth_auth.py +14 -1
  10. crypticorn/auth/client/models/whoami200_response.py +6 -1
  11. crypticorn/cli/init.py +3 -0
  12. crypticorn/common/__init__.py +2 -1
  13. crypticorn/common/auth.py +13 -9
  14. crypticorn/common/errors.py +312 -105
  15. crypticorn/common/exceptions.py +38 -4
  16. crypticorn/common/mixins.py +19 -0
  17. crypticorn/common/pagination.py +49 -0
  18. crypticorn/common/scopes.py +27 -24
  19. crypticorn/common/status_router.py +9 -7
  20. crypticorn/common/utils.py +12 -6
  21. crypticorn/hive/client/__init__.py +3 -5
  22. crypticorn/hive/client/api/data_api.py +1 -33
  23. crypticorn/hive/client/api/models_api.py +351 -160
  24. crypticorn/hive/client/api/status_api.py +481 -9
  25. crypticorn/hive/client/configuration.py +12 -4
  26. crypticorn/hive/client/models/__init__.py +3 -5
  27. crypticorn/hive/client/models/coins.py +0 -1
  28. crypticorn/hive/client/models/data_info.py +44 -12
  29. crypticorn/hive/client/models/data_version.py +0 -1
  30. crypticorn/{pay/client/models/now_api_status_res.py → hive/client/models/data_version_info.py} +17 -11
  31. crypticorn/hive/client/models/exception_detail.py +114 -0
  32. crypticorn/hive/client/models/model.py +2 -3
  33. crypticorn/hive/client/models/{validation_error.py → target_info.py} +14 -25
  34. crypticorn/hive/client/rest.py +4 -1
  35. crypticorn/klines/client/api/status_api.py +481 -6
  36. crypticorn/klines/client/api/udf_api.py +0 -227
  37. crypticorn/metrics/client/api/status_api.py +476 -1
  38. crypticorn/pay/client/__init__.py +3 -8
  39. crypticorn/pay/client/api/now_payments_api.py +14 -17
  40. crypticorn/pay/client/api/payments_api.py +2 -11
  41. crypticorn/pay/client/api/products_api.py +2 -11
  42. crypticorn/pay/client/api/status_api.py +483 -8
  43. crypticorn/pay/client/api_client.py +2 -2
  44. crypticorn/pay/client/configuration.py +3 -3
  45. crypticorn/pay/client/exceptions.py +2 -2
  46. crypticorn/pay/client/models/__init__.py +3 -8
  47. crypticorn/pay/client/models/{validation_error.py → exception_detail.py} +37 -28
  48. crypticorn/pay/client/models/now_create_invoice_req.py +2 -2
  49. crypticorn/pay/client/models/now_create_invoice_res.py +2 -2
  50. crypticorn/pay/client/models/payment.py +2 -2
  51. crypticorn/pay/client/models/payment_status.py +2 -2
  52. crypticorn/pay/client/models/product_create.py +2 -2
  53. crypticorn/pay/client/models/product_read.py +2 -2
  54. crypticorn/pay/client/models/product_sub_read.py +2 -2
  55. crypticorn/pay/client/models/product_update.py +2 -2
  56. crypticorn/pay/client/models/scope.py +2 -2
  57. crypticorn/pay/client/models/services.py +2 -2
  58. crypticorn/pay/client/rest.py +2 -2
  59. crypticorn/trade/client/__init__.py +3 -7
  60. crypticorn/trade/client/api/api_keys_api.py +5 -20
  61. crypticorn/trade/client/api/bots_api.py +7 -19
  62. crypticorn/trade/client/api/exchanges_api.py +2 -2
  63. crypticorn/trade/client/api/futures_trading_panel_api.py +10 -22
  64. crypticorn/trade/client/api/notifications_api.py +10 -25
  65. crypticorn/trade/client/api/orders_api.py +2 -5
  66. crypticorn/trade/client/api/status_api.py +483 -8
  67. crypticorn/trade/client/api/strategies_api.py +5 -17
  68. crypticorn/trade/client/api/trading_actions_api.py +2 -11
  69. crypticorn/trade/client/api_client.py +2 -2
  70. crypticorn/trade/client/configuration.py +3 -3
  71. crypticorn/trade/client/exceptions.py +2 -2
  72. crypticorn/trade/client/models/__init__.py +3 -7
  73. crypticorn/trade/client/models/action_model.py +2 -2
  74. crypticorn/trade/client/models/bot_model.py +2 -2
  75. crypticorn/trade/client/models/bot_status.py +2 -2
  76. crypticorn/trade/client/models/{validation_error.py → exception_detail.py} +37 -28
  77. crypticorn/trade/client/models/exchange_key_model.py +2 -2
  78. crypticorn/trade/client/models/execution_ids.py +2 -2
  79. crypticorn/trade/client/models/futures_balance.py +2 -2
  80. crypticorn/trade/client/models/futures_trading_action.py +2 -2
  81. crypticorn/trade/client/models/margin_mode.py +2 -2
  82. crypticorn/trade/client/models/notification_model.py +2 -2
  83. crypticorn/trade/client/models/order_model.py +2 -2
  84. crypticorn/trade/client/models/order_status.py +2 -2
  85. crypticorn/trade/client/models/post_futures_action.py +2 -2
  86. crypticorn/trade/client/models/spot_trading_action.py +2 -2
  87. crypticorn/trade/client/models/strategy_exchange_info.py +2 -2
  88. crypticorn/trade/client/models/strategy_model_input.py +2 -2
  89. crypticorn/trade/client/models/strategy_model_output.py +2 -2
  90. crypticorn/trade/client/models/tpsl.py +2 -2
  91. crypticorn/trade/client/models/trading_action_type.py +2 -2
  92. crypticorn/trade/client/rest.py +2 -2
  93. {crypticorn-2.5.2.dist-info → crypticorn-2.6.0.dist-info}/METADATA +1 -1
  94. {crypticorn-2.5.2.dist-info → crypticorn-2.6.0.dist-info}/RECORD +97 -100
  95. {crypticorn-2.5.2.dist-info → crypticorn-2.6.0.dist-info}/WHEEL +1 -1
  96. crypticorn/hive/client/models/validation_error_loc_inner.py +0 -159
  97. crypticorn/pay/client/models/http_validation_error.py +0 -99
  98. crypticorn/pay/client/models/validation_error_loc_inner.py +0 -159
  99. crypticorn/trade/client/models/http_validation_error.py +0 -99
  100. crypticorn/trade/client/models/validation_error_loc_inner.py +0 -159
  101. {crypticorn-2.5.2.dist-info → crypticorn-2.6.0.dist-info}/entry_points.txt +0 -0
  102. {crypticorn-2.5.2.dist-info → crypticorn-2.6.0.dist-info}/top_level.txt +0 -0
@@ -1,23 +1,4 @@
1
- from enum import StrEnum, EnumMeta
2
- import logging
3
-
4
- logger = logging.getLogger("uvicorn")
5
-
6
-
7
- class Fallback(EnumMeta):
8
- """Fallback to no scope for unknown scopes."""
9
-
10
- # Note: This is a workaround to avoid the AttributeError when an unknown scope is accessed.
11
- # As soon as we have stable scopes, we can remove this.
12
-
13
- def __getattr__(cls, name):
14
- # Let Pydantic/internal stuff pass silently ! fragile
15
- if name.startswith("__"):
16
- raise AttributeError(name)
17
- logger.warning(
18
- f"Unknown scope '{name}' - falling back to no scope - update crypticorn package or check for typos"
19
- )
20
- return None
1
+ from enum import StrEnum
21
2
 
22
3
 
23
4
  class Scope(StrEnum):
@@ -27,10 +8,6 @@ class Scope(StrEnum):
27
8
 
28
9
  # If you update anything here, also update the scopes in the auth-service repository
29
10
 
30
- @classmethod
31
- def from_str(cls, value: str) -> "Scope":
32
- return cls(value)
33
-
34
11
  # Scopes that can be purchased - these actually exist in the jwt token
35
12
  READ_PREDICTIONS = "read:predictions"
36
13
 
@@ -68,3 +45,29 @@ class Scope(StrEnum):
68
45
  READ_METRICS_EXCHANGES = "read:metrics:exchanges"
69
46
  READ_METRICS_TOKENS = "read:metrics:tokens"
70
47
  READ_METRICS_MARKETS = "read:metrics:markets"
48
+
49
+ # Sentiment scopes
50
+ READ_SENTIMENT = "read:sentiment"
51
+
52
+ @classmethod
53
+ def admin_scopes(cls) -> list["Scope"]:
54
+ """Scopes that are only available to admins"""
55
+ return [
56
+ cls.WRITE_TRADE_STRATEGIES,
57
+ cls.WRITE_PAY_PRODUCTS,
58
+ cls.WRITE_PAY_NOW,
59
+ ]
60
+
61
+ @classmethod
62
+ def internal_scopes(cls) -> list["Scope"]:
63
+ """Scopes that are only available to internal services"""
64
+ return [
65
+ cls.WRITE_TRADE_ACTIONS,
66
+ ]
67
+
68
+ @classmethod
69
+ def purchaseable_scopes(cls) -> list["Scope"]:
70
+ """Scopes that can be purchased"""
71
+ return [
72
+ cls.READ_PREDICTIONS,
73
+ ]
@@ -4,6 +4,7 @@ from fastapi import APIRouter
4
4
 
5
5
  router = APIRouter(tags=["Status"], prefix="")
6
6
 
7
+
7
8
  @router.get("/", operation_id="ping")
8
9
  async def ping() -> str:
9
10
  """
@@ -11,10 +12,9 @@ async def ping() -> str:
11
12
  """
12
13
  return "OK"
13
14
 
15
+
14
16
  @router.get("/time", operation_id="getTime")
15
- async def time(
16
- type: Literal["iso", "unix"] = "iso"
17
- ) -> str:
17
+ async def time(type: Literal["iso", "unix"] = "iso") -> str:
18
18
  """
19
19
  Returns the current time in the specified format.
20
20
  """
@@ -22,7 +22,8 @@ async def time(
22
22
  return datetime.now().isoformat()
23
23
  else:
24
24
  return str(int(datetime.now().timestamp()))
25
-
25
+
26
+
26
27
  @router.get("/config", operation_id="getConfig")
27
28
  async def config() -> dict:
28
29
  """
@@ -31,12 +32,13 @@ async def config() -> dict:
31
32
  import importlib.metadata
32
33
  import os
33
34
  from dotenv import load_dotenv
35
+
34
36
  load_dotenv()
35
- try:
36
- crypticorn_version = importlib.metadata.version("flask")
37
+ try:
38
+ crypticorn_version = importlib.metadata.version("crypticorn")
37
39
  except importlib.metadata.PackageNotFoundError:
38
40
  crypticorn_version = "not installed"
39
41
  return {
40
- "crypticorn": crypticorn_version,
42
+ "crypticorn": f"v{crypticorn_version}",
41
43
  "environment": os.getenv("API_ENV", "not set"),
42
44
  }
@@ -8,16 +8,22 @@ from typing_extensions import deprecated
8
8
  from crypticorn.common import ApiError, HTTPException, ExceptionContent
9
9
 
10
10
 
11
- def throw_if_none(value: Any, error: ApiError = ApiError.OBJECT_NOT_FOUND) -> None:
12
- """Throws an FastAPI HTTPException if the value is None."""
11
+ def throw_if_none(
12
+ value: Any,
13
+ exception: ExceptionContent = ExceptionContent(error=ApiError.OBJECT_NOT_FOUND),
14
+ ) -> None:
15
+ """Throws an FastAPI HTTPException if the value is None. https://docs.python.org/3/library/stdtypes.html#truth-value-testing"""
13
16
  if value is None:
14
- raise HTTPException(content=ExceptionContent(error=error))
17
+ raise HTTPException(content=exception)
15
18
 
16
19
 
17
- def throw_if_falsy(value: Any, error: ApiError = ApiError.OBJECT_NOT_FOUND) -> None:
18
- """Throws an FastAPI HTTPException if the value is False."""
20
+ def throw_if_falsy(
21
+ value: Any,
22
+ exception: ExceptionContent = ExceptionContent(error=ApiError.OBJECT_NOT_FOUND),
23
+ ) -> None:
24
+ """Throws an FastAPI HTTPException if the value is False. https://docs.python.org/3/library/stdtypes.html#truth-value-testing"""
19
25
  if not value:
20
- raise HTTPException(content=ExceptionContent(error=error))
26
+ raise HTTPException(content=exception)
21
27
 
22
28
 
23
29
  def gen_random_id(length: int = 20) -> str:
@@ -40,18 +40,16 @@ from crypticorn.hive.client.models.data_value_value_value_inner import (
40
40
  DataValueValueValueInner,
41
41
  )
42
42
  from crypticorn.hive.client.models.data_version import DataVersion
43
+ from crypticorn.hive.client.models.data_version_info import DataVersionInfo
43
44
  from crypticorn.hive.client.models.download_links import DownloadLinks
44
45
  from crypticorn.hive.client.models.evaluation import Evaluation
45
46
  from crypticorn.hive.client.models.evaluation_response import EvaluationResponse
47
+ from crypticorn.hive.client.models.exception_detail import ExceptionDetail
46
48
  from crypticorn.hive.client.models.feature_size import FeatureSize
47
- from crypticorn.hive.client.models.http_validation_error import HTTPValidationError
48
49
  from crypticorn.hive.client.models.model import Model
49
50
  from crypticorn.hive.client.models.model_create import ModelCreate
50
51
  from crypticorn.hive.client.models.model_status import ModelStatus
51
52
  from crypticorn.hive.client.models.model_update import ModelUpdate
52
53
  from crypticorn.hive.client.models.target import Target
54
+ from crypticorn.hive.client.models.target_info import TargetInfo
53
55
  from crypticorn.hive.client.models.target_type import TargetType
54
- from crypticorn.hive.client.models.validation_error import ValidationError
55
- from crypticorn.hive.client.models.validation_error_loc_inner import (
56
- ValidationErrorLocInner,
57
- )
@@ -16,7 +16,7 @@ from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
16
16
  from typing import Any, Dict, List, Optional, Tuple, Union
17
17
  from typing_extensions import Annotated
18
18
 
19
- from pydantic import Field, StrictInt, StrictStr
19
+ from pydantic import Field, StrictInt
20
20
  from typing import Optional
21
21
  from typing_extensions import Annotated
22
22
  from crypticorn.hive.client.models.data_download_response import DataDownloadResponse
@@ -52,7 +52,6 @@ class DataApi:
52
52
  feature_size: Annotated[
53
53
  Optional[FeatureSize], Field(description="Feature size")
54
54
  ] = None,
55
- access_token: Optional[StrictStr] = None,
56
55
  _request_timeout: Union[
57
56
  None,
58
57
  Annotated[StrictFloat, Field(gt=0)],
@@ -75,8 +74,6 @@ class DataApi:
75
74
  :type version: DataVersion
76
75
  :param feature_size: Feature size
77
76
  :type feature_size: FeatureSize
78
- :param access_token:
79
- :type access_token: str
80
77
  :param _request_timeout: timeout setting for this request. If one
81
78
  number provided, it will be total request
82
79
  timeout. It can also be a pair (tuple) of
@@ -103,7 +100,6 @@ class DataApi:
103
100
  model_id=model_id,
104
101
  version=version,
105
102
  feature_size=feature_size,
106
- access_token=access_token,
107
103
  _request_auth=_request_auth,
108
104
  _content_type=_content_type,
109
105
  _headers=_headers,
@@ -112,7 +108,6 @@ class DataApi:
112
108
 
113
109
  _response_types_map: Dict[str, Optional[str]] = {
114
110
  "200": "DataDownloadResponse",
115
- "422": "HTTPValidationError",
116
111
  }
117
112
  response_data = await self.api_client.call_api(
118
113
  *_param, _request_timeout=_request_timeout
@@ -134,7 +129,6 @@ class DataApi:
134
129
  feature_size: Annotated[
135
130
  Optional[FeatureSize], Field(description="Feature size")
136
131
  ] = None,
137
- access_token: Optional[StrictStr] = None,
138
132
  _request_timeout: Union[
139
133
  None,
140
134
  Annotated[StrictFloat, Field(gt=0)],
@@ -157,8 +151,6 @@ class DataApi:
157
151
  :type version: DataVersion
158
152
  :param feature_size: Feature size
159
153
  :type feature_size: FeatureSize
160
- :param access_token:
161
- :type access_token: str
162
154
  :param _request_timeout: timeout setting for this request. If one
163
155
  number provided, it will be total request
164
156
  timeout. It can also be a pair (tuple) of
@@ -185,7 +177,6 @@ class DataApi:
185
177
  model_id=model_id,
186
178
  version=version,
187
179
  feature_size=feature_size,
188
- access_token=access_token,
189
180
  _request_auth=_request_auth,
190
181
  _content_type=_content_type,
191
182
  _headers=_headers,
@@ -194,7 +185,6 @@ class DataApi:
194
185
 
195
186
  _response_types_map: Dict[str, Optional[str]] = {
196
187
  "200": "DataDownloadResponse",
197
- "422": "HTTPValidationError",
198
188
  }
199
189
  response_data = await self.api_client.call_api(
200
190
  *_param, _request_timeout=_request_timeout
@@ -216,7 +206,6 @@ class DataApi:
216
206
  feature_size: Annotated[
217
207
  Optional[FeatureSize], Field(description="Feature size")
218
208
  ] = None,
219
- access_token: Optional[StrictStr] = None,
220
209
  _request_timeout: Union[
221
210
  None,
222
211
  Annotated[StrictFloat, Field(gt=0)],
@@ -239,8 +228,6 @@ class DataApi:
239
228
  :type version: DataVersion
240
229
  :param feature_size: Feature size
241
230
  :type feature_size: FeatureSize
242
- :param access_token:
243
- :type access_token: str
244
231
  :param _request_timeout: timeout setting for this request. If one
245
232
  number provided, it will be total request
246
233
  timeout. It can also be a pair (tuple) of
@@ -267,7 +254,6 @@ class DataApi:
267
254
  model_id=model_id,
268
255
  version=version,
269
256
  feature_size=feature_size,
270
- access_token=access_token,
271
257
  _request_auth=_request_auth,
272
258
  _content_type=_content_type,
273
259
  _headers=_headers,
@@ -276,7 +262,6 @@ class DataApi:
276
262
 
277
263
  _response_types_map: Dict[str, Optional[str]] = {
278
264
  "200": "DataDownloadResponse",
279
- "422": "HTTPValidationError",
280
265
  }
281
266
  response_data = await self.api_client.call_api(
282
267
  *_param, _request_timeout=_request_timeout
@@ -288,7 +273,6 @@ class DataApi:
288
273
  model_id,
289
274
  version,
290
275
  feature_size,
291
- access_token,
292
276
  _request_auth,
293
277
  _content_type,
294
278
  _headers,
@@ -353,7 +337,6 @@ class DataApi:
353
337
  @validate_call
354
338
  async def get_data_info(
355
339
  self,
356
- access_token: Optional[StrictStr] = None,
357
340
  _request_timeout: Union[
358
341
  None,
359
342
  Annotated[StrictFloat, Field(gt=0)],
@@ -370,8 +353,6 @@ class DataApi:
370
353
 
371
354
  Get information about available data and options for the latest data version
372
355
 
373
- :param access_token:
374
- :type access_token: str
375
356
  :param _request_timeout: timeout setting for this request. If one
376
357
  number provided, it will be total request
377
358
  timeout. It can also be a pair (tuple) of
@@ -395,7 +376,6 @@ class DataApi:
395
376
  """ # noqa: E501
396
377
 
397
378
  _param = self._get_data_info_serialize(
398
- access_token=access_token,
399
379
  _request_auth=_request_auth,
400
380
  _content_type=_content_type,
401
381
  _headers=_headers,
@@ -404,7 +384,6 @@ class DataApi:
404
384
 
405
385
  _response_types_map: Dict[str, Optional[str]] = {
406
386
  "200": "DataInfo",
407
- "422": "HTTPValidationError",
408
387
  }
409
388
  response_data = await self.api_client.call_api(
410
389
  *_param, _request_timeout=_request_timeout
@@ -418,7 +397,6 @@ class DataApi:
418
397
  @validate_call
419
398
  async def get_data_info_with_http_info(
420
399
  self,
421
- access_token: Optional[StrictStr] = None,
422
400
  _request_timeout: Union[
423
401
  None,
424
402
  Annotated[StrictFloat, Field(gt=0)],
@@ -435,8 +413,6 @@ class DataApi:
435
413
 
436
414
  Get information about available data and options for the latest data version
437
415
 
438
- :param access_token:
439
- :type access_token: str
440
416
  :param _request_timeout: timeout setting for this request. If one
441
417
  number provided, it will be total request
442
418
  timeout. It can also be a pair (tuple) of
@@ -460,7 +436,6 @@ class DataApi:
460
436
  """ # noqa: E501
461
437
 
462
438
  _param = self._get_data_info_serialize(
463
- access_token=access_token,
464
439
  _request_auth=_request_auth,
465
440
  _content_type=_content_type,
466
441
  _headers=_headers,
@@ -469,7 +444,6 @@ class DataApi:
469
444
 
470
445
  _response_types_map: Dict[str, Optional[str]] = {
471
446
  "200": "DataInfo",
472
- "422": "HTTPValidationError",
473
447
  }
474
448
  response_data = await self.api_client.call_api(
475
449
  *_param, _request_timeout=_request_timeout
@@ -483,7 +457,6 @@ class DataApi:
483
457
  @validate_call
484
458
  async def get_data_info_without_preload_content(
485
459
  self,
486
- access_token: Optional[StrictStr] = None,
487
460
  _request_timeout: Union[
488
461
  None,
489
462
  Annotated[StrictFloat, Field(gt=0)],
@@ -500,8 +473,6 @@ class DataApi:
500
473
 
501
474
  Get information about available data and options for the latest data version
502
475
 
503
- :param access_token:
504
- :type access_token: str
505
476
  :param _request_timeout: timeout setting for this request. If one
506
477
  number provided, it will be total request
507
478
  timeout. It can also be a pair (tuple) of
@@ -525,7 +496,6 @@ class DataApi:
525
496
  """ # noqa: E501
526
497
 
527
498
  _param = self._get_data_info_serialize(
528
- access_token=access_token,
529
499
  _request_auth=_request_auth,
530
500
  _content_type=_content_type,
531
501
  _headers=_headers,
@@ -534,7 +504,6 @@ class DataApi:
534
504
 
535
505
  _response_types_map: Dict[str, Optional[str]] = {
536
506
  "200": "DataInfo",
537
- "422": "HTTPValidationError",
538
507
  }
539
508
  response_data = await self.api_client.call_api(
540
509
  *_param, _request_timeout=_request_timeout
@@ -543,7 +512,6 @@ class DataApi:
543
512
 
544
513
  def _get_data_info_serialize(
545
514
  self,
546
- access_token,
547
515
  _request_auth,
548
516
  _content_type,
549
517
  _headers,