crypticorn 2.17.0rc7__py3-none-any.whl → 2.18.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 (78) hide show
  1. crypticorn/auth/client/api/admin_api.py +2 -0
  2. crypticorn/auth/client/api/auth_api.py +1417 -545
  3. crypticorn/auth/client/api/service_api.py +4 -0
  4. crypticorn/auth/client/api/user_api.py +4 -0
  5. crypticorn/auth/client/api/wallet_api.py +4 -0
  6. crypticorn/auth/client/api_client.py +5 -0
  7. crypticorn/auth/client/configuration.py +2 -2
  8. crypticorn/auth/client/models/add_wallet_request.py +1 -1
  9. crypticorn/auth/client/models/authorize_user_request.py +1 -1
  10. crypticorn/auth/client/models/create_api_key_request.py +3 -3
  11. crypticorn/auth/client/models/create_user_request.py +1 -1
  12. crypticorn/auth/client/models/get_api_keys200_response_inner.py +3 -3
  13. crypticorn/auth/client/models/list_wallets200_response_balances_inner_sale_round.py +1 -1
  14. crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet.py +1 -1
  15. crypticorn/auth/client/models/list_wallets200_response_balances_inner_wallet_vesting_wallets_inner.py +1 -1
  16. crypticorn/auth/client/models/list_wallets200_response_data_inner.py +1 -1
  17. crypticorn/auth/client/models/logout_default_response.py +1 -1
  18. crypticorn/auth/client/models/oauth_callback200_response_user.py +1 -1
  19. crypticorn/auth/client/models/refresh_token_info200_response_user_session.py +1 -1
  20. crypticorn/auth/client/models/rotate_tokens200_response.py +1 -1
  21. crypticorn/auth/client/models/token_info200_response.py +1 -1
  22. crypticorn/auth/client/models/update_user_request.py +1 -1
  23. crypticorn/auth/client/models/user_by_username200_response.py +1 -1
  24. crypticorn/auth/client/models/verify200_response.py +1 -1
  25. crypticorn/auth/client/models/verify_email200_response_auth.py +1 -1
  26. crypticorn/auth/client/models/verify_email200_response_auth_auth.py +1 -1
  27. crypticorn/auth/client/models/whoami200_response.py +1 -1
  28. crypticorn/common/__init__.py +11 -11
  29. crypticorn/common/auth.py +109 -57
  30. crypticorn/common/decorators.py +1 -1
  31. crypticorn/common/enums.py +1 -0
  32. crypticorn/common/errors.py +7 -21
  33. crypticorn/common/exceptions.py +33 -17
  34. crypticorn/common/logging.py +5 -4
  35. crypticorn/common/metrics.py +17 -5
  36. crypticorn/common/middleware.py +61 -12
  37. crypticorn/common/mixins.py +2 -1
  38. crypticorn/common/pagination.py +3 -2
  39. crypticorn/common/router/admin_router.py +17 -6
  40. crypticorn/common/router/status_router.py +3 -26
  41. crypticorn/common/utils.py +6 -6
  42. crypticorn/common/warnings.py +1 -0
  43. crypticorn/dex/client/api/admin_api.py +3 -0
  44. crypticorn/dex/client/api/signals_api.py +27 -23
  45. crypticorn/dex/client/api/status_api.py +3 -0
  46. crypticorn/dex/client/api_client.py +5 -0
  47. crypticorn/dex/client/configuration.py +2 -2
  48. crypticorn/dex/client/models/exception_detail.py +1 -1
  49. crypticorn/dex/client/models/paginated_response_signal_with_token.py +1 -1
  50. crypticorn/dex/client/models/signal_overview_stats.py +4 -2
  51. crypticorn/dex/client/models/signal_volume.py +4 -4
  52. crypticorn/dex/client/models/signal_with_token.py +2 -2
  53. crypticorn/dex/client/models/token_detail.py +1 -1
  54. crypticorn/klines/main.py +1 -1
  55. crypticorn/metrics/main.py +1 -1
  56. crypticorn/trade/client/__init__.py +1 -7
  57. crypticorn/trade/client/api/admin_api.py +0 -402
  58. crypticorn/trade/client/api/trading_actions_api.py +86 -315
  59. crypticorn/trade/client/models/__init__.py +1 -7
  60. crypticorn/trade/client/models/actions_count.py +88 -0
  61. crypticorn/trade/client/models/api_error_identifier.py +1 -0
  62. crypticorn/trade/client/models/exchange_key.py +1 -1
  63. crypticorn/trade/client/models/exchange_key_balance.py +1 -1
  64. crypticorn/trade/client/models/execution_ids.py +1 -1
  65. crypticorn/trade/client/models/notification_create.py +1 -1
  66. crypticorn/trade/client/models/post_futures_action.py +1 -1
  67. crypticorn/trade/client/models/spot_balance.py +6 -7
  68. crypticorn/trade/client/models/tpsl.py +4 -19
  69. crypticorn/trade/client/models/tpsl_create.py +6 -19
  70. {crypticorn-2.17.0rc7.dist-info → crypticorn-2.18.0.dist-info}/METADATA +1 -1
  71. {crypticorn-2.17.0rc7.dist-info → crypticorn-2.18.0.dist-info}/RECORD +75 -77
  72. crypticorn/trade/client/models/paginated_response_union_futures_trading_action_spot_trading_action.py +0 -141
  73. crypticorn/trade/client/models/paginated_response_union_futures_trading_action_spot_trading_action_data_inner.py +0 -165
  74. crypticorn/trade/client/models/spot_trading_action.py +0 -207
  75. {crypticorn-2.17.0rc7.dist-info → crypticorn-2.18.0.dist-info}/WHEEL +0 -0
  76. {crypticorn-2.17.0rc7.dist-info → crypticorn-2.18.0.dist-info}/entry_points.txt +0 -0
  77. {crypticorn-2.17.0rc7.dist-info → crypticorn-2.18.0.dist-info}/licenses/LICENSE +0 -0
  78. {crypticorn-2.17.0rc7.dist-info → crypticorn-2.18.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,9 @@
1
1
  """Comprehensive error handling system defining various API error types, HTTP exceptions, and error content structures."""
2
2
 
3
3
  from enum import Enum
4
- from fastapi import status
4
+
5
5
  from crypticorn.common.mixins import ApiErrorFallback
6
+ from fastapi import status
6
7
 
7
8
  try:
8
9
  from enum import StrEnum
@@ -80,8 +81,6 @@ class ApiErrorIdentifier(StrEnum):
80
81
  LIQUIDATION_PRICE_VIOLATION = "order_violates_liquidation_price_constraints"
81
82
  MARGIN_MODE_CLASH = "margin_mode_clash"
82
83
  NAME_NOT_UNIQUE = "name_not_unique"
83
- NO_API_KEY = "no_api_key"
84
- NO_BEARER = "no_bearer"
85
84
  NO_CREDENTIALS = "no_credentials"
86
85
  NOW_API_DOWN = "now_api_down"
87
86
  OBJECT_ALREADY_EXISTS = "object_already_exists"
@@ -353,16 +352,6 @@ class ApiError(Enum, metaclass=ApiErrorFallback):
353
352
  ApiErrorType.USER_ERROR,
354
353
  ApiErrorLevel.ERROR,
355
354
  )
356
- NO_API_KEY = (
357
- ApiErrorIdentifier.NO_API_KEY,
358
- ApiErrorType.USER_ERROR,
359
- ApiErrorLevel.ERROR,
360
- )
361
- NO_BEARER = (
362
- ApiErrorIdentifier.NO_BEARER,
363
- ApiErrorType.USER_ERROR,
364
- ApiErrorLevel.ERROR,
365
- )
366
355
  NO_CREDENTIALS = (
367
356
  ApiErrorIdentifier.NO_CREDENTIALS,
368
357
  ApiErrorType.USER_ERROR,
@@ -565,6 +554,11 @@ class ApiError(Enum, metaclass=ApiErrorFallback):
565
554
  """WebSocket status code for the error."""
566
555
  return StatusCodeMapper.get_websocket_code(self)
567
556
 
557
+ @classmethod
558
+ def from_json(cls, data: dict) -> "ApiError":
559
+ """Load an ApiError from a dictionary. Must contain the identifier with the key 'code'."""
560
+ return next(error for error in cls if error.identifier == data["code"])
561
+
568
562
 
569
563
  class StatusCodeMapper:
570
564
  """Mapping of API errors to HTTP/Websocket status codes."""
@@ -595,14 +589,6 @@ class StatusCodeMapper:
595
589
  status.HTTP_401_UNAUTHORIZED,
596
590
  status.WS_1008_POLICY_VIOLATION,
597
591
  ),
598
- ApiError.NO_API_KEY: (
599
- status.HTTP_401_UNAUTHORIZED,
600
- status.WS_1008_POLICY_VIOLATION,
601
- ),
602
- ApiError.NO_BEARER: (
603
- status.HTTP_401_UNAUTHORIZED,
604
- status.WS_1008_POLICY_VIOLATION,
605
- ),
606
592
  ApiError.INSUFFICIENT_SCOPES: (
607
593
  status.HTTP_403_FORBIDDEN,
608
594
  status.WS_1008_POLICY_VIOLATION,
@@ -1,11 +1,19 @@
1
- from typing import Optional, Dict, Any
2
- from pydantic import BaseModel, Field
3
- from fastapi import HTTPException as FastAPIHTTPException, Request, FastAPI
1
+ import json
2
+ import logging
3
+ from typing import Any, Optional
4
+
5
+ from crypticorn.common.errors import (
6
+ ApiError,
7
+ ApiErrorIdentifier,
8
+ ApiErrorLevel,
9
+ ApiErrorType,
10
+ )
11
+ from fastapi import FastAPI
12
+ from fastapi import HTTPException as FastAPIHTTPException
13
+ from fastapi import Request
4
14
  from fastapi.exceptions import RequestValidationError, ResponseValidationError
5
15
  from fastapi.responses import JSONResponse
6
- from crypticorn.common import ApiError, ApiErrorIdentifier, ApiErrorType, ApiErrorLevel
7
- import logging
8
- import json
16
+ from pydantic import BaseModel, Field
9
17
 
10
18
  try:
11
19
  from enum import StrEnum
@@ -66,7 +74,7 @@ class HTTPException(FastAPIHTTPException):
66
74
  def __init__(
67
75
  self,
68
76
  content: ExceptionContent,
69
- headers: Optional[Dict[str, str]] = None,
77
+ headers: Optional[dict[str, str]] = None,
70
78
  _type: Optional[_ExceptionType] = _ExceptionType.HTTP,
71
79
  ):
72
80
  self.content = content
@@ -86,7 +94,7 @@ class WebSocketException(HTTPException):
86
94
  """
87
95
 
88
96
  def __init__(
89
- self, content: ExceptionContent, headers: Optional[Dict[str, str]] = None
97
+ self, content: ExceptionContent, headers: Optional[dict[str, str]] = None
90
98
  ):
91
99
  super().__init__(content, headers, _type=_ExceptionType.WEBSOCKET)
92
100
 
@@ -102,11 +110,13 @@ class WebSocketException(HTTPException):
102
110
  async def general_handler(request: Request, exc: Exception) -> JSONResponse:
103
111
  """Default exception handler for all exceptions."""
104
112
  body = ExceptionContent(message=str(exc), error=ApiError.UNKNOWN_ERROR)
113
+ http_exc = HTTPException(content=body)
105
114
  res = JSONResponse(
106
- status_code=body.enrich().status_code,
107
- content=HTTPException(content=body).detail,
115
+ status_code=http_exc.status_code,
116
+ content=http_exc.detail,
117
+ headers=http_exc.headers,
108
118
  )
109
- _logger.error(f"Response validation error: {json.loads(res.__dict__.get('body'))}")
119
+ _logger.error(f"General error: {json.loads(res.__dict__.get('body'))}")
110
120
  return res
111
121
 
112
122
 
@@ -115,11 +125,13 @@ async def request_validation_handler(
115
125
  ) -> JSONResponse:
116
126
  """Exception handler for all request validation errors."""
117
127
  body = ExceptionContent(message=str(exc), error=ApiError.INVALID_DATA_REQUEST)
128
+ http_exc = HTTPException(content=body)
118
129
  res = JSONResponse(
119
- status_code=body.enrich().status_code,
120
- content=HTTPException(content=body).detail,
130
+ status_code=http_exc.status_code,
131
+ content=http_exc.detail,
132
+ headers=http_exc.headers,
121
133
  )
122
- _logger.error(f"Response validation error: {json.loads(res.__dict__.get('body'))}")
134
+ _logger.error(f"Request validation error: {json.loads(res.__dict__.get('body'))}")
123
135
  return res
124
136
 
125
137
 
@@ -128,9 +140,11 @@ async def response_validation_handler(
128
140
  ) -> JSONResponse:
129
141
  """Exception handler for all response validation errors."""
130
142
  body = ExceptionContent(message=str(exc), error=ApiError.INVALID_DATA_RESPONSE)
143
+ http_exc = HTTPException(content=body)
131
144
  res = JSONResponse(
132
- status_code=body.enrich().status_code,
133
- content=HTTPException(content=body).detail,
145
+ status_code=http_exc.status_code,
146
+ content=http_exc.detail,
147
+ headers=http_exc.headers,
134
148
  )
135
149
  _logger.error(f"Response validation error: {json.loads(res.__dict__.get('body'))}")
136
150
  return res
@@ -138,7 +152,9 @@ async def response_validation_handler(
138
152
 
139
153
  async def http_handler(request: Request, exc: HTTPException) -> JSONResponse:
140
154
  """Exception handler for HTTPExceptions. It unwraps the HTTPException and returns the detail in a flat JSON response."""
141
- res = JSONResponse(status_code=exc.status_code, content=exc.detail)
155
+ res = JSONResponse(
156
+ status_code=exc.status_code, content=exc.detail, headers=exc.headers
157
+ )
142
158
  _logger.error(f"HTTP error: {json.loads(res.__dict__.get('body'))}")
143
159
  return res
144
160
 
@@ -1,12 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from logging.handlers import RotatingFileHandler
4
+ import os
5
5
  import sys
6
- from crypticorn.common.mixins import ValidateEnumMixin
7
- from crypticorn.common.ansi_colors import AnsiColors as C
8
6
  from datetime import datetime
9
- import os
7
+ from logging.handlers import RotatingFileHandler
8
+
9
+ from crypticorn.common.ansi_colors import AnsiColors as C
10
+ from crypticorn.common.mixins import ValidateEnumMixin
10
11
 
11
12
  try:
12
13
  from enum import StrEnum
@@ -1,18 +1,30 @@
1
1
  # metrics/registry.py
2
- from prometheus_client import Counter, Histogram, CollectorRegistry
2
+ from prometheus_client import CollectorRegistry, Counter, Histogram
3
3
 
4
4
  registry = CollectorRegistry()
5
5
 
6
- http_requests_total = Counter(
6
+ HTTP_REQUESTS_COUNT = Counter(
7
7
  "http_requests_total",
8
8
  "Total HTTP requests",
9
- ["method", "endpoint", "status_code"],
9
+ ["method", "endpoint", "status_code", "auth_type"],
10
10
  registry=registry,
11
11
  )
12
12
 
13
- http_request_duration_seconds = Histogram(
13
+ HTTP_REQUEST_DURATION = Histogram(
14
14
  "http_request_duration_seconds",
15
15
  "HTTP request duration in seconds",
16
- ["endpoint"],
16
+ ["endpoint", "method"],
17
+ registry=registry,
18
+ )
19
+
20
+ REQUEST_SIZE = Histogram(
21
+ "http_request_size_bytes", "Size of HTTP request bodies", ["method", "endpoint"]
22
+ )
23
+
24
+
25
+ RESPONSE_SIZE = Histogram(
26
+ "http_response_size_bytes",
27
+ "Size of HTTP responses",
28
+ ["method", "endpoint"],
17
29
  registry=registry,
18
30
  )
@@ -1,30 +1,79 @@
1
1
  import time
2
- from fastapi import FastAPI
2
+ import warnings
3
+ from contextlib import asynccontextmanager
4
+
5
+ from crypticorn.common.logging import configure_logging
6
+ from crypticorn.common.metrics import (
7
+ HTTP_REQUEST_DURATION,
8
+ HTTP_REQUESTS_COUNT,
9
+ REQUEST_SIZE,
10
+ RESPONSE_SIZE,
11
+ )
12
+ from crypticorn.common.warnings import CrypticornDeprecatedSince217
13
+ from fastapi import FastAPI, Request
3
14
  from fastapi.middleware.cors import CORSMiddleware
4
15
  from starlette.middleware.base import BaseHTTPMiddleware
5
- from crypticorn.common.logging import configure_logging
6
- from contextlib import asynccontextmanager
7
16
  from typing_extensions import deprecated
8
- import warnings
9
- from crypticorn.common.warnings import CrypticornDeprecatedSince217
10
- from crypticorn.common.metrics import http_requests_total, http_request_duration_seconds
11
17
 
12
18
 
13
19
  class PrometheusMiddleware(BaseHTTPMiddleware):
14
- async def dispatch(self, request, call_next):
20
+ async def dispatch(self, request: Request, call_next):
21
+
22
+ if "authorization" in request.headers:
23
+ auth_type = (
24
+ request.headers["authorization"].split()[0]
25
+ if " " in request.headers["authorization"]
26
+ else "none"
27
+ )
28
+ elif "x-api-key" in request.headers:
29
+ auth_type = "X-API-KEY"
30
+ else:
31
+ auth_type = "none"
32
+
33
+ try:
34
+ endpoint = request.get(
35
+ "route"
36
+ ).path # use /time/{type} instead of dynamic route to avoid high cardinality
37
+ except Exception:
38
+ endpoint = request.url.path
39
+
15
40
  start = time.perf_counter()
16
41
  response = await call_next(request)
17
42
  duration = time.perf_counter() - start
18
43
 
19
- http_requests_total.labels(
44
+ HTTP_REQUESTS_COUNT.labels(
20
45
  method=request.method,
21
- endpoint=request.url.path,
46
+ endpoint=endpoint,
22
47
  status_code=response.status_code,
48
+ auth_type=auth_type,
23
49
  ).inc()
24
50
 
25
- http_request_duration_seconds.labels(endpoint=request.url.path).observe(
26
- duration
27
- )
51
+ try:
52
+ body = await request.body()
53
+ size = len(body)
54
+ except Exception:
55
+ size = 0
56
+
57
+ REQUEST_SIZE.labels(
58
+ method=request.method,
59
+ endpoint=endpoint,
60
+ ).observe(size)
61
+
62
+ try:
63
+ body = await response.body()
64
+ size = len(body)
65
+ except Exception:
66
+ size = 0
67
+
68
+ RESPONSE_SIZE.labels(
69
+ method=request.method,
70
+ endpoint=endpoint,
71
+ ).observe(size)
72
+
73
+ HTTP_REQUEST_DURATION.labels(
74
+ endpoint=endpoint,
75
+ method=request.method,
76
+ ).observe(duration)
28
77
 
29
78
  return response
30
79
 
@@ -1,6 +1,7 @@
1
- from enum import EnumMeta
2
1
  import logging
3
2
  import warnings
3
+ from enum import EnumMeta
4
+
4
5
  from crypticorn.common.warnings import CrypticornDeprecatedSince28
5
6
 
6
7
  _logger = logging.getLogger("crypticorn")
@@ -1,8 +1,9 @@
1
1
  """Utilities for handling paginated API responses, cursor-based pagination, filtering, sorting, etc."""
2
2
 
3
- from typing import Annotated, Any, Generic, Type, TypeVar, Optional, Literal
4
- from pydantic import BaseModel, Field, model_validator
5
3
  import math
4
+ from typing import Annotated, Any, Generic, Literal, Optional, Type, TypeVar
5
+
6
+ from pydantic import BaseModel, Field, model_validator
6
7
 
7
8
  T = TypeVar("T")
8
9
 
@@ -2,19 +2,22 @@
2
2
  This module contains the admin router for the API.
3
3
  It provides endpoints for monitoring the server and getting information about the environment.
4
4
  ONLY ALLOW ACCESS TO THIS ROUTER WITH ADMIN SCOPES.
5
- >>> app.include_router(admin_router, dependencies=[Security(auth_handler.combined_auth, scopes=[Scope.READ_ADMIN, Scope.WRITE_ADMIN])])
5
+ >>> app.include_router(admin_router, dependencies=[Security(auth_handler.full_auth, scopes=[Scope.READ_ADMIN, Scope.WRITE_ADMIN])])
6
6
  """
7
7
 
8
- import os
9
8
  import importlib.metadata
9
+ import logging
10
+ import os
11
+ import re
10
12
  import threading
11
13
  import time
12
- import psutil
13
- import re
14
- import logging
15
14
  from typing import Literal
16
- from fastapi import APIRouter, Query
15
+
16
+ import psutil
17
17
  from crypticorn.common.logging import LogLevel
18
+ from crypticorn.common.metrics import registry
19
+ from fastapi import APIRouter, Query, Response
20
+ from prometheus_client import CONTENT_TYPE_LATEST, generate_latest
18
21
 
19
22
  router = APIRouter(tags=["Admin"], prefix="/admin")
20
23
 
@@ -104,3 +107,11 @@ def list_installed_packages(
104
107
  or any(re.match(pattern, dist.metadata["Name"]) for pattern in include)
105
108
  }
106
109
  return dict(sorted(packages.items()))
110
+
111
+
112
+ @router.get("/metrics", operation_id="getMetrics")
113
+ def metrics():
114
+ """
115
+ Get Prometheus metrics for the application. Returns plain text.
116
+ """
117
+ return Response(generate_latest(registry), media_type=CONTENT_TYPE_LATEST)
@@ -10,25 +10,11 @@ Then include the router in the FastAPI app.
10
10
  """
11
11
 
12
12
  from datetime import datetime
13
- from fastapi import APIRouter, Request
14
- from typing import Annotated, Literal
15
- from fastapi import APIRouter, Response, Depends
16
- from prometheus_client import generate_latest, CONTENT_TYPE_LATEST
17
- from crypticorn.common.metrics import registry
18
- from crypticorn.common.auth import AuthHandler
13
+ from typing import Literal
19
14
 
20
- class EnhancedApiRouter(APIRouter):
21
- def __init__(self, enable_metrics: bool = False, auth_handler: AuthHandler = AuthHandler(), *args, **kwargs):
22
- """
23
- Enhanced API Router that allows for metrics and authentication.
24
- If enable_metrics is True, the router will include the metrics endpoint.
25
- If auth_handler is provided, the router will use the auth handler to authenticate requests with
26
- """
27
- super().__init__(*args, **kwargs)
28
- self.enable_metrics = enable_metrics
29
- self.auth_handler = auth_handler
15
+ from fastapi import APIRouter, Request
30
16
 
31
- router = EnhancedApiRouter(tags=["Status"], prefix="")
17
+ router = APIRouter(tags=["Status"], prefix="")
32
18
 
33
19
 
34
20
  @router.get("/", operation_id="ping")
@@ -48,12 +34,3 @@ async def time(type: Literal["iso", "unix"] = "iso") -> str:
48
34
  return datetime.now().isoformat()
49
35
  elif type == "unix":
50
36
  return str(int(datetime.now().timestamp()))
51
-
52
-
53
- @router.get("/metrics", operation_id="getMetrics", include_in_schema=router.enable_metrics)
54
- def metrics(username: Annotated[str, Depends(router.auth_handler.basic_auth)]):
55
- """
56
- Get Prometheus metrics for the application. Returns plain text.
57
- """
58
- return Response(generate_latest(registry), media_type=CONTENT_TYPE_LATEST)
59
-
@@ -1,14 +1,14 @@
1
1
  """General utility functions and helper methods used across the codebase."""
2
2
 
3
- from datetime import datetime
4
- from typing import Any, Union
5
- from decimal import Decimal
6
- import string
7
3
  import random
8
- import typing_extensions
4
+ import string
9
5
  import warnings
6
+ from datetime import datetime
7
+ from decimal import Decimal
8
+ from typing import Any, Union
10
9
 
11
- from crypticorn.common.exceptions import ApiError, HTTPException, ExceptionContent
10
+ import typing_extensions
11
+ from crypticorn.common.exceptions import ApiError, ExceptionContent, HTTPException
12
12
  from crypticorn.common.warnings import CrypticornDeprecatedSince25
13
13
 
14
14
 
@@ -1,6 +1,7 @@
1
1
  """Crypticorn-specific warnings."""
2
2
 
3
3
  from __future__ import annotations
4
+
4
5
  from typing import Union
5
6
 
6
7
 
@@ -16,6 +16,9 @@ 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, StrictFloat, StrictInt, StrictStr, field_validator
20
+ from typing import Any, Dict, List, Optional, Union
21
+ from typing_extensions import Annotated
19
22
  from crypticorn.dex.client.models.log_level import LogLevel
20
23
 
21
24
  from crypticorn.dex.client.api_client import ApiClient, RequestSerialized
@@ -11,10 +11,14 @@ Generated by OpenAPI Generator (https://openapi-generator.tech)
11
11
  Do not edit the class manually.
12
12
  """ # noqa: E501
13
13
 
14
+ import warnings
14
15
  from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
15
16
  from typing import Any, Dict, List, Optional, Tuple, Union
16
17
  from typing_extensions import Annotated
17
18
 
19
+ from pydantic import Field, StrictInt, StrictStr, field_validator
20
+ from typing import Optional
21
+ from typing_extensions import Annotated
18
22
  from crypticorn.dex.client.models.paginated_response_signal_with_token import (
19
23
  PaginatedResponseSignalWithToken,
20
24
  )
@@ -176,7 +180,7 @@ class SignalsApi:
176
180
  ) -> SignalOverviewStats:
177
181
  """Get Stats
178
182
 
179
- Get comprehensive statistics for all signals.
183
+ Retrieve comprehensive statistics and analytics for all trading signals. Returns hourly-updated aggregated metrics including performance summaries and trading volumes.
180
184
 
181
185
  :param _request_timeout: timeout setting for this request. If one
182
186
  number provided, it will be total request
@@ -236,7 +240,7 @@ class SignalsApi:
236
240
  ) -> ApiResponse[SignalOverviewStats]:
237
241
  """Get Stats
238
242
 
239
- Get comprehensive statistics for all signals.
243
+ Retrieve comprehensive statistics and analytics for all trading signals. Returns hourly-updated aggregated metrics including performance summaries and trading volumes.
240
244
 
241
245
  :param _request_timeout: timeout setting for this request. If one
242
246
  number provided, it will be total request
@@ -295,7 +299,7 @@ class SignalsApi:
295
299
  ) -> RESTResponseType:
296
300
  """Get Stats
297
301
 
298
- Get comprehensive statistics for all signals.
302
+ Retrieve comprehensive statistics and analytics for all trading signals. Returns hourly-updated aggregated metrics including performance summaries and trading volumes.
299
303
 
300
304
  :param _request_timeout: timeout setting for this request. If one
301
305
  number provided, it will be total request
@@ -465,7 +469,7 @@ class SignalsApi:
465
469
  Optional[StrictStr], Field(description="The field to filter by")
466
470
  ] = None,
467
471
  filter_value: Annotated[
468
- Optional[Any], Field(description="The value to filter with")
472
+ Optional[StrictStr], Field(description="The value to filter with")
469
473
  ] = None,
470
474
  sort_order: Annotated[
471
475
  Optional[StrictStr], Field(description="The order to sort by")
@@ -532,7 +536,7 @@ class SignalsApi:
532
536
  Optional[StrictStr], Field(description="The field to filter by")
533
537
  ] = None,
534
538
  filter_value: Annotated[
535
- Optional[Any], Field(description="The value to filter with")
539
+ Optional[StrictStr], Field(description="The value to filter with")
536
540
  ] = None,
537
541
  sort_order: Annotated[
538
542
  Optional[StrictStr], Field(description="The order to sort by")
@@ -599,7 +603,7 @@ class SignalsApi:
599
603
  Optional[StrictStr], Field(description="The field to filter by")
600
604
  ] = None,
601
605
  filter_value: Annotated[
602
- Optional[Any], Field(description="The value to filter with")
606
+ Optional[StrictStr], Field(description="The value to filter with")
603
607
  ] = None,
604
608
  sort_order: Annotated[
605
609
  Optional[StrictStr], Field(description="The order to sort by")
@@ -667,7 +671,7 @@ class SignalsApi:
667
671
  Optional[StrictStr], Field(description="The field to filter by")
668
672
  ] = None,
669
673
  filter_value: Annotated[
670
- Optional[Any], Field(description="The value to filter with")
674
+ Optional[StrictStr], Field(description="The value to filter with")
671
675
  ] = None,
672
676
  sort_order: Annotated[
673
677
  Optional[StrictStr], Field(description="The order to sort by")
@@ -698,12 +702,12 @@ class SignalsApi:
698
702
  ) -> PaginatedResponseSignalWithToken:
699
703
  """Get Signals
700
704
 
701
- Get all signals. Returns the latest 10 signals by default. The default sort is `called_at` and the default order is `desc`.
705
+ Retrieve all trading signals with pagination, filtering, and sorting support. Returns signals enriched with token metadata. Default sort is by call time (newest first).
702
706
 
703
707
  :param filter_by: The field to filter by
704
708
  :type filter_by: str
705
709
  :param filter_value: The value to filter with
706
- :type filter_value: AnyOf
710
+ :type filter_value: str
707
711
  :param sort_order: The order to sort by
708
712
  :type sort_order: str
709
713
  :param sort_by: The field to sort by
@@ -766,7 +770,7 @@ class SignalsApi:
766
770
  Optional[StrictStr], Field(description="The field to filter by")
767
771
  ] = None,
768
772
  filter_value: Annotated[
769
- Optional[Any], Field(description="The value to filter with")
773
+ Optional[StrictStr], Field(description="The value to filter with")
770
774
  ] = None,
771
775
  sort_order: Annotated[
772
776
  Optional[StrictStr], Field(description="The order to sort by")
@@ -797,12 +801,12 @@ class SignalsApi:
797
801
  ) -> ApiResponse[PaginatedResponseSignalWithToken]:
798
802
  """Get Signals
799
803
 
800
- Get all signals. Returns the latest 10 signals by default. The default sort is `called_at` and the default order is `desc`.
804
+ Retrieve all trading signals with pagination, filtering, and sorting support. Returns signals enriched with token metadata. Default sort is by call time (newest first).
801
805
 
802
806
  :param filter_by: The field to filter by
803
807
  :type filter_by: str
804
808
  :param filter_value: The value to filter with
805
- :type filter_value: AnyOf
809
+ :type filter_value: str
806
810
  :param sort_order: The order to sort by
807
811
  :type sort_order: str
808
812
  :param sort_by: The field to sort by
@@ -864,7 +868,7 @@ class SignalsApi:
864
868
  Optional[StrictStr], Field(description="The field to filter by")
865
869
  ] = None,
866
870
  filter_value: Annotated[
867
- Optional[Any], Field(description="The value to filter with")
871
+ Optional[StrictStr], Field(description="The value to filter with")
868
872
  ] = None,
869
873
  sort_order: Annotated[
870
874
  Optional[StrictStr], Field(description="The order to sort by")
@@ -895,12 +899,12 @@ class SignalsApi:
895
899
  ) -> RESTResponseType:
896
900
  """Get Signals
897
901
 
898
- Get all signals. Returns the latest 10 signals by default. The default sort is `called_at` and the default order is `desc`.
902
+ Retrieve all trading signals with pagination, filtering, and sorting support. Returns signals enriched with token metadata. Default sort is by call time (newest first).
899
903
 
900
904
  :param filter_by: The field to filter by
901
905
  :type filter_by: str
902
906
  :param filter_value: The value to filter with
903
- :type filter_value: AnyOf
907
+ :type filter_value: str
904
908
  :param sort_order: The order to sort by
905
909
  :type sort_order: str
906
910
  :param sort_by: The field to sort by
@@ -960,7 +964,7 @@ class SignalsApi:
960
964
  Optional[StrictStr], Field(description="The field to filter by")
961
965
  ] = None,
962
966
  filter_value: Annotated[
963
- Optional[Any], Field(description="The value to filter with")
967
+ Optional[StrictStr], Field(description="The value to filter with")
964
968
  ] = None,
965
969
  sort_order: Annotated[
966
970
  Optional[StrictStr], Field(description="The order to sort by")
@@ -1011,7 +1015,7 @@ class SignalsApi:
1011
1015
  Optional[StrictStr], Field(description="The field to filter by")
1012
1016
  ] = None,
1013
1017
  filter_value: Annotated[
1014
- Optional[Any], Field(description="The value to filter with")
1018
+ Optional[StrictStr], Field(description="The value to filter with")
1015
1019
  ] = None,
1016
1020
  sort_order: Annotated[
1017
1021
  Optional[StrictStr], Field(description="The order to sort by")
@@ -1062,7 +1066,7 @@ class SignalsApi:
1062
1066
  Optional[StrictStr], Field(description="The field to filter by")
1063
1067
  ] = None,
1064
1068
  filter_value: Annotated[
1065
- Optional[Any], Field(description="The value to filter with")
1069
+ Optional[StrictStr], Field(description="The value to filter with")
1066
1070
  ] = None,
1067
1071
  sort_order: Annotated[
1068
1072
  Optional[StrictStr], Field(description="The order to sort by")
@@ -1170,7 +1174,7 @@ class SignalsApi:
1170
1174
  )
1171
1175
 
1172
1176
  # authentication setting
1173
- _auth_settings: List[str] = ["APIKeyHeader", "HTTPBearer"]
1177
+ _auth_settings: List[str] = []
1174
1178
 
1175
1179
  return self.api_client.param_serialize(
1176
1180
  method="GET",
@@ -1385,7 +1389,7 @@ class SignalsApi:
1385
1389
  ) -> PaginatedResponseSignalWithToken:
1386
1390
  """Get Top Signals
1387
1391
 
1388
- Get the top performing signals from the last X hours.The default is from the last 24 hours.
1392
+ Retrieve top-performing signals ranked by performance within a specified time window. Returns the highest-performing signals from the last X hours (default: 24 hours).
1389
1393
 
1390
1394
  :param page: The current page number
1391
1395
  :type page: int
@@ -1469,7 +1473,7 @@ class SignalsApi:
1469
1473
  ) -> ApiResponse[PaginatedResponseSignalWithToken]:
1470
1474
  """Get Top Signals
1471
1475
 
1472
- Get the top performing signals from the last X hours.The default is from the last 24 hours.
1476
+ Retrieve top-performing signals ranked by performance within a specified time window. Returns the highest-performing signals from the last X hours (default: 24 hours).
1473
1477
 
1474
1478
  :param page: The current page number
1475
1479
  :type page: int
@@ -1552,7 +1556,7 @@ class SignalsApi:
1552
1556
  ) -> RESTResponseType:
1553
1557
  """Get Top Signals
1554
1558
 
1555
- Get the top performing signals from the last X hours.The default is from the last 24 hours.
1559
+ Retrieve top-performing signals ranked by performance within a specified time window. Returns the highest-performing signals from the last X hours (default: 24 hours).
1556
1560
 
1557
1561
  :param page: The current page number
1558
1562
  :type page: int
@@ -1776,7 +1780,7 @@ class SignalsApi:
1776
1780
  )
1777
1781
 
1778
1782
  # authentication setting
1779
- _auth_settings: List[str] = ["APIKeyHeader", "HTTPBearer"]
1783
+ _auth_settings: List[str] = []
1780
1784
 
1781
1785
  return self.api_client.param_serialize(
1782
1786
  method="GET",