squirrels 0.4.1__py3-none-any.whl → 0.5.0rc0__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.
Potentially problematic release.
This version of squirrels might be problematic. Click here for more details.
- squirrels/__init__.py +10 -6
- squirrels/_api_response_models.py +93 -44
- squirrels/_api_server.py +571 -219
- squirrels/_auth.py +451 -0
- squirrels/_command_line.py +61 -20
- squirrels/_connection_set.py +38 -25
- squirrels/_constants.py +44 -34
- squirrels/_dashboards_io.py +34 -16
- squirrels/_exceptions.py +57 -0
- squirrels/_initializer.py +117 -44
- squirrels/_manifest.py +124 -62
- squirrels/_model_builder.py +111 -0
- squirrels/_model_configs.py +74 -0
- squirrels/_model_queries.py +52 -0
- squirrels/_models.py +860 -354
- squirrels/_package_loader.py +8 -4
- squirrels/_parameter_configs.py +45 -65
- squirrels/_parameter_sets.py +15 -13
- squirrels/_project.py +561 -0
- squirrels/_py_module.py +4 -3
- squirrels/_seeds.py +35 -16
- squirrels/_sources.py +106 -0
- squirrels/_utils.py +166 -63
- squirrels/_version.py +1 -1
- squirrels/arguments/init_time_args.py +78 -15
- squirrels/arguments/run_time_args.py +62 -101
- squirrels/dashboards.py +4 -4
- squirrels/data_sources.py +94 -162
- squirrels/dataset_result.py +86 -0
- squirrels/dateutils.py +4 -4
- squirrels/package_data/base_project/.env +30 -0
- squirrels/package_data/base_project/.env.example +30 -0
- squirrels/package_data/base_project/.gitignore +3 -2
- squirrels/package_data/base_project/assets/expenses.db +0 -0
- squirrels/package_data/base_project/connections.yml +11 -3
- squirrels/package_data/base_project/dashboards/dashboard_example.py +15 -13
- squirrels/package_data/base_project/dashboards/dashboard_example.yml +22 -0
- squirrels/package_data/base_project/docker/.dockerignore +5 -2
- squirrels/package_data/base_project/docker/Dockerfile +3 -3
- squirrels/package_data/base_project/docker/compose.yml +1 -1
- squirrels/package_data/base_project/duckdb_init.sql +9 -0
- squirrels/package_data/base_project/macros/macros_example.sql +15 -0
- squirrels/package_data/base_project/models/builds/build_example.py +26 -0
- squirrels/package_data/base_project/models/builds/build_example.sql +16 -0
- squirrels/package_data/base_project/models/builds/build_example.yml +55 -0
- squirrels/package_data/base_project/models/dbviews/dbview_example.sql +12 -22
- squirrels/package_data/base_project/models/dbviews/dbview_example.yml +26 -0
- squirrels/package_data/base_project/models/federates/federate_example.py +38 -15
- squirrels/package_data/base_project/models/federates/federate_example.sql +16 -2
- squirrels/package_data/base_project/models/federates/federate_example.yml +65 -0
- squirrels/package_data/base_project/models/sources.yml +39 -0
- squirrels/package_data/base_project/parameters.yml +36 -21
- squirrels/package_data/base_project/pyconfigs/connections.py +6 -11
- squirrels/package_data/base_project/pyconfigs/context.py +20 -33
- squirrels/package_data/base_project/pyconfigs/parameters.py +19 -21
- squirrels/package_data/base_project/pyconfigs/user.py +23 -0
- squirrels/package_data/base_project/seeds/seed_categories.yml +15 -0
- squirrels/package_data/base_project/seeds/seed_subcategories.csv +15 -15
- squirrels/package_data/base_project/seeds/seed_subcategories.yml +21 -0
- squirrels/package_data/base_project/squirrels.yml.j2 +17 -40
- squirrels/parameters.py +20 -20
- {squirrels-0.4.1.dist-info → squirrels-0.5.0rc0.dist-info}/METADATA +31 -32
- squirrels-0.5.0rc0.dist-info/RECORD +70 -0
- {squirrels-0.4.1.dist-info → squirrels-0.5.0rc0.dist-info}/WHEEL +1 -1
- squirrels-0.5.0rc0.dist-info/entry_points.txt +3 -0
- {squirrels-0.4.1.dist-info → squirrels-0.5.0rc0.dist-info/licenses}/LICENSE +1 -1
- squirrels/_authenticator.py +0 -85
- squirrels/_environcfg.py +0 -84
- squirrels/package_data/assets/favicon.ico +0 -0
- squirrels/package_data/assets/index.css +0 -1
- squirrels/package_data/assets/index.js +0 -58
- squirrels/package_data/base_project/dashboards.yml +0 -10
- squirrels/package_data/base_project/env.yml +0 -29
- squirrels/package_data/base_project/models/dbviews/dbview_example.py +0 -47
- squirrels/package_data/base_project/pyconfigs/auth.py +0 -45
- squirrels/package_data/templates/index.html +0 -18
- squirrels/project.py +0 -378
- squirrels/user_base.py +0 -55
- squirrels-0.4.1.dist-info/RECORD +0 -60
- squirrels-0.4.1.dist-info/entry_points.txt +0 -4
|
@@ -1,36 +1,46 @@
|
|
|
1
|
-
from typing import
|
|
2
|
-
|
|
3
|
-
from sqlalchemy import Engine
|
|
4
|
-
import pandas as pd
|
|
1
|
+
from typing import Callable, Any, Coroutine
|
|
2
|
+
import polars as pl
|
|
5
3
|
|
|
6
|
-
from .init_time_args import
|
|
7
|
-
from ..
|
|
4
|
+
from .init_time_args import _WithConnectionDictArgs, ParametersArgs, BuildModelArgs, ConnectionsArgs
|
|
5
|
+
from .._auth import BaseUser
|
|
8
6
|
from ..parameters import Parameter, TextValue
|
|
9
|
-
from .. import _utils as _u
|
|
10
7
|
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
class AuthArgs(ConnectionsArgs):
|
|
14
|
-
_connections: dict[str, Engine]
|
|
15
|
-
username: str
|
|
16
|
-
password: str
|
|
9
|
+
class AuthLoginArgs(_WithConnectionDictArgs):
|
|
17
10
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
def __init__(
|
|
12
|
+
self, conn_args: ConnectionsArgs, _connections: dict[str, Any],
|
|
13
|
+
username: str,
|
|
14
|
+
password: str
|
|
15
|
+
):
|
|
16
|
+
super().__init__(conn_args.project_path, conn_args.proj_vars, conn_args.env_vars, _connections)
|
|
17
|
+
self.username = username
|
|
18
|
+
self.password = password
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AuthTokenArgs(_WithConnectionDictArgs):
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self, conn_args: ConnectionsArgs, _connections: dict[str, Any],
|
|
25
|
+
token: str
|
|
26
|
+
):
|
|
27
|
+
super().__init__(conn_args.project_path, conn_args.proj_vars, conn_args.env_vars, _connections)
|
|
28
|
+
self.token = token
|
|
26
29
|
|
|
27
30
|
|
|
28
|
-
@dataclass
|
|
29
31
|
class ContextArgs(ParametersArgs):
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self, param_args: ParametersArgs,
|
|
35
|
+
user: BaseUser | None,
|
|
36
|
+
prms: dict[str, Parameter],
|
|
37
|
+
traits: dict[str, Any]
|
|
38
|
+
):
|
|
39
|
+
super().__init__(param_args.project_path, param_args.proj_vars, param_args.env_vars)
|
|
40
|
+
self.user = user
|
|
41
|
+
self._prms = prms
|
|
42
|
+
self._traits = traits
|
|
43
|
+
self._placeholders = {}
|
|
34
44
|
|
|
35
45
|
@property
|
|
36
46
|
def prms(self) -> dict[str, Parameter]:
|
|
@@ -80,9 +90,25 @@ class ContextArgs(ParametersArgs):
|
|
|
80
90
|
return (param_name in self.prms and self.prms[param_name].is_enabled())
|
|
81
91
|
|
|
82
92
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
93
|
+
class ModelArgs(BuildModelArgs, ContextArgs):
|
|
94
|
+
|
|
95
|
+
def __init__(
|
|
96
|
+
self, ctx_args: ContextArgs, build_model_args: BuildModelArgs,
|
|
97
|
+
ctx: dict[str, Any]
|
|
98
|
+
):
|
|
99
|
+
super(ContextArgs, self).__init__(ctx_args.project_path, ctx_args.proj_vars, ctx_args.env_vars)
|
|
100
|
+
self._project_path = ctx_args.project_path
|
|
101
|
+
self._proj_vars = ctx_args.proj_vars
|
|
102
|
+
self._env_vars = ctx_args.env_vars
|
|
103
|
+
self.user = ctx_args.user
|
|
104
|
+
self._prms = ctx_args.prms
|
|
105
|
+
self._traits = ctx_args.traits
|
|
106
|
+
self._placeholders = ctx_args.placeholders
|
|
107
|
+
self._connections = build_model_args.connections
|
|
108
|
+
self._dependencies = build_model_args.dependencies
|
|
109
|
+
self._ref = build_model_args.ref
|
|
110
|
+
self._run_external_sql = build_model_args.run_external_sql
|
|
111
|
+
self._ctx = ctx
|
|
86
112
|
|
|
87
113
|
@property
|
|
88
114
|
def ctx(self) -> dict[str, Any]:
|
|
@@ -90,32 +116,6 @@ class ModelDepsArgs(ContextArgs):
|
|
|
90
116
|
Dictionary of context variables
|
|
91
117
|
"""
|
|
92
118
|
return self._ctx.copy()
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
@dataclass
|
|
96
|
-
class ModelArgs(ModelDepsArgs):
|
|
97
|
-
connection_name: str
|
|
98
|
-
_connections: dict[str, Engine]
|
|
99
|
-
_dependencies: Iterable[str]
|
|
100
|
-
_ref: Callable[[str], pd.DataFrame]
|
|
101
|
-
_run_external_sql: Callable[[str, str | None], pd.DataFrame]
|
|
102
|
-
_use_duckdb: bool
|
|
103
|
-
|
|
104
|
-
@property
|
|
105
|
-
def connections(self) -> dict[str, Engine]:
|
|
106
|
-
"""
|
|
107
|
-
A dictionary of connection keys to SQLAlchemy Engines for database connections.
|
|
108
|
-
|
|
109
|
-
Can also be used to store other in-memory objects in advance such as ML models.
|
|
110
|
-
"""
|
|
111
|
-
return self._connections.copy()
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def dependencies(self) -> set[str]:
|
|
115
|
-
"""
|
|
116
|
-
The set of dependent data model names
|
|
117
|
-
"""
|
|
118
|
-
return set(self._dependencies)
|
|
119
119
|
|
|
120
120
|
def is_placeholder(self, placeholder: str) -> bool:
|
|
121
121
|
"""
|
|
@@ -142,57 +142,18 @@ class ModelArgs(ModelDepsArgs):
|
|
|
142
142
|
An type for the value of the placeholder
|
|
143
143
|
"""
|
|
144
144
|
return self._placeholders.get(placeholder)
|
|
145
|
-
|
|
146
|
-
def ref(self, model: str) -> pd.DataFrame:
|
|
147
|
-
"""
|
|
148
|
-
Returns the result (as pandas DataFrame) of a dependent model (predefined in "dependencies" function)
|
|
149
145
|
|
|
150
|
-
Note: This is different behaviour than the "ref" function for SQL models, which figures out the dependent models for you,
|
|
151
|
-
and returns a string for the table/view name in SQLite instead of a pandas DataFrame.
|
|
152
146
|
|
|
153
|
-
Arguments:
|
|
154
|
-
model: The model name
|
|
155
|
-
|
|
156
|
-
Returns:
|
|
157
|
-
A pandas DataFrame
|
|
158
|
-
"""
|
|
159
|
-
return self._ref(model)
|
|
160
|
-
|
|
161
|
-
def run_external_sql(self, sql_query: str, *, connection_name: str | None = None, **kwargs) -> pd.DataFrame:
|
|
162
|
-
"""
|
|
163
|
-
Runs a SQL query against an external database, with option to specify the connection name. Placeholder values are provided automatically
|
|
164
|
-
|
|
165
|
-
Arguments:
|
|
166
|
-
sql_query: The SQL query. Can be parameterized with placeholders
|
|
167
|
-
connection_name: The connection name for the database. If None, uses the one configured for the model
|
|
168
|
-
|
|
169
|
-
Returns:
|
|
170
|
-
The query result as a pandas DataFrame
|
|
171
|
-
"""
|
|
172
|
-
return self._run_external_sql(sql_query, connection_name)
|
|
173
|
-
|
|
174
|
-
def run_sql_on_dataframes(self, sql_query: str, *, dataframes: dict[str, pd.DataFrame] | None = None, **kwargs) -> pd.DataFrame:
|
|
175
|
-
"""
|
|
176
|
-
Uses a dictionary of dataframes to execute a SQL query in an embedded in-memory database (sqlite or duckdb based on setting)
|
|
177
|
-
|
|
178
|
-
Arguments:
|
|
179
|
-
sql_query: The SQL query to run
|
|
180
|
-
dataframes: A dictionary of table names to their pandas Dataframe. If None, uses results of dependent models
|
|
181
|
-
|
|
182
|
-
Returns:
|
|
183
|
-
The result as a pandas Dataframe from running the query
|
|
184
|
-
"""
|
|
185
|
-
if dataframes is None:
|
|
186
|
-
dataframes = {x: self.ref(x) for x in self._dependencies}
|
|
187
|
-
|
|
188
|
-
return _u.run_sql_on_dataframes(sql_query, dataframes, self._use_duckdb)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
@dataclass
|
|
192
147
|
class DashboardArgs(ParametersArgs):
|
|
193
|
-
_get_dataset: Callable[[str, dict[str, Any]], Coroutine[Any, Any, pd.DataFrame]]
|
|
194
148
|
|
|
195
|
-
|
|
149
|
+
def __init__(
|
|
150
|
+
self, param_args: ParametersArgs,
|
|
151
|
+
get_dataset: Callable[[str, dict[str, Any]], Coroutine[Any, Any, pl.DataFrame]]
|
|
152
|
+
):
|
|
153
|
+
super().__init__(param_args.project_path, param_args.proj_vars, param_args.env_vars)
|
|
154
|
+
self._get_dataset = get_dataset
|
|
155
|
+
|
|
156
|
+
async def dataset(self, name: str, *, fixed_parameters: dict[str, Any] = {}) -> pl.DataFrame:
|
|
196
157
|
"""
|
|
197
158
|
Get dataset as DataFrame given dataset name. Can use this to access protected/private datasets regardless of user authenticated to the dashboard.
|
|
198
159
|
|
squirrels/dashboards.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import matplotlib.figure as _figure, io as _io, abc as _abc, typing as _t
|
|
2
2
|
|
|
3
|
-
from . import _constants as
|
|
3
|
+
from . import _constants as c
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class Dashboard(metaclass=_abc.ABCMeta):
|
|
@@ -33,7 +33,7 @@ class PngDashboard(Dashboard):
|
|
|
33
33
|
"""
|
|
34
34
|
if isinstance(content, _figure.Figure):
|
|
35
35
|
buffer = _io.BytesIO()
|
|
36
|
-
content.savefig(buffer, format=
|
|
36
|
+
content.savefig(buffer, format=c.PNG)
|
|
37
37
|
content = buffer.getvalue()
|
|
38
38
|
|
|
39
39
|
if isinstance(content, _io.BytesIO):
|
|
@@ -47,7 +47,7 @@ class PngDashboard(Dashboard):
|
|
|
47
47
|
|
|
48
48
|
@property
|
|
49
49
|
def _format(self) -> _t.Literal['png']:
|
|
50
|
-
return
|
|
50
|
+
return c.PNG
|
|
51
51
|
|
|
52
52
|
def _repr_png_(self):
|
|
53
53
|
return self._content
|
|
@@ -76,7 +76,7 @@ class HtmlDashboard(Dashboard):
|
|
|
76
76
|
|
|
77
77
|
@property
|
|
78
78
|
def _format(self) -> _t.Literal['html']:
|
|
79
|
-
return
|
|
79
|
+
return c.HTML
|
|
80
80
|
|
|
81
81
|
def _repr_html_(self):
|
|
82
82
|
return self._content
|