dara-core 1.22.4__py3-none-any.whl → 1.23.0a1__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/utils.py CHANGED
@@ -17,12 +17,11 @@ limitations under the License.
17
17
 
18
18
  import asyncio
19
19
  import uuid
20
- from collections.abc import Callable
20
+ from collections.abc import Awaitable, Callable
21
21
  from datetime import datetime, timedelta, timezone
22
22
  from typing import Any
23
23
 
24
24
  import jwt
25
- from anyio import to_thread
26
25
 
27
26
  from dara.core.auth.definitions import (
28
27
  EXPIRED_TOKEN_ERROR,
@@ -187,7 +186,9 @@ Shared token refresh cache instance
187
186
 
188
187
 
189
188
  async def cached_refresh_token(
190
- do_refresh_token: Callable[[TokenData, str], tuple[str, str]], old_token_data: TokenData, refresh_token: str
189
+ do_refresh_token: Callable[[TokenData, str], Awaitable[tuple[str, str]]],
190
+ old_token_data: TokenData,
191
+ refresh_token: str,
191
192
  ):
192
193
  """
193
194
  A utility to run a token refresh method with caching to prevent multiple concurrent refreshes
@@ -214,7 +215,7 @@ async def cached_refresh_token(
214
215
  return cached_result
215
216
 
216
217
  # Run the refresh function
217
- result = await to_thread.run_sync(do_refresh_token, old_token_data, refresh_token)
218
+ result = await do_refresh_token(old_token_data, refresh_token)
218
219
 
219
220
  # update cache
220
221
  token_refresh_cache.set_cached_value(cache_key, result)
@@ -582,6 +582,10 @@ class ConfigurationBuilder:
582
582
  if len(self._errors) > 0:
583
583
  raise ValueError('This configuration has errors: \n' + '\n'.join(self._errors))
584
584
 
585
+ # Merge selected auth config's configuration
586
+ all_startup_functions = [self.auth_config.startup_hook, *self.startup_functions]
587
+ all_routes = [*self.auth_config.required_routes, *self.routes]
588
+
585
589
  return Configuration(
586
590
  actions=self._actions,
587
591
  auth_config=self.auth_config,
@@ -595,11 +599,11 @@ class ConfigurationBuilder:
595
599
  pages=self._pages,
596
600
  powered_by_causalens=self.powered_by_causalens,
597
601
  package_tag_processors=self._package_tags_processors,
598
- routes=self.routes,
602
+ routes=all_routes,
599
603
  router=self.router,
600
604
  static_files_dir=self.static_files_dir,
601
605
  scheduled_jobs=self.scheduled_jobs,
602
- startup_functions=self.startup_functions,
606
+ startup_functions=all_startup_functions,
603
607
  static_folders=self._static_folders,
604
608
  task_module=self.task_module,
605
609
  template=self.template,
@@ -35,15 +35,6 @@ class Settings(BaseSettings):
35
35
  # Feature flags
36
36
  cgroup_memory_limit_enabled: bool = False
37
37
 
38
- # SSO envs
39
- sso_issuer_url: str = 'https://login.causalens.com/api/authentication'
40
- sso_client_id: str = ''
41
- sso_client_secret: str = ''
42
- sso_redirect_uri: str = ''
43
- sso_groups: str = ''
44
- sso_jwt_algo: str = 'ES256'
45
- sso_verify_audience: bool = False
46
- sso_extra_audience: list[str] | None = None
47
38
  model_config = SettingsConfigDict(env_file='.env', extra='allow')
48
39
 
49
40
 
@@ -53,12 +44,6 @@ def generate_env_content():
53
44
  """
54
45
  env_content = {
55
46
  'JWT_SECRET': token_hex(32),
56
- 'SSO_ISSUER_URL': '',
57
- 'SSO_CLIENT_ID': '',
58
- 'SSO_CLIENT_SECRET': '',
59
- 'SSO_REDIRECT_URI': '',
60
- 'SSO_GROUPS': 'Everyone',
61
- 'SSO_VERIFY_AUDIENCE': False,
62
47
  }
63
48
  return '\n'.join(f'{key}={value}' for key, value in env_content.items())
64
49
 
@@ -86,7 +71,8 @@ def get_settings():
86
71
 
87
72
  env_error = False
88
73
 
89
- # Generate .env file if it's missing
74
+ # Generate .env file if it's missing - this is to persistn the JWT_SECRET so
75
+ # tokens are valid across restarts
90
76
  if not os.path.isfile(os.path.join(os.getcwd(), '.env')):
91
77
  dev_logger.debug('.env file not found, generating the file...')
92
78
  try:
@@ -99,15 +85,4 @@ def get_settings():
99
85
  if env_error:
100
86
  settings_kwargs['_env_file'] = None
101
87
 
102
- # If AUDIENCE sso env variants are provided, use them and force verify audience to True
103
- # SSO_VERIFY_AUDIENCE can be set explicitly to False to override this behavior.
104
- dotenv_vals = dotenv_values(os.path.join(os.getcwd(), '.env')) if not env_error else {}
105
- audience_id = os.environ.get('SSO_AUDIENCE_CLIENT_ID', dotenv_vals.get('SSO_AUDIENCE_CLIENT_ID'))
106
- audience_secret = os.environ.get('SSO_AUDIENCE_CLIENT_SECRET', dotenv_vals.get('SSO_AUDIENCE_CLIENT_SECRET'))
107
- enable_audience_check = os.environ.get('SSO_VERIFY_AUDIENCE', dotenv_vals.get('SSO_VERIFY_AUDIENCE'))
108
- if enable_audience_check != 'False' and audience_id is not None and audience_secret is not None:
109
- return Settings(
110
- sso_client_id=audience_id, sso_client_secret=audience_secret, sso_verify_audience=True, **settings_kwargs
111
- )
112
-
113
88
  return Settings(**settings_kwargs)
@@ -162,15 +162,10 @@ def enforce_sso(conf: ConfigurationBuilder):
162
162
 
163
163
  Raises if SSO is not used
164
164
  """
165
- try:
166
- from dara.enterprise import SSOAuthConfig # pyright: ignore[reportMissingImports]
167
-
168
- if conf.auth_config is None or not isinstance(conf.auth_config, SSOAuthConfig):
169
- raise ValueError('Config does not have SSO auth enabled. Please update your application to configure SSO.')
170
- except ImportError as err:
171
- raise ValueError(
172
- 'SSO is not enabled. Please install the dara_enterprise package and configure SSO to use this feature.'
173
- ) from err
165
+ from dara.core.auth.oidc.config import OIDCAuthConfig
166
+
167
+ if conf.auth_config is None or not isinstance(conf.auth_config, OIDCAuthConfig):
168
+ raise ValueError('Config does not have SSO auth enabled. Please update your application to configure SSO.')
174
169
 
175
170
 
176
171
  P = ParamSpec('P')
@@ -39,9 +39,6 @@ from pydantic import (
39
39
  )
40
40
  from starlette.websockets import WebSocket, WebSocketDisconnect
41
41
 
42
- from dara.core.auth.base import BaseAuthConfig
43
- from dara.core.auth.definitions import AuthError, TokenData
44
- from dara.core.auth.utils import decode_token
45
42
  from dara.core.base_definitions import DaraBaseModel as BaseModel
46
43
  from dara.core.logging import dev_logger, eng_logger
47
44
 
@@ -434,7 +431,9 @@ async def ws_handler(websocket: WebSocket, token: str | None = Query(default=Non
434
431
  if token is None:
435
432
  raise WebSocketException(code=403, reason='Token missing from websocket connection query parameter')
436
433
 
437
- from dara.core.auth.definitions import ID_TOKEN, SESSION_ID, USER, UserData
434
+ from dara.core.auth.base import BaseAuthConfig
435
+ from dara.core.auth.definitions import ID_TOKEN, SESSION_ID, USER, AuthError, TokenData, UserData
436
+ from dara.core.auth.utils import decode_token
438
437
  from dara.core.internal.registries import (
439
438
  auth_registry,
440
439
  pending_tokens_registry,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dara-core
3
- Version: 1.22.4
3
+ Version: 1.23.0a1
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)
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.22.4)
24
+ Requires-Dist: create-dara-app (==1.23.0-alpha.1)
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.22.4) ; extra == "all"
27
+ Requires-Dist: dara-components (==1.23.0-alpha.1) ; 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.22.4/img/dara_light.svg?raw=true">
58
+ <img src="https://github.com/causalens/dara/blob/v1.23.0-alpha.1/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.22.4/img/components_gallery.png?raw=true)
103
+ ![Dara App](https://github.com/causalens/dara/blob/v1.23.0-alpha.1/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.22.4/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.4/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.4/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.23.0-alpha.1/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.23.0-alpha.1/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.23.0-alpha.1/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.22.4/CONTRIBUTING.md) file.
149
+ More information on the repository structure can be found in the [CONTRIBUTING.md](https://github.com/causalens/dara/blob/v1.23.0-alpha.1/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.22.4/LICENSE).
153
+ Dara is open-source and licensed under the [Apache 2.0 License](https://github.com/causalens/dara/blob/v1.23.0-alpha.1/LICENSE).
154
154
 
@@ -1,7 +1,7 @@
1
1
  dara/core/__init__.py,sha256=yTp-lXT0yy9XqLGYWlmjPgFG5g2eEg2KhKo8KheTHoo,1408
2
2
  dara/core/_assets/__init__.py,sha256=13vMoWHvl1zcFcjNHh8lbTwWOvu4f7krYSco978qxwM,723
3
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
4
+ dara/core/_assets/auto_js/dara.core.umd.cjs,sha256=T9MOYSRnuHnraSboQ7NcfodV8vrBkNGISoCZQCuc4Ec,5163725
5
5
  dara/core/_assets/auto_js/react-dom.development.js,sha256=vR2Fq5LXMKS5JsTo2CMl6oGCJT8scJV2wXSteTtx8aE,1077040
6
6
  dara/core/_assets/auto_js/react-is.development.js,sha256=2IRgmaphdMq6wx2MbsmVUQ0UwapGETNjgano3XEkGcc,7932
7
7
  dara/core/_assets/auto_js/react-query.development.js,sha256=lI2fTKMvWmjbagGQaVtZYr51_-C_U_so064JwetuDS0,130366
@@ -9,15 +9,21 @@ dara/core/_assets/auto_js/react.development.js,sha256=suVuJ5m2DeVlNaMn0ZXgSNv1Ch
9
9
  dara/core/_assets/auto_js/styled-components.min.js,sha256=lkKPu9UEzt3nP-0GdH0T1xG1kJ89GHvB4oAcdU8NG2I,33596
10
10
  dara/core/_assets/common/jquery.min.js,sha256=w8CvhFs7iHNVUtnSP0YKEg00p9Ih13rlL9zGqvLdePA,72535
11
11
  dara/core/actions.py,sha256=rC5Tu79AFNWMv0CJuchBnoy6pETIFh_1RTSqxrolArI,947
12
- dara/core/auth/__init__.py,sha256=H0bJoXff5wIRZmHvvQ3y9p5SXA9lM8OuLCGceYGqfb0,851
13
- dara/core/auth/base.py,sha256=fPkRXmgMYCbsED4SxRu3h729KIPi1PUSTeiGRLhUOm8,3263
12
+ dara/core/auth/__init__.py,sha256=HJoYIVPzbpwzN_RUHjGpSJj4o5TmHz9yFyZGiRiObCk,906
13
+ dara/core/auth/base.py,sha256=NJmUJqA-W8AVKIQbX_0BoHoZqtU1Iz6cJ16RKdcdIyU,3642
14
14
  dara/core/auth/basic.py,sha256=sglIaogCslG2HlDMjFsaaJhOJeXUW-QQLTIYPaUPxAU,4927
15
- dara/core/auth/definitions.py,sha256=DWvhvXTLQyJ0x-P_r4SycVOWht7R_us_ca2a4biJlTY,3379
15
+ dara/core/auth/definitions.py,sha256=OzJshDLuut8MaM_pbfyQFkSlUuMNBWNszA57jRXF0Cg,3848
16
+ dara/core/auth/oidc/__init__.py,sha256=UWdhFvDqLCoILaKVWbmrrJgiMgg9wlVZgCxRvf_HGHM,65
17
+ dara/core/auth/oidc/config.py,sha256=5rDxbr3wVZdjIz8USYNeUmKwKfeucHtLgfXwM3_weaE,20835
18
+ dara/core/auth/oidc/definitions.py,sha256=KLlUl2Y7n6prX0JSAwPde6J43iMs6uUY07OG7kumRPw,17568
19
+ dara/core/auth/oidc/routes.py,sha256=uvNHYUieaXy9hu6MYe_5eZvflX5TmFaIv6EGpCRP-dw,5335
20
+ dara/core/auth/oidc/settings.py,sha256=k1CKDTUKSFoCEp1ASI_R5L_lsNkFzjfAymMMIMmI1AE,2097
21
+ dara/core/auth/oidc/utils.py,sha256=IL17tStRNpkAQI3M17nrzGeb4xr47zSLPo4wT7LMwBQ,5145
16
22
  dara/core/auth/routes.py,sha256=dtOxpFotnt4XQ4spW3mbyM7ThYRvfIA_oRK5X5lyYHg,7256
17
- dara/core/auth/utils.py,sha256=12dbakr4DkZu8PjS57YlV79Oh-SVaqkoYliCSAseywQ,7307
23
+ dara/core/auth/utils.py,sha256=_aHZ98qMJ0VLE9Zfvj5biPARhe973_eyTx2qxnufzRE,7290
18
24
  dara/core/base_definitions.py,sha256=mwaeUjmS1SNMcj3IUHw6M4sNq0NkOozMpMQXS0EAD_s,21965
19
25
  dara/core/cli.py,sha256=i9-Xtdee80b153TSU9fFSWbHQYCi01ci_Lo8SzwnW7M,8130
20
- dara/core/configuration.py,sha256=PAxtnIF86kRh3D7DrdB3lxwl2QkA008aKSykvcLGlCE,23353
26
+ dara/core/configuration.py,sha256=Zy9wj2VDZd-mo4xAo3oSe8mJ0NHT6eYxz4hhqIJ9rXo,23565
21
27
  dara/core/css.py,sha256=c1TMGzOcXYIy-qU-TxeirGlq2BNEigP80eDG3ItjRbU,1740
22
28
  dara/core/data_utils.py,sha256=haR-SPCFm90RfOIndPBGOpFtOEmhiJgizmzcqzZOZBg,12455
23
29
  dara/core/defaults.py,sha256=ejSXYKm78vd0_3b-3x6K8lffU-7BWyEhqQuwdBkkWwU,4884
@@ -72,11 +78,11 @@ dara/core/internal/registry.py,sha256=Wqt7tEOmf5bR8D6lFIcLd3W1EtlENT364vRhxSqeOI
72
78
  dara/core/internal/registry_lookup.py,sha256=XgZ4PL4RLyKWNTXkh08lL6mmU492xgdPUsvFKA6pKDY,2411
73
79
  dara/core/internal/routing.py,sha256=C4_GLsXHueQ2Q4VVDgrY9bezr3YGZFdL6Yfs6C81Op8,26458
74
80
  dara/core/internal/scheduler.py,sha256=3LYdWAyFp8N1s9Xfud9XYwUbjcHpI-hCay3jZ5zRAiQ,12991
75
- dara/core/internal/settings.py,sha256=tlJmmpN_bSwxIZPJcb9EyUcCxicV4LM0xj2G6Qvj_9A,3900
81
+ dara/core/internal/settings.py,sha256=2g-PIoYVLlGoBNKoXTIbkH1FGV8TXUXRdwuhQ6cTrkE,2614
76
82
  dara/core/internal/store.py,sha256=aq37Tk4J3DoqzLVHuZRbZFkpghKP-oiCbpQfIE95gCo,6399
77
83
  dara/core/internal/tasks.py,sha256=qkJH3cu4o27SBKxkFjS_TUDispq0R0uHICKRbzMYOmU,35989
78
- dara/core/internal/utils.py,sha256=rlxxLXPVZ0SpzGDHEe2bqSTvOJCRD5Fn6YeUNflrWC4,9007
79
- dara/core/internal/websocket.py,sha256=etFWnCZwFg9aiLpjB1sMSfJUjPRvSAq_5RyOu_AH_dY,21864
84
+ dara/core/internal/utils.py,sha256=vcrqnV8e4jvewS14w7RizAmerVWBwcqHjTEe5rcgARE,8766
85
+ dara/core/internal/websocket.py,sha256=nkxLdRPzGSNFM_JHKDyT8codIHPtbbziwpOv2i00XiE,21834
80
86
  dara/core/jinja/index.html,sha256=O3uyA9Hozwbqh--wQq5IHuLNEFUNf2BykWLGuIZqUjo,3025
81
87
  dara/core/jinja/index_autojs.html,sha256=ov9qg_ymClTL9BdhZw86jS4UKC5jy5PufIrb9F7sy9w,3009
82
88
  dara/core/js_tooling/custom_js_scaffold/index.tsx,sha256=FEzSV5o5Nyzxw6eXvGLi7BkEBkXf3brV34_7ATLnY7o,68
@@ -128,8 +134,8 @@ dara/core/visual/themes/__init__.py,sha256=aM4mgoIYo2neBSw5FRzswsht7PUKjLthiHLmF
128
134
  dara/core/visual/themes/dark.py,sha256=QazCRDqh_SCOyQhdwMkH1wbHf301oL7gCFj91plbLww,2020
129
135
  dara/core/visual/themes/definitions.py,sha256=dtET2YUlwXkO6gJ23MqSb8gIq-LxJ343CWsgueWSifM,2787
130
136
  dara/core/visual/themes/light.py,sha256=dtHb6Q1HOb5r_AvJfe0vZajikVc-GnBEUrGsTcI5MHA,2022
131
- dara_core-1.22.4.dist-info/LICENSE,sha256=r9u1w2RvpLMV6YjuXHIKXRBKzia3fx_roPwboGcLqCc,10944
132
- dara_core-1.22.4.dist-info/METADATA,sha256=kasdTO9djraqpTHeJ3mC-TXl-bVKyD3Fuzz_lmPclwA,7524
133
- dara_core-1.22.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
134
- dara_core-1.22.4.dist-info/entry_points.txt,sha256=nAT9o1kJCmTK1saDh29PFGFD6cbxDDDjTj31HDEDwfU,197
135
- dara_core-1.22.4.dist-info/RECORD,,
137
+ dara_core-1.23.0a1.dist-info/LICENSE,sha256=r9u1w2RvpLMV6YjuXHIKXRBKzia3fx_roPwboGcLqCc,10944
138
+ dara_core-1.23.0a1.dist-info/METADATA,sha256=WH9TER9_ycRXWaU40zxhvD5teCWhUbExsBay21YHW_w,7598
139
+ dara_core-1.23.0a1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
140
+ dara_core-1.23.0a1.dist-info/entry_points.txt,sha256=nAT9o1kJCmTK1saDh29PFGFD6cbxDDDjTj31HDEDwfU,197
141
+ dara_core-1.23.0a1.dist-info/RECORD,,