dara-core 1.14.0a0__py3-none-any.whl → 1.14.0a2__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.
- dara/core/auth/base.py +4 -1
- dara/core/auth/routes.py +44 -4
- dara/core/auth/utils.py +8 -3
- dara/core/internal/routing.py +5 -3
- dara/core/internal/websocket.py +56 -12
- dara/core/umd/dara.core.umd.js +9 -9
- {dara_core-1.14.0a0.dist-info → dara_core-1.14.0a2.dist-info}/METADATA +10 -10
- {dara_core-1.14.0a0.dist-info → dara_core-1.14.0a2.dist-info}/RECORD +11 -11
- {dara_core-1.14.0a0.dist-info → dara_core-1.14.0a2.dist-info}/LICENSE +0 -0
- {dara_core-1.14.0a0.dist-info → dara_core-1.14.0a2.dist-info}/WHEEL +0 -0
- {dara_core-1.14.0a0.dist-info → dara_core-1.14.0a2.dist-info}/entry_points.txt +0 -0
dara/core/auth/base.py
CHANGED
|
@@ -91,10 +91,13 @@ class BaseAuthConfig(BaseModel, abc.ABC):
|
|
|
91
91
|
:param token: encoded token
|
|
92
92
|
"""
|
|
93
93
|
|
|
94
|
-
def refresh_token(self, refresh_token: str) -> tuple[str, str]:
|
|
94
|
+
def refresh_token(self, old_token: TokenData, refresh_token: str) -> tuple[str, str]:
|
|
95
95
|
"""
|
|
96
96
|
Create a new session token and refresh token from a refresh token.
|
|
97
97
|
|
|
98
|
+
Note: the new issued session token should include the same session_id as the old token
|
|
99
|
+
|
|
100
|
+
:param old_token: old session token data
|
|
98
101
|
:param refresh_token: encoded refresh token
|
|
99
102
|
:return: new session token, new refresh token
|
|
100
103
|
"""
|
dara/core/auth/routes.py
CHANGED
|
@@ -19,7 +19,15 @@ from inspect import iscoroutinefunction
|
|
|
19
19
|
from typing import Union, cast
|
|
20
20
|
|
|
21
21
|
import jwt
|
|
22
|
-
from fastapi import
|
|
22
|
+
from fastapi import (
|
|
23
|
+
APIRouter,
|
|
24
|
+
BackgroundTasks,
|
|
25
|
+
Cookie,
|
|
26
|
+
Depends,
|
|
27
|
+
HTTPException,
|
|
28
|
+
Request,
|
|
29
|
+
Response,
|
|
30
|
+
)
|
|
23
31
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
24
32
|
|
|
25
33
|
from dara.core.auth.base import BaseAuthConfig
|
|
@@ -32,6 +40,7 @@ from dara.core.auth.definitions import (
|
|
|
32
40
|
AuthError,
|
|
33
41
|
SessionRequestBody,
|
|
34
42
|
)
|
|
43
|
+
from dara.core.auth.utils import decode_token
|
|
35
44
|
from dara.core.logging import dev_logger
|
|
36
45
|
|
|
37
46
|
auth_router = APIRouter()
|
|
@@ -107,7 +116,9 @@ async def _revoke_session(response: Response, credentials: HTTPAuthorizationCred
|
|
|
107
116
|
@auth_router.post('/refresh-token')
|
|
108
117
|
async def handle_refresh_token(
|
|
109
118
|
response: Response,
|
|
119
|
+
background_tasks: BackgroundTasks,
|
|
110
120
|
dara_refresh_token: Union[str, None] = Cookie(default=None),
|
|
121
|
+
credentials: HTTPAuthorizationCredentials = Depends(HTTPBearer()),
|
|
111
122
|
):
|
|
112
123
|
"""
|
|
113
124
|
Given a refresh token, issues a new session token and refresh token cookie.
|
|
@@ -119,13 +130,42 @@ async def handle_refresh_token(
|
|
|
119
130
|
if dara_refresh_token is None:
|
|
120
131
|
raise HTTPException(status_code=400, detail=BAD_REQUEST_ERROR('No refresh token provided'))
|
|
121
132
|
|
|
122
|
-
|
|
133
|
+
# Check scheme is correct
|
|
134
|
+
if credentials.scheme != 'Bearer':
|
|
135
|
+
raise HTTPException(
|
|
136
|
+
status_code=400,
|
|
137
|
+
detail=BAD_REQUEST_ERROR(
|
|
138
|
+
'Invalid authentication scheme, previous Bearer token must be included in the refresh request'
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
from dara.core.internal.registries import (
|
|
143
|
+
auth_registry,
|
|
144
|
+
utils_registry,
|
|
145
|
+
websocket_registry,
|
|
146
|
+
)
|
|
147
|
+
from dara.core.internal.websocket import WebsocketManager
|
|
123
148
|
|
|
124
149
|
auth_config: BaseAuthConfig = auth_registry.get('auth_config')
|
|
150
|
+
ws_manager: WebsocketManager = utils_registry.get('WebsocketManager')
|
|
125
151
|
|
|
126
152
|
try:
|
|
127
|
-
#
|
|
128
|
-
|
|
153
|
+
# decode the old token ignoring expiry date
|
|
154
|
+
old_token_data = decode_token(credentials.credentials, options={'verify_exp': False})
|
|
155
|
+
|
|
156
|
+
# Refresh logic up to implementation - passing in old token data so session_id can be preserved
|
|
157
|
+
session_token, refresh_token = auth_config.refresh_token(old_token_data, dara_refresh_token)
|
|
158
|
+
|
|
159
|
+
# Notify the active websocket handlers (i.e. active connections, per each tab open)
|
|
160
|
+
# so they can update the data in ContextVars
|
|
161
|
+
async def notify_ws_connections():
|
|
162
|
+
session_token_data = decode_token(session_token)
|
|
163
|
+
channels = websocket_registry.get(old_token_data.session_id)
|
|
164
|
+
for channel in channels:
|
|
165
|
+
if handler := ws_manager.handlers.get(channel):
|
|
166
|
+
await handler.update_token(session_token_data)
|
|
167
|
+
|
|
168
|
+
background_tasks.add_task(notify_ws_connections)
|
|
129
169
|
|
|
130
170
|
# Using 'Strict' as it is only used for the refresh-token endpoint so cross-site requests are not expected
|
|
131
171
|
response.set_cookie(
|
dara/core/auth/utils.py
CHANGED
|
@@ -33,12 +33,15 @@ from dara.core.internal.settings import get_settings
|
|
|
33
33
|
from dara.core.logging import dev_logger
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def decode_token(token: str) -> TokenData:
|
|
36
|
+
def decode_token(token: str, **kwargs) -> TokenData:
|
|
37
37
|
"""
|
|
38
38
|
Decode a JWT token
|
|
39
|
+
|
|
40
|
+
:param token: the JWT token to decode
|
|
41
|
+
:param kwargs: additional arguments to pass to the jwt.decode function
|
|
39
42
|
"""
|
|
40
43
|
try:
|
|
41
|
-
return TokenData.parse_obj(jwt.decode(token, get_settings().jwt_secret, algorithms=[JWT_ALGO]))
|
|
44
|
+
return TokenData.parse_obj(jwt.decode(token, get_settings().jwt_secret, algorithms=[JWT_ALGO], **kwargs))
|
|
42
45
|
except jwt.ExpiredSignatureError:
|
|
43
46
|
raise AuthError(code=401, detail=EXPIRED_TOKEN_ERROR)
|
|
44
47
|
except jwt.DecodeError:
|
|
@@ -52,11 +55,13 @@ def sign_jwt(
|
|
|
52
55
|
groups: List[str],
|
|
53
56
|
id_token: Optional[str] = None,
|
|
54
57
|
exp: Optional[Union[datetime, int]] = None,
|
|
58
|
+
session_id: Optional[str] = None,
|
|
55
59
|
):
|
|
56
60
|
"""
|
|
57
61
|
Create a new Dara JWT token
|
|
58
62
|
"""
|
|
59
|
-
session_id
|
|
63
|
+
if session_id is None:
|
|
64
|
+
session_id = str(uuid.uuid4())
|
|
60
65
|
|
|
61
66
|
# Default expiry is 1 day unless specified
|
|
62
67
|
if exp is None:
|
dara/core/internal/routing.py
CHANGED
|
@@ -208,9 +208,11 @@ def create_router(config: Configuration):
|
|
|
208
208
|
'application_name': get_settings().project_name,
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
@core_api_router.get('/auth-
|
|
212
|
-
async def
|
|
213
|
-
return
|
|
211
|
+
@core_api_router.get('/auth-config')
|
|
212
|
+
async def get_auth_config(): # pylint: disable=unused-variable
|
|
213
|
+
return {
|
|
214
|
+
'auth_components': config.auth_config.component_config.dict(),
|
|
215
|
+
}
|
|
214
216
|
|
|
215
217
|
@core_api_router.get('/components', dependencies=[Depends(verify_session)])
|
|
216
218
|
async def get_components(name: Optional[str] = None): # pylint: disable=unused-variable
|
dara/core/internal/websocket.py
CHANGED
|
@@ -156,6 +156,16 @@ class WebSocketHandler:
|
|
|
156
156
|
Stream containing messages to send to the client.
|
|
157
157
|
"""
|
|
158
158
|
|
|
159
|
+
token_send_stream: MemoryObjectSendStream[TokenData]
|
|
160
|
+
"""
|
|
161
|
+
Stream for sending token updates to the WS connection.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
token_receive_stream: MemoryObjectReceiveStream[TokenData]
|
|
165
|
+
"""
|
|
166
|
+
Stream for receiving token updates in the WS connection.
|
|
167
|
+
"""
|
|
168
|
+
|
|
159
169
|
pending_responses: Dict[str, Tuple[Event, Optional[Any]]]
|
|
160
170
|
"""
|
|
161
171
|
A map of pending responses from the client. The key is the message ID and the value is a tuple of the event to
|
|
@@ -167,11 +177,38 @@ class WebSocketHandler:
|
|
|
167
177
|
|
|
168
178
|
def __init__(self, channel_id: str):
|
|
169
179
|
send_stream, receive_stream = create_memory_object_stream[ServerMessage](math.inf)
|
|
170
|
-
self.channel_id = channel_id
|
|
171
|
-
self.send_stream = send_stream
|
|
172
180
|
self.receive_stream = receive_stream
|
|
181
|
+
self.send_stream = send_stream
|
|
182
|
+
|
|
183
|
+
token_send_stream, token_receive_stream = anyio.create_memory_object_stream[TokenData](math.inf)
|
|
184
|
+
self.token_send_stream = token_send_stream
|
|
185
|
+
self.token_receive_stream = token_receive_stream
|
|
186
|
+
|
|
187
|
+
self.channel_id = channel_id
|
|
173
188
|
self.pending_responses = {}
|
|
174
189
|
|
|
190
|
+
async def update_token(self, token_data: TokenData):
|
|
191
|
+
"""
|
|
192
|
+
Update the token for the client.
|
|
193
|
+
Should be used if the token is refreshed or changed in some way
|
|
194
|
+
so the live WS connection can update it's ContextVars accordingly
|
|
195
|
+
and they're up to date in custom message handlers.
|
|
196
|
+
|
|
197
|
+
:param token_data: The new token data
|
|
198
|
+
"""
|
|
199
|
+
await self.token_send_stream.send(token_data)
|
|
200
|
+
|
|
201
|
+
def get_token_update(self) -> Optional[TokenData]:
|
|
202
|
+
"""
|
|
203
|
+
Get the latest token update for the client.
|
|
204
|
+
|
|
205
|
+
:return: The latest token update
|
|
206
|
+
"""
|
|
207
|
+
try:
|
|
208
|
+
return self.token_receive_stream.receive_nowait()
|
|
209
|
+
except Exception:
|
|
210
|
+
return None
|
|
211
|
+
|
|
175
212
|
async def send_message(self, message: ServerMessage):
|
|
176
213
|
"""
|
|
177
214
|
Send a message to the client.
|
|
@@ -446,17 +483,20 @@ async def ws_handler(websocket: WebSocket, token: Optional[str] = Query(default=
|
|
|
446
483
|
else:
|
|
447
484
|
sessions_registry.set(user_identifier, {token_content.session_id})
|
|
448
485
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
486
|
+
def update_context(token_data: TokenData):
|
|
487
|
+
USER.set(
|
|
488
|
+
UserData(
|
|
489
|
+
identity_id=token_data.identity_id,
|
|
490
|
+
identity_name=token_data.identity_name,
|
|
491
|
+
identity_email=token_data.identity_email,
|
|
492
|
+
groups=token_data.groups,
|
|
493
|
+
)
|
|
456
494
|
)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
495
|
+
SESSION_ID.set(token_data.session_id)
|
|
496
|
+
ID_TOKEN.set(token_data.id_token)
|
|
497
|
+
|
|
498
|
+
# Set initial Auth context vars for the WS connection
|
|
499
|
+
update_context(token_content)
|
|
460
500
|
|
|
461
501
|
# Change protocol from http to ws - from this point exceptions can't be raised
|
|
462
502
|
await websocket.accept()
|
|
@@ -488,6 +528,10 @@ async def ws_handler(websocket: WebSocket, token: Optional[str] = Query(default=
|
|
|
488
528
|
# as the latter does not properly handle disconnections e.g. when relaoading the server
|
|
489
529
|
data = await websocket.receive_json()
|
|
490
530
|
|
|
531
|
+
# update Auth context vars for the WS connection
|
|
532
|
+
while new_token_data := handler.get_token_update():
|
|
533
|
+
update_context(new_token_data)
|
|
534
|
+
|
|
491
535
|
# Heartbeat to keep connection alive
|
|
492
536
|
if data['type'] == 'ping':
|
|
493
537
|
await websocket.send_json({'type': 'pong', 'message': None})
|
dara/core/umd/dara.core.umd.js
CHANGED
|
@@ -54981,8 +54981,8 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
|
|
|
54981
54981
|
return __privateGet(this, _state)[key];
|
|
54982
54982
|
}
|
|
54983
54983
|
setValue(key, value) {
|
|
54984
|
-
__privateMethod(this, _notify, notify_fn).call(this, key, value);
|
|
54985
54984
|
__privateGet(this, _state)[key] = value;
|
|
54985
|
+
__privateMethod(this, _notify, notify_fn).call(this, key, value);
|
|
54986
54986
|
}
|
|
54987
54987
|
async replaceValue(key, fn) {
|
|
54988
54988
|
if (__privateGet(this, _locks)[key]) {
|
|
@@ -54998,10 +54998,8 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
|
|
|
54998
54998
|
let result;
|
|
54999
54999
|
try {
|
|
55000
55000
|
result = await fn();
|
|
55001
|
-
__privateGet(this, _state)[key] = result;
|
|
55002
|
-
__privateMethod(this, _notify, notify_fn).call(this, key, result);
|
|
55003
|
-
unlock(result);
|
|
55004
55001
|
this.setValue(key, result);
|
|
55002
|
+
unlock(result);
|
|
55005
55003
|
} catch (e3) {
|
|
55006
55004
|
unlockError(e3);
|
|
55007
55005
|
} finally {
|
|
@@ -56141,11 +56139,11 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
|
|
|
56141
56139
|
message.reason
|
|
56142
56140
|
);
|
|
56143
56141
|
}
|
|
56144
|
-
function
|
|
56142
|
+
function useAuthConfig() {
|
|
56145
56143
|
return reactQuery.useQuery(
|
|
56146
|
-
["auth-
|
|
56144
|
+
["auth-config"],
|
|
56147
56145
|
async () => {
|
|
56148
|
-
const response = await request("/api/core/auth-
|
|
56146
|
+
const response = await request("/api/core/auth-config", {
|
|
56149
56147
|
method: HTTP_METHOD.GET
|
|
56150
56148
|
});
|
|
56151
56149
|
return response.json();
|
|
@@ -59120,7 +59118,7 @@ Inferred class string: "${iconClasses}."`
|
|
|
59120
59118
|
return component;
|
|
59121
59119
|
}
|
|
59122
59120
|
function AuthWrapper(props) {
|
|
59123
|
-
const { data:
|
|
59121
|
+
const { data: authConfig, isLoading } = useAuthConfig();
|
|
59124
59122
|
const isMounted = React.useRef(false);
|
|
59125
59123
|
if (!isMounted.current) {
|
|
59126
59124
|
isMounted.current = true;
|
|
@@ -59139,7 +59137,7 @@ Inferred class string: "${iconClasses}."`
|
|
|
59139
59137
|
if (isLoading) {
|
|
59140
59138
|
return /* @__PURE__ */ React__default.default.createElement(Center, null, /* @__PURE__ */ React__default.default.createElement(DefaultFallback, null));
|
|
59141
59139
|
}
|
|
59142
|
-
const { login, logout, ...extraRoutes } =
|
|
59140
|
+
const { login, logout, ...extraRoutes } = authConfig.auth_components;
|
|
59143
59141
|
return /* @__PURE__ */ React__default.default.createElement(Switch$1, null, /* @__PURE__ */ React__default.default.createElement(Route, { path: "/login" }, /* @__PURE__ */ React__default.default.createElement(DynamicAuthComponent, { component: login })), /* @__PURE__ */ React__default.default.createElement(Route, { path: "/logout" }, /* @__PURE__ */ React__default.default.createElement(DynamicAuthComponent, { component: logout })), Object.entries(extraRoutes).map(([path, component]) => /* @__PURE__ */ React__default.default.createElement(Route, { key: path, path: `/${path}` }, /* @__PURE__ */ React__default.default.createElement(DynamicAuthComponent, { component }))), /* @__PURE__ */ React__default.default.createElement(Route, { component: ErrorPage, path: "/error" }), /* @__PURE__ */ React__default.default.createElement(Route, { path: "/", render: () => /* @__PURE__ */ React__default.default.createElement(PrivateRoute, null, props.children) }));
|
|
59144
59142
|
}
|
|
59145
59143
|
const index = "";
|
|
@@ -86454,6 +86452,7 @@ Inferred class string: "${iconClasses}."`
|
|
|
86454
86452
|
exports.combineFilters = combineFilters;
|
|
86455
86453
|
exports.default = run;
|
|
86456
86454
|
exports.getIcon = getIcon;
|
|
86455
|
+
exports.getSessionToken = getSessionToken;
|
|
86457
86456
|
exports.getToken = getToken;
|
|
86458
86457
|
exports.getTokenKey = getTokenKey;
|
|
86459
86458
|
exports.handleAuthErrors = handleAuthErrors;
|
|
@@ -86464,6 +86463,7 @@ Inferred class string: "${iconClasses}."`
|
|
|
86464
86463
|
exports.request = request;
|
|
86465
86464
|
exports.resolveValue = resolveValue;
|
|
86466
86465
|
exports.revokeSession = revokeSession;
|
|
86466
|
+
exports.setSessionToken = setSessionToken;
|
|
86467
86467
|
exports.useAction = useAction;
|
|
86468
86468
|
exports.useActionIsLoading = useActionIsLoading;
|
|
86469
86469
|
exports.useAnyVariable = useAnyVariable;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dara-core
|
|
3
|
-
Version: 1.14.
|
|
3
|
+
Version: 1.14.0a2
|
|
4
4
|
Summary: Dara Framework Core
|
|
5
5
|
Home-page: https://dara.causalens.com/
|
|
6
6
|
License: Apache-2.0
|
|
@@ -20,10 +20,10 @@ Requires-Dist: async-asgi-testclient (>=1.4.11,<2.0.0)
|
|
|
20
20
|
Requires-Dist: certifi (>=2024.7.4)
|
|
21
21
|
Requires-Dist: click (==8.1.3)
|
|
22
22
|
Requires-Dist: colorama (>=0.4.6,<0.5.0)
|
|
23
|
-
Requires-Dist: create-dara-app (==1.14.0-alpha.
|
|
23
|
+
Requires-Dist: create-dara-app (==1.14.0-alpha.2)
|
|
24
24
|
Requires-Dist: croniter (>=1.0.15,<2.0.0)
|
|
25
25
|
Requires-Dist: cryptography (>=42.0.4)
|
|
26
|
-
Requires-Dist: dara-components (==1.14.0-alpha.
|
|
26
|
+
Requires-Dist: dara-components (==1.14.0-alpha.2) ; extra == "all"
|
|
27
27
|
Requires-Dist: exceptiongroup (>=1.1.3,<2.0.0)
|
|
28
28
|
Requires-Dist: fastapi (==0.109.0)
|
|
29
29
|
Requires-Dist: fastapi-vite (==0.3.1)
|
|
@@ -51,7 +51,7 @@ Description-Content-Type: text/markdown
|
|
|
51
51
|
|
|
52
52
|
# Dara Application Framework
|
|
53
53
|
|
|
54
|
-
<img src="https://github.com/causalens/dara/blob/v1.14.0-alpha.
|
|
54
|
+
<img src="https://github.com/causalens/dara/blob/v1.14.0-alpha.2/img/dara_light.svg?raw=true">
|
|
55
55
|
|
|
56
56
|

|
|
57
57
|
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
@@ -96,7 +96,7 @@ source .venv/bin/activate
|
|
|
96
96
|
dara start
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-

|
|
100
100
|
|
|
101
101
|
Note: `pip` installation uses [PEP 660](https://peps.python.org/pep-0660/) `pyproject.toml`-based editable installs which require `pip >= 21.3` and `setuptools >= 64.0.0`. You can upgrade both with:
|
|
102
102
|
|
|
@@ -113,9 +113,9 @@ Explore some of our favorite apps - a great way of getting started and getting t
|
|
|
113
113
|
|
|
114
114
|
| Dara App | Description |
|
|
115
115
|
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
116
|
-
|  | Demonstrates how to use incorporate a LLM chat box into your decision app to understand model insights |
|
|
117
|
+
|  | Demonstrates how to enable the user to interact with plots, trigger actions based on clicks, mouse movements and other interactions with `Bokeh` or `Plotly` plots |
|
|
118
|
+
|  | Demonstrates how to use the `CausalGraphViewer` component to display your graphs or networks, customising the displayed information through colors and tooltips, and updating the page based on user interaction. |
|
|
119
119
|
|
|
120
120
|
Check out our [App Gallery](https://dara.causalens.com/gallery) for more inspiration!
|
|
121
121
|
|
|
@@ -142,9 +142,9 @@ And the supporting UI packages and tools.
|
|
|
142
142
|
- `ui-utils` - miscellaneous utility functions
|
|
143
143
|
- `ui-widgets` - widget components
|
|
144
144
|
|
|
145
|
-
More information on the repository structure can be found in the [CONTRIBUTING.md](https://github.com/causalens/dara/blob/v1.14.0-alpha.
|
|
145
|
+
More information on the repository structure can be found in the [CONTRIBUTING.md](https://github.com/causalens/dara/blob/v1.14.0-alpha.2/CONTRIBUTING.md) file.
|
|
146
146
|
|
|
147
147
|
## License
|
|
148
148
|
|
|
149
|
-
Dara is open-source and licensed under the [Apache 2.0 License](https://github.com/causalens/dara/blob/v1.14.0-alpha.
|
|
149
|
+
Dara is open-source and licensed under the [Apache 2.0 License](https://github.com/causalens/dara/blob/v1.14.0-alpha.2/LICENSE).
|
|
150
150
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
dara/core/__init__.py,sha256=w3OUU03lGXA45_Sf99CsNWL6SZ7tr7y4wRYq6pdGmhM,2186
|
|
2
2
|
dara/core/actions.py,sha256=gARcrrtzYuBAVJUCtuHwpFc6PPVPb7x3ITIISCLw0GA,965
|
|
3
3
|
dara/core/auth/__init__.py,sha256=H0bJoXff5wIRZmHvvQ3y9p5SXA9lM8OuLCGceYGqfb0,851
|
|
4
|
-
dara/core/auth/base.py,sha256=
|
|
4
|
+
dara/core/auth/base.py,sha256=jZNuCMoBHQcxWeLpTUzcxdbkbWUJ42jbtKgnnrwvNVA,3201
|
|
5
5
|
dara/core/auth/basic.py,sha256=IMkoC1OeeRmnmjIqPHpybs8zSdbLlNKYLRvj08ajirg,4692
|
|
6
6
|
dara/core/auth/definitions.py,sha256=fx-VCsElP9X97gM0Eql-4lFpLa0UryokmGZhQQat2NU,3511
|
|
7
|
-
dara/core/auth/routes.py,sha256=
|
|
8
|
-
dara/core/auth/utils.py,sha256=
|
|
7
|
+
dara/core/auth/routes.py,sha256=x3oFLOkgi7-r0mqFD0GgM3hdS1JkmLHWQ6mNnEKRDDk,7951
|
|
8
|
+
dara/core/auth/utils.py,sha256=ngOi5j71Xu-G59yWxGoejBEmMnVyGS67aF7czt_0i7A,3062
|
|
9
9
|
dara/core/base_definitions.py,sha256=r_W_qk6_VvvskbPEPjTF6xUh3o_lkNBWMFhN1Pic8Ks,14868
|
|
10
10
|
dara/core/cli.py,sha256=ycTB7QHCB-74OnKnjXqkXq-GBqyjBqo7u4v1kTgv2jE,7656
|
|
11
11
|
dara/core/configuration.py,sha256=8VynDds7a_uKXSpeNvjOUK3qfclg0WPniFEspL-6fi8,21153
|
|
@@ -54,13 +54,13 @@ dara/core/internal/port_utils.py,sha256=AQOUNiFNBYKVUwQ7i9UlY1NQ3sWb5xh5GkO6P1Bm
|
|
|
54
54
|
dara/core/internal/registries.py,sha256=9WDczIsNeSmzi6aViIq_b14lmmYGGkdsUGHpv0Sg9zo,3278
|
|
55
55
|
dara/core/internal/registry.py,sha256=ONCDusqaL0q59Py_r8-fFVN3vbkkDf5TXzNvbB9SrGQ,4305
|
|
56
56
|
dara/core/internal/registry_lookup.py,sha256=8snHu2wUUsngXjHyHh6eZqL_WwonTTQB6-WBX-R_WZg,2238
|
|
57
|
-
dara/core/internal/routing.py,sha256=
|
|
57
|
+
dara/core/internal/routing.py,sha256=Wdy11iWDeAf2PyHXZv5mPeJ_BEcoR0XftOl3M8vUhJU,22782
|
|
58
58
|
dara/core/internal/scheduler.py,sha256=z6OYwazBf3GYo8CzMC9IuGC2P96gI7JwxquT8GaoTMk,12944
|
|
59
59
|
dara/core/internal/settings.py,sha256=wAWxl-HXjq7PW3twe_CrR-UuMRw9VBudC3eRmevZAhM,3869
|
|
60
60
|
dara/core/internal/store.py,sha256=qVyU7JfC3zE2vYC2mfjmvECWMlFS9b-nMF1k-alg4Y8,7756
|
|
61
61
|
dara/core/internal/tasks.py,sha256=XK-GTIyge8RBYAfzNs3rmLYVNSKIarCzPdqRSVGg-4M,24728
|
|
62
62
|
dara/core/internal/utils.py,sha256=b1YYkn8qHl6-GY6cCm2MS1NXRS9j_rElYCKMZOxJgrY,8232
|
|
63
|
-
dara/core/internal/websocket.py,sha256=
|
|
63
|
+
dara/core/internal/websocket.py,sha256=i6QXWHfcWbQDT3dk9F_7yw5CNhkC-lnqMoH7EKHBqC4,21676
|
|
64
64
|
dara/core/jinja/index.html,sha256=iykqiRh3H_HkcjHJeeSRXRu45nZ2y1sZX5FLdPRhlQY,726
|
|
65
65
|
dara/core/jinja/index_autojs.html,sha256=MRF5J0vNfzZQm9kPEeLl23sbr08fVSRd_PAUD6Fkc_0,1253
|
|
66
66
|
dara/core/js_tooling/custom_js_scaffold/index.tsx,sha256=FEzSV5o5Nyzxw6eXvGLi7BkEBkXf3brV34_7ATLnY7o,68
|
|
@@ -81,7 +81,7 @@ dara/core/metrics/cache.py,sha256=ybofUhZO0TCHeyhB_AtldWk1QTmTKh7GucTXpOkeTFA,25
|
|
|
81
81
|
dara/core/metrics/runtime.py,sha256=YP-6Dz0GeI9_Yr7bUk_-OqShyFySGH_AKpDO126l6es,1833
|
|
82
82
|
dara/core/metrics/utils.py,sha256=rYlBinxFc7VehFT5cTNXLk8gC74UEj7ZGq6vLgIDpSg,2247
|
|
83
83
|
dara/core/persistence.py,sha256=TO94rPAN7jxZKVCC5YA4eE7GGDoNlCPe-BkkItV2VUE,10379
|
|
84
|
-
dara/core/umd/dara.core.umd.js,sha256=
|
|
84
|
+
dara/core/umd/dara.core.umd.js,sha256=yJvT54abv74o8fFuSoeH1NucuJVl90UFfeM3ZsCp3c8,4877860
|
|
85
85
|
dara/core/umd/style.css,sha256=YQtQ4veiSktnyONl0CU1iU1kKfcQhreH4iASi1MP7Ak,4095007
|
|
86
86
|
dara/core/visual/__init__.py,sha256=QN0wbG9HPQ_vXh8BO8DnBXeYLIENVTNtRmYzZf1lx7c,577
|
|
87
87
|
dara/core/visual/components/__init__.py,sha256=O-Em_glGdZNO0LLl2RWmJSrQiXKxliXg_PuhVXGT81I,1811
|
|
@@ -105,8 +105,8 @@ dara/core/visual/themes/__init__.py,sha256=aM4mgoIYo2neBSw5FRzswsht7PUKjLthiHLmF
|
|
|
105
105
|
dara/core/visual/themes/dark.py,sha256=UQGDooOc8ric73eHs9E0ltYP4UCrwqQ3QxqN_fb4PwY,1942
|
|
106
106
|
dara/core/visual/themes/definitions.py,sha256=m3oN0txs65MZepqjj7AKMMxybf2aq5fTjcTwJmHqEbk,2744
|
|
107
107
|
dara/core/visual/themes/light.py,sha256=-Tviq8oEwGbdFULoDOqPuHO0UpAZGsBy8qFi0kAGolQ,1944
|
|
108
|
-
dara_core-1.14.
|
|
109
|
-
dara_core-1.14.
|
|
110
|
-
dara_core-1.14.
|
|
111
|
-
dara_core-1.14.
|
|
112
|
-
dara_core-1.14.
|
|
108
|
+
dara_core-1.14.0a2.dist-info/LICENSE,sha256=r9u1w2RvpLMV6YjuXHIKXRBKzia3fx_roPwboGcLqCc,10944
|
|
109
|
+
dara_core-1.14.0a2.dist-info/METADATA,sha256=RLDwxR63x52m9wlBKPA8P5Eg8s8bKifiPIybYPcpTT0,7457
|
|
110
|
+
dara_core-1.14.0a2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
111
|
+
dara_core-1.14.0a2.dist-info/entry_points.txt,sha256=H__D5sNIGuPIhVam0DChNL-To5k8Y7nY7TAFz9Mz6cc,139
|
|
112
|
+
dara_core-1.14.0a2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|