dara-core 1.21.25__py3-none-any.whl → 1.22.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.
@@ -16,19 +16,18 @@ limitations under the License.
16
16
  """
17
17
 
18
18
  import contextlib
19
- import importlib
20
19
  import json
21
20
  import os
22
- import pathlib
23
21
  import shutil
24
- import sys
25
22
  from enum import Enum
26
- from importlib.metadata import version
27
- from typing import Any, ClassVar, Literal, Optional, Union, cast
23
+ from importlib.metadata import EntryPoint, entry_points, version
24
+ from pathlib import Path
25
+ from typing import Any, ClassVar, Literal, Optional, Union
28
26
 
29
27
  from packaging.version import Version
30
28
  from pydantic import BaseModel
31
29
 
30
+ from dara.core.base_definitions import AssetManifest
32
31
  from dara.core.configuration import Configuration
33
32
  from dara.core.internal.settings import get_settings
34
33
  from dara.core.logging import dev_logger
@@ -63,7 +62,8 @@ class JsConfig(BaseModel):
63
62
  if not os.path.exists(path):
64
63
  return None
65
64
 
66
- return JsConfig.parse_file(path)
65
+ with open(path) as f:
66
+ return JsConfig.model_validate_json(f.read())
67
67
 
68
68
 
69
69
  class BuildConfig(BaseModel):
@@ -151,6 +151,10 @@ class BuildCache(BaseModel):
151
151
 
152
152
  FILENAME: ClassVar[str] = '_build.json'
153
153
 
154
+ def __init__(self, **data):
155
+ super().__init__(**data)
156
+ self._asset_manifests_cache: dict[str, AssetManifest] | None = None
157
+
154
158
  @staticmethod
155
159
  def from_config(config: Configuration, build_config: BuildConfig | None = None):
156
160
  """
@@ -274,11 +278,62 @@ class BuildCache(BaseModel):
274
278
  for module in self.package_map:
275
279
  py_modules.add(module)
276
280
 
277
- if 'dara.core' in py_modules:
278
- py_modules.remove('dara.core')
279
-
280
281
  return list(py_modules)
281
282
 
283
+ def get_asset_manifests(self) -> dict[str, AssetManifest]:
284
+ """
285
+ Get a map of package name to asset manifest for this BuildCache
286
+ """
287
+ # Return cached result if available
288
+ if self._asset_manifests_cache is not None:
289
+ return self._asset_manifests_cache
290
+
291
+ def _match_package_name(ep: EntryPoint) -> str | None:
292
+ """
293
+ Given an entrypoint module name, return the package name it matches
294
+ Tries matching the name or module name with the package_map keys
295
+ """
296
+ for pkg in self.package_map:
297
+ if ep.module.startswith(pkg):
298
+ return pkg
299
+ if ep.name == pkg:
300
+ return pkg
301
+
302
+ normalized = _normalize_dara_name(pkg)
303
+ if ep.module.startswith(normalized):
304
+ return pkg
305
+ if ep.name == normalized:
306
+ return pkg
307
+
308
+ return None
309
+
310
+ manifests = {}
311
+
312
+ eps = entry_points(group='dara_assets')
313
+
314
+ for ep in eps:
315
+ module = _match_package_name(ep)
316
+ # Unrecognized packages are ignored, name must match a package included
317
+ # Could be installed but not used
318
+ if module is None:
319
+ dev_logger.warning(
320
+ f'Unrecognized `dara_assets` entrypoint {ep.name}, skipping as no matching used package was found'
321
+ )
322
+ continue
323
+
324
+ manifest = ep.load()
325
+
326
+ if not isinstance(manifest, AssetManifest):
327
+ raise ValueError(
328
+ f'Invalid asset manifest entrypoint for {module}: {manifest}, expected instance of dara.core.base_definitions.AssetManifest'
329
+ )
330
+
331
+ manifests[module] = manifest
332
+
333
+ # Cache the result before returning
334
+ self._asset_manifests_cache = AssetManifest.topo_sort(manifests)
335
+ return self._asset_manifests_cache
336
+
282
337
  def get_package_json(self) -> dict[str, Any]:
283
338
  """
284
339
  Generate a package.json file for this BuildCache
@@ -333,7 +388,8 @@ class BuildCache(BaseModel):
333
388
  path = other or os.path.join(self.static_files_dir, BuildCache.FILENAME)
334
389
 
335
390
  try:
336
- other_cache = BuildCache.parse_file(path)
391
+ with open(path) as f:
392
+ other_cache = BuildCache.model_validate_json(f.read())
337
393
  except BaseException:
338
394
  return BuildCacheDiff.full_diff()
339
395
  else:
@@ -360,16 +416,16 @@ def setup_js_scaffolding():
360
416
  """
361
417
  Create a dara custom js config
362
418
  """
363
- jsconfig_template_path = os.path.join(pathlib.Path(__file__).parent.absolute(), 'templates/dara.config.json')
419
+ jsconfig_template_path = os.path.join(Path(__file__).parent.absolute(), 'templates/dara.config.json')
364
420
  js_config_path = os.path.join(os.getcwd(), 'dara.config.json')
365
421
 
366
422
  shutil.copyfile(jsconfig_template_path, js_config_path)
367
423
 
368
- js_scaffold_path = os.path.join(pathlib.Path(__file__).parent.absolute(), 'custom_js_scaffold')
424
+ js_scaffold_path = os.path.join(Path(__file__).parent.absolute(), 'custom_js_scaffold')
369
425
  shutil.copytree(js_scaffold_path, os.path.join(os.getcwd(), 'js'))
370
426
 
371
427
 
372
- def _copytree(src: str, dst: str):
428
+ def _copytree(src: str | Path, dst: str | Path):
373
429
  """
374
430
  Copy a directory recursively.
375
431
  Works like shutil.copytree, except replaces files if they already exist.
@@ -383,15 +439,21 @@ def _copytree(src: str, dst: str):
383
439
  shutil.copy2(from_file, to_file)
384
440
 
385
441
 
386
- def _get_py_version(package_name: str) -> str:
442
+ def _normalize_dara_name(package_name: str) -> str:
387
443
  """
388
- Get the python version for a given package name
444
+ Normalize a dara package name to a standard format
389
445
  """
390
446
  # For dara.* packages, replace . with -
391
447
  if package_name.startswith('dara.'):
392
448
  package_name = package_name.replace('.', '-')
449
+ return package_name
450
+
393
451
 
394
- return version(package_name)
452
+ def _get_py_version(package_name: str) -> str:
453
+ """
454
+ Get the python version for a given package name
455
+ """
456
+ return version(_normalize_dara_name(package_name))
395
457
 
396
458
 
397
459
  def _py_version_to_js(package_name: str) -> str:
@@ -425,20 +487,6 @@ def _py_version_to_js(package_name: str) -> str:
425
487
  return raw_version
426
488
 
427
489
 
428
- def _get_module_file(module: str) -> str:
429
- """
430
- Get the file containing the given module
431
-
432
- :param module: module name, e.g. 'dara.core'
433
- """
434
- try:
435
- return cast(str, sys.modules[module].__file__)
436
- except KeyError:
437
- # module wasn't imported, try to load it explicitly
438
- imported_module = importlib.import_module(module)
439
- return cast(str, imported_module.__file__)
440
-
441
-
442
490
  def rebuild_js(build_cache: BuildCache, build_diff: BuildCacheDiff | None = None):
443
491
  """
444
492
  Generic 'rebuild' function which bundles/prepares assets depending on the build mode chosen
@@ -469,12 +517,14 @@ def rebuild_js(build_cache: BuildCache, build_diff: BuildCacheDiff | None = None
469
517
 
470
518
  # JS rebuild required, run mode-specific logic
471
519
  if build_diff.should_rebuild_js():
472
- # If we are in autoJS mode, just prepare pre-built assets to be included directly
473
- if build_cache.build_config.mode == BuildMode.AUTO_JS:
474
- prepare_autojs_assets(build_cache)
475
- else:
520
+ migrate_package_assets(build_cache)
521
+
522
+ if build_cache.build_config.mode == BuildMode.PRODUCTION:
476
523
  # In production mode, build using Vite production build
477
524
  bundle_js(build_cache)
525
+ else:
526
+ # If we are in autoJS mode, also move pre-built assets
527
+ migrate_core_autojs_assets(build_cache)
478
528
 
479
529
  # Always migrate static assets
480
530
  build_cache.migrate_static_assets()
@@ -505,10 +555,10 @@ def bundle_js(build_cache: BuildCache, copy_js: bool = False):
505
555
  build_cache.symlink_js()
506
556
 
507
557
  # Determine template paths
508
- entry_template = os.path.join(pathlib.Path(__file__).parent.absolute(), 'templates/_entry.template.tsx')
509
- vite_template = os.path.join(pathlib.Path(__file__).parent.absolute(), 'templates/vite.config.template.ts')
510
- npmrc_template = os.path.join(pathlib.Path(__file__).parent.absolute(), 'templates/.npmrc')
511
- statics = os.path.join(pathlib.Path(__file__).parent.absolute(), 'statics')
558
+ entry_template = os.path.join(Path(__file__).parent.absolute(), 'templates/_entry.template.tsx')
559
+ vite_template = os.path.join(Path(__file__).parent.absolute(), 'templates/vite.config.template.ts')
560
+ npmrc_template = os.path.join(Path(__file__).parent.absolute(), 'templates/.npmrc')
561
+ statics = os.path.join(Path(__file__).parent.absolute(), 'statics')
512
562
 
513
563
  # Ensure the static files directory exists
514
564
  os.makedirs(build_cache.static_files_dir, exist_ok=True)
@@ -591,7 +641,54 @@ def bundle_js(build_cache: BuildCache, copy_js: bool = False):
591
641
  os.chdir(cwd)
592
642
 
593
643
 
594
- def prepare_autojs_assets(build_cache: BuildCache):
644
+ def migrate_package_assets(build_cache: BuildCache):
645
+ """
646
+ Migrate package assets based on asset manifests.
647
+ Handles common and autojs assets, moving them to the static_files_dir under the package name.
648
+
649
+ E.g.
650
+
651
+ ```
652
+ dara/core
653
+ - _assets/
654
+ - common/
655
+ - jquery.min.js
656
+ - auto_js/
657
+ - dara.core.umd.js
658
+ - dara.core.css
659
+ ```
660
+
661
+ Assuming `static_files_dir` is set to `dist/`, the above would result in:
662
+
663
+ ```
664
+ dist/
665
+ - dara.core/
666
+ - jquery.min.js
667
+ - dara.core.umd.js
668
+ - dara.core.css
669
+ ```
670
+
671
+ Files are nested to avoid name collisions.
672
+ """
673
+ for pkg, manifest in build_cache.get_asset_manifests().items():
674
+ (Path(build_cache.static_files_dir) / pkg).mkdir(parents=True, exist_ok=True)
675
+
676
+ try:
677
+ # Always move common assets
678
+ for cdn_asset in manifest.resolved_common_assets():
679
+ shutil.copy2(cdn_asset, Path(build_cache.static_files_dir) / pkg)
680
+
681
+ # In autojs mode, also copy autojs assets
682
+ if build_cache.build_config.mode == BuildMode.AUTO_JS:
683
+ for autojs_asset in manifest.resolved_autojs_assets():
684
+ shutil.copy2(autojs_asset, Path(build_cache.static_files_dir) / pkg)
685
+ except Exception as e:
686
+ available_assets = list(Path(manifest.base_path).glob('**/*'))
687
+ dev_logger.error(f'Failed to copy assets for package {pkg}, available assets: {available_assets}', error=e)
688
+ raise
689
+
690
+
691
+ def migrate_core_autojs_assets(build_cache: BuildCache):
595
692
  """
596
693
  Prepare the JS (and CSS) assets to use in autoJS mode.
597
694
  Copies over UMD pre-bundled files from loaded packages into static_files_dir directory,
@@ -599,11 +696,7 @@ def prepare_autojs_assets(build_cache: BuildCache):
599
696
 
600
697
  :param config: the main app configuration
601
698
  """
602
- # copy over dara.core js/css into static dir
603
- core_path = os.path.dirname(_get_module_file('dara.core'))
604
- core_js_path = os.path.join(core_path, 'umd', 'dara.core.umd.cjs')
605
- core_css_path = os.path.join(core_path, 'umd', 'style.css')
606
- statics = os.path.join(pathlib.Path(__file__).parent.absolute(), 'statics')
699
+ statics = os.path.join(Path(__file__).parent.absolute(), 'statics')
607
700
 
608
701
  # Copy dara-core statics, i.e. default favicon, tsconfig, etc.
609
702
  files = os.listdir(statics)
@@ -615,30 +708,31 @@ def prepare_autojs_assets(build_cache: BuildCache):
615
708
  if custom_favicon is not None:
616
709
  shutil.copyfile(custom_favicon, os.path.join(build_cache.static_files_dir, 'favicon.ico'))
617
710
 
618
- shutil.copy(core_js_path, os.path.join(build_cache.static_files_dir, 'dara.core.umd.js'))
619
- shutil.copy(core_css_path, os.path.join(build_cache.static_files_dir, 'dara.core.css'))
620
711
 
621
- py_modules = build_cache.get_py_modules()
712
+ def build_common_tags(build_cache: BuildCache) -> list[str]:
713
+ """
714
+ Build common HTML tags based on declared order in the asset manifests.
622
715
 
623
- # Copy over js/css for all modules
624
- for module_name in py_modules:
625
- # Get path to the module
626
- module_path = os.path.dirname(_get_module_file(module_name))
716
+ Excludes autojs assets.
717
+ """
718
+ settings = get_settings()
719
+ tags: list[str] = []
720
+
721
+ # Iterate in manifest topo order, and in tag_order - to ensure tags are added in the correct order
722
+ for pkg, manifest in build_cache.get_asset_manifests().items():
723
+ py_version = _get_py_version(pkg)
724
+
725
+ for path in manifest.tag_order:
726
+ if path not in manifest.common_assets:
727
+ continue
627
728
 
628
- # Build paths to the JS and CSS assets for the given module
629
- # Note: this assumes assets structure of module/umd folder with the module.umd.(c)js and style.css file
630
- js_asset_path = os.path.join(module_path, 'umd', f'{module_name}.umd.js')
631
- cjs_asset_path = os.path.join(module_path, 'umd', f'{module_name}.umd.cjs')
632
- css_asset_path = os.path.join(module_path, 'umd', 'style.css')
729
+ file_name = Path(path).name
633
730
 
634
- # copy over the JSS/CSS from python package into dist/umd so they are available under /static
635
- if os.path.exists(js_asset_path):
636
- shutil.copy(js_asset_path, os.path.join(build_cache.static_files_dir, f'{module_name}.umd.js'))
637
- elif os.path.exists(cjs_asset_path):
638
- shutil.copy(cjs_asset_path, os.path.join(build_cache.static_files_dir, f'{module_name}.umd.js'))
731
+ tags.append(
732
+ f'<script crossorigin src="{settings.dara_base_url}/static/{pkg}/{file_name}?v={py_version}"></script>'
733
+ )
639
734
 
640
- if os.path.exists(css_asset_path):
641
- shutil.copy(css_asset_path, os.path.join(build_cache.static_files_dir, f'{module_name}.css'))
735
+ return tags
642
736
 
643
737
 
644
738
  def build_autojs_template(build_cache: BuildCache, config: Configuration) -> dict[str, Any]:
@@ -652,7 +746,7 @@ def build_autojs_template(build_cache: BuildCache, config: Configuration) -> dic
652
746
  """
653
747
 
654
748
  settings = get_settings()
655
- entry_template = os.path.join(pathlib.Path(__file__).parent.absolute(), 'templates/_entry_autojs.template.tsx')
749
+ entry_template = os.path.join(Path(__file__).parent.absolute(), 'templates/_entry_autojs.template.tsx')
656
750
  with open(entry_template, encoding='utf-8') as f:
657
751
  entry_template_str = f.read()
658
752
 
@@ -667,34 +761,27 @@ def build_autojs_template(build_cache: BuildCache, config: Configuration) -> dic
667
761
  '$$extraJs$$', config.template_extra_js + '\n' + settings.dara_template_extra_js
668
762
  )
669
763
 
670
- core_version = _get_py_version('dara.core')
671
-
672
- package_tags: dict[str, list[str]] = {
673
- 'dara.core': [
674
- f'<script crossorigin src="{settings.dara_base_url}/static/dara.core.umd.js?v={core_version}"></script>',
675
- f'<link rel="stylesheet" href="{settings.dara_base_url}/static/dara.core.css?v={core_version}"></link>',
676
- ]
677
- }
678
-
679
- py_modules = build_cache.get_py_modules()
764
+ # In autojs mode, we add both autojs and common tags
765
+ package_tags: dict[str, list[str]] = {}
680
766
 
681
- for module_name in py_modules:
767
+ # topo-sorted modules
768
+ for module_name, manifest in build_cache.get_asset_manifests().items():
769
+ py_version = _get_py_version(module_name)
682
770
  module_tags = []
683
- version = _get_py_version(module_name)
684
771
 
685
- # Include tag for JS if file exists
686
- if os.path.exists(os.path.join(config.static_files_dir, f'{module_name}.umd.js')):
687
- js_tag = (
688
- f'<script crossorigin src="{settings.dara_base_url}/static/{module_name}.umd.js?v={version}"></script>'
689
- )
690
- module_tags.append(js_tag)
772
+ # respect tag_order in manifest
773
+ for asset_path in manifest.tag_order:
774
+ asset_name = Path(asset_path).name
691
775
 
692
- # Include tag for CSS if file exists
693
- if os.path.exists(os.path.join(config.static_files_dir, f'{module_name}.css')):
694
- css_tag = (
695
- f'<link rel="stylesheet" href="{settings.dara_base_url}/static/{module_name}.css?v={version}"></link>'
696
- )
697
- module_tags.append(css_tag)
776
+ # simple heuristic - .css is link, .js is script
777
+ if asset_name.endswith('.css'):
778
+ module_tags.append(
779
+ f'<link rel="stylesheet" href="{settings.dara_base_url}/static/{module_name}/{asset_name}?v={py_version}"></link>'
780
+ )
781
+ elif asset_name.endswith('.js') or asset_name.endswith('.cjs'):
782
+ module_tags.append(
783
+ f'<script crossorigin src="{settings.dara_base_url}/static/{module_name}/{asset_name}?v={py_version}"></script>'
784
+ )
698
785
 
699
786
  package_tags[module_name] = module_tags
700
787
 
@@ -706,12 +793,19 @@ def build_autojs_template(build_cache: BuildCache, config: Configuration) -> dic
706
793
  tags = [tag for tags in package_tags.values() for tag in tags]
707
794
 
708
795
  tags.append(f'<script type="module">{start_script}</script>')
709
- # Include tag for favicon
710
- tags.append(
711
- f'<link id="favicon" rel="icon" type="image/x-icon" href="{settings.dara_base_url}/static/favicon.ico"></link>'
712
- )
713
796
 
714
797
  return {
715
798
  'assets': '\n'.join(tags),
716
799
  'base_url': settings.dara_base_url,
717
800
  }
801
+
802
+
803
+ def build_vite_template(build_cache: BuildCache, config: Configuration) -> dict[str, Any]:
804
+ """
805
+ Build the vite template context
806
+ """
807
+ tags = build_common_tags(build_cache)
808
+
809
+ return {
810
+ 'common_tags': '\n'.join(tags),
811
+ }
dara/core/main.py CHANGED
@@ -31,8 +31,9 @@ from fastapi import FastAPI, HTTPException, Request
31
31
  from fastapi.encoders import ENCODERS_BY_TYPE, jsonable_encoder
32
32
  from fastapi.staticfiles import StaticFiles
33
33
  from prometheus_client import start_http_server
34
- from starlette.responses import FileResponse
34
+ from starlette.staticfiles import PathLike
35
35
  from starlette.templating import Jinja2Templates, _TemplateResponse
36
+ from starlette.types import Scope
36
37
 
37
38
  from dara.core.auth import auth_router
38
39
  from dara.core.configuration import Configuration, ConfigurationBuilder
@@ -70,6 +71,7 @@ from dara.core.js_tooling.js_utils import (
70
71
  BuildCache,
71
72
  BuildMode,
72
73
  build_autojs_template,
74
+ build_vite_template,
73
75
  rebuild_js,
74
76
  )
75
77
  from dara.core.logging import LoggingMiddleware, dev_logger, eng_logger, http_logger
@@ -77,12 +79,18 @@ from dara.core.router import convert_template_to_router
77
79
 
78
80
 
79
81
  class CacheStaticFiles(StaticFiles):
80
- async def get_response(self, path, scope):
81
- response = await super().get_response(path, scope)
82
- # add 1 year cache for static assets
83
- if isinstance(response, FileResponse) and path.endswith('.css') or path.endswith('.umd.js'):
84
- response.headers['Cache-Control'] = 'public, max-age=31536000'
85
- return response
82
+ def file_response(
83
+ self,
84
+ full_path: PathLike,
85
+ stat_result: os.stat_result,
86
+ scope: Scope,
87
+ status_code: int = 200,
88
+ ):
89
+ resp = super().file_response(full_path, stat_result, scope, status_code)
90
+ # add 1 year cache for static assets which are versioned or favicon
91
+ if '?v=' in str(full_path) or 'favicon.ico' in str(full_path):
92
+ resp.headers.setdefault('Cache-Control', 'public, max-age=31536000, immutable')
93
+ return resp
86
94
 
87
95
 
88
96
  def _start_application(config: Configuration):
@@ -430,6 +438,8 @@ def _start_application(config: Configuration):
430
438
  if build_cache.build_config.mode == BuildMode.AUTO_JS:
431
439
  template_name = 'index_autojs.html'
432
440
  context.update(build_autojs_template(build_cache, config))
441
+ else:
442
+ context.update(build_vite_template(build_cache, config))
433
443
 
434
444
  @app.get('/{full_path:path}', include_in_schema=False, response_class=_TemplateResponse)
435
445
  async def serve_app(full_path: str, request: Request):
@@ -152,7 +152,7 @@ class BaseRoute(BaseModel):
152
152
  the route path.
153
153
  """
154
154
 
155
- metadata: dict = Field(default_factory=dict, exclude=True)
155
+ metadata: dict[str, Any] = Field(default_factory=dict, exclude=True)
156
156
  """
157
157
  Metadata for the route. This is used to store arbitrary data that can be used by the application.
158
158
  """
@@ -353,7 +353,7 @@ class HasChildRoutes(BaseModel):
353
353
  case_sensitive: bool = False,
354
354
  name: str | None = None,
355
355
  id: str | None = None,
356
- metadata: dict | None = None,
356
+ metadata: dict[str, Any] | None = None,
357
357
  on_load: Action | None = None,
358
358
  fallback: ComponentInstance | None = None,
359
359
  ):
@@ -392,7 +392,7 @@ class HasChildRoutes(BaseModel):
392
392
  content: Callable[..., ComponentInstance] | ComponentInstance,
393
393
  case_sensitive: bool = False,
394
394
  id: str | None = None,
395
- metadata: dict | None = None,
395
+ metadata: dict[str, Any] | None = None,
396
396
  on_load: Action | None = None,
397
397
  fallback: ComponentInstance | None = None,
398
398
  ):
@@ -449,7 +449,7 @@ class HasChildRoutes(BaseModel):
449
449
  path: str,
450
450
  case_sensitive: bool = False,
451
451
  id: str | None = None,
452
- metadata: dict | None = None,
452
+ metadata: dict[str, Any] | None = None,
453
453
  on_load: Action | None = None,
454
454
  fallback: ComponentInstance | None = None,
455
455
  ):
@@ -493,7 +493,7 @@ class HasChildRoutes(BaseModel):
493
493
  case_sensitive: bool = False,
494
494
  name: str | None = None,
495
495
  id: str | None = None,
496
- metadata: dict | None = None,
496
+ metadata: dict[str, Any] | None = None,
497
497
  on_load: Action | None = None,
498
498
  fallback: ComponentInstance | None = None,
499
499
  ):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dara-core
3
- Version: 1.21.25
3
+ Version: 1.22.0
4
4
  Summary: Dara Framework Core
5
5
  Home-page: https://dara.causalens.com/
6
6
  License: Apache-2.0
@@ -21,10 +21,10 @@ Requires-Dist: cachetools (>=5.0.0,<6.0.0)
21
21
  Requires-Dist: certifi (>=2024.7.4)
22
22
  Requires-Dist: click (>=8.1.3,<9.0.0)
23
23
  Requires-Dist: colorama (>=0.4.6,<0.5.0)
24
- Requires-Dist: create-dara-app (==1.21.25)
24
+ Requires-Dist: create-dara-app (==1.22.0)
25
25
  Requires-Dist: croniter (>=6.0.0,<7.0.0)
26
26
  Requires-Dist: cryptography (>=42.0.4)
27
- Requires-Dist: dara-components (==1.21.25) ; extra == "all"
27
+ Requires-Dist: dara-components (==1.22.0) ; extra == "all"
28
28
  Requires-Dist: exceptiongroup (>=1.1.3,<2.0.0)
29
29
  Requires-Dist: fastapi (>=0.115.0,<0.121.0)
30
30
  Requires-Dist: fastapi_vite_dara (==0.4.0)
@@ -55,7 +55,7 @@ Description-Content-Type: text/markdown
55
55
 
56
56
  # Dara Application Framework
57
57
 
58
- <img src="https://github.com/causalens/dara/blob/v1.21.25/img/dara_light.svg?raw=true">
58
+ <img src="https://github.com/causalens/dara/blob/v1.22.0/img/dara_light.svg?raw=true">
59
59
 
60
60
  ![Master tests](https://github.com/causalens/dara/actions/workflows/tests.yml/badge.svg?branch=master)
61
61
  [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
@@ -100,7 +100,7 @@ source .venv/bin/activate
100
100
  dara start
101
101
  ```
102
102
 
103
- ![Dara App](https://github.com/causalens/dara/blob/v1.21.25/img/components_gallery.png?raw=true)
103
+ ![Dara App](https://github.com/causalens/dara/blob/v1.22.0/img/components_gallery.png?raw=true)
104
104
 
105
105
  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:
106
106
 
@@ -117,9 +117,9 @@ Explore some of our favorite apps - a great way of getting started and getting t
117
117
 
118
118
  | Dara App | Description |
119
119
  | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
120
- | ![Large Language Model](https://github.com/causalens/dara/blob/v1.21.25/img/llm.png?raw=true) | Demonstrates how to use incorporate a LLM chat box into your decision app to understand model insights |
121
- | ![Plot Interactivity](https://github.com/causalens/dara/blob/v1.21.25/img/plot_interactivity.png?raw=true) | 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 |
122
- | ![Graph Editor](https://github.com/causalens/dara/blob/v1.21.25/img/graph_viewer.png?raw=true) | 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. |
120
+ | ![Large Language Model](https://github.com/causalens/dara/blob/v1.22.0/img/llm.png?raw=true) | Demonstrates how to use incorporate a LLM chat box into your decision app to understand model insights |
121
+ | ![Plot Interactivity](https://github.com/causalens/dara/blob/v1.22.0/img/plot_interactivity.png?raw=true) | 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 |
122
+ | ![Graph Editor](https://github.com/causalens/dara/blob/v1.22.0/img/graph_viewer.png?raw=true) | 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. |
123
123
 
124
124
  Check out our [App Gallery](https://dara.causalens.com/gallery) for more inspiration!
125
125
 
@@ -146,9 +146,9 @@ And the supporting UI packages and tools.
146
146
  - `ui-utils` - miscellaneous utility functions
147
147
  - `ui-widgets` - widget components
148
148
 
149
- More information on the repository structure can be found in the [CONTRIBUTING.md](https://github.com/causalens/dara/blob/v1.21.25/CONTRIBUTING.md) file.
149
+ More information on the repository structure can be found in the [CONTRIBUTING.md](https://github.com/causalens/dara/blob/v1.22.0/CONTRIBUTING.md) file.
150
150
 
151
151
  ## License
152
152
 
153
- Dara is open-source and licensed under the [Apache 2.0 License](https://github.com/causalens/dara/blob/v1.21.25/LICENSE).
153
+ Dara is open-source and licensed under the [Apache 2.0 License](https://github.com/causalens/dara/blob/v1.22.0/LICENSE).
154
154
 
@@ -1,4 +1,13 @@
1
1
  dara/core/__init__.py,sha256=yTp-lXT0yy9XqLGYWlmjPgFG5g2eEg2KhKo8KheTHoo,1408
2
+ dara/core/_assets/__init__.py,sha256=13vMoWHvl1zcFcjNHh8lbTwWOvu4f7krYSco978qxwM,723
3
+ dara/core/_assets/auto_js/dara.core.css,sha256=yT3PKpi2sKI2-kQIF8xtVbTPQqgpK7-Ua7tfzDPuSsI,4095881
4
+ dara/core/_assets/auto_js/dara.core.umd.cjs,sha256=MAAtfLJqG-7TJoXDMv_PU6_ovsXLNYfsyBtxJk0gsbs,5158199
5
+ dara/core/_assets/auto_js/react-dom.development.js,sha256=vR2Fq5LXMKS5JsTo2CMl6oGCJT8scJV2wXSteTtx8aE,1077040
6
+ dara/core/_assets/auto_js/react-is.development.js,sha256=2IRgmaphdMq6wx2MbsmVUQ0UwapGETNjgano3XEkGcc,7932
7
+ dara/core/_assets/auto_js/react-query.development.js,sha256=lI2fTKMvWmjbagGQaVtZYr51_-C_U_so064JwetuDS0,130366
8
+ dara/core/_assets/auto_js/react.development.js,sha256=suVuJ5m2DeVlNaMn0ZXgSNv1ChQwTDU8DfFADyIHDdI,109928
9
+ dara/core/_assets/auto_js/styled-components.min.js,sha256=lkKPu9UEzt3nP-0GdH0T1xG1kJ89GHvB4oAcdU8NG2I,33596
10
+ dara/core/_assets/common/jquery.min.js,sha256=w8CvhFs7iHNVUtnSP0YKEg00p9Ih13rlL9zGqvLdePA,72535
2
11
  dara/core/actions.py,sha256=rC5Tu79AFNWMv0CJuchBnoy6pETIFh_1RTSqxrolArI,947
3
12
  dara/core/auth/__init__.py,sha256=H0bJoXff5wIRZmHvvQ3y9p5SXA9lM8OuLCGceYGqfb0,851
4
13
  dara/core/auth/base.py,sha256=fPkRXmgMYCbsED4SxRu3h729KIPi1PUSTeiGRLhUOm8,3263
@@ -6,7 +15,7 @@ dara/core/auth/basic.py,sha256=sglIaogCslG2HlDMjFsaaJhOJeXUW-QQLTIYPaUPxAU,4927
6
15
  dara/core/auth/definitions.py,sha256=DWvhvXTLQyJ0x-P_r4SycVOWht7R_us_ca2a4biJlTY,3379
7
16
  dara/core/auth/routes.py,sha256=dtOxpFotnt4XQ4spW3mbyM7ThYRvfIA_oRK5X5lyYHg,7256
8
17
  dara/core/auth/utils.py,sha256=12dbakr4DkZu8PjS57YlV79Oh-SVaqkoYliCSAseywQ,7307
9
- dara/core/base_definitions.py,sha256=JZWTgAGpnhH6PIcrzgFC-torkoTGzapQ_5bqzKCL-Fs,19108
18
+ dara/core/base_definitions.py,sha256=mwaeUjmS1SNMcj3IUHw6M4sNq0NkOozMpMQXS0EAD_s,21965
10
19
  dara/core/cli.py,sha256=i9-Xtdee80b153TSU9fFSWbHQYCi01ci_Lo8SzwnW7M,8130
11
20
  dara/core/configuration.py,sha256=PAxtnIF86kRh3D7DrdB3lxwl2QkA008aKSykvcLGlCE,23353
12
21
  dara/core/css.py,sha256=c1TMGzOcXYIy-qU-TxeirGlq2BNEigP80eDG3ItjRbU,1740
@@ -68,11 +77,11 @@ dara/core/internal/store.py,sha256=aq37Tk4J3DoqzLVHuZRbZFkpghKP-oiCbpQfIE95gCo,6
68
77
  dara/core/internal/tasks.py,sha256=qkJH3cu4o27SBKxkFjS_TUDispq0R0uHICKRbzMYOmU,35989
69
78
  dara/core/internal/utils.py,sha256=rlxxLXPVZ0SpzGDHEe2bqSTvOJCRD5Fn6YeUNflrWC4,9007
70
79
  dara/core/internal/websocket.py,sha256=etFWnCZwFg9aiLpjB1sMSfJUjPRvSAq_5RyOu_AH_dY,21864
71
- dara/core/jinja/index.html,sha256=5Sq_FwXn0F4dOyRFprfoh_tn0GUq6_aLYyYdpzQLdeM,3312
72
- dara/core/jinja/index_autojs.html,sha256=wkDPReUsMKfVvafFEawrj_3TdH8m_nliV0XuuGK8dyM,3884
80
+ dara/core/jinja/index.html,sha256=O3uyA9Hozwbqh--wQq5IHuLNEFUNf2BykWLGuIZqUjo,3025
81
+ dara/core/jinja/index_autojs.html,sha256=ov9qg_ymClTL9BdhZw86jS4UKC5jy5PufIrb9F7sy9w,3009
73
82
  dara/core/js_tooling/custom_js_scaffold/index.tsx,sha256=FEzSV5o5Nyzxw6eXvGLi7BkEBkXf3brV34_7ATLnY7o,68
74
83
  dara/core/js_tooling/custom_js_scaffold/local-js-component.tsx,sha256=Ojsyeh9MYJnH_XJXGkSc8PAUZIqJcqcGTu_uRITo_88,709
75
- dara/core/js_tooling/js_utils.py,sha256=uGQK55ysRth2Ji4FkbXVweJOpwbZ5CvFt5UC0hwsNyE,27506
84
+ dara/core/js_tooling/js_utils.py,sha256=eZgt-gidj0yaxbu87cVzslTOCstBOfBouSlH3ouT8XI,29960
76
85
  dara/core/js_tooling/statics/favicon.ico,sha256=CJP26erMMIwQB8FFmyhoUJ-Cx1cXEopiVGxFwyxcpo0,47068
77
86
  dara/core/js_tooling/statics/tsconfig.json,sha256=ubnFjwvPHbx2F7wVWsU2VHLDeEnnOwXkTIk7hLNY8ZM,446
78
87
  dara/core/js_tooling/templates/.npmrc,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -82,7 +91,7 @@ dara/core/js_tooling/templates/dara.config.json,sha256=RZG_R_xJv_5rYIoz2QZulcG49
82
91
  dara/core/js_tooling/templates/vite.config.template.ts,sha256=W-R9LtXPMv7vQkqMawMmeFrjaQ22xrGU0iYyS_nHkh4,1199
83
92
  dara/core/log_configs/logging.yaml,sha256=YJyD18psAmSVz6587dcEOyoulLuRFFu1g8yMXl1ylM0,706
84
93
  dara/core/logging.py,sha256=Exe8dz8sbE1NDwRnqSoPCTnWtYe8BPLrO1n9gJQ1neQ,13214
85
- dara/core/main.py,sha256=-5ODqC0e2r8zh48tg0owv5-V-vyvT7_ASUSacek3qHs,20960
94
+ dara/core/main.py,sha256=QQZ0KflOHX8OLHpOyvwesmczDt03F6FRH5FVNDwlIdY,21253
86
95
  dara/core/metrics/__init__.py,sha256=2UqpWHv-Ie58QLJIHJ9Szfjq8xifAuwy5FYGUIFwWtI,823
87
96
  dara/core/metrics/cache.py,sha256=3Sw2JWofa1vxc39NwQ8LOdTd9sX3gkrPSojjjnr-u1I,2594
88
97
  dara/core/metrics/runtime.py,sha256=YP-6Dz0GeI9_Yr7bUk_-OqShyFySGH_AKpDO126l6es,1833
@@ -92,9 +101,7 @@ dara/core/router/__init__.py,sha256=yGI_MgLQU37ircCtYVNjnhqCjWQxKd5amoNqvMyrhOs,
92
101
  dara/core/router/compat.py,sha256=B83wq46AwQARTDfZwGrpr0slrnQmi_T7shOUNpqltSM,3112
93
102
  dara/core/router/components.py,sha256=Wsf_bBnnN-1EE5jhbjPSOyDv_TVKEsY4royyOQOazM4,6132
94
103
  dara/core/router/dependency_graph.py,sha256=A0xGuZWSOCGs7rwHbeZC5vLvZouUt-2fnEX9VM2Ukp0,2280
95
- dara/core/router/router.py,sha256=cjIOOD2UpjdxvvDBnOegfso37AbalKekVLpsdbcTMOk,32543
96
- dara/core/umd/dara.core.umd.cjs,sha256=ukclcCaCGe0D3b-SkwMXmcxUV7XnlG5F2gvCm8lHOdQ,5155131
97
- dara/core/umd/style.css,sha256=yT3PKpi2sKI2-kQIF8xtVbTPQqgpK7-Ua7tfzDPuSsI,4095881
104
+ dara/core/router/router.py,sha256=ys3k48pIjTdbmch5516O4TAeo8IIUPThdqgeoXC-kMQ,32593
98
105
  dara/core/visual/__init__.py,sha256=QN0wbG9HPQ_vXh8BO8DnBXeYLIENVTNtRmYzZf1lx7c,577
99
106
  dara/core/visual/components/__init__.py,sha256=Jrh38Q4Lc8iFFVKPuEaDeloYHVLohTTHgK92u1e_ZtY,2515
100
107
  dara/core/visual/components/dynamic_component.py,sha256=F_UxogMQ9I5GB6BLqDmGaojRQyOOmwJBB5kaIk1iPpI,867
@@ -121,8 +128,8 @@ dara/core/visual/themes/__init__.py,sha256=aM4mgoIYo2neBSw5FRzswsht7PUKjLthiHLmF
121
128
  dara/core/visual/themes/dark.py,sha256=QazCRDqh_SCOyQhdwMkH1wbHf301oL7gCFj91plbLww,2020
122
129
  dara/core/visual/themes/definitions.py,sha256=dtET2YUlwXkO6gJ23MqSb8gIq-LxJ343CWsgueWSifM,2787
123
130
  dara/core/visual/themes/light.py,sha256=dtHb6Q1HOb5r_AvJfe0vZajikVc-GnBEUrGsTcI5MHA,2022
124
- dara_core-1.21.25.dist-info/LICENSE,sha256=r9u1w2RvpLMV6YjuXHIKXRBKzia3fx_roPwboGcLqCc,10944
125
- dara_core-1.21.25.dist-info/METADATA,sha256=UGtLYAygR13NWBAN_Nx6BmlF_Qcww8g_DVC73D8eu5E,7541
126
- dara_core-1.21.25.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
127
- dara_core-1.21.25.dist-info/entry_points.txt,sha256=H__D5sNIGuPIhVam0DChNL-To5k8Y7nY7TAFz9Mz6cc,139
128
- dara_core-1.21.25.dist-info/RECORD,,
131
+ dara_core-1.22.0.dist-info/LICENSE,sha256=r9u1w2RvpLMV6YjuXHIKXRBKzia3fx_roPwboGcLqCc,10944
132
+ dara_core-1.22.0.dist-info/METADATA,sha256=D9hUg61jHsWQv5LLS4JnSB5aREJcxR-K6cv-aco37tw,7531
133
+ dara_core-1.22.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
134
+ dara_core-1.22.0.dist-info/entry_points.txt,sha256=nAT9o1kJCmTK1saDh29PFGFD6cbxDDDjTj31HDEDwfU,197
135
+ dara_core-1.22.0.dist-info/RECORD,,