dara-core 1.14.8__py3-none-any.whl → 1.15.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.
- dara/core/internal/routing.py +2 -1
- dara/core/internal/websocket.py +31 -11
- dara/core/persistence.py +3 -2
- dara/core/umd/dara.core.umd.js +33 -23
- {dara_core-1.14.8.dist-info → dara_core-1.15.0.dist-info}/METADATA +10 -10
- {dara_core-1.14.8.dist-info → dara_core-1.15.0.dist-info}/RECORD +9 -9
- {dara_core-1.14.8.dist-info → dara_core-1.15.0.dist-info}/LICENSE +0 -0
- {dara_core-1.14.8.dist-info → dara_core-1.15.0.dist-info}/WHEEL +0 -0
- {dara_core-1.14.8.dist-info → dara_core-1.15.0.dist-info}/entry_points.txt +0 -0
dara/core/internal/routing.py
CHANGED
|
@@ -490,10 +490,11 @@ def create_router(config: Configuration):
|
|
|
490
490
|
return result
|
|
491
491
|
|
|
492
492
|
@core_api_router.post('/store', dependencies=[Depends(verify_session)])
|
|
493
|
-
async def sync_backend_store(values: Dict[str, Any] = Body()):
|
|
493
|
+
async def sync_backend_store(ws_channel: str = Body(), values: Dict[str, Any] = Body()):
|
|
494
494
|
registry_mgr: RegistryLookup = utils_registry.get('RegistryLookup')
|
|
495
495
|
|
|
496
496
|
async def _write(store_uid: str, value: Any):
|
|
497
|
+
WS_CHANNEL.set(ws_channel)
|
|
497
498
|
store_entry: BackendStoreEntry = await registry_mgr.get(backend_store_registry, store_uid)
|
|
498
499
|
result = store_entry.store.write(value)
|
|
499
500
|
|
dara/core/internal/websocket.py
CHANGED
|
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
14
14
|
See the License for the specific language governing permissions and
|
|
15
15
|
limitations under the License.
|
|
16
16
|
"""
|
|
17
|
+
|
|
17
18
|
import asyncio
|
|
18
19
|
import inspect
|
|
19
20
|
import math
|
|
@@ -26,7 +27,7 @@ import anyio
|
|
|
26
27
|
from anyio import Event, create_memory_object_stream, create_task_group
|
|
27
28
|
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
|
|
28
29
|
from exceptiongroup import catch
|
|
29
|
-
from fastapi import
|
|
30
|
+
from fastapi import Query, WebSocketException
|
|
30
31
|
from fastapi.encoders import jsonable_encoder
|
|
31
32
|
from jwt import DecodeError
|
|
32
33
|
from pydantic import BaseModel, Field, parse_obj_as
|
|
@@ -80,6 +81,7 @@ class CustomClientMessage(BaseModel):
|
|
|
80
81
|
|
|
81
82
|
ClientMessage = Union[DaraClientMessage, CustomClientMessage]
|
|
82
83
|
|
|
84
|
+
|
|
83
85
|
# Server message types
|
|
84
86
|
class ServerMessagePayload(BaseModel):
|
|
85
87
|
rchan: Optional[str] = Field(default=None, alias='__rchan')
|
|
@@ -117,7 +119,7 @@ class DaraServerMessage(BaseModel):
|
|
|
117
119
|
"""
|
|
118
120
|
|
|
119
121
|
type: Literal['message'] = Field(default='message', const=True)
|
|
120
|
-
message: ServerMessagePayload
|
|
122
|
+
message: ServerMessagePayload # exact messages expected by frontend are defined in js/api/websocket.tsx
|
|
121
123
|
|
|
122
124
|
|
|
123
125
|
class CustomServerMessage(BaseModel):
|
|
@@ -204,7 +206,10 @@ class WebSocketHandler:
|
|
|
204
206
|
existing_messages.append(message.message)
|
|
205
207
|
else:
|
|
206
208
|
existing_messages = [message.message]
|
|
207
|
-
self.pending_responses[message_id] = (
|
|
209
|
+
self.pending_responses[message_id] = (
|
|
210
|
+
event,
|
|
211
|
+
existing_messages,
|
|
212
|
+
)
|
|
208
213
|
|
|
209
214
|
# If all chunks have been received, set the event to notify the waiting coroutine
|
|
210
215
|
if len(existing_messages) == message.chunk_count:
|
|
@@ -235,7 +240,9 @@ class WebSocketHandler:
|
|
|
235
240
|
await self.send_message(
|
|
236
241
|
CustomServerMessage(
|
|
237
242
|
message=CustomServerMessagePayload(
|
|
238
|
-
kind=kind,
|
|
243
|
+
kind=kind,
|
|
244
|
+
data=response,
|
|
245
|
+
__response_for=message.message.rchan,
|
|
239
246
|
)
|
|
240
247
|
)
|
|
241
248
|
)
|
|
@@ -249,7 +256,9 @@ class WebSocketHandler:
|
|
|
249
256
|
return self.send_message(
|
|
250
257
|
CustomServerMessage(
|
|
251
258
|
message=CustomServerMessagePayload(
|
|
252
|
-
kind=kind,
|
|
259
|
+
kind=kind,
|
|
260
|
+
data=response,
|
|
261
|
+
__response_for=message.message.rchan,
|
|
253
262
|
)
|
|
254
263
|
)
|
|
255
264
|
)
|
|
@@ -312,6 +321,9 @@ class WebsocketManager:
|
|
|
312
321
|
|
|
313
322
|
def __init__(self):
|
|
314
323
|
self.handlers: Dict[str, WebSocketHandler] = {}
|
|
324
|
+
"""
|
|
325
|
+
A mapping of channel IDs to WebSocketHandler instances.
|
|
326
|
+
"""
|
|
315
327
|
|
|
316
328
|
def _construct_message(self, payload: LoosePayload, custom: bool) -> ServerMessage:
|
|
317
329
|
"""
|
|
@@ -335,24 +347,30 @@ class WebsocketManager:
|
|
|
335
347
|
self.handlers[channel_id] = handler
|
|
336
348
|
return handler
|
|
337
349
|
|
|
338
|
-
async def broadcast(self, message: LoosePayload, custom=False):
|
|
350
|
+
async def broadcast(self, message: LoosePayload, custom=False, ignore_channel: Optional[str] = None):
|
|
339
351
|
"""
|
|
340
352
|
Send a message to all connected clients.
|
|
341
353
|
|
|
342
354
|
:param message: The message to send
|
|
343
355
|
:param custom: Whether the message is a custom message
|
|
356
|
+
:param ignore_channel: A channel ID to ignore when broadcasting
|
|
344
357
|
"""
|
|
345
358
|
async with anyio.create_task_group() as tg:
|
|
346
359
|
for handler in self.handlers.values():
|
|
360
|
+
if ignore_channel is not None and handler.channel_id == ignore_channel:
|
|
361
|
+
continue
|
|
347
362
|
tg.start_soon(handler.send_message, self._construct_message(message, custom))
|
|
348
363
|
|
|
349
|
-
async def send_message_to_user(
|
|
364
|
+
async def send_message_to_user(
|
|
365
|
+
self, user_id: str, message: LoosePayload, custom=False, ignore_channel: Optional[str] = None
|
|
366
|
+
):
|
|
350
367
|
"""
|
|
351
368
|
Send a message to all connected channels associated with the given user.
|
|
352
369
|
|
|
353
370
|
:param user_id: The user ID to send the message to
|
|
354
371
|
:param message: The message payload to send
|
|
355
372
|
:param custom: Whether the message is a custom message
|
|
373
|
+
:param ignore_channel: A channel ID to ignore when sending
|
|
356
374
|
"""
|
|
357
375
|
channels = get_user_channels(user_id)
|
|
358
376
|
|
|
@@ -361,6 +379,8 @@ class WebsocketManager:
|
|
|
361
379
|
|
|
362
380
|
async with anyio.create_task_group() as tg:
|
|
363
381
|
for channel in channels:
|
|
382
|
+
if ignore_channel is not None and channel == ignore_channel:
|
|
383
|
+
continue
|
|
364
384
|
tg.start_soon(self.send_message, channel, message, custom)
|
|
365
385
|
|
|
366
386
|
async def send_message(self, channel_id: str, message: LoosePayload, custom=False):
|
|
@@ -405,7 +425,7 @@ async def ws_handler(websocket: WebSocket, token: Optional[str] = Query(default=
|
|
|
405
425
|
:param token: The authentication token
|
|
406
426
|
"""
|
|
407
427
|
if token is None:
|
|
408
|
-
raise
|
|
428
|
+
raise WebSocketException(code=403, reason='Token missing from websocket connection query parameter')
|
|
409
429
|
|
|
410
430
|
from dara.core.auth.definitions import ID_TOKEN, SESSION_ID, USER, UserData
|
|
411
431
|
from dara.core.internal.registries import (
|
|
@@ -420,10 +440,10 @@ async def ws_handler(websocket: WebSocket, token: Optional[str] = Query(default=
|
|
|
420
440
|
|
|
421
441
|
try:
|
|
422
442
|
token_content: TokenData = decode_token(token)
|
|
423
|
-
except DecodeError:
|
|
424
|
-
raise
|
|
443
|
+
except DecodeError as err:
|
|
444
|
+
raise WebSocketException(code=403, reason='Invalid or expired token') from err
|
|
425
445
|
except AuthError as err:
|
|
426
|
-
raise
|
|
446
|
+
raise WebSocketException(code=403, reason=str(err.detail)) from err
|
|
427
447
|
|
|
428
448
|
# Register once accepted - map session id to the channel so subsequent requests can identify the client
|
|
429
449
|
if websocket_registry.has(token_content.session_id):
|
dara/core/persistence.py
CHANGED
|
@@ -10,6 +10,7 @@ from pydantic import BaseModel, Field, PrivateAttr, validator
|
|
|
10
10
|
|
|
11
11
|
from dara.core.auth.definitions import USER
|
|
12
12
|
from dara.core.internal.utils import run_user_handler
|
|
13
|
+
from dara.core.internal.websocket import WS_CHANNEL
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
16
|
from dara.core.interactivity.plain_variable import Variable
|
|
@@ -257,7 +258,7 @@ class BackendStore(PersistenceStore):
|
|
|
257
258
|
msg = {'store_uid': self.uid, 'value': value}
|
|
258
259
|
|
|
259
260
|
if self.scope == 'global':
|
|
260
|
-
return await ws_mgr.broadcast(msg)
|
|
261
|
+
return await ws_mgr.broadcast(msg, ignore_channel=WS_CHANNEL.get())
|
|
261
262
|
|
|
262
263
|
# For user scope, we need to find channels for the user and notify them
|
|
263
264
|
user = USER.get()
|
|
@@ -266,7 +267,7 @@ class BackendStore(PersistenceStore):
|
|
|
266
267
|
return
|
|
267
268
|
|
|
268
269
|
user_identifier = user.identity_id or user.identity_name
|
|
269
|
-
return await ws_mgr.send_message_to_user(user_identifier, msg)
|
|
270
|
+
return await ws_mgr.send_message_to_user(user_identifier, msg, ignore_channel=WS_CHANNEL.get())
|
|
270
271
|
|
|
271
272
|
async def init(self, variable: 'Variable'):
|
|
272
273
|
"""
|
dara/core/umd/dara.core.umd.js
CHANGED
|
@@ -56448,6 +56448,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
|
|
|
56448
56448
|
}
|
|
56449
56449
|
initialize(isReconnect = false) {
|
|
56450
56450
|
const url = new URL(__privateGet(this, _socketUrl));
|
|
56451
|
+
this.token = store.getValueSync(getTokenKey());
|
|
56451
56452
|
url.searchParams.set("token", this.token);
|
|
56452
56453
|
const socket = new WebSocket(url);
|
|
56453
56454
|
__privateSet(this, _pingInterval, setInterval(() => {
|
|
@@ -56591,6 +56592,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
|
|
|
56591
56592
|
}
|
|
56592
56593
|
}
|
|
56593
56594
|
updateToken(newToken) {
|
|
56595
|
+
this.token = newToken;
|
|
56594
56596
|
if (this.socket.readyState === WebSocket.OPEN) {
|
|
56595
56597
|
this.socket.send(
|
|
56596
56598
|
JSON.stringify({
|
|
@@ -56598,7 +56600,6 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
|
|
|
56598
56600
|
type: "token_update"
|
|
56599
56601
|
})
|
|
56600
56602
|
);
|
|
56601
|
-
this.token = newToken;
|
|
56602
56603
|
}
|
|
56603
56604
|
}
|
|
56604
56605
|
sendCustomMessage(kind, data, awaitResponse = false) {
|
|
@@ -58143,30 +58144,39 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
|
|
|
58143
58144
|
const val = await response.json();
|
|
58144
58145
|
return val;
|
|
58145
58146
|
}, []);
|
|
58146
|
-
const syncStoreValues = React__namespace.useCallback(
|
|
58147
|
-
|
|
58148
|
-
|
|
58149
|
-
const
|
|
58150
|
-
|
|
58151
|
-
extrasMap.
|
|
58147
|
+
const syncStoreValues = React__namespace.useCallback(
|
|
58148
|
+
async ({ diff }) => {
|
|
58149
|
+
const extrasMap = /* @__PURE__ */ new Map();
|
|
58150
|
+
for (const [itemKey, value] of diff.entries()) {
|
|
58151
|
+
const extras = STORE_EXTRAS_MAP.get(itemKey);
|
|
58152
|
+
if (!extrasMap.has(extras)) {
|
|
58153
|
+
extrasMap.set(extras, {});
|
|
58154
|
+
}
|
|
58155
|
+
extrasMap.get(extras)[itemKey] = value;
|
|
58156
|
+
}
|
|
58157
|
+
async function sendRequest(serializableExtras, storeDiff) {
|
|
58158
|
+
const response = await request(
|
|
58159
|
+
`/api/core/store`,
|
|
58160
|
+
{
|
|
58161
|
+
body: JSON.stringify({
|
|
58162
|
+
values: storeDiff,
|
|
58163
|
+
ws_channel: await client.getChannel()
|
|
58164
|
+
}),
|
|
58165
|
+
method: "POST"
|
|
58166
|
+
},
|
|
58167
|
+
serializableExtras.extras
|
|
58168
|
+
);
|
|
58169
|
+
await handleAuthErrors(response, true);
|
|
58170
|
+
await validateResponse(response, `Failed to sync the store values`);
|
|
58152
58171
|
}
|
|
58153
|
-
|
|
58154
|
-
|
|
58155
|
-
|
|
58156
|
-
|
|
58157
|
-
`/api/core/store`,
|
|
58158
|
-
{ body: JSON.stringify(storeDiff), method: "POST" },
|
|
58159
|
-
serializableExtras.extras
|
|
58172
|
+
await Promise.allSettled(
|
|
58173
|
+
Array.from(extrasMap.entries()).map(
|
|
58174
|
+
([serializableExtras, storeDiff]) => sendRequest(serializableExtras, storeDiff)
|
|
58175
|
+
)
|
|
58160
58176
|
);
|
|
58161
|
-
|
|
58162
|
-
|
|
58163
|
-
|
|
58164
|
-
await Promise.allSettled(
|
|
58165
|
-
Array.from(extrasMap.entries()).map(
|
|
58166
|
-
([serializableExtras, storeDiff]) => sendRequest(serializableExtras, storeDiff)
|
|
58167
|
-
)
|
|
58168
|
-
);
|
|
58169
|
-
}, []);
|
|
58177
|
+
},
|
|
58178
|
+
[client]
|
|
58179
|
+
);
|
|
58170
58180
|
const listenToStoreChanges = React__namespace.useCallback(
|
|
58171
58181
|
({ updateItem }) => {
|
|
58172
58182
|
if (!client) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dara-core
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.15.0
|
|
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.
|
|
23
|
+
Requires-Dist: create-dara-app (==1.15.0)
|
|
24
24
|
Requires-Dist: croniter (>=1.0.15,<3.0.0)
|
|
25
25
|
Requires-Dist: cryptography (>=42.0.4)
|
|
26
|
-
Requires-Dist: dara-components (==1.
|
|
26
|
+
Requires-Dist: dara-components (==1.15.0) ; 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_dara (==0.3.1.0)
|
|
@@ -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.
|
|
54
|
+
<img src="https://github.com/causalens/dara/blob/v1.15.0/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.
|
|
145
|
+
More information on the repository structure can be found in the [CONTRIBUTING.md](https://github.com/causalens/dara/blob/v1.15.0/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.
|
|
149
|
+
Dara is open-source and licensed under the [Apache 2.0 License](https://github.com/causalens/dara/blob/v1.15.0/LICENSE).
|
|
150
150
|
|
|
@@ -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=XViBysQSchhX9yoFyDoGe4r5OQ8xMfn6rvA2fi8Yd70,22847
|
|
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=yj_IVDfwyjPmljY-9NWktaM0QGG50KrWQERWrpfNn00,21480
|
|
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
|
|
@@ -80,8 +80,8 @@ dara/core/metrics/__init__.py,sha256=2UqpWHv-Ie58QLJIHJ9Szfjq8xifAuwy5FYGUIFwWtI
|
|
|
80
80
|
dara/core/metrics/cache.py,sha256=ybofUhZO0TCHeyhB_AtldWk1QTmTKh7GucTXpOkeTFA,2580
|
|
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
|
-
dara/core/persistence.py,sha256=
|
|
84
|
-
dara/core/umd/dara.core.umd.js,sha256=
|
|
83
|
+
dara/core/persistence.py,sha256=9GBLhK_so-T-DnNOVT3zo7mHXNjwIU2TzgcIOr7XEro,10497
|
|
84
|
+
dara/core/umd/dara.core.umd.js,sha256=AjBfi7G00OO78EvnWerCpfruED4xAI4PiKgApSQ2HIM,4879029
|
|
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.
|
|
109
|
-
dara_core-1.
|
|
110
|
-
dara_core-1.
|
|
111
|
-
dara_core-1.
|
|
112
|
-
dara_core-1.
|
|
108
|
+
dara_core-1.15.0.dist-info/LICENSE,sha256=r9u1w2RvpLMV6YjuXHIKXRBKzia3fx_roPwboGcLqCc,10944
|
|
109
|
+
dara_core-1.15.0.dist-info/METADATA,sha256=IhMXPa_0o-eECRfArK7m9tXmrGTPYB8k8elFdHI86ME,7390
|
|
110
|
+
dara_core-1.15.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
111
|
+
dara_core-1.15.0.dist-info/entry_points.txt,sha256=H__D5sNIGuPIhVam0DChNL-To5k8Y7nY7TAFz9Mz6cc,139
|
|
112
|
+
dara_core-1.15.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|