squirrels 0.1.0__py3-none-any.whl → 0.6.0.post0__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.
- dateutils/__init__.py +6 -0
- dateutils/_enums.py +25 -0
- squirrels/dateutils.py → dateutils/_implementation.py +409 -380
- dateutils/types.py +6 -0
- squirrels/__init__.py +21 -18
- squirrels/_api_routes/__init__.py +5 -0
- squirrels/_api_routes/auth.py +337 -0
- squirrels/_api_routes/base.py +196 -0
- squirrels/_api_routes/dashboards.py +156 -0
- squirrels/_api_routes/data_management.py +148 -0
- squirrels/_api_routes/datasets.py +220 -0
- squirrels/_api_routes/project.py +289 -0
- squirrels/_api_server.py +552 -134
- squirrels/_arguments/__init__.py +0 -0
- squirrels/_arguments/init_time_args.py +83 -0
- squirrels/_arguments/run_time_args.py +111 -0
- squirrels/_auth.py +777 -0
- squirrels/_command_line.py +239 -107
- squirrels/_compile_prompts.py +147 -0
- squirrels/_connection_set.py +94 -0
- squirrels/_constants.py +141 -64
- squirrels/_dashboards.py +179 -0
- squirrels/_data_sources.py +570 -0
- squirrels/_dataset_types.py +91 -0
- squirrels/_env_vars.py +209 -0
- squirrels/_exceptions.py +29 -0
- squirrels/_http_error_responses.py +52 -0
- squirrels/_initializer.py +319 -110
- squirrels/_logging.py +121 -0
- squirrels/_manifest.py +357 -187
- squirrels/_mcp_server.py +578 -0
- squirrels/_model_builder.py +69 -0
- squirrels/_model_configs.py +74 -0
- squirrels/_model_queries.py +52 -0
- squirrels/_models.py +1201 -0
- squirrels/_package_data/base_project/.env +7 -0
- squirrels/_package_data/base_project/.env.example +44 -0
- squirrels/_package_data/base_project/connections.yml +16 -0
- squirrels/_package_data/base_project/dashboards/dashboard_example.py +40 -0
- squirrels/_package_data/base_project/dashboards/dashboard_example.yml +22 -0
- squirrels/_package_data/base_project/docker/.dockerignore +16 -0
- squirrels/_package_data/base_project/docker/Dockerfile +16 -0
- squirrels/_package_data/base_project/docker/compose.yml +7 -0
- squirrels/_package_data/base_project/duckdb_init.sql +10 -0
- squirrels/_package_data/base_project/gitignore +13 -0
- squirrels/_package_data/base_project/macros/macros_example.sql +17 -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 +57 -0
- squirrels/_package_data/base_project/models/dbviews/dbview_example.sql +17 -0
- squirrels/_package_data/base_project/models/dbviews/dbview_example.yml +32 -0
- squirrels/_package_data/base_project/models/federates/federate_example.py +51 -0
- squirrels/_package_data/base_project/models/federates/federate_example.sql +21 -0
- squirrels/_package_data/base_project/models/federates/federate_example.yml +65 -0
- squirrels/_package_data/base_project/models/sources.yml +38 -0
- squirrels/_package_data/base_project/parameters.yml +142 -0
- squirrels/_package_data/base_project/pyconfigs/connections.py +19 -0
- squirrels/_package_data/base_project/pyconfigs/context.py +96 -0
- squirrels/_package_data/base_project/pyconfigs/parameters.py +141 -0
- squirrels/_package_data/base_project/pyconfigs/user.py +56 -0
- squirrels/_package_data/base_project/resources/expenses.db +0 -0
- squirrels/_package_data/base_project/resources/public/.gitkeep +0 -0
- squirrels/_package_data/base_project/resources/weather.db +0 -0
- squirrels/_package_data/base_project/seeds/seed_categories.csv +6 -0
- squirrels/_package_data/base_project/seeds/seed_categories.yml +15 -0
- squirrels/_package_data/base_project/seeds/seed_subcategories.csv +15 -0
- squirrels/_package_data/base_project/seeds/seed_subcategories.yml +21 -0
- squirrels/_package_data/base_project/squirrels.yml.j2 +61 -0
- squirrels/_package_data/base_project/tmp/.gitignore +2 -0
- squirrels/_package_data/templates/login_successful.html +53 -0
- squirrels/_package_data/templates/squirrels_studio.html +22 -0
- squirrels/_package_loader.py +29 -0
- squirrels/_parameter_configs.py +592 -0
- squirrels/_parameter_options.py +348 -0
- squirrels/_parameter_sets.py +207 -0
- squirrels/_parameters.py +1703 -0
- squirrels/_project.py +796 -0
- squirrels/_py_module.py +122 -0
- squirrels/_request_context.py +33 -0
- squirrels/_schemas/__init__.py +0 -0
- squirrels/_schemas/auth_models.py +83 -0
- squirrels/_schemas/query_param_models.py +70 -0
- squirrels/_schemas/request_models.py +26 -0
- squirrels/_schemas/response_models.py +286 -0
- squirrels/_seeds.py +97 -0
- squirrels/_sources.py +112 -0
- squirrels/_utils.py +540 -149
- squirrels/_version.py +1 -3
- squirrels/arguments.py +7 -0
- squirrels/auth.py +4 -0
- squirrels/connections.py +3 -0
- squirrels/dashboards.py +3 -0
- squirrels/data_sources.py +14 -282
- squirrels/parameter_options.py +13 -189
- squirrels/parameters.py +14 -801
- squirrels/types.py +18 -0
- squirrels-0.6.0.post0.dist-info/METADATA +148 -0
- squirrels-0.6.0.post0.dist-info/RECORD +101 -0
- {squirrels-0.1.0.dist-info → squirrels-0.6.0.post0.dist-info}/WHEEL +1 -2
- {squirrels-0.1.0.dist-info → squirrels-0.6.0.post0.dist-info}/entry_points.txt +1 -0
- squirrels-0.6.0.post0.dist-info/licenses/LICENSE +201 -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 -21
- squirrels/package_data/base_project/database/sample_database.db +0 -0
- squirrels/package_data/base_project/database/seattle_weather.db +0 -0
- squirrels/package_data/base_project/datasets/sample_dataset/context.py +0 -8
- squirrels/package_data/base_project/datasets/sample_dataset/database_view1.py +0 -23
- squirrels/package_data/base_project/datasets/sample_dataset/database_view1.sql.j2 +0 -7
- squirrels/package_data/base_project/datasets/sample_dataset/final_view.py +0 -10
- squirrels/package_data/base_project/datasets/sample_dataset/final_view.sql.j2 +0 -2
- squirrels/package_data/base_project/datasets/sample_dataset/parameters.py +0 -30
- squirrels/package_data/base_project/datasets/sample_dataset/selections.cfg +0 -6
- squirrels/package_data/base_project/squirrels.yaml +0 -26
- squirrels/package_data/static/favicon.ico +0 -0
- squirrels/package_data/static/script.js +0 -234
- squirrels/package_data/static/style.css +0 -110
- squirrels/package_data/templates/index.html +0 -32
- squirrels-0.1.0.dist-info/LICENSE +0 -22
- squirrels-0.1.0.dist-info/METADATA +0 -67
- squirrels-0.1.0.dist-info/RECORD +0 -40
- squirrels-0.1.0.dist-info/top_level.txt +0 -1
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
from typing import Dict, Any
|
|
2
|
-
import pandas as pd
|
|
3
|
-
import squirrels as sr
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def main(database_views: Dict[str, pd.DataFrame],
|
|
7
|
-
prms: Dict[str, sr.Parameter], ctx: Dict[str, Any], proj: Dict[str, Any],
|
|
8
|
-
*p_args, **kwargs) -> pd.DataFrame:
|
|
9
|
-
df = database_views['database_view1']
|
|
10
|
-
return df
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
from typing import Dict, Sequence, Any
|
|
2
|
-
import squirrels as sr
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def main(args: Dict[str, Any], *p_args, **kwargs) -> Sequence[sr.Parameter]:
|
|
6
|
-
single_select_options = (
|
|
7
|
-
sr.SelectParameterOption('a0', 'Primary Colors'),
|
|
8
|
-
sr.SelectParameterOption('a1', 'Secondary Colors')
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
multi_select_options = (
|
|
12
|
-
sr.SelectParameterOption('x0', 'Red', parent_option_id='a0'),
|
|
13
|
-
sr.SelectParameterOption('x1', 'Yellow', parent_option_id='a0'),
|
|
14
|
-
sr.SelectParameterOption('x2', 'Blue', parent_option_id='a0'),
|
|
15
|
-
sr.SelectParameterOption('x3', 'Green', parent_option_id='a1'),
|
|
16
|
-
sr.SelectParameterOption('x4', 'Orange', parent_option_id='a1'),
|
|
17
|
-
sr.SelectParameterOption('x5', 'Purple', parent_option_id='a1')
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
single_select_example = sr.SingleSelectParameter('color_type', 'Color Type', single_select_options)
|
|
21
|
-
|
|
22
|
-
multi_select_example = sr.MultiSelectParameter('colors', 'Colors', multi_select_options,
|
|
23
|
-
parent=single_select_example)
|
|
24
|
-
|
|
25
|
-
date_example = sr.DateParameter('as_of_date', 'As Of Date', '2020-01-01')
|
|
26
|
-
|
|
27
|
-
number_example = sr.NumberParameter('upper_bound', 'Upper Bound', min_value=1, max_value=10,
|
|
28
|
-
increment=1, default_value=5)
|
|
29
|
-
|
|
30
|
-
return [single_select_example, multi_select_example, date_example, number_example]
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
modules: []
|
|
2
|
-
|
|
3
|
-
project_variables:
|
|
4
|
-
# product, major_version, and minor_version are required project variables
|
|
5
|
-
product: sample
|
|
6
|
-
major_version: 1
|
|
7
|
-
minor_version: 0
|
|
8
|
-
# additional project variables can be added here
|
|
9
|
-
|
|
10
|
-
db_connections: # optional if connections.py exists
|
|
11
|
-
default:
|
|
12
|
-
credential_key: null # optional if null
|
|
13
|
-
url: 'sqlite://${username}:${password}@/./database/sample_database.db'
|
|
14
|
-
|
|
15
|
-
datasets:
|
|
16
|
-
sample_dataset:
|
|
17
|
-
label: Sample Dataset
|
|
18
|
-
database_views:
|
|
19
|
-
database_view1:
|
|
20
|
-
file: database_view1.sql.j2
|
|
21
|
-
db_connection: default # optional if default
|
|
22
|
-
args: {} # optional if empty
|
|
23
|
-
final_view: database_view1
|
|
24
|
-
args: {} # optional if empty
|
|
25
|
-
|
|
26
|
-
settings: {}
|
|
Binary file
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
const datasetSelect = document.getElementById('dataset-select');
|
|
2
|
-
const generatedParamsDiv = document.getElementById('generated-parameters');
|
|
3
|
-
|
|
4
|
-
const tableContainers = document.getElementById('table-container');
|
|
5
|
-
const resultTable = document.getElementById("result-table");
|
|
6
|
-
const tableHeader = document.getElementById('table-header');
|
|
7
|
-
const tableBody = document.getElementById('table-body');
|
|
8
|
-
|
|
9
|
-
const loadingIndicator = document.getElementById('loading-indicator');
|
|
10
|
-
|
|
11
|
-
const datasetsMap = new Map();
|
|
12
|
-
const parametersMap = new Map();
|
|
13
|
-
|
|
14
|
-
function callJsonAPI(path, func) {
|
|
15
|
-
loadingIndicator.style.display = 'flex';
|
|
16
|
-
fetch(path)
|
|
17
|
-
.then(response => response.json())
|
|
18
|
-
.then(data => {
|
|
19
|
-
func(data);
|
|
20
|
-
})
|
|
21
|
-
.catch(error => {
|
|
22
|
-
alert('Server error...')
|
|
23
|
-
console.log(error)
|
|
24
|
-
})
|
|
25
|
-
.then(_ => {
|
|
26
|
-
loadingIndicator.style.display = 'none'
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function changeDatasetSelection() {
|
|
31
|
-
tableContainers.style.display = 'none';
|
|
32
|
-
parametersMap.clear()
|
|
33
|
-
refreshParameters();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function renderDatasetsSelection(data) {
|
|
37
|
-
const datasets = data.products[0].versions[0].datasets
|
|
38
|
-
datasets.forEach(resource => {
|
|
39
|
-
const option = document.createElement('option');
|
|
40
|
-
option.value = resource.name;
|
|
41
|
-
option.textContent = resource.label;
|
|
42
|
-
datasetSelect.appendChild(option);
|
|
43
|
-
datasetsMap.set(option.value, resource);
|
|
44
|
-
});
|
|
45
|
-
changeDatasetSelection();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function refreshParameters(provoker = null) {
|
|
49
|
-
const selectedDatasetValue = datasetSelect.value;
|
|
50
|
-
const parametersPath = datasetsMap.get(selectedDatasetValue).parameters_path;
|
|
51
|
-
const queryParameters = getQueryParams(provoker)
|
|
52
|
-
const parametersRequest = parametersPath + '?' + queryParameters
|
|
53
|
-
console.log('Parameters request:', parametersRequest)
|
|
54
|
-
|
|
55
|
-
callJsonAPI(parametersRequest, (jsonResponse) => {
|
|
56
|
-
jsonResponse.parameters.forEach(function(param) {
|
|
57
|
-
parametersMap.set(param.name, param);
|
|
58
|
-
})
|
|
59
|
-
generatedParamsDiv.innerHTML = "";
|
|
60
|
-
for (const param of parametersMap.values()) {
|
|
61
|
-
const newDiv = document.createElement('div')
|
|
62
|
-
|
|
63
|
-
const addLabel = function() {
|
|
64
|
-
const paramLabel = document.createElement('label')
|
|
65
|
-
paramLabel.innerHTML = param.label
|
|
66
|
-
newDiv.appendChild(paramLabel)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (param.widget_type === "DateParameter") {
|
|
70
|
-
addLabel()
|
|
71
|
-
const dateInput = document.createElement('input')
|
|
72
|
-
dateInput.type = 'date'
|
|
73
|
-
dateInput.id = param.name
|
|
74
|
-
dateInput.value = param.selected_date
|
|
75
|
-
dateInput.onchange = updateParameter
|
|
76
|
-
newDiv.appendChild(dateInput)
|
|
77
|
-
} else if (param.widget_type === "NumberParameter") {
|
|
78
|
-
addLabel()
|
|
79
|
-
const sliderInput = document.createElement('input')
|
|
80
|
-
sliderInput.type = 'range'
|
|
81
|
-
sliderInput.id = param.name
|
|
82
|
-
sliderInput.min = param.min_value
|
|
83
|
-
sliderInput.max = param.max_value
|
|
84
|
-
sliderInput.step = param.increment
|
|
85
|
-
sliderInput.value = param.selected_value
|
|
86
|
-
|
|
87
|
-
const sliderValue = document.createElement('div')
|
|
88
|
-
sliderValue.id = param.name + '_value'
|
|
89
|
-
sliderValue.className = 'slider-value'
|
|
90
|
-
sliderValue.innerText = param.selected_value
|
|
91
|
-
|
|
92
|
-
sliderInput.oninput = function() {
|
|
93
|
-
sliderValue.innerText = this.value;
|
|
94
|
-
}
|
|
95
|
-
sliderInput.onchange = updateParameter
|
|
96
|
-
|
|
97
|
-
newDiv.appendChild(sliderInput)
|
|
98
|
-
newDiv.appendChild(sliderValue)
|
|
99
|
-
} else if (param.widget_type === "NumRangeParameter") {
|
|
100
|
-
// TODO
|
|
101
|
-
} else if (param.widget_type === "SingleSelectParameter" && param.options.length > 0) {
|
|
102
|
-
addLabel()
|
|
103
|
-
const singleSelect = document.createElement('select');
|
|
104
|
-
singleSelect.id = param.name;
|
|
105
|
-
param.options.forEach(function(option) {
|
|
106
|
-
const selectOption = document.createElement('option');
|
|
107
|
-
selectOption.value = option.id;
|
|
108
|
-
if (option.id === param.selected_id) {
|
|
109
|
-
selectOption.selected = true;
|
|
110
|
-
}
|
|
111
|
-
selectOption.innerText = option.label;
|
|
112
|
-
singleSelect.appendChild(selectOption);
|
|
113
|
-
});
|
|
114
|
-
singleSelect.onchange = updateParameter
|
|
115
|
-
newDiv.appendChild(singleSelect);
|
|
116
|
-
} else if (param.widget_type === "MultiSelectParameter" && param.options.length > 0) {
|
|
117
|
-
addLabel()
|
|
118
|
-
const multiSelect = document.createElement('select');
|
|
119
|
-
multiSelect.id = param.name;
|
|
120
|
-
multiSelect.multiple = true;
|
|
121
|
-
param.options.forEach(function(option) {
|
|
122
|
-
const selectOption = document.createElement('option');
|
|
123
|
-
selectOption.value = option.id;
|
|
124
|
-
if (param.selected_ids.includes(option.id)) {
|
|
125
|
-
selectOption.selected = true;
|
|
126
|
-
}
|
|
127
|
-
selectOption.innerText = option.label;
|
|
128
|
-
multiSelect.appendChild(selectOption);
|
|
129
|
-
});
|
|
130
|
-
multiSelect.onchange = updateParameter
|
|
131
|
-
newDiv.appendChild(multiSelect);
|
|
132
|
-
}
|
|
133
|
-
generatedParamsDiv.appendChild(newDiv);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function updateParameter() {
|
|
139
|
-
const param = parametersMap.get(this.id)
|
|
140
|
-
if (param.widget_type === "DateParameter") {
|
|
141
|
-
param.selected_date = this.value
|
|
142
|
-
} else if (param.widget_type === "NumberParameter") {
|
|
143
|
-
param.selected_value = this.value
|
|
144
|
-
} else if (param.widget_type === "NumRangeParameter") {
|
|
145
|
-
// TODO
|
|
146
|
-
} else if (param.widget_type === "SingleSelectParameter") {
|
|
147
|
-
param.selected_id = this.options[this.selectedIndex].value
|
|
148
|
-
} else if (param.widget_type === "MultiSelectParameter") {
|
|
149
|
-
param.selected_ids = [...this.selectedOptions].map(option => option.value)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (param.trigger_refresh) {
|
|
153
|
-
refreshParameters(param)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function getQueryParams(provoker = null) {
|
|
158
|
-
const queryParams = {}
|
|
159
|
-
function addToQueryParams(key, value) {
|
|
160
|
-
if (value.widget_type === "DateParameter") {
|
|
161
|
-
queryParams[key] = value.selected_date
|
|
162
|
-
} else if (value.widget_type === "NumberParameter") {
|
|
163
|
-
queryParams[key] = value.selected_value
|
|
164
|
-
} else if (value.widget_type === "NumRangeParameter") {
|
|
165
|
-
// TODO
|
|
166
|
-
} else if (value.widget_type === "SingleSelectParameter") {
|
|
167
|
-
queryParams[key] = value.selected_id
|
|
168
|
-
} else if (value.widget_type === "MultiSelectParameter") {
|
|
169
|
-
result = JSON.stringify(value.selected_ids)
|
|
170
|
-
if (result !== '') queryParams[key] = result
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
if (provoker !== null) {
|
|
174
|
-
addToQueryParams(provoker.name, provoker)
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
for (const [key, value] of parametersMap.entries()) {
|
|
178
|
-
addToQueryParams(key, value)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
console.log(queryParams)
|
|
182
|
-
return new URLSearchParams(queryParams)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function getDatasetResults() {
|
|
186
|
-
const selectedDatasetValue = datasetSelect.value;
|
|
187
|
-
const resultPath = datasetsMap.get(selectedDatasetValue).result_path;
|
|
188
|
-
const resultRequest = resultPath + '?' + getQueryParams()
|
|
189
|
-
console.log('Result request:', resultRequest)
|
|
190
|
-
|
|
191
|
-
callJsonAPI(resultRequest, (jsonResponse) => {
|
|
192
|
-
tableHeader.innerHTML = ''
|
|
193
|
-
tableBody.innerHTML = ''
|
|
194
|
-
|
|
195
|
-
// Create the table header row
|
|
196
|
-
const headerRow = document.createElement('tr');
|
|
197
|
-
jsonResponse.schema.fields.forEach(field => {
|
|
198
|
-
const th = document.createElement('th');
|
|
199
|
-
th.textContent = field.name;
|
|
200
|
-
headerRow.appendChild(th);
|
|
201
|
-
});
|
|
202
|
-
tableHeader.appendChild(headerRow);
|
|
203
|
-
|
|
204
|
-
// Create the table data rows
|
|
205
|
-
jsonResponse.data.forEach(dataObject => {
|
|
206
|
-
const row = document.createElement('tr');
|
|
207
|
-
jsonResponse.schema.fields.forEach(field => {
|
|
208
|
-
const td = document.createElement('td');
|
|
209
|
-
td.textContent = dataObject[field.name];
|
|
210
|
-
row.appendChild(td);
|
|
211
|
-
});
|
|
212
|
-
tableBody.appendChild(row);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
tableContainers.style.display = 'block'
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function copyTable() {
|
|
220
|
-
let text = "";
|
|
221
|
-
|
|
222
|
-
for (let i = 0; i < resultTable.rows.length; i++) {
|
|
223
|
-
for (let j = 0; j < resultTable.rows[i].cells.length; j++) {
|
|
224
|
-
text += resultTable.rows[i].cells[j].innerHTML + "\t";
|
|
225
|
-
}
|
|
226
|
-
text += "\n";
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
navigator.clipboard.writeText(text).then(function() {
|
|
230
|
-
alert("Table copied to clipboard!");
|
|
231
|
-
}, function() {
|
|
232
|
-
alert("Copying failed.");
|
|
233
|
-
});
|
|
234
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
table {
|
|
2
|
-
border-collapse: collapse;
|
|
3
|
-
width: 100%;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
th, td {
|
|
7
|
-
text-align: left;
|
|
8
|
-
padding: 8px;
|
|
9
|
-
min-width: 50px;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
th {
|
|
13
|
-
background-color: #4285f4;
|
|
14
|
-
color: white;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
tr:nth-child(even) {
|
|
18
|
-
background-color: #f2f2f2;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
input, select {
|
|
22
|
-
width: 100%;
|
|
23
|
-
padding: 12px 20px;
|
|
24
|
-
margin: 8px 0;
|
|
25
|
-
box-sizing: border-box;
|
|
26
|
-
border: 2px solid #ccc;
|
|
27
|
-
border-radius: 4px;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
input[type="range"] {
|
|
31
|
-
width: 80%;
|
|
32
|
-
padding: 12px 0px;
|
|
33
|
-
border: 0px;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
input[type=submit] {
|
|
37
|
-
background-color: #4285f4;
|
|
38
|
-
color: white;
|
|
39
|
-
padding: 12px 20px;
|
|
40
|
-
border: none;
|
|
41
|
-
border-radius: 4px;
|
|
42
|
-
cursor: pointer;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
input[type=submit]:hover {
|
|
46
|
-
background-color: #3076c5;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
#main-container {
|
|
50
|
-
display: flex;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
#parameter-container {
|
|
54
|
-
width: 250px;
|
|
55
|
-
min-width: 250px;
|
|
56
|
-
margin-right: 50px;
|
|
57
|
-
padding: 10px;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
#table-container {
|
|
61
|
-
display: none;
|
|
62
|
-
padding: 10px 20px;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
#result-table {
|
|
66
|
-
margin: 20px 0px;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.slider-value {
|
|
70
|
-
display: inline-block;
|
|
71
|
-
position: relative;
|
|
72
|
-
left: 10px;
|
|
73
|
-
bottom: 14px;
|
|
74
|
-
font-size: 18px;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/* Loading section */
|
|
78
|
-
#loading-indicator {
|
|
79
|
-
display: none;
|
|
80
|
-
justify-content: center;
|
|
81
|
-
align-items: center;
|
|
82
|
-
text-align: center;
|
|
83
|
-
font-weight: bold;
|
|
84
|
-
position: absolute;
|
|
85
|
-
top: 0;
|
|
86
|
-
left: 0;
|
|
87
|
-
width: 100%;
|
|
88
|
-
height: 100%;
|
|
89
|
-
background-color: rgba(255, 255, 255, 0.5);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.spinner {
|
|
93
|
-
margin: 20px auto;
|
|
94
|
-
width: 40px;
|
|
95
|
-
height: 40px;
|
|
96
|
-
position: relative;
|
|
97
|
-
border-radius: 50%;
|
|
98
|
-
border: 3px solid transparent;
|
|
99
|
-
border-top-color: #3498db;
|
|
100
|
-
animation: spin 1s linear infinite;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
@keyframes spin {
|
|
104
|
-
0% {
|
|
105
|
-
transform: rotate(0deg);
|
|
106
|
-
}
|
|
107
|
-
100% {
|
|
108
|
-
transform: rotate(360deg);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
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=0') }}" rel="stylesheet">
|
|
7
|
-
<script src="{{ url_for('static', path='/script.js?version=2') }}" defer></script>
|
|
8
|
-
</head>
|
|
9
|
-
<body onload="callJsonAPI('{{ catalog_path }}', renderDatasetsSelection)">
|
|
10
|
-
<div id="main-container">
|
|
11
|
-
<div id="parameter-container">
|
|
12
|
-
<label for="dataset-select">Select a Dataset:</label>
|
|
13
|
-
<select id="dataset-select" onchange="changeDatasetSelection()"></select>
|
|
14
|
-
<div id="generated-parameters"></div>
|
|
15
|
-
<input type="submit" value="Apply" onclick="getDatasetResults()">
|
|
16
|
-
</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
|
-
</body>
|
|
32
|
-
</html>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 Tim Huang
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
22
|
-
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: squirrels
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Python Package for Configuring SQL Generating APIs
|
|
5
|
-
Author: Tim Huang
|
|
6
|
-
Author-email: tim.yuting@hotmail.com
|
|
7
|
-
License: MIT
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
License-File: LICENSE
|
|
10
|
-
Requires-Dist: openpyxl
|
|
11
|
-
Requires-Dist: inquirer
|
|
12
|
-
Requires-Dist: pwinput
|
|
13
|
-
Requires-Dist: cachetools
|
|
14
|
-
Requires-Dist: fastapi
|
|
15
|
-
Requires-Dist: uvicorn
|
|
16
|
-
Requires-Dist: Jinja2
|
|
17
|
-
Requires-Dist: GitPython
|
|
18
|
-
Requires-Dist: sqlalchemy
|
|
19
|
-
Requires-Dist: pandas
|
|
20
|
-
Requires-Dist: pyyaml
|
|
21
|
-
|
|
22
|
-
# Squirrels
|
|
23
|
-
|
|
24
|
-
Squirrels is an API framework for creating REST APIs that generate sql queries & dataframes dynamically from query parameters.
|
|
25
|
-
|
|
26
|
-
## Setup
|
|
27
|
-
|
|
28
|
-
First, install the library and all dependencies **in a new virtual environment**.
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
# create and activate virtual environment...
|
|
32
|
-
pip install -e .
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
To confirm that the setup worked, run this to show the help page for all squirrels CLI commands:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
squirrels -h
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Testing
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
python setup.py pytest
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Usage Documentation
|
|
48
|
-
|
|
49
|
-
To learn about using the squirrels framework, check out the documentation website [here](https://squirrels-nest.github.io/squirrels-docs/).
|
|
50
|
-
|
|
51
|
-
## Developer Guide
|
|
52
|
-
|
|
53
|
-
From the root of the git repo, the source code can be found in the `squirrels` folder and unit tests can be found in the `tests` folder.
|
|
54
|
-
|
|
55
|
-
To understand what a specific squirrels command line utility is doing, start from the `_command_line.py` file as your entry point.
|
|
56
|
-
|
|
57
|
-
The library version is maintained in both the `setup.py` file (for the next release or release-candidate version) and the `squirrels/_version.py` file (for the next release version only).
|
|
58
|
-
|
|
59
|
-
When a user initializes a squirrels project using `squirrels init`, the files are copied from the `squirrels/package_data/base_project` folder. The contents in the `database` subfolder were constructed from the scripts in the `database_elt` folder at the top level.
|
|
60
|
-
|
|
61
|
-
For the Squirrels UI activated by `squirrels run`, the HTML, CSS, and Javascript files can be found in the `static` and `templates` subfolders of `squirrels/package_data`.
|
|
62
|
-
|
|
63
|
-
## License
|
|
64
|
-
|
|
65
|
-
Squirrels is released under the MIT license.
|
|
66
|
-
|
|
67
|
-
See the file LICENSE for more details.
|
squirrels-0.1.0.dist-info/RECORD
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
squirrels/__init__.py,sha256=ip4oa-N6yvsqx2IP_X71j6RkYUNt4dK-al_XdzC8X30,822
|
|
2
|
-
squirrels/_api_server.py,sha256=2qxtKzztmHgbSFDb_gbhaY8SiRuhdQsByRAnBfkB46k,6455
|
|
3
|
-
squirrels/_command_line.py,sha256=VmvqT9TMUKtxlU3q893uoGrTE4n-5-qrEW_aK69jYuE,5978
|
|
4
|
-
squirrels/_constants.py,sha256=1qBHjBSB76iBiLDyWEFpgNpVSzhecl-_f1cnODbJ_lc,1901
|
|
5
|
-
squirrels/_credentials_manager.py,sha256=mKiafRc6MS_REOhF4QJzzhTjr46hTzgLF4y0bjR-Zk4,3063
|
|
6
|
-
squirrels/_initializer.py,sha256=no28jwF6GKhjISmuQ6QD911FC3cn2ZRSm2rHVH0bzkk,4839
|
|
7
|
-
squirrels/_manifest.py,sha256=KBsYAc1U4hQNgjGJgdFdH8jP1yJWF3l1pYtUKtnAgMc,8292
|
|
8
|
-
squirrels/_module_loader.py,sha256=g8nPn2ECgfprp1dHdQHZCDQARGUYFq7ubDnNYJXlEOU,1257
|
|
9
|
-
squirrels/_parameter_set.py,sha256=mtlVpdhkmn_lk1UTOB_tsts-YZxQNma7a9QpGsvIqHM,6176
|
|
10
|
-
squirrels/_renderer.py,sha256=P9EkqPZtOoxRJb8MYkNr6MUd0i6bt7GPp4oq266DcoI,14484
|
|
11
|
-
squirrels/_timed_imports.py,sha256=9rrZQNy3hAovWrDxyBnmGV-pm3ckkRh8TDpTwpqG1Ds,1179
|
|
12
|
-
squirrels/_utils.py,sha256=970BeDX6tpZPhHTh9TDr7Sr-WKF6BC0__4XVBAJ0_kA,4170
|
|
13
|
-
squirrels/_version.py,sha256=Q9M5JeO0CpFcO38J2uerLp6w7GDM2UbiAhiMjWnBFvQ,95
|
|
14
|
-
squirrels/connection_set.py,sha256=GxGxTGnxpfbofnEEcbW2CbGONDLC1XPoid5EuFaWago,4382
|
|
15
|
-
squirrels/data_sources.py,sha256=eDB6jKO--DBmtrROQGKQPrb92rS6nBF10GwPaeXBlfU,12943
|
|
16
|
-
squirrels/dateutils.py,sha256=G60MafCxuYpZw4nfku7IyB_gKeGh0mKlJ0mC7vU5F-4,13433
|
|
17
|
-
squirrels/parameter_options.py,sha256=BWAlzTzQ7Nevdt9VBTAVxOA9ErrWl0m10_PMEpdSpoY,8281
|
|
18
|
-
squirrels/parameters.py,sha256=MKphRK2toEqVBdlWG6MzCyHvCkEr4wehSHf3SSmPoE4,32879
|
|
19
|
-
squirrels/package_data/base_project/.gitignore,sha256=Q6CsDx4ecfoRvgnIYHfLi-oxEqJfzwVDKJdoOc_lark,40
|
|
20
|
-
squirrels/package_data/base_project/connections.py,sha256=Pyjt5-7Pkt5Mryi08BlYuzvZXHmMNHUgmdlkxsP-O3k,923
|
|
21
|
-
squirrels/package_data/base_project/squirrels.yaml,sha256=Cu3Onb4WicSo8jHHDrOaa-sdGWQi0XYrzXATwaOUM6Y,728
|
|
22
|
-
squirrels/package_data/base_project/database/sample_database.db,sha256=MB3Cycr6w64V76VsaVGFlL_VT9g_h6KT7JQNANvdkPA,8192
|
|
23
|
-
squirrels/package_data/base_project/database/seattle_weather.db,sha256=PldWB7PLY_ltY-OWxN9ALcFEdiVDaP3Kef0I2k7WPso,188416
|
|
24
|
-
squirrels/package_data/base_project/datasets/sample_dataset/context.py,sha256=5XjG-Nnxz7s-rzTEjNm15CJcb6zIcedcXPrTV7-o15M,306
|
|
25
|
-
squirrels/package_data/base_project/datasets/sample_dataset/database_view1.py,sha256=cqIJ7UJWu1bFPWyve0RduhUFo5fCNx7vyxbBfK-GNkc,929
|
|
26
|
-
squirrels/package_data/base_project/datasets/sample_dataset/database_view1.sql.j2,sha256=uy8X4oKYtJOAPf81V0kZA-thhWlAUFUuX4f2KQgYx8U,376
|
|
27
|
-
squirrels/package_data/base_project/datasets/sample_dataset/final_view.py,sha256=7Y5kXqWMsM52r69uDghS0pV8QXAwZ4TekFNBmAGTq00,320
|
|
28
|
-
squirrels/package_data/base_project/datasets/sample_dataset/final_view.sql.j2,sha256=vWcUvH9xN6awyHS4RVOfZKGENZwDxAokcY9xC168ZMA,31
|
|
29
|
-
squirrels/package_data/base_project/datasets/sample_dataset/parameters.py,sha256=nbayTKYbvVvpk7LEppc0IkvO35TLd3kyNoFd9-LRrjA,1429
|
|
30
|
-
squirrels/package_data/base_project/datasets/sample_dataset/selections.cfg,sha256=zIqzUyqqgAyKdAOazbBtTIlTLVU0WuuuVC86Dh1qjmY,148
|
|
31
|
-
squirrels/package_data/static/favicon.ico,sha256=369AMckPCruYh3O2PnSLLmy8kLvTwhoaS_uu2pP6Tqs,4638
|
|
32
|
-
squirrels/package_data/static/script.js,sha256=mFv6hTK-0PWA5zLUmo4JSOpZOPr3Opr5CBnZ3QBOTPQ,9179
|
|
33
|
-
squirrels/package_data/static/style.css,sha256=RotwFHkFhgRH6TB7KP9fTISKUzez4q5bqUNx3XhZBAM,1841
|
|
34
|
-
squirrels/package_data/templates/index.html,sha256=tWxV3US6rQ16KmRXMcVBE2pT6w1gBlIFDQ165REm174,1276
|
|
35
|
-
squirrels-0.1.0.dist-info/LICENSE,sha256=i6pwBFWTz4jmhAK_BXGWy4tvFh1UKyr7_D9ZgwqC7_Q,1088
|
|
36
|
-
squirrels-0.1.0.dist-info/METADATA,sha256=s2SDUN03bxVW7gmlP9p-m64Mf7aUKxgStOzLgDf38uE,2230
|
|
37
|
-
squirrels-0.1.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
38
|
-
squirrels-0.1.0.dist-info/entry_points.txt,sha256=WNFiEjziFJP1KZrscef4Ec9-wjUFGZTAIowXqUK0t80,59
|
|
39
|
-
squirrels-0.1.0.dist-info/top_level.txt,sha256=XuG5BFy3DJzGxLhguuYnJyjRmVCOePgmKyTWLlyKLsM,10
|
|
40
|
-
squirrels-0.1.0.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
squirrels
|