squirrels 0.1.1.post1__py3-none-any.whl → 0.2.0.dev0__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 -16
- squirrels/_api_server.py +234 -80
- squirrels/_authenticator.py +84 -0
- squirrels/_command_line.py +60 -72
- squirrels/_connection_set.py +96 -0
- squirrels/_constants.py +114 -33
- squirrels/_environcfg.py +77 -0
- squirrels/_initializer.py +126 -67
- squirrels/_manifest.py +195 -168
- squirrels/_models.py +495 -0
- squirrels/_package_loader.py +26 -0
- squirrels/_parameter_configs.py +401 -0
- squirrels/_parameter_sets.py +188 -0
- squirrels/_py_module.py +60 -0
- squirrels/_timer.py +36 -0
- squirrels/_utils.py +81 -49
- squirrels/_version.py +2 -2
- squirrels/arguments/init_time_args.py +32 -0
- squirrels/arguments/run_time_args.py +82 -0
- squirrels/data_sources.py +380 -155
- squirrels/dateutils.py +86 -57
- squirrels/package_data/base_project/Dockerfile +15 -0
- squirrels/package_data/base_project/connections.yml +7 -0
- squirrels/package_data/base_project/database/{sample_database.db → expenses.db} +0 -0
- squirrels/package_data/base_project/environcfg.yml +29 -0
- squirrels/package_data/base_project/ignores/.dockerignore +8 -0
- squirrels/package_data/base_project/ignores/.gitignore +7 -0
- squirrels/package_data/base_project/models/dbviews/database_view1.py +36 -0
- squirrels/package_data/base_project/models/dbviews/database_view1.sql +15 -0
- squirrels/package_data/base_project/models/federates/dataset_example.py +20 -0
- squirrels/package_data/base_project/models/federates/dataset_example.sql +3 -0
- squirrels/package_data/base_project/parameters.yml +109 -0
- squirrels/package_data/base_project/pyconfigs/auth.py +47 -0
- squirrels/package_data/base_project/pyconfigs/connections.py +28 -0
- squirrels/package_data/base_project/pyconfigs/context.py +45 -0
- squirrels/package_data/base_project/pyconfigs/parameters.py +55 -0
- squirrels/package_data/base_project/seeds/mocks/category.csv +3 -0
- squirrels/package_data/base_project/seeds/mocks/max_filter.csv +2 -0
- squirrels/package_data/base_project/seeds/mocks/subcategory.csv +6 -0
- squirrels/package_data/base_project/squirrels.yml.j2 +57 -0
- squirrels/package_data/base_project/tmp/.gitignore +2 -0
- squirrels/package_data/static/script.js +159 -63
- squirrels/package_data/static/style.css +79 -15
- squirrels/package_data/static/widgets.js +133 -0
- squirrels/package_data/templates/index.html +65 -23
- squirrels/package_data/templates/index2.html +22 -0
- squirrels/parameter_options.py +216 -119
- squirrels/parameters.py +407 -478
- squirrels/user_base.py +58 -0
- squirrels-0.2.0.dev0.dist-info/METADATA +126 -0
- squirrels-0.2.0.dev0.dist-info/RECORD +56 -0
- {squirrels-0.1.1.post1.dist-info → squirrels-0.2.0.dev0.dist-info}/WHEEL +1 -2
- squirrels-0.2.0.dev0.dist-info/entry_points.txt +3 -0
- squirrels/_credentials_manager.py +0 -87
- squirrels/_module_loader.py +0 -37
- squirrels/_parameter_set.py +0 -151
- squirrels/_renderer.py +0 -286
- squirrels/_timed_imports.py +0 -37
- squirrels/connection_set.py +0 -126
- squirrels/package_data/base_project/.gitignore +0 -4
- squirrels/package_data/base_project/connections.py +0 -20
- squirrels/package_data/base_project/datasets/sample_dataset/context.py +0 -22
- squirrels/package_data/base_project/datasets/sample_dataset/database_view1.py +0 -29
- squirrels/package_data/base_project/datasets/sample_dataset/database_view1.sql.j2 +0 -12
- squirrels/package_data/base_project/datasets/sample_dataset/final_view.py +0 -11
- squirrels/package_data/base_project/datasets/sample_dataset/final_view.sql.j2 +0 -3
- squirrels/package_data/base_project/datasets/sample_dataset/parameters.py +0 -47
- squirrels/package_data/base_project/datasets/sample_dataset/selections.cfg +0 -9
- squirrels/package_data/base_project/squirrels.yaml +0 -22
- squirrels-0.1.1.post1.dist-info/METADATA +0 -67
- squirrels-0.1.1.post1.dist-info/RECORD +0 -40
- squirrels-0.1.1.post1.dist-info/entry_points.txt +0 -2
- squirrels-0.1.1.post1.dist-info/top_level.txt +0 -1
- {squirrels-0.1.1.post1.dist-info → squirrels-0.2.0.dev0.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const elem = React.createElement;
|
|
4
|
+
|
|
5
|
+
function refreshWidgets(target = null) {
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function processState(stateMap, name, selection) {
|
|
10
|
+
const [selected, setSelected] = React.useState(selection);
|
|
11
|
+
stateMap.set(name, selected);
|
|
12
|
+
|
|
13
|
+
return (targetValue, trigger_refresh) => {
|
|
14
|
+
setSelected(targetValue);
|
|
15
|
+
if (trigger_refresh) {
|
|
16
|
+
refreshWidgets({ [name]: targetValue });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function createWidgetDiv(label, widgetElement) {
|
|
22
|
+
return (
|
|
23
|
+
<div className="widget-div">
|
|
24
|
+
<label className="widget-label" htmlFor={widgetElement.id}>{label}</label>
|
|
25
|
+
{widgetElement}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function createOptionsDom(options) {
|
|
31
|
+
return options.map(option =>
|
|
32
|
+
<option key={option.id} value={option.id}>{option.label}</option>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function SingleSelectWidget({ name, label, options, trigger_refresh, selected_id, stateMap }) {
|
|
37
|
+
if (options.length === 0) return null;
|
|
38
|
+
|
|
39
|
+
const handleChange = processState(stateMap, name, selected_id);
|
|
40
|
+
const optionsDom = createOptionsDom(options);
|
|
41
|
+
const widgetDom = (
|
|
42
|
+
<select
|
|
43
|
+
id={name}
|
|
44
|
+
className="single-select widget"
|
|
45
|
+
defaultValue={selected_id}
|
|
46
|
+
onChange={e => handleChange(e.target.value, trigger_refresh)}
|
|
47
|
+
>
|
|
48
|
+
{optionsDom}
|
|
49
|
+
</select>
|
|
50
|
+
);
|
|
51
|
+
return createWidgetDiv(label, widgetDom);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function MultiSelectWidget({ name, label, options, include_all, order_matters, trigger_refresh, selected_ids, stateMap }) {
|
|
55
|
+
if (options.length === 0) return null;
|
|
56
|
+
|
|
57
|
+
const handleChange = processState(stateMap, name, selected_ids);
|
|
58
|
+
const optionsDom = createOptionsDom(options);
|
|
59
|
+
const getSelectedOptions = (target => [...target.selectedOptions].map(option => option.value));
|
|
60
|
+
const widgetDom = (
|
|
61
|
+
<select multiple
|
|
62
|
+
id={name}
|
|
63
|
+
className="multi-select widget"
|
|
64
|
+
defaultValue={selected_ids}
|
|
65
|
+
onChange={e => handleChange(getSelectedOptions(e.target), trigger_refresh)}
|
|
66
|
+
>
|
|
67
|
+
{optionsDom}
|
|
68
|
+
</select>
|
|
69
|
+
);
|
|
70
|
+
return createWidgetDiv(label, widgetDom);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function DateWidget({ name, label, selected_date, stateMap }) {
|
|
74
|
+
const handleChange = processState(stateMap, name, selected_date);
|
|
75
|
+
const widgetDom = <input type="date"
|
|
76
|
+
id={name}
|
|
77
|
+
defaultValue={selected_date}
|
|
78
|
+
onChange={e => handleChange(e.target.value, false)}
|
|
79
|
+
/>
|
|
80
|
+
return createWidgetDiv(label, widgetDom)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const optionsSingle = [
|
|
84
|
+
{
|
|
85
|
+
"id": "g0",
|
|
86
|
+
"label": "Transaction"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "g1",
|
|
90
|
+
"label": "Date"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "g2",
|
|
94
|
+
"label": "Category"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "g3",
|
|
98
|
+
"label": "Subcategory"
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
const optionsMulti = [
|
|
103
|
+
{
|
|
104
|
+
"id": "0",
|
|
105
|
+
"label": "Food"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "1",
|
|
109
|
+
"label": "Bills"
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
const stateMap = new Map();
|
|
114
|
+
const root = ReactDOM.createRoot(document.getElementById('root'));
|
|
115
|
+
root.render(
|
|
116
|
+
<SingleSelectWidget
|
|
117
|
+
name="group_by" label="Group By"
|
|
118
|
+
options={optionsSingle}
|
|
119
|
+
trigger_refresh={false}
|
|
120
|
+
selected_id="g2"
|
|
121
|
+
stateMap={stateMap}
|
|
122
|
+
/>
|
|
123
|
+
// <MultiSelectWidget
|
|
124
|
+
// name="category" label="Category Filter"
|
|
125
|
+
// include_all={true}
|
|
126
|
+
// order_matters={false}
|
|
127
|
+
// options={optionsMulti}
|
|
128
|
+
// trigger_refresh={false}
|
|
129
|
+
// selected_ids={["0", "1"]}
|
|
130
|
+
// stateMap={stateMap}
|
|
131
|
+
// />
|
|
132
|
+
// <DateWidget name="start_date" label="Start Date" selected_date="2023-01-01" stateMap={stateMap} />
|
|
133
|
+
);
|
|
@@ -3,30 +3,72 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<title>Squirrels UI</title>
|
|
5
5
|
<link id="favicon" rel="icon" type="image/x-icon" href="static/favicon.ico">
|
|
6
|
-
<link href="{{ url_for('static', path='/style.css?version=0') }}" rel="stylesheet">
|
|
7
|
-
<script
|
|
6
|
+
<link href="{{ url_for('static', path='/style.css?version=0.2.0') }}" rel="stylesheet">
|
|
7
|
+
<script>
|
|
8
|
+
const token_path = '{{ token_path }}';
|
|
9
|
+
const catalog_path = '{{ catalog_path }}';
|
|
10
|
+
</script>
|
|
11
|
+
<script src="{{ url_for('static', path='/script.js?version=0.2.0') }}" defer></script>
|
|
8
12
|
</head>
|
|
9
|
-
<body onload="callJsonAPI(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
<body onload="callJsonAPI(catalog_path, renderDatasetsSelection)">
|
|
14
|
+
<div id="root">
|
|
15
|
+
<div id="main-container" class="horizontal-container">
|
|
16
|
+
<div id="parameter-container">
|
|
17
|
+
<div>
|
|
18
|
+
<label for="project-select">Select a Project:</label>
|
|
19
|
+
<select id="project-select"></select>
|
|
20
|
+
<label for="dataset-select">Select a Dataset:</label>
|
|
21
|
+
<select id="dataset-select" onchange="changeDatasetSelection()"></select>
|
|
22
|
+
</div>
|
|
23
|
+
<div id="generated-parameters"></div>
|
|
24
|
+
<input type="submit" class="blue-button" value="Apply" onclick="getDatasetResults()">
|
|
25
|
+
</div>
|
|
26
|
+
<div id="right-container">
|
|
27
|
+
<div id="header-container">
|
|
28
|
+
<div class="horizontal-container">
|
|
29
|
+
<button class="white-button" onclick="copyTable()">Copy Table</button>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="horizontal-container">
|
|
32
|
+
<div style="margin-right: 10px;">
|
|
33
|
+
Logged in as <span id="username-txt">guest</span>
|
|
34
|
+
</div>
|
|
35
|
+
<button class="white-button" onclick="openLoginModal()">Authenticate</button>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div id="table-container">
|
|
39
|
+
<table id="result-table">
|
|
40
|
+
<thead id="table-header"></thead>
|
|
41
|
+
<tbody id="table-body"></tbody>
|
|
42
|
+
</table>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div id="loading-indicator">
|
|
48
|
+
<div>
|
|
49
|
+
<div class="spinner"></div>
|
|
50
|
+
<div>Loading...</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div id="login-modal" class="modal-background">
|
|
55
|
+
<form id="login-form" class="modal-content">
|
|
56
|
+
<label for="username"><b>Username</b></label>
|
|
57
|
+
<input type="text" placeholder="Enter Username" name="username" required>
|
|
58
|
+
|
|
59
|
+
<label for="password"><b>Password</b></label>
|
|
60
|
+
<input type="password" placeholder="Enter Password" name="password" required>
|
|
61
|
+
|
|
62
|
+
<div id="incorrectpwd" style="display: none;">
|
|
63
|
+
Incorrect username or password. Please try again
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div style="margin-top: 5px;">
|
|
67
|
+
<button type="submit" class="blue-button">Login</button>
|
|
68
|
+
<button type="reset" class="blue-button">Cancel</button>
|
|
69
|
+
</div>
|
|
70
|
+
</form>
|
|
71
|
+
</div>
|
|
16
72
|
</div>
|
|
17
|
-
<div id="table-container">
|
|
18
|
-
<button onclick="copyTable()">Copy Table</button>
|
|
19
|
-
<table id="result-table">
|
|
20
|
-
<thead id="table-header"></thead>
|
|
21
|
-
<tbody id="table-body"></tbody>
|
|
22
|
-
</table>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
<div id="loading-indicator">
|
|
26
|
-
<div>
|
|
27
|
-
<div class="spinner"></div>
|
|
28
|
-
<div>Loading...</div>
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
73
|
</body>
|
|
32
74
|
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Squirrels UI</title>
|
|
5
|
+
<link id="favicon" rel="icon" type="image/x-icon" href="static/favicon.ico">
|
|
6
|
+
<link href="{{ url_for('static', path='/style.css?version=1') }}" rel="stylesheet">
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
|
|
11
|
+
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
|
|
12
|
+
<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
|
|
13
|
+
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>
|
|
14
|
+
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
|
15
|
+
|
|
16
|
+
<script>
|
|
17
|
+
const token_path = '{{ token_path }}';
|
|
18
|
+
const catalog_path = '{{ catalog_path }}';
|
|
19
|
+
</script>
|
|
20
|
+
<script type="text/babel" src="{{ url_for('static', path='/widgets.js') }}"></script>
|
|
21
|
+
</body>
|
|
22
|
+
</html>
|