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
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Project metadata routes
|
|
3
|
+
"""
|
|
4
|
+
from typing import Any
|
|
5
|
+
from fastapi import FastAPI, Depends, Request
|
|
6
|
+
from fastapi.responses import JSONResponse
|
|
7
|
+
from fastapi.security import HTTPBearer
|
|
8
|
+
from dataclasses import asdict
|
|
9
|
+
from cachetools import TTLCache
|
|
10
|
+
import time
|
|
11
|
+
|
|
12
|
+
from .. import _utils as u, _constants as c
|
|
13
|
+
from .._schemas import response_models as rm
|
|
14
|
+
from .._parameter_configs import APIParamFieldInfo
|
|
15
|
+
from .._parameter_sets import ParameterSet
|
|
16
|
+
from .._exceptions import ConfigurationError, InvalidInputError
|
|
17
|
+
from .._manifest import PermissionScope, AuthType, AuthStrategy
|
|
18
|
+
from .._schemas.query_param_models import get_query_models_for_parameters
|
|
19
|
+
from .._schemas.auth_models import AbstractUser
|
|
20
|
+
from .base import RouteBase
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ProjectRoutes(RouteBase):
|
|
24
|
+
"""Project metadata and data catalog routes"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, get_bearer_token: HTTPBearer, project, no_cache: bool = False):
|
|
27
|
+
super().__init__(get_bearer_token, project, no_cache)
|
|
28
|
+
|
|
29
|
+
# Setup caches
|
|
30
|
+
self.parameters_cache = TTLCache(
|
|
31
|
+
maxsize=self.env_vars.parameters_cache_size,
|
|
32
|
+
ttl=self.env_vars.parameters_cache_ttl_minutes*60
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
async def _get_parameters_helper(
|
|
36
|
+
self, parameters_tuple: tuple[str, ...] | None, entity_type: str, entity_name: str, entity_scope: PermissionScope,
|
|
37
|
+
user: AbstractUser, selections: tuple[tuple[str, Any], ...]
|
|
38
|
+
) -> ParameterSet:
|
|
39
|
+
"""Helper for getting parameters"""
|
|
40
|
+
selections_dict = dict(selections)
|
|
41
|
+
if "x_parent_param" not in selections_dict:
|
|
42
|
+
if len(selections_dict) > 1:
|
|
43
|
+
raise InvalidInputError(400, "invalid_input_for_cascading_parameters", f"The parameters endpoint takes at most 1 widget parameter selection (unless x_parent_param is provided). Got {selections_dict}")
|
|
44
|
+
elif len(selections_dict) == 1:
|
|
45
|
+
parent_param = next(iter(selections_dict))
|
|
46
|
+
selections_dict["x_parent_param"] = parent_param
|
|
47
|
+
|
|
48
|
+
parent_param = selections_dict.get("x_parent_param")
|
|
49
|
+
if parent_param is not None and parent_param not in selections_dict:
|
|
50
|
+
# this condition is possible for multi-select parameters with empty selection
|
|
51
|
+
selections_dict[parent_param] = list()
|
|
52
|
+
|
|
53
|
+
if not self.authenticator.can_user_access_scope(user, entity_scope):
|
|
54
|
+
raise self.project._permission_error(user, entity_type, entity_name, entity_scope.name)
|
|
55
|
+
|
|
56
|
+
param_set = self.param_cfg_set.apply_selections(parameters_tuple, selections_dict, user, parent_param=parent_param)
|
|
57
|
+
return param_set
|
|
58
|
+
|
|
59
|
+
async def _get_parameters_cachable(
|
|
60
|
+
self, parameters_tuple: tuple[str, ...] | None, entity_type: str, entity_name: str, entity_scope: PermissionScope,
|
|
61
|
+
user: AbstractUser, selections: tuple[tuple[str, Any], ...]
|
|
62
|
+
) -> ParameterSet:
|
|
63
|
+
"""Cachable version of parameters helper"""
|
|
64
|
+
return await self.do_cachable_action(
|
|
65
|
+
self.parameters_cache, self._get_parameters_helper, parameters_tuple, entity_type, entity_name, entity_scope, user, selections
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def setup_routes(
|
|
69
|
+
self, app: FastAPI, param_fields: dict[str, APIParamFieldInfo]
|
|
70
|
+
):
|
|
71
|
+
"""Setup project metadata routes"""
|
|
72
|
+
project_name = self.manifest_cfg.project_variables.name
|
|
73
|
+
project_version = str(self.manifest_cfg.project_variables.major_version)
|
|
74
|
+
label = self.manifest_cfg.project_variables.label
|
|
75
|
+
description = self.manifest_cfg.project_variables.description
|
|
76
|
+
auth_type = self.manifest_cfg.project_variables.auth_type.value
|
|
77
|
+
|
|
78
|
+
elevated_access_level = self.env_vars.elevated_access_level
|
|
79
|
+
if elevated_access_level != "admin":
|
|
80
|
+
self.logger.warning(f"{c.SQRL_PERMISSIONS_ELEVATED_ACCESS_LEVEL} has been set to a non-admin access level. For security reasons, DO NOT expose the APIs for this app publicly!")
|
|
81
|
+
|
|
82
|
+
# Project metadata endpoint
|
|
83
|
+
@app.get("/", summary="Get project metadata and API endpoint paths", tags=["Project Metadata"], response_class=JSONResponse)
|
|
84
|
+
async def get_project_metadata(request: Request) -> rm.ProjectMetadataModel:
|
|
85
|
+
project_name_for_api = u.normalize_name_for_api(project_name)
|
|
86
|
+
auth_strategy = self.manifest_cfg.project_variables.auth_strategy
|
|
87
|
+
is_external = (auth_strategy == AuthStrategy.EXTERNAL)
|
|
88
|
+
|
|
89
|
+
_, root_path = self._get_base_url_for_current_app(request)
|
|
90
|
+
api_routes = rm.ApiRoutesModel(
|
|
91
|
+
get_data_catalog_url = root_path + "/data-catalog",
|
|
92
|
+
get_parameters_url = root_path + "/parameters",
|
|
93
|
+
get_dataset_parameters_url = root_path + "/datasets/{dataset_name}/parameters",
|
|
94
|
+
get_dataset_results_url = root_path + "/datasets/{dataset_name}",
|
|
95
|
+
get_dashboard_parameters_url = root_path + "/dashboards/{dashboard_name}/parameters",
|
|
96
|
+
get_dashboard_results_url = root_path + "/dashboards/{dashboard_name}",
|
|
97
|
+
trigger_build_url = root_path + "/build",
|
|
98
|
+
get_query_result_url = root_path + "/query-result",
|
|
99
|
+
get_compiled_model_url = root_path + "/compiled-models/{model_name}",
|
|
100
|
+
get_user_session_url = root_path + "/auth/user-session",
|
|
101
|
+
list_providers_url = root_path + "/auth/providers",
|
|
102
|
+
login_url = None if is_external else root_path + "/auth/login",
|
|
103
|
+
logout_url = root_path + "/auth/logout",
|
|
104
|
+
change_password_url = None if is_external else root_path + "/auth/password",
|
|
105
|
+
list_api_keys_url = None if is_external else root_path + "/auth/api-keys",
|
|
106
|
+
create_api_key_url = None if is_external else root_path + "/auth/api-keys",
|
|
107
|
+
revoke_api_key_url = None if is_external else root_path + "/auth/api-keys/{key_id}",
|
|
108
|
+
list_user_fields_url = None if is_external else root_path + "/auth/user-management/user-fields",
|
|
109
|
+
list_users_url = None if is_external else root_path + "/auth/user-management/users",
|
|
110
|
+
add_user_url = None if is_external else root_path + "/auth/user-management/users",
|
|
111
|
+
update_user_url = None if is_external else root_path + "/auth/user-management/users/{username}",
|
|
112
|
+
delete_user_url = None if is_external else root_path + "/auth/user-management/users/{username}",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return rm.ProjectMetadataModel(
|
|
116
|
+
name = project_name,
|
|
117
|
+
name_for_api = project_name_for_api,
|
|
118
|
+
version = project_version,
|
|
119
|
+
label = label,
|
|
120
|
+
description = description,
|
|
121
|
+
auth_strategy = auth_strategy.value,
|
|
122
|
+
auth_type = auth_type,
|
|
123
|
+
password_requirements = None if is_external else self.authenticator.password_requirements,
|
|
124
|
+
elevated_access_level = elevated_access_level,
|
|
125
|
+
api_routes = api_routes,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Data catalog endpoint
|
|
129
|
+
data_catalog_path = '/data-catalog'
|
|
130
|
+
|
|
131
|
+
async def get_data_catalog0(user: AbstractUser) -> rm.CatalogModel:
|
|
132
|
+
parameters = self.param_cfg_set.apply_selections(None, {}, user)
|
|
133
|
+
parameters_model = parameters.to_api_response_model0()
|
|
134
|
+
full_parameters_list = [p.name for p in parameters_model.parameters]
|
|
135
|
+
user_has_elevated_privileges = u.user_has_elevated_privileges(user.access_level, elevated_access_level)
|
|
136
|
+
|
|
137
|
+
dataset_items: list[rm.DatasetItemModel] = []
|
|
138
|
+
for name, config in self.manifest_cfg.datasets.items():
|
|
139
|
+
if self.authenticator.can_user_access_scope(user, config.scope):
|
|
140
|
+
name_for_api = u.normalize_name_for_api(name)
|
|
141
|
+
metadata = self.project.dataset_metadata(name).to_json()
|
|
142
|
+
parameters = config.parameters if config.parameters is not None else full_parameters_list
|
|
143
|
+
|
|
144
|
+
# Build dataset-specific configurables list
|
|
145
|
+
if user_has_elevated_privileges:
|
|
146
|
+
dataset_configurables_defaults = self.manifest_cfg.get_default_configurables(overrides=config.configurables)
|
|
147
|
+
dataset_configurables_list = [
|
|
148
|
+
rm.ConfigurableOverrideModel(name=name, default=default)
|
|
149
|
+
for name, default in dataset_configurables_defaults.items()
|
|
150
|
+
]
|
|
151
|
+
else:
|
|
152
|
+
dataset_configurables_list = []
|
|
153
|
+
|
|
154
|
+
dataset_items.append(rm.DatasetItemModel(
|
|
155
|
+
name=name, name_for_api=name_for_api,
|
|
156
|
+
label=config.label,
|
|
157
|
+
description=config.description,
|
|
158
|
+
schema=metadata["schema"], # type: ignore
|
|
159
|
+
configurables=dataset_configurables_list,
|
|
160
|
+
parameters=parameters
|
|
161
|
+
))
|
|
162
|
+
|
|
163
|
+
dashboard_items: list[rm.DashboardItemModel] = []
|
|
164
|
+
for name, dashboard in self.project._dashboards.items():
|
|
165
|
+
config = dashboard.config
|
|
166
|
+
if self.authenticator.can_user_access_scope(user, config.scope):
|
|
167
|
+
name_for_api = u.normalize_name_for_api(name)
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
dashboard_format = self.project._dashboards[name].get_dashboard_format()
|
|
171
|
+
except KeyError:
|
|
172
|
+
raise ConfigurationError(f"No dashboard file found for: {name}")
|
|
173
|
+
|
|
174
|
+
if user_has_elevated_privileges:
|
|
175
|
+
dashboard_configurables_defaults = self.manifest_cfg.get_default_configurables(overrides=config.configurables)
|
|
176
|
+
dashboard_configurables_list = [
|
|
177
|
+
rm.ConfigurableOverrideModel(name=name, default=default)
|
|
178
|
+
for name, default in dashboard_configurables_defaults.items()
|
|
179
|
+
]
|
|
180
|
+
else:
|
|
181
|
+
dashboard_configurables_list = []
|
|
182
|
+
|
|
183
|
+
parameters = config.parameters if config.parameters is not None else full_parameters_list
|
|
184
|
+
dashboard_items.append(rm.DashboardItemModel(
|
|
185
|
+
name=name, name_for_api=name_for_api,
|
|
186
|
+
label=config.label,
|
|
187
|
+
description=config.description,
|
|
188
|
+
result_format=dashboard_format,
|
|
189
|
+
configurables=dashboard_configurables_list,
|
|
190
|
+
parameters=parameters
|
|
191
|
+
))
|
|
192
|
+
|
|
193
|
+
if user_has_elevated_privileges:
|
|
194
|
+
compiled_dag = await self.project._get_compiled_dag(user)
|
|
195
|
+
connections_items = self.project._get_all_connections()
|
|
196
|
+
data_models = self.project._get_all_data_models(compiled_dag)
|
|
197
|
+
lineage_items = self.project._get_all_data_lineage(compiled_dag)
|
|
198
|
+
configurables_list = [
|
|
199
|
+
rm.ConfigurableItemModel(name=name, label=cfg.label, default=cfg.default, description=cfg.description)
|
|
200
|
+
for name, cfg in self.manifest_cfg.configurables.items()
|
|
201
|
+
]
|
|
202
|
+
else:
|
|
203
|
+
connections_items = []
|
|
204
|
+
data_models = []
|
|
205
|
+
lineage_items = []
|
|
206
|
+
configurables_list = []
|
|
207
|
+
|
|
208
|
+
return rm.CatalogModel(
|
|
209
|
+
parameters=parameters_model.parameters,
|
|
210
|
+
datasets=dataset_items,
|
|
211
|
+
dashboards=dashboard_items,
|
|
212
|
+
connections=connections_items,
|
|
213
|
+
models=data_models,
|
|
214
|
+
lineage=lineage_items,
|
|
215
|
+
configurables=configurables_list,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
@app.get(data_catalog_path, tags=["Project Metadata"], summary="Get catalog of datasets and dashboards available for user")
|
|
219
|
+
async def get_data_catalog(
|
|
220
|
+
user: AbstractUser = Depends(self.get_current_user)
|
|
221
|
+
) -> rm.CatalogModel:
|
|
222
|
+
"""
|
|
223
|
+
Get catalog of datasets and dashboards available for the authenticated user.
|
|
224
|
+
|
|
225
|
+
For admin users, this endpoint will also return detailed information about all models and their lineage in the project.
|
|
226
|
+
"""
|
|
227
|
+
start = time.time()
|
|
228
|
+
|
|
229
|
+
# If authentication is required, require user to be authenticated to access catalog
|
|
230
|
+
if self.manifest_cfg.project_variables.auth_type == AuthType.REQUIRED and user.access_level == "guest":
|
|
231
|
+
raise InvalidInputError(401, "user_required", "Authentication is required to access the data catalog")
|
|
232
|
+
data_catalog = await get_data_catalog0(user)
|
|
233
|
+
|
|
234
|
+
self.logger.log_activity_time("GET REQUEST for DATA CATALOG", start)
|
|
235
|
+
return data_catalog
|
|
236
|
+
|
|
237
|
+
async def get_data_catalog_for_mcp(user: AbstractUser) -> rm.CatalogModelForMcp:
|
|
238
|
+
"""Get data catalog for MCP tools/resources. Takes user object."""
|
|
239
|
+
data_catalog = await get_data_catalog0(user)
|
|
240
|
+
return rm.CatalogModelForMcp(parameters=data_catalog.parameters, datasets=data_catalog.datasets)
|
|
241
|
+
|
|
242
|
+
# Store the MCP function as an instance attribute for access by McpServerBuilder
|
|
243
|
+
self._get_data_catalog_for_mcp = get_data_catalog_for_mcp
|
|
244
|
+
|
|
245
|
+
# Project-level parameters endpoints
|
|
246
|
+
project_level_parameters_path = '/parameters'
|
|
247
|
+
parameters_description = "Selections of one parameter may cascade the available options in another parameter. " \
|
|
248
|
+
"For example, if the dataset has parameters for 'country' and 'city', available options for 'city' would " \
|
|
249
|
+
"depend on the selected option 'country'. If a parameter has 'trigger_refresh' as true, provide the parameter " \
|
|
250
|
+
"selection to this endpoint whenever it changes to refresh the parameter options of children parameters."
|
|
251
|
+
|
|
252
|
+
QueryModelForGetProjectParams, QueryModelForPostProjectParams = get_query_models_for_parameters(param_fields)
|
|
253
|
+
|
|
254
|
+
async def get_parameters_definition(
|
|
255
|
+
parameters_list: list[str] | None, entity_type: str, entity_name: str, entity_scope: PermissionScope,
|
|
256
|
+
user: AbstractUser, params: dict
|
|
257
|
+
) -> rm.ParametersModel:
|
|
258
|
+
# self._validate_request_params(all_request_params, params, headers)
|
|
259
|
+
|
|
260
|
+
get_parameters_function = self._get_parameters_helper if self.no_cache else self._get_parameters_cachable
|
|
261
|
+
selections = self.get_selections_as_immutable(params, uncached_keys=set())
|
|
262
|
+
parameters_tuple = tuple(parameters_list) if parameters_list is not None else None
|
|
263
|
+
result = await get_parameters_function(parameters_tuple, entity_type, entity_name, entity_scope, user, selections)
|
|
264
|
+
return result.to_api_response_model0()
|
|
265
|
+
|
|
266
|
+
@app.get(project_level_parameters_path, tags=["Project Metadata"], description=parameters_description)
|
|
267
|
+
async def get_project_parameters(
|
|
268
|
+
params: QueryModelForGetProjectParams, user=Depends(self.get_current_user)
|
|
269
|
+
) -> rm.ParametersModel:
|
|
270
|
+
start = time.time()
|
|
271
|
+
result = await get_parameters_definition(
|
|
272
|
+
None, "project", "", PermissionScope.PUBLIC, user, asdict(params)
|
|
273
|
+
)
|
|
274
|
+
self.logger.log_activity_time("GET REQUEST for PROJECT PARAMETERS", start)
|
|
275
|
+
return result
|
|
276
|
+
|
|
277
|
+
@app.post(project_level_parameters_path, tags=["Project Metadata"], description=parameters_description)
|
|
278
|
+
async def get_project_parameters_with_post(
|
|
279
|
+
params: QueryModelForPostProjectParams, user=Depends(self.get_current_user)
|
|
280
|
+
) -> rm.ParametersModel:
|
|
281
|
+
start = time.time()
|
|
282
|
+
result = await get_parameters_definition(
|
|
283
|
+
None, "project", "", PermissionScope.PUBLIC, user, params.model_dump()
|
|
284
|
+
)
|
|
285
|
+
self.logger.log_activity_time("POST REQUEST for PROJECT PARAMETERS", start)
|
|
286
|
+
return result
|
|
287
|
+
|
|
288
|
+
return get_parameters_definition
|
|
289
|
+
|