crypticorn 2.0.0__py3-none-any.whl → 2.1.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.
- crypticorn/auth/client/__init__.py +13 -0
- crypticorn/auth/client/api/auth_api.py +1023 -46
- crypticorn/auth/client/models/__init__.py +13 -0
- crypticorn/auth/client/models/create_api_key200_response.py +83 -0
- crypticorn/auth/client/models/create_api_key_request.py +141 -0
- crypticorn/auth/client/models/get_api_keys200_response_inner.py +144 -0
- crypticorn/auth/client/models/oauth_callback200_response.py +109 -0
- crypticorn/auth/client/models/oauth_callback200_response_user.py +104 -0
- crypticorn/auth/client/models/whoami200_response.py +3 -0
- crypticorn/common/auth.py +6 -6
- crypticorn/common/auth_client.py +104 -50
- crypticorn/common/scopes.py +37 -19
- {crypticorn-2.0.0.dist-info → crypticorn-2.1.0.dist-info}/METADATA +32 -14
- {crypticorn-2.0.0.dist-info → crypticorn-2.1.0.dist-info}/RECORD +16 -11
- {crypticorn-2.0.0.dist-info → crypticorn-2.1.0.dist-info}/WHEEL +0 -0
- {crypticorn-2.0.0.dist-info → crypticorn-2.1.0.dist-info}/top_level.txt +0 -0
crypticorn/common/auth_client.py
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
from fastapi import Depends, HTTPException, status
|
1
|
+
from fastapi import Depends, HTTPException, Query, status
|
2
2
|
from fastapi.security import HTTPAuthorizationCredentials
|
3
3
|
from typing_extensions import Annotated, Doc
|
4
|
+
import json
|
4
5
|
|
5
6
|
from crypticorn.auth import AuthClient, Verify200Response
|
6
|
-
from crypticorn.auth.client.exceptions import
|
7
|
+
from crypticorn.auth.client.exceptions import ApiException
|
7
8
|
from crypticorn.common import (
|
8
9
|
ApiError,
|
9
|
-
|
10
|
+
Scope,
|
10
11
|
ApiVersion,
|
11
12
|
BaseURL,
|
12
13
|
Domain,
|
@@ -41,29 +42,16 @@ class AuthHandler:
|
|
41
42
|
self.whitelist = whitelist
|
42
43
|
self.auth_client = AuthClient(base_url=base_url, api_version=api_version)
|
43
44
|
|
44
|
-
self.invalid_scopes_exception = HTTPException(
|
45
|
-
status_code=status.HTTP_403_FORBIDDEN,
|
46
|
-
detail=ApiError.INSUFFICIENT_SCOPES.identifier,
|
47
|
-
)
|
48
45
|
self.no_credentials_exception = HTTPException(
|
49
46
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
50
47
|
detail=ApiError.NO_CREDENTIALS.identifier,
|
51
48
|
)
|
52
|
-
self.invalid_api_key_exception = HTTPException(
|
53
|
-
status_code=status.HTTP_401_UNAUTHORIZED,
|
54
|
-
detail=ApiError.INVALID_API_KEY.identifier,
|
55
|
-
)
|
56
|
-
self.invalid_bearer_exception = HTTPException(
|
57
|
-
status_code=status.HTTP_401_UNAUTHORIZED,
|
58
|
-
detail=ApiError.INVALID_BEARER.identifier,
|
59
|
-
)
|
60
49
|
|
61
50
|
async def _verify_api_key(self, api_key: str) -> None:
|
62
51
|
"""
|
63
52
|
Verifies the API key.
|
64
53
|
"""
|
65
|
-
|
66
|
-
return NotImplementedError()
|
54
|
+
return await self.auth_client.login.verify_api_key(api_key)
|
67
55
|
|
68
56
|
async def _verify_bearer(
|
69
57
|
self, bearer: HTTPAuthorizationCredentials
|
@@ -74,32 +62,60 @@ class AuthHandler:
|
|
74
62
|
self.auth_client.config.access_token = bearer.credentials
|
75
63
|
return await self.auth_client.login.verify()
|
76
64
|
|
77
|
-
async def
|
78
|
-
self, api_scopes: list[
|
65
|
+
async def _validate_scopes(
|
66
|
+
self, api_scopes: list[Scope], user_scopes: list[Scope]
|
79
67
|
) -> bool:
|
80
68
|
"""
|
81
69
|
Checks if the user scopes are a subset of the API scopes.
|
82
70
|
"""
|
83
|
-
|
71
|
+
if not set(api_scopes).issubset(user_scopes):
|
72
|
+
raise HTTPException(
|
73
|
+
status_code=status.HTTP_403_FORBIDDEN,
|
74
|
+
detail=ApiError.INSUFFICIENT_SCOPES.identifier,
|
75
|
+
)
|
76
|
+
|
77
|
+
async def _extract_message(self, e: ApiException) -> str:
|
78
|
+
"""
|
79
|
+
Tries to extract the message from the body of the exception.
|
80
|
+
"""
|
81
|
+
try:
|
82
|
+
load = json.loads(e.body)
|
83
|
+
except (json.JSONDecodeError, TypeError):
|
84
|
+
return e.body
|
85
|
+
else:
|
86
|
+
common_keys = ["message"]
|
87
|
+
for key in common_keys:
|
88
|
+
if key in load:
|
89
|
+
return load[key]
|
90
|
+
return load
|
91
|
+
|
92
|
+
async def _handle_exception(self, e: Exception) -> HTTPException:
|
93
|
+
"""
|
94
|
+
Handles exceptions and returns a HTTPException with the appropriate status code and detail.
|
95
|
+
"""
|
96
|
+
if isinstance(e, ApiException):
|
97
|
+
return HTTPException(
|
98
|
+
status_code=e.status,
|
99
|
+
detail=await self._extract_message(e),
|
100
|
+
)
|
101
|
+
elif isinstance(e, HTTPException):
|
102
|
+
return e
|
103
|
+
else:
|
104
|
+
return HTTPException(
|
105
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
106
|
+
detail=str(e),
|
107
|
+
)
|
84
108
|
|
85
109
|
async def api_key_auth(
|
86
110
|
self,
|
87
111
|
api_key: Annotated[str | None, Depends(apikey_header)] = None,
|
88
|
-
scopes: list[
|
112
|
+
scopes: list[Scope] = [],
|
89
113
|
) -> Verify200Response:
|
90
114
|
"""
|
91
115
|
Verifies the API key and checks if the user scopes are a subset of the API scopes.
|
116
|
+
Use this function if you only want to allow access via the API key.
|
92
117
|
"""
|
93
|
-
|
94
|
-
raise self.no_credentials_exception
|
95
|
-
try:
|
96
|
-
res = await self._verify_api_key(api_key)
|
97
|
-
except UnauthorizedException as e:
|
98
|
-
raise self.invalid_api_key_exception
|
99
|
-
valid_scopes = await self._check_scopes(scopes, res.scopes)
|
100
|
-
if not valid_scopes:
|
101
|
-
raise self.invalid_scopes_exception
|
102
|
-
return res
|
118
|
+
return await self.combined_auth(bearer=None, api_key=api_key, scopes=scopes)
|
103
119
|
|
104
120
|
async def bearer_auth(
|
105
121
|
self,
|
@@ -107,22 +123,13 @@ class AuthHandler:
|
|
107
123
|
HTTPAuthorizationCredentials | None,
|
108
124
|
Depends(http_bearer),
|
109
125
|
] = None,
|
110
|
-
scopes: list[
|
126
|
+
scopes: list[Scope] = [],
|
111
127
|
) -> Verify200Response:
|
112
128
|
"""
|
113
129
|
Verifies the bearer token and checks if the user scopes are a subset of the API scopes.
|
130
|
+
Use this function if you only want to allow access via the bearer token.
|
114
131
|
"""
|
115
|
-
|
116
|
-
raise self.no_credentials_exception
|
117
|
-
|
118
|
-
try:
|
119
|
-
res = await self._verify_bearer(bearer)
|
120
|
-
except UnauthorizedException as e:
|
121
|
-
raise self.invalid_bearer_exception
|
122
|
-
valid_scopes = await self._check_scopes(scopes, res.scopes)
|
123
|
-
if not valid_scopes:
|
124
|
-
raise self.invalid_scopes_exception
|
125
|
-
return res
|
132
|
+
return await self.combined_auth(bearer=bearer, api_key=None, scopes=scopes)
|
126
133
|
|
127
134
|
async def combined_auth(
|
128
135
|
self,
|
@@ -130,11 +137,12 @@ class AuthHandler:
|
|
130
137
|
HTTPAuthorizationCredentials | None, Depends(http_bearer)
|
131
138
|
] = None,
|
132
139
|
api_key: Annotated[str | None, Depends(apikey_header)] = None,
|
133
|
-
scopes: list[
|
140
|
+
scopes: list[Scope] = [],
|
134
141
|
) -> Verify200Response:
|
135
142
|
"""
|
136
|
-
Verifies the bearer token and API key and checks if the user scopes are a subset of the API scopes.
|
143
|
+
Verifies the bearer token and/or API key and checks if the user scopes are a subset of the API scopes.
|
137
144
|
Returns early on the first successful verification, otherwise tries all available tokens.
|
145
|
+
Use this function if you want to allow access via either the bearer token or the API key.
|
138
146
|
"""
|
139
147
|
tokens = [bearer, api_key]
|
140
148
|
|
@@ -151,13 +159,59 @@ class AuthHandler:
|
|
151
159
|
if res is None:
|
152
160
|
continue
|
153
161
|
if scopes:
|
154
|
-
|
155
|
-
|
156
|
-
|
162
|
+
await self._validate_scopes(
|
163
|
+
scopes, [Scope.from_str(scope) for scope in res.scopes]
|
164
|
+
)
|
157
165
|
return res
|
158
166
|
|
159
|
-
except
|
160
|
-
last_error = e
|
167
|
+
except Exception as e:
|
168
|
+
last_error = await self._handle_exception(e)
|
161
169
|
continue
|
162
170
|
|
163
171
|
raise last_error or self.no_credentials_exception
|
172
|
+
|
173
|
+
async def ws_api_key_auth(
|
174
|
+
self,
|
175
|
+
api_key: Annotated[str | None, Query()] = None,
|
176
|
+
scopes: list[Scope] = [],
|
177
|
+
) -> Verify200Response:
|
178
|
+
"""
|
179
|
+
Verifies the API key and checks if the user scopes are a subset of the API scopes.
|
180
|
+
Use this function if you only want to allow access via the API key.
|
181
|
+
"""
|
182
|
+
return await self.api_key_auth(api_key=api_key, scopes=scopes)
|
183
|
+
|
184
|
+
async def ws_bearer_auth(
|
185
|
+
self,
|
186
|
+
bearer: Annotated[str | None, Query()] = None,
|
187
|
+
scopes: list[Scope] = [],
|
188
|
+
) -> Verify200Response:
|
189
|
+
"""
|
190
|
+
Verifies the bearer token and checks if the user scopes are a subset of the API scopes.
|
191
|
+
Use this function if you only want to allow access via the bearer token.
|
192
|
+
"""
|
193
|
+
credentials = (
|
194
|
+
HTTPAuthorizationCredentials(scheme="Bearer", credentials=bearer)
|
195
|
+
if bearer
|
196
|
+
else None
|
197
|
+
)
|
198
|
+
return await self.bearer_auth(bearer=credentials, scopes=scopes)
|
199
|
+
|
200
|
+
async def ws_combined_auth(
|
201
|
+
self,
|
202
|
+
bearer: Annotated[str | None, Query()] = None,
|
203
|
+
api_key: Annotated[str | None, Query()] = None,
|
204
|
+
scopes: list[Scope] = [],
|
205
|
+
) -> Verify200Response:
|
206
|
+
"""
|
207
|
+
Verifies the bearer token and/or API key and checks if the user scopes are a subset of the API scopes.
|
208
|
+
Use this function if you want to allow access via either the bearer token or the API key.
|
209
|
+
"""
|
210
|
+
credentials = (
|
211
|
+
HTTPAuthorizationCredentials(scheme="Bearer", credentials=bearer)
|
212
|
+
if bearer
|
213
|
+
else None
|
214
|
+
)
|
215
|
+
return await self.combined_auth(
|
216
|
+
bearer=credentials, api_key=api_key, scopes=scopes
|
217
|
+
)
|
crypticorn/common/scopes.py
CHANGED
@@ -1,29 +1,47 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
|
3
3
|
|
4
|
-
class
|
4
|
+
class Scope(str, Enum):
|
5
5
|
"""
|
6
6
|
The permission scopes for the API.
|
7
7
|
"""
|
8
8
|
|
9
|
+
# If you update anything here, also update the scopes in the auth-service repository
|
10
|
+
|
11
|
+
@classmethod
|
12
|
+
def from_str(cls, value: str) -> "Scope":
|
13
|
+
return cls(value)
|
14
|
+
|
9
15
|
# Hive scopes
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
16
|
+
READ_HIVE_MODEL = "read:hive:model"
|
17
|
+
READ_HIVE_DATA = "read:hive:data"
|
18
|
+
WRITE_HIVE_MODEL = "write:hive:model"
|
19
|
+
WRITE_HIVE_DATA = "write:hive:data"
|
14
20
|
|
15
21
|
# Trade scopes
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
READ_TRADE_BOTS = "read:trade:bots"
|
23
|
+
WRITE_TRADE_BOTS = "write:trade:bots"
|
24
|
+
READ_TRADE_API_KEYS = "read:trade:api_keys"
|
25
|
+
WRITE_TRADE_API_KEYS = "write:trade:api_keys"
|
26
|
+
READ_TRADE_ORDERS = "read:trade:orders"
|
27
|
+
READ_TRADE_ACTIONS = "read:trade:actions"
|
28
|
+
WRITE_TRADE_ACTIONS = "write:trade:actions"
|
29
|
+
READ_TRADE_EXCHANGES = "read:trade:exchanges"
|
30
|
+
READ_TRADE_FUTURES = "read:trade:futures"
|
31
|
+
WRITE_TRADE_FUTURES = "write:trade:futures"
|
32
|
+
READ_TRADE_NOTIFICATIONS = "read:trade:notifications"
|
33
|
+
WRITE_TRADE_NOTIFICATIONS = "write:trade:notifications"
|
34
|
+
READ_TRADE_STRATEGIES = "read:trade:strategies"
|
35
|
+
WRITE_TRADE_STRATEGIES = "write:trade:strategies"
|
36
|
+
|
37
|
+
# Payment scopes
|
38
|
+
READ_PAY_PAYMENTS = "read:pay:payments"
|
39
|
+
READ_PAY_PRODUCTS = "read:pay:products"
|
40
|
+
WRITE_PAY_PRODUCTS = "write:pay:products"
|
41
|
+
READ_PAY_SUBSCRIPTIONS = "read:pay:subscriptions"
|
42
|
+
WRITE_PAY_SUBSCRIPTIONS = "write:pay:subscriptions"
|
43
|
+
READ_PAY_NOW = "read:pay:now"
|
44
|
+
WRITE_PAY_NOW = "write:pay:now"
|
45
|
+
|
46
|
+
# Read projections
|
47
|
+
READ_PREDICTIONS = "read:predictions"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: crypticorn
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.1.0
|
4
4
|
Summary: Maximise Your Crypto Trading Profits with AI Predictions
|
5
5
|
Author-email: Crypticorn <timon@crypticorn.com>
|
6
6
|
Project-URL: Homepage, https://crypticorn.com
|
@@ -13,16 +13,16 @@ Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Typing :: Typed
|
14
14
|
Requires-Python: >=3.10
|
15
15
|
Description-Content-Type: text/markdown
|
16
|
+
Requires-Dist: fastapi
|
16
17
|
Requires-Dist: urllib3<3.0.0,>=1.25.3
|
17
|
-
Requires-Dist: python_dateutil
|
18
|
-
Requires-Dist: aiohttp
|
19
|
-
Requires-Dist: aiohttp-retry
|
20
|
-
Requires-Dist: pydantic
|
21
|
-
Requires-Dist: typing-extensions
|
18
|
+
Requires-Dist: python_dateutil<3.0.0,>=2.8.2
|
19
|
+
Requires-Dist: aiohttp<4.0.0,>=3.8.4
|
20
|
+
Requires-Dist: aiohttp-retry<3.0.0,>=2.8.3
|
21
|
+
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
22
|
+
Requires-Dist: typing-extensions<5.0.0,>=4.7.1
|
22
23
|
Requires-Dist: pandas<3.0.0,>=2.2.0
|
23
24
|
Requires-Dist: requests<3.0.0,>=2.32.0
|
24
25
|
Requires-Dist: tqdm<5.0.0,>=4.67.0
|
25
|
-
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
26
26
|
Provides-Extra: dev
|
27
27
|
Requires-Dist: streamlit; extra == "dev"
|
28
28
|
Requires-Dist: httpx; extra == "dev"
|
@@ -31,12 +31,10 @@ Requires-Dist: black; extra == "dev"
|
|
31
31
|
Requires-Dist: twine; extra == "dev"
|
32
32
|
Requires-Dist: pyflakes; extra == "dev"
|
33
33
|
Provides-Extra: test
|
34
|
-
Requires-Dist: pytest
|
35
|
-
Requires-Dist: pytest-
|
36
|
-
Requires-Dist:
|
37
|
-
Requires-Dist:
|
38
|
-
Requires-Dist: types-python-dateutil>=2.8.19.14; extra == "test"
|
39
|
-
Requires-Dist: mypy>=1.5; extra == "test"
|
34
|
+
Requires-Dist: pytest==8.3.5; extra == "test"
|
35
|
+
Requires-Dist: pytest-asyncio==0.26.0; extra == "test"
|
36
|
+
Requires-Dist: pytest-cov==6.1.1; extra == "test"
|
37
|
+
Requires-Dist: python-dotenv==1.0.1; extra == "test"
|
40
38
|
|
41
39
|
# What is Crypticorn?
|
42
40
|
|
@@ -50,9 +48,28 @@ Crypticorn offers AI-based solutions for both active and passive investors, incl
|
|
50
48
|
Use this API Client to contribute to the so-called Hive AI, a community driven AI Meta Model for predicting the
|
51
49
|
cryptocurrency market.
|
52
50
|
|
51
|
+
## Installation
|
52
|
+
|
53
|
+
You can install the latest stable version from PyPi:
|
54
|
+
```bash
|
55
|
+
pip install crypticorn
|
56
|
+
```
|
57
|
+
|
58
|
+
If you want a specific version, run:
|
59
|
+
```bash
|
60
|
+
pip install crypticorn==2.0.0
|
61
|
+
```
|
62
|
+
|
63
|
+
If you want the latest version, which could be a pre release, run:
|
64
|
+
```bash
|
65
|
+
pip install --pre crypticorn
|
66
|
+
```
|
67
|
+
|
53
68
|
## Usage
|
54
69
|
|
55
|
-
|
70
|
+
As of know the library is available in async mode only. There are two was of using it.
|
71
|
+
|
72
|
+
## With Async Context Protocol
|
56
73
|
```python
|
57
74
|
async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
|
58
75
|
# json response
|
@@ -66,6 +83,7 @@ async with ApiClient(base_url="http://localhost", jwt=jwt) as client:
|
|
66
83
|
print(response)
|
67
84
|
```
|
68
85
|
|
86
|
+
## Without Async Context Protocol
|
69
87
|
Without the context you need to close the session manually.
|
70
88
|
```python
|
71
89
|
client = ApiClient(base_url="http://localhost", jwt=jwt)
|
@@ -2,7 +2,7 @@ crypticorn/__init__.py,sha256=TL41V09dmtbd2ee07wmOuG9KJJpyvLMPJi5DEd9bDyU,129
|
|
2
2
|
crypticorn/client.py,sha256=PHtTaV8hWiR-IXcZhQlwEY38q-PhqQjf-JiqaN2MPWg,1844
|
3
3
|
crypticorn/auth/__init__.py,sha256=JAl1tBLK9pYLr_-YKaj581c-c94PWLoqnatTIVAVvMM,81
|
4
4
|
crypticorn/auth/main.py,sha256=ljPuO27VDiOO-jnNycBn96X8UbVHPgOUglj46ib3OjM,1336
|
5
|
-
crypticorn/auth/client/__init__.py,sha256=
|
5
|
+
crypticorn/auth/client/__init__.py,sha256=yLmQpHhmGXXucIcLSHi8S8QkT5NkQMS5su8u0UWWw6c,5205
|
6
6
|
crypticorn/auth/client/api_client.py,sha256=H2jviD8CKiFnK1ZZXWKbSdBszBYcCQNcga9pwgM03D4,26908
|
7
7
|
crypticorn/auth/client/api_response.py,sha256=WhxwYDSMm6wPixp9CegO8dJzjFxDz3JF1yCq9s0ZqKE,639
|
8
8
|
crypticorn/auth/client/configuration.py,sha256=GNyY6hld-m9Dr7YPngRP5RQGg7o90SsSsSsq7VhyGVs,17715
|
@@ -11,17 +11,20 @@ crypticorn/auth/client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
11
11
|
crypticorn/auth/client/rest.py,sha256=RPbNRRbq7GtH9EBsQxaKT6NtSN8pIp1NmO1SKYZ9vVo,6944
|
12
12
|
crypticorn/auth/client/api/__init__.py,sha256=c-MlPvmOXSsk_ragrcUe8WkOuCPTTpJ8maSp2sER0EU,339
|
13
13
|
crypticorn/auth/client/api/admin_api.py,sha256=Bp52mo4XPDSzVsHolqAykAFpsaioNASY8qDfAUInxgU,21223
|
14
|
-
crypticorn/auth/client/api/auth_api.py,sha256=
|
14
|
+
crypticorn/auth/client/api/auth_api.py,sha256=6kelzbiV3uVxChZ1d53pXW_1COZxoSFfVUJG4_Xx9ug,124292
|
15
15
|
crypticorn/auth/client/api/service_api.py,sha256=xMQKbP9p6fNdJmFa3qMq2RXvE_Brt9HmtprBxEzb0Nk,12423
|
16
16
|
crypticorn/auth/client/api/user_api.py,sha256=nJJ_qD2RYDd6yQ9twHjtwhMJ9lEMSSE91IKltpFC3h0,103457
|
17
17
|
crypticorn/auth/client/api/wallet_api.py,sha256=AF6PSfv5bAnHpThe0Mtz1LD9qhWcd99lMOo7TJDGIt0,68927
|
18
|
-
crypticorn/auth/client/models/__init__.py,sha256=
|
18
|
+
crypticorn/auth/client/models/__init__.py,sha256=Un7vNZ7LoyUd16FTfU6A8bI_e0i61daLnL65gVvcRjo,4297
|
19
19
|
crypticorn/auth/client/models/add_wallet200_response.py,sha256=ibNUhAku-i2Bglo6ibyQ3V-JlFFauvswYy4doZUNiN4,2559
|
20
20
|
crypticorn/auth/client/models/add_wallet_request.py,sha256=w86tiy1vtlymB7ET0opmENQiEKAGAEjXTC-w4T3LHT4,3204
|
21
21
|
crypticorn/auth/client/models/authorize_user200_response.py,sha256=tkhq7TaQK4li03HKXzrH0GzXa-GIkDVJTUKZ-Qp0USE,3381
|
22
22
|
crypticorn/auth/client/models/authorize_user200_response_auth.py,sha256=h1PFbqzF96ssj7t7dMMKiNtRjRu44kPNUydevJm8vKo,3228
|
23
23
|
crypticorn/auth/client/models/authorize_user_request.py,sha256=VZKmGc91nIhWwoKNTbYZ4oFPYuFNcLxEBvWl-HcM0r8,2981
|
24
|
+
crypticorn/auth/client/models/create_api_key200_response.py,sha256=dj6G4vqSTDoUY3jT3_RbUxsLdg_2W-BvfYfwP9O9RJE,2479
|
25
|
+
crypticorn/auth/client/models/create_api_key_request.py,sha256=_pnaq1fksWWEXlI0di6ChqBmS7OLOSv4Yke8F9bo6Ao,4947
|
24
26
|
crypticorn/auth/client/models/create_user_request.py,sha256=kqVBJatlPtoYC1-nZnP2Mx2qZP2ATXffod7hTdWtoCY,3501
|
27
|
+
crypticorn/auth/client/models/get_api_keys200_response_inner.py,sha256=AGBp8CBwF4UKbn34DjEZ6H33Ys_G3cys0HHTxmJR5RE,5085
|
25
28
|
crypticorn/auth/client/models/list_wallets200_response.py,sha256=OB8nKlBflpj8dXhjTeTewxjSRok3LnllZZ5ZKISDRvE,4752
|
26
29
|
crypticorn/auth/client/models/list_wallets200_response_balances_inner.py,sha256=sLebeWVenEeiHpiCgxQR8iCMlAgjtC6K8CKq6v9g-Ok,4043
|
27
30
|
crypticorn/auth/client/models/list_wallets200_response_balances_inner_sale_round.py,sha256=rqXN7WVEhmeJxDKCSK5sxwWXvmn-Gnf810MGWwIUXII,3623
|
@@ -31,6 +34,8 @@ crypticorn/auth/client/models/list_wallets200_response_data_inner.py,sha256=IxZr
|
|
31
34
|
crypticorn/auth/client/models/list_wallets200_response_user_value.py,sha256=e0LbNMdI77IVRt9glwquB6C790o6OWfvitlfyuIoupQ,3841
|
32
35
|
crypticorn/auth/client/models/logout_default_response.py,sha256=ioZ8FrV2DDUdCX2XIkS0X1Y2H0ZjLBCl4_5t_OzrnXE,3395
|
33
36
|
crypticorn/auth/client/models/logout_default_response_issues_inner.py,sha256=_aOp_ngnk19-YLM07nSiqClp6-l6Qa5g6u6Habd1BEc,2487
|
37
|
+
crypticorn/auth/client/models/oauth_callback200_response.py,sha256=E7NaQVrrlPtkkaFHG-QNJCQWQzFGXfpjotd2sVZ-gE4,3436
|
38
|
+
crypticorn/auth/client/models/oauth_callback200_response_user.py,sha256=ABTvVFLHPR8jMOOHJDvy4_fIVLKuL753ImHLifNQzVg,3018
|
34
39
|
crypticorn/auth/client/models/refresh_token_info200_response.py,sha256=YZITc7MeCrKIVewQxtwOv9xcr26fFhwhnl6o59Ry024,3082
|
35
40
|
crypticorn/auth/client/models/refresh_token_info200_response_user_session.py,sha256=QUz7M-lgSDdvLg2RqFYJkTEJuZtvKlD1CB5BfXo4kFo,3101
|
36
41
|
crypticorn/auth/client/models/resend_verification_email_request.py,sha256=Gx5OONaDxeXaXU7Q30NLMIAvX1XkzmdqbuC6EPlxumk,2546
|
@@ -48,12 +53,12 @@ crypticorn/auth/client/models/verify_email200_response_auth_auth.py,sha256=bc819
|
|
48
53
|
crypticorn/auth/client/models/verify_email_request.py,sha256=8MBfxPTLn5X6Z3vE2blxmOtqDhU9tu7O7AyaxkHBG6w,2464
|
49
54
|
crypticorn/auth/client/models/verify_wallet_request.py,sha256=b0DAocvhKzPXPjM62DZqezlHxq3cNL7UVKl0d2judHQ,2691
|
50
55
|
crypticorn/auth/client/models/wallet_verified200_response.py,sha256=QILnTLsCKdI-WdV_fsLBy1UH4ZZU-U-wWJ9ot8v08tI,2465
|
51
|
-
crypticorn/auth/client/models/whoami200_response.py,sha256=
|
56
|
+
crypticorn/auth/client/models/whoami200_response.py,sha256=JhJAuL_N2yXGt5gfX4Dx46isuFfcNmpi2Qw7z0UJpMU,3086
|
52
57
|
crypticorn/common/__init__.py,sha256=lY87VMTkIEqto6kcEjC1YWsUvT03QuPmXwxCaeWE854,196
|
53
|
-
crypticorn/common/auth.py,sha256=
|
54
|
-
crypticorn/common/auth_client.py,sha256=
|
58
|
+
crypticorn/common/auth.py,sha256=kO03VKuFRIoWXMDLPmgnVZ49EeTqOMzgJ2yEXt_SmQM,1223
|
59
|
+
crypticorn/common/auth_client.py,sha256=7ptCkWZwuMSIFTx3gajOH4CScPFG-Pn5gLe1m_NY5AQ,7622
|
55
60
|
crypticorn/common/errors.py,sha256=jGAS7TONKhdaRfft7w-0wrJ3BBTzqS6u03susiqAF0w,12723
|
56
|
-
crypticorn/common/scopes.py,sha256=
|
61
|
+
crypticorn/common/scopes.py,sha256=E3P8JeoziZjEv-nef1PakjowjmhIebkvIeLYD_NRY0Q,1570
|
57
62
|
crypticorn/common/urls.py,sha256=_NMhvhZXOsZpDBbgucqu0yboRFox6JVMlOoQq_Y5SGA,432
|
58
63
|
crypticorn/hive/__init__.py,sha256=hRfTlEzEql4msytdUC_04vfaHzVKG5CGZle1M-9QFgY,81
|
59
64
|
crypticorn/hive/main.py,sha256=RmCYSR0jwmfYWTK89dt79DuGPjEaip9XQs_LWNWr_tc,1036
|
@@ -220,7 +225,7 @@ crypticorn/trade/client/models/trading_action_type.py,sha256=jW0OsNz_ZNXlITxAfh9
|
|
220
225
|
crypticorn/trade/client/models/update_notification.py,sha256=B9QUuVRNpk1e5G8o0WFgIg3inm-OX7KJAJcjVnRzYx8,3046
|
221
226
|
crypticorn/trade/client/models/validation_error.py,sha256=uTkvsKrOAt-21UC0YPqCdRl_OMsuu7uhPtWuwRSYvv0,3228
|
222
227
|
crypticorn/trade/client/models/validation_error_loc_inner.py,sha256=22ql-H829xTBgfxNQZsqd8fS3zQt9tLW1pj0iobo0jY,5131
|
223
|
-
crypticorn-2.
|
224
|
-
crypticorn-2.
|
225
|
-
crypticorn-2.
|
226
|
-
crypticorn-2.
|
228
|
+
crypticorn-2.1.0.dist-info/METADATA,sha256=oQ5ZEl55q9O3z1_EjUSlwGSxepxwaTANO8RAVjzj_ZI,3120
|
229
|
+
crypticorn-2.1.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
230
|
+
crypticorn-2.1.0.dist-info/top_level.txt,sha256=EP3NY216qIBYfmvGl0L2Zc9ItP0DjGSkiYqd9xJwGcM,11
|
231
|
+
crypticorn-2.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|