crypticorn 2.11.0__py3-none-any.whl → 2.11.5__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 (36) hide show
  1. crypticorn/auth/client/configuration.py +2 -2
  2. crypticorn/auth/client/models/create_api_key_request.py +2 -1
  3. crypticorn/auth/client/models/get_api_keys200_response_inner.py +2 -1
  4. crypticorn/cli/templates/merge-env.sh +3 -5
  5. crypticorn/client.py +2 -2
  6. crypticorn/common/ansi_colors.py +1 -0
  7. crypticorn/common/auth.py +2 -3
  8. crypticorn/common/errors.py +1 -0
  9. crypticorn/common/exceptions.py +1 -0
  10. crypticorn/common/scopes.py +10 -0
  11. crypticorn/common/warnings.py +1 -0
  12. crypticorn/klines/client/api/admin_api.py +14 -14
  13. crypticorn/klines/client/api/status_api.py +6 -6
  14. crypticorn/klines/client/configuration.py +4 -2
  15. crypticorn/klines/client/models/api_error_identifier.py +1 -1
  16. crypticorn/klines/client/models/api_error_level.py +1 -1
  17. crypticorn/klines/client/models/api_error_type.py +1 -1
  18. crypticorn/klines/client/models/exception_detail.py +1 -1
  19. crypticorn/klines/client/models/ohlcv.py +31 -6
  20. crypticorn/klines/main.py +13 -1
  21. crypticorn/metrics/client/__init__.py +4 -0
  22. crypticorn/metrics/client/api/exchanges_api.py +7 -6
  23. crypticorn/metrics/client/api/indicators_api.py +12 -6
  24. crypticorn/metrics/client/api/marketcap_api.py +49 -31
  25. crypticorn/metrics/client/configuration.py +2 -2
  26. crypticorn/metrics/client/models/__init__.py +4 -0
  27. crypticorn/metrics/client/models/exchange_availability.py +88 -0
  28. crypticorn/metrics/client/models/marketcap_ranking.py +9 -6
  29. crypticorn/metrics/client/models/marketcap_symbol_ranking.py +86 -0
  30. crypticorn/metrics/main.py +12 -19
  31. {crypticorn-2.11.0.dist-info → crypticorn-2.11.5.dist-info}/METADATA +9 -19
  32. {crypticorn-2.11.0.dist-info → crypticorn-2.11.5.dist-info}/RECORD +36 -34
  33. {crypticorn-2.11.0.dist-info → crypticorn-2.11.5.dist-info}/WHEEL +1 -1
  34. {crypticorn-2.11.0.dist-info → crypticorn-2.11.5.dist-info}/entry_points.txt +0 -0
  35. {crypticorn-2.11.0.dist-info → crypticorn-2.11.5.dist-info}/licenses/LICENSE +0 -0
  36. {crypticorn-2.11.0.dist-info → crypticorn-2.11.5.dist-info}/top_level.txt +0 -0
@@ -21,6 +21,9 @@ from typing import Any, Dict, List, Optional
21
21
  from typing_extensions import Annotated
22
22
  from crypticorn.metrics.client.models.market_type import MarketType
23
23
  from crypticorn.metrics.client.models.marketcap_ranking import MarketcapRanking
24
+ from crypticorn.metrics.client.models.marketcap_symbol_ranking import (
25
+ MarketcapSymbolRanking,
26
+ )
24
27
  from crypticorn.metrics.client.models.ohlcv import OHLCV
25
28
 
26
29
  from crypticorn.metrics.client.api_client import ApiClient, RequestSerialized
@@ -313,7 +316,7 @@ class MarketcapApi:
313
316
  _content_type: Optional[StrictStr] = None,
314
317
  _headers: Optional[Dict[StrictStr, Any]] = None,
315
318
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
316
- ) -> List[Dict[str, object]]:
319
+ ) -> List[MarketcapRanking]:
317
320
  """Get Marketcap Between Timestamps
318
321
 
319
322
  Retrieve marketcap data between timestamps.
@@ -354,7 +357,7 @@ class MarketcapApi:
354
357
  )
355
358
 
356
359
  _response_types_map: Dict[str, Optional[str]] = {
357
- "200": "List[Dict[str, object]]",
360
+ "200": "List[MarketcapRanking]",
358
361
  }
359
362
  response_data = await self.api_client.call_api(
360
363
  *_param, _request_timeout=_request_timeout
@@ -385,7 +388,7 @@ class MarketcapApi:
385
388
  _content_type: Optional[StrictStr] = None,
386
389
  _headers: Optional[Dict[StrictStr, Any]] = None,
387
390
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
388
- ) -> ApiResponse[List[Dict[str, object]]]:
391
+ ) -> ApiResponse[List[MarketcapRanking]]:
389
392
  """Get Marketcap Between Timestamps
390
393
 
391
394
  Retrieve marketcap data between timestamps.
@@ -426,7 +429,7 @@ class MarketcapApi:
426
429
  )
427
430
 
428
431
  _response_types_map: Dict[str, Optional[str]] = {
429
- "200": "List[Dict[str, object]]",
432
+ "200": "List[MarketcapRanking]",
430
433
  }
431
434
  response_data = await self.api_client.call_api(
432
435
  *_param, _request_timeout=_request_timeout
@@ -498,7 +501,7 @@ class MarketcapApi:
498
501
  )
499
502
 
500
503
  _response_types_map: Dict[str, Optional[str]] = {
501
- "200": "List[Dict[str, object]]",
504
+ "200": "List[MarketcapRanking]",
502
505
  }
503
506
  response_data = await self.api_client.call_api(
504
507
  *_param, _request_timeout=_request_timeout
@@ -581,11 +584,15 @@ class MarketcapApi:
581
584
  ] = None,
582
585
  market: Annotated[
583
586
  Optional[MarketType],
584
- Field(description="Market for which to fetch symbols and marketcap data"),
587
+ Field(
588
+ description="Market for which to fetch symbols and marketcap data. Defaults to futures."
589
+ ),
585
590
  ] = None,
586
591
  exchange: Annotated[
587
592
  Optional[StrictStr],
588
- Field(description="Exchange for which to fetch symbols and marketcap data"),
593
+ Field(
594
+ description="Exchange for which to fetch symbols and marketcap data. If not provided, all exchanges will be returned."
595
+ ),
589
596
  ] = None,
590
597
  _request_timeout: Union[
591
598
  None,
@@ -598,10 +605,10 @@ class MarketcapApi:
598
605
  _content_type: Optional[StrictStr] = None,
599
606
  _headers: Optional[Dict[StrictStr, Any]] = None,
600
607
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
601
- ) -> List[MarketcapRanking]:
608
+ ) -> List[MarketcapSymbolRanking]:
602
609
  """Get Symbols Marketcap Between Timestamps
603
610
 
604
- Retrieve marketcap data for symbols between timestamps with optional filtering.
611
+ Retrieve a ranking of symbols by marketcap between timestamps.
605
612
 
606
613
  :param start_timestamp: Start timestamp
607
614
  :type start_timestamp: int
@@ -609,9 +616,9 @@ class MarketcapApi:
609
616
  :type end_timestamp: int
610
617
  :param interval: Interval for which to fetch symbols and marketcap data
611
618
  :type interval: str
612
- :param market: Market for which to fetch symbols and marketcap data
619
+ :param market: Market for which to fetch symbols and marketcap data. Defaults to futures.
613
620
  :type market: MarketType
614
- :param exchange: Exchange for which to fetch symbols and marketcap data
621
+ :param exchange: Exchange for which to fetch symbols and marketcap data. If not provided, all exchanges will be returned.
615
622
  :type exchange: str
616
623
  :param _request_timeout: timeout setting for this request. If one
617
624
  number provided, it will be total request
@@ -648,7 +655,7 @@ class MarketcapApi:
648
655
  )
649
656
 
650
657
  _response_types_map: Dict[str, Optional[str]] = {
651
- "200": "List[MarketcapRanking]",
658
+ "200": "List[MarketcapSymbolRanking]",
652
659
  }
653
660
  response_data = await self.api_client.call_api(
654
661
  *_param, _request_timeout=_request_timeout
@@ -674,11 +681,15 @@ class MarketcapApi:
674
681
  ] = None,
675
682
  market: Annotated[
676
683
  Optional[MarketType],
677
- Field(description="Market for which to fetch symbols and marketcap data"),
684
+ Field(
685
+ description="Market for which to fetch symbols and marketcap data. Defaults to futures."
686
+ ),
678
687
  ] = None,
679
688
  exchange: Annotated[
680
689
  Optional[StrictStr],
681
- Field(description="Exchange for which to fetch symbols and marketcap data"),
690
+ Field(
691
+ description="Exchange for which to fetch symbols and marketcap data. If not provided, all exchanges will be returned."
692
+ ),
682
693
  ] = None,
683
694
  _request_timeout: Union[
684
695
  None,
@@ -691,10 +702,10 @@ class MarketcapApi:
691
702
  _content_type: Optional[StrictStr] = None,
692
703
  _headers: Optional[Dict[StrictStr, Any]] = None,
693
704
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
694
- ) -> ApiResponse[List[MarketcapRanking]]:
705
+ ) -> ApiResponse[List[MarketcapSymbolRanking]]:
695
706
  """Get Symbols Marketcap Between Timestamps
696
707
 
697
- Retrieve marketcap data for symbols between timestamps with optional filtering.
708
+ Retrieve a ranking of symbols by marketcap between timestamps.
698
709
 
699
710
  :param start_timestamp: Start timestamp
700
711
  :type start_timestamp: int
@@ -702,9 +713,9 @@ class MarketcapApi:
702
713
  :type end_timestamp: int
703
714
  :param interval: Interval for which to fetch symbols and marketcap data
704
715
  :type interval: str
705
- :param market: Market for which to fetch symbols and marketcap data
716
+ :param market: Market for which to fetch symbols and marketcap data. Defaults to futures.
706
717
  :type market: MarketType
707
- :param exchange: Exchange for which to fetch symbols and marketcap data
718
+ :param exchange: Exchange for which to fetch symbols and marketcap data. If not provided, all exchanges will be returned.
708
719
  :type exchange: str
709
720
  :param _request_timeout: timeout setting for this request. If one
710
721
  number provided, it will be total request
@@ -741,7 +752,7 @@ class MarketcapApi:
741
752
  )
742
753
 
743
754
  _response_types_map: Dict[str, Optional[str]] = {
744
- "200": "List[MarketcapRanking]",
755
+ "200": "List[MarketcapSymbolRanking]",
745
756
  }
746
757
  response_data = await self.api_client.call_api(
747
758
  *_param, _request_timeout=_request_timeout
@@ -767,11 +778,15 @@ class MarketcapApi:
767
778
  ] = None,
768
779
  market: Annotated[
769
780
  Optional[MarketType],
770
- Field(description="Market for which to fetch symbols and marketcap data"),
781
+ Field(
782
+ description="Market for which to fetch symbols and marketcap data. Defaults to futures."
783
+ ),
771
784
  ] = None,
772
785
  exchange: Annotated[
773
786
  Optional[StrictStr],
774
- Field(description="Exchange for which to fetch symbols and marketcap data"),
787
+ Field(
788
+ description="Exchange for which to fetch symbols and marketcap data. If not provided, all exchanges will be returned."
789
+ ),
775
790
  ] = None,
776
791
  _request_timeout: Union[
777
792
  None,
@@ -787,7 +802,7 @@ class MarketcapApi:
787
802
  ) -> RESTResponseType:
788
803
  """Get Symbols Marketcap Between Timestamps
789
804
 
790
- Retrieve marketcap data for symbols between timestamps with optional filtering.
805
+ Retrieve a ranking of symbols by marketcap between timestamps.
791
806
 
792
807
  :param start_timestamp: Start timestamp
793
808
  :type start_timestamp: int
@@ -795,9 +810,9 @@ class MarketcapApi:
795
810
  :type end_timestamp: int
796
811
  :param interval: Interval for which to fetch symbols and marketcap data
797
812
  :type interval: str
798
- :param market: Market for which to fetch symbols and marketcap data
813
+ :param market: Market for which to fetch symbols and marketcap data. Defaults to futures.
799
814
  :type market: MarketType
800
- :param exchange: Exchange for which to fetch symbols and marketcap data
815
+ :param exchange: Exchange for which to fetch symbols and marketcap data. If not provided, all exchanges will be returned.
801
816
  :type exchange: str
802
817
  :param _request_timeout: timeout setting for this request. If one
803
818
  number provided, it will be total request
@@ -834,7 +849,7 @@ class MarketcapApi:
834
849
  )
835
850
 
836
851
  _response_types_map: Dict[str, Optional[str]] = {
837
- "200": "List[MarketcapRanking]",
852
+ "200": "List[MarketcapSymbolRanking]",
838
853
  }
839
854
  response_data = await self.api_client.call_api(
840
855
  *_param, _request_timeout=_request_timeout
@@ -928,7 +943,8 @@ class MarketcapApi:
928
943
  Optional[StrictStr], Field(description="Timeframe for OHLCV data")
929
944
  ] = None,
930
945
  market: Annotated[
931
- Optional[MarketType], Field(description="Market for OHLCV data")
946
+ Optional[MarketType],
947
+ Field(description="Market for OHLCV data. Defaults to futures."),
932
948
  ] = None,
933
949
  top_n: Annotated[
934
950
  Optional[StrictInt], Field(description="Number of symbols to fetch")
@@ -957,7 +973,7 @@ class MarketcapApi:
957
973
  :type timestamp: int
958
974
  :param timeframe: Timeframe for OHLCV data
959
975
  :type timeframe: str
960
- :param market: Market for OHLCV data
976
+ :param market: Market for OHLCV data. Defaults to futures.
961
977
  :type market: MarketType
962
978
  :param top_n: Number of symbols to fetch
963
979
  :type top_n: int
@@ -1020,7 +1036,8 @@ class MarketcapApi:
1020
1036
  Optional[StrictStr], Field(description="Timeframe for OHLCV data")
1021
1037
  ] = None,
1022
1038
  market: Annotated[
1023
- Optional[MarketType], Field(description="Market for OHLCV data")
1039
+ Optional[MarketType],
1040
+ Field(description="Market for OHLCV data. Defaults to futures."),
1024
1041
  ] = None,
1025
1042
  top_n: Annotated[
1026
1043
  Optional[StrictInt], Field(description="Number of symbols to fetch")
@@ -1049,7 +1066,7 @@ class MarketcapApi:
1049
1066
  :type timestamp: int
1050
1067
  :param timeframe: Timeframe for OHLCV data
1051
1068
  :type timeframe: str
1052
- :param market: Market for OHLCV data
1069
+ :param market: Market for OHLCV data. Defaults to futures.
1053
1070
  :type market: MarketType
1054
1071
  :param top_n: Number of symbols to fetch
1055
1072
  :type top_n: int
@@ -1112,7 +1129,8 @@ class MarketcapApi:
1112
1129
  Optional[StrictStr], Field(description="Timeframe for OHLCV data")
1113
1130
  ] = None,
1114
1131
  market: Annotated[
1115
- Optional[MarketType], Field(description="Market for OHLCV data")
1132
+ Optional[MarketType],
1133
+ Field(description="Market for OHLCV data. Defaults to futures."),
1116
1134
  ] = None,
1117
1135
  top_n: Annotated[
1118
1136
  Optional[StrictInt], Field(description="Number of symbols to fetch")
@@ -1141,7 +1159,7 @@ class MarketcapApi:
1141
1159
  :type timestamp: int
1142
1160
  :param timeframe: Timeframe for OHLCV data
1143
1161
  :type timeframe: str
1144
- :param market: Market for OHLCV data
1162
+ :param market: Market for OHLCV data. Defaults to futures.
1145
1163
  :type market: MarketType
1146
1164
  :param top_n: Number of symbols to fetch
1147
1165
  :type top_n: int
@@ -215,7 +215,7 @@ class Configuration:
215
215
  debug: Optional[bool] = None,
216
216
  ) -> None:
217
217
  """Constructor"""
218
- self._base_path = "http://127.0.0.1:8000/v1/metrics" if host is None else host
218
+ self._base_path = "http://localhost/v1/metrics" if host is None else host
219
219
  """Default Base url
220
220
  """
221
221
  self.server_index = 0 if server_index is None and host is None else server_index
@@ -557,7 +557,7 @@ class Configuration:
557
557
  """
558
558
  return [
559
559
  {
560
- "url": "http://127.0.0.1:8000/v1/metrics",
560
+ "url": "http://localhost/v1/metrics",
561
561
  "description": "No description provided",
562
562
  }
563
563
  ]
@@ -18,11 +18,15 @@ from crypticorn.metrics.client.models.api_error_identifier import ApiErrorIdenti
18
18
  from crypticorn.metrics.client.models.api_error_level import ApiErrorLevel
19
19
  from crypticorn.metrics.client.models.api_error_type import ApiErrorType
20
20
  from crypticorn.metrics.client.models.exception_detail import ExceptionDetail
21
+ from crypticorn.metrics.client.models.exchange_availability import ExchangeAvailability
21
22
  from crypticorn.metrics.client.models.exchange_mapping import ExchangeMapping
22
23
  from crypticorn.metrics.client.models.internal_exchange import InternalExchange
23
24
  from crypticorn.metrics.client.models.log_level import LogLevel
24
25
  from crypticorn.metrics.client.models.market_type import MarketType
25
26
  from crypticorn.metrics.client.models.marketcap_ranking import MarketcapRanking
27
+ from crypticorn.metrics.client.models.marketcap_symbol_ranking import (
28
+ MarketcapSymbolRanking,
29
+ )
26
30
  from crypticorn.metrics.client.models.ohlcv import OHLCV
27
31
  from crypticorn.metrics.client.models.severity import Severity
28
32
  from crypticorn.metrics.client.models.time_interval import TimeInterval
@@ -0,0 +1,88 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ Marketcap Service API
5
+
6
+ API for retrieving historical marketcap data, available exchanges, and indicators.
7
+
8
+ The version of the OpenAPI document: 1.0.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+ from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt
21
+ from typing import Any, ClassVar, Dict, List
22
+ from typing import Optional, Set
23
+ from typing_extensions import Self
24
+
25
+
26
+ class ExchangeAvailability(BaseModel):
27
+ """
28
+ ExchangeAvailability
29
+ """ # noqa: E501
30
+
31
+ timestamp: StrictInt = Field(description="The timestamp of the availability")
32
+ exchanges: Dict[str, StrictBool] = Field(
33
+ description="The availability of the exchange. Returns a dictionary of exchange names and their availability as a boolean."
34
+ )
35
+ __properties: ClassVar[List[str]] = ["timestamp", "exchanges"]
36
+
37
+ model_config = ConfigDict(
38
+ populate_by_name=True,
39
+ validate_assignment=True,
40
+ protected_namespaces=(),
41
+ )
42
+
43
+ def to_str(self) -> str:
44
+ """Returns the string representation of the model using alias"""
45
+ return pprint.pformat(self.model_dump(by_alias=True))
46
+
47
+ def to_json(self) -> str:
48
+ """Returns the JSON representation of the model using alias"""
49
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
50
+ return json.dumps(self.to_dict())
51
+
52
+ @classmethod
53
+ def from_json(cls, json_str: str) -> Optional[Self]:
54
+ """Create an instance of ExchangeAvailability from a JSON string"""
55
+ return cls.from_dict(json.loads(json_str))
56
+
57
+ def to_dict(self) -> Dict[str, Any]:
58
+ """Return the dictionary representation of the model using alias.
59
+
60
+ This has the following differences from calling pydantic's
61
+ `self.model_dump(by_alias=True)`:
62
+
63
+ * `None` is only added to the output dict for nullable fields that
64
+ were set at model initialization. Other fields with value `None`
65
+ are ignored.
66
+ """
67
+ excluded_fields: Set[str] = set([])
68
+
69
+ _dict = self.model_dump(
70
+ by_alias=True,
71
+ exclude=excluded_fields,
72
+ exclude_none=True,
73
+ )
74
+ return _dict
75
+
76
+ @classmethod
77
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
78
+ """Create an instance of ExchangeAvailability from a dict"""
79
+ if obj is None:
80
+ return None
81
+
82
+ if not isinstance(obj, dict):
83
+ return cls.model_validate(obj)
84
+
85
+ _obj = cls.model_validate(
86
+ {"timestamp": obj.get("timestamp"), "exchanges": obj.get("exchanges")}
87
+ )
88
+ return _obj
@@ -17,20 +17,20 @@ import pprint
17
17
  import re # noqa: F401
18
18
  import json
19
19
 
20
- from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr
21
- from typing import Any, ClassVar, Dict, List, Optional
20
+ from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt
21
+ from typing import Any, ClassVar, Dict, List, Optional, Union
22
22
  from typing import Optional, Set
23
23
  from typing_extensions import Self
24
24
 
25
25
 
26
26
  class MarketcapRanking(BaseModel):
27
27
  """
28
- MarketcapRanking
28
+ A ranking of symbols by marketcap at a given timestamp.
29
29
  """ # noqa: E501
30
30
 
31
31
  timestamp: StrictInt
32
- symbols: List[Optional[StrictStr]]
33
- __properties: ClassVar[List[str]] = ["timestamp", "symbols"]
32
+ marketcap_values: List[Optional[Union[StrictFloat, StrictInt]]]
33
+ __properties: ClassVar[List[str]] = ["timestamp", "marketcap_values"]
34
34
 
35
35
  model_config = ConfigDict(
36
36
  populate_by_name=True,
@@ -81,6 +81,9 @@ class MarketcapRanking(BaseModel):
81
81
  return cls.model_validate(obj)
82
82
 
83
83
  _obj = cls.model_validate(
84
- {"timestamp": obj.get("timestamp"), "symbols": obj.get("symbols")}
84
+ {
85
+ "timestamp": obj.get("timestamp"),
86
+ "marketcap_values": obj.get("marketcap_values"),
87
+ }
85
88
  )
86
89
  return _obj
@@ -0,0 +1,86 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ Marketcap Service API
5
+
6
+ API for retrieving historical marketcap data, available exchanges, and indicators.
7
+
8
+ The version of the OpenAPI document: 1.0.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+ from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr
21
+ from typing import Any, ClassVar, Dict, List, Optional
22
+ from typing import Optional, Set
23
+ from typing_extensions import Self
24
+
25
+
26
+ class MarketcapSymbolRanking(BaseModel):
27
+ """
28
+ A ranking of marketcap values at a given timestamp.
29
+ """ # noqa: E501
30
+
31
+ timestamp: StrictInt
32
+ symbols: List[Optional[StrictStr]]
33
+ __properties: ClassVar[List[str]] = ["timestamp", "symbols"]
34
+
35
+ model_config = ConfigDict(
36
+ populate_by_name=True,
37
+ validate_assignment=True,
38
+ protected_namespaces=(),
39
+ )
40
+
41
+ def to_str(self) -> str:
42
+ """Returns the string representation of the model using alias"""
43
+ return pprint.pformat(self.model_dump(by_alias=True))
44
+
45
+ def to_json(self) -> str:
46
+ """Returns the JSON representation of the model using alias"""
47
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
48
+ return json.dumps(self.to_dict())
49
+
50
+ @classmethod
51
+ def from_json(cls, json_str: str) -> Optional[Self]:
52
+ """Create an instance of MarketcapSymbolRanking from a JSON string"""
53
+ return cls.from_dict(json.loads(json_str))
54
+
55
+ def to_dict(self) -> Dict[str, Any]:
56
+ """Return the dictionary representation of the model using alias.
57
+
58
+ This has the following differences from calling pydantic's
59
+ `self.model_dump(by_alias=True)`:
60
+
61
+ * `None` is only added to the output dict for nullable fields that
62
+ were set at model initialization. Other fields with value `None`
63
+ are ignored.
64
+ """
65
+ excluded_fields: Set[str] = set([])
66
+
67
+ _dict = self.model_dump(
68
+ by_alias=True,
69
+ exclude=excluded_fields,
70
+ exclude_none=True,
71
+ )
72
+ return _dict
73
+
74
+ @classmethod
75
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
76
+ """Create an instance of MarketcapSymbolRanking from a dict"""
77
+ if obj is None:
78
+ return None
79
+
80
+ if not isinstance(obj, dict):
81
+ return cls.model_validate(obj)
82
+
83
+ _obj = cls.model_validate(
84
+ {"timestamp": obj.get("timestamp"), "symbols": obj.get("symbols")}
85
+ )
86
+ return _obj
@@ -54,7 +54,7 @@ class MarketcapApiWrapper(MarketcapApi):
54
54
  rows = []
55
55
  for item in response:
56
56
  row = {"timestamp": item.timestamp}
57
- row.update({i+1: sym for i, sym in enumerate(item.symbols)})
57
+ row.update({i + 1: sym for i, sym in enumerate(item.symbols)})
58
58
  rows.append(row)
59
59
  df = pd.DataFrame(rows)
60
60
  return df
@@ -93,22 +93,15 @@ class ExchangesApiWrapper(ExchangesApi):
93
93
  """
94
94
  pd = optional_import("pandas", "extra")
95
95
  response = await self.get_available_exchanges(*args, **kwargs)
96
- processed_results = []
97
- for row in response:
98
- data = {"timestamp": row["timestamp"]}
99
- data.update(row["exchanges"])
100
- processed_results.append(data)
101
-
102
- # Create DataFrame and sort columns
103
- df = pd.DataFrame(processed_results)
104
- cols = ["timestamp"] + sorted([col for col in df.columns if col != "timestamp"])
105
- df = df[cols]
106
-
107
- # Convert exchange availability to boolean integers (0/1)
108
- df = df.astype(
109
- {
110
- "timestamp": "int64",
111
- **{col: "int8" for col in df.columns if col != "timestamp"},
112
- }
113
- )
96
+
97
+ # Create list of dictionaries with timestamp and flattened exchange data
98
+ rows = []
99
+ for item in response:
100
+ row = {"timestamp": item.timestamp}
101
+ row.update(
102
+ item.exchanges
103
+ ) # This spreads the exchanges dict into individual columns
104
+ rows.append(row)
105
+
106
+ df = pd.DataFrame(rows)
114
107
  return df
@@ -1,23 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crypticorn
3
- Version: 2.11.0
3
+ Version: 2.11.5
4
4
  Summary: Maximise Your Crypto Trading Profits with Machine Learning
5
5
  Author-email: Crypticorn <timon@crypticorn.com>
6
- License: Copyright © 2025 Crypticorn
7
-
8
- All rights reserved. This software and accompanying documentation files (collectively referred to as "the Software") are the proprietary property of Crypticorn. Any unauthorised reproduction, modification, integration, publication, distribution, sublicensing, sale, or enabling access to the Software without explicit written permission from Crypticorn is strictly prohibited, subject to the conditions outlined herein:
9
-
10
- 1. The aforementioned copyright notice and this permission notice must be included unaltered in all copies, or significant portions, of the Software.
11
-
12
- 2. The Software is provided "AS IS", without any warranty, whether express or implied. Crypticorn expressly disclaims any guarantees, including but not limited to those of satisfactory quality, fitness for a particular purpose, or non-infringement of third-party rights.
13
-
14
- 3. In no event shall Crypticorn, its authors, or copyright holders be held liable for any claim, damages, or other liability arising from or associated with the use of the Software or any other dealings involving the Software, to the extent that such liability can be limited or excluded by applicable law.
15
-
16
- Changes to this agreement may be made without notice, and it is the user's responsibility to keep abreast of any changes. This agreement and its interpretation are subject to the laws of the Federal Republic of Germany.
17
-
18
- If any provision of this license agreement is held to be invalid or unenforceable under applicable law, the remaining provisions will continue in full force and effect. Crypticorn's failure to enforce any provision of this agreement does not constitute a waiver of its right to do so in the future.
19
-
20
- This agreement is written in English. In the event of any discrepancy between the English version and any translation, the English version shall prevail.
6
+ License-Expression: MIT
21
7
  Project-URL: Homepage, https://crypticorn.com
22
8
  Project-URL: Documentation, https://docs.crypticorn.com
23
9
  Project-URL: Dashboard, https://app.crypticorn.com
@@ -26,7 +12,6 @@ Classifier: Topic :: Scientific/Engineering
26
12
  Classifier: Development Status :: 4 - Beta
27
13
  Classifier: Intended Audience :: Developers
28
14
  Classifier: Operating System :: OS Independent
29
- Classifier: License :: OSI Approved :: MIT License
30
15
  Classifier: Programming Language :: Python :: 3.10
31
16
  Classifier: Programming Language :: Python :: 3.11
32
17
  Classifier: Programming Language :: Python :: 3.12
@@ -99,7 +84,7 @@ from crypticorn import ApiClient
99
84
  ```
100
85
  The ApiClient serves as the central interface for API operations. It instantiates multiple API wrappers corresponding to our micro services. These are structured the following:
101
86
 
102
- <img src="pip-structure.svg" alt="pip package structure" />
87
+ <img src="static/pip-structure.svg" alt="pip package structure" />
103
88
 
104
89
  You can either explore each API by clicking through the library or checkout the [API Documentation](https://docs.crypticorn.com/api).
105
90
 
@@ -116,7 +101,12 @@ from crypticorn.common import Scope, Exchange
116
101
 
117
102
  ## Authentication
118
103
 
119
- To get started, [create an API key in your dashboard](https://app.crypticorn.com/account/developer). Then instantiate the `ApiClient` class with your copied key.
104
+ To get started, [create an API key in your dashboard](https://app.crypticorn.com/account/developer).
105
+
106
+ The scopes you can assign, resemble the [package structure](#structure). The first part defines if the scopes is for reading or writing a ressource, the second matches the API, the third the ROUTER being used. `read` scopes gives access to GET, `write` to PUT, PATCH, POST, DELETE endpoints.
107
+
108
+ There are scopes which don't follow this structure. Those are either scopes that must be purchased (e.g. `read:predictions`), give access to endpoints existing in all APIs (e.g. `read:admin`) or provide access to an entire service (e.g. `read:sentiment`).
109
+
120
110
 
121
111
  ## Basic Usage
122
112