squirrels 0.3.3__py3-none-any.whl → 0.4.0__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.

Files changed (56) hide show
  1. squirrels/__init__.py +7 -3
  2. squirrels/_api_response_models.py +96 -72
  3. squirrels/_api_server.py +375 -201
  4. squirrels/_authenticator.py +23 -22
  5. squirrels/_command_line.py +70 -46
  6. squirrels/_connection_set.py +23 -25
  7. squirrels/_constants.py +29 -78
  8. squirrels/_dashboards_io.py +61 -0
  9. squirrels/_environcfg.py +53 -50
  10. squirrels/_initializer.py +184 -141
  11. squirrels/_manifest.py +168 -195
  12. squirrels/_models.py +159 -292
  13. squirrels/_package_loader.py +7 -8
  14. squirrels/_parameter_configs.py +173 -141
  15. squirrels/_parameter_sets.py +49 -38
  16. squirrels/_py_module.py +7 -7
  17. squirrels/_seeds.py +13 -12
  18. squirrels/_utils.py +114 -54
  19. squirrels/_version.py +1 -1
  20. squirrels/arguments/init_time_args.py +16 -10
  21. squirrels/arguments/run_time_args.py +89 -24
  22. squirrels/dashboards.py +82 -0
  23. squirrels/data_sources.py +212 -232
  24. squirrels/dateutils.py +29 -26
  25. squirrels/package_data/assets/index.css +1 -1
  26. squirrels/package_data/assets/index.js +27 -18
  27. squirrels/package_data/base_project/.gitignore +2 -2
  28. squirrels/package_data/base_project/connections.yml +1 -1
  29. squirrels/package_data/base_project/dashboards/dashboard_example.py +32 -0
  30. squirrels/package_data/base_project/dashboards.yml +10 -0
  31. squirrels/package_data/base_project/docker/.dockerignore +9 -4
  32. squirrels/package_data/base_project/docker/Dockerfile +7 -6
  33. squirrels/package_data/base_project/docker/compose.yml +1 -1
  34. squirrels/package_data/base_project/env.yml +2 -2
  35. squirrels/package_data/base_project/models/dbviews/{database_view1.py → dbview_example.py} +2 -1
  36. squirrels/package_data/base_project/models/dbviews/{database_view1.sql → dbview_example.sql} +3 -2
  37. squirrels/package_data/base_project/models/federates/{dataset_example.py → federate_example.py} +6 -6
  38. squirrels/package_data/base_project/models/federates/{dataset_example.sql → federate_example.sql} +1 -1
  39. squirrels/package_data/base_project/parameters.yml +6 -4
  40. squirrels/package_data/base_project/pyconfigs/auth.py +1 -1
  41. squirrels/package_data/base_project/pyconfigs/connections.py +1 -1
  42. squirrels/package_data/base_project/pyconfigs/context.py +38 -10
  43. squirrels/package_data/base_project/pyconfigs/parameters.py +15 -7
  44. squirrels/package_data/base_project/squirrels.yml.j2 +14 -7
  45. squirrels/package_data/templates/index.html +3 -3
  46. squirrels/parameter_options.py +103 -106
  47. squirrels/parameters.py +347 -195
  48. squirrels/project.py +378 -0
  49. squirrels/user_base.py +14 -6
  50. {squirrels-0.3.3.dist-info → squirrels-0.4.0.dist-info}/METADATA +9 -21
  51. squirrels-0.4.0.dist-info/RECORD +60 -0
  52. squirrels/_timer.py +0 -23
  53. squirrels-0.3.3.dist-info/RECORD +0 -56
  54. {squirrels-0.3.3.dist-info → squirrels-0.4.0.dist-info}/LICENSE +0 -0
  55. {squirrels-0.3.3.dist-info → squirrels-0.4.0.dist-info}/WHEEL +0 -0
  56. {squirrels-0.3.3.dist-info → squirrels-0.4.0.dist-info}/entry_points.txt +0 -0
squirrels/__init__.py CHANGED
@@ -1,15 +1,19 @@
1
- __version__ = '0.3.3'
1
+ from ._version import __version__
2
2
 
3
3
  from .arguments.init_time_args import ConnectionsArgs, ParametersArgs
4
- from .arguments.run_time_args import AuthArgs, ContextArgs, ModelDepsArgs, ModelArgs
4
+ from .arguments.run_time_args import AuthArgs, ContextArgs, ModelDepsArgs, ModelArgs, DashboardArgs
5
5
 
6
6
  from .parameter_options import SelectParameterOption, DateParameterOption, DateRangeParameterOption
7
7
  from .parameter_options import NumberParameterOption, NumberRangeParameterOption, TextParameterOption
8
8
 
9
9
  from .parameters import SingleSelectParameter, MultiSelectParameter, DateParameter, DateRangeParameter
10
- from .parameters import NumberParameter, NumberRangeParameter, TextParameter
10
+ from .parameters import NumberParameter, NumberRangeParameter, TextParameter, TextValue
11
11
 
12
12
  from .data_sources import SingleSelectDataSource, MultiSelectDataSource, SelectDataSource, DateDataSource, DateRangeDataSource
13
13
  from .data_sources import NumberDataSource, NumberRangeDataSource, TextDataSource
14
14
 
15
15
  from .user_base import User, WrongPassword
16
+
17
+ from .dashboards import PngDashboard, HtmlDashboard
18
+
19
+ from .project import SquirrelsProject
@@ -1,117 +1,141 @@
1
- from typing import Annotated, Union, Optional
1
+ from typing import Annotated
2
2
  from pydantic import BaseModel, Field
3
3
  from datetime import datetime, date
4
4
 
5
5
 
6
6
  class LoginReponse(BaseModel):
7
- access_token: Annotated[str, Field(examples=["encoded_jwt_token"])]
8
- token_type: Annotated[str, Field(examples=["bearer"])]
9
- username: Annotated[str, Field(examples=["johndoe"])]
10
- expiry_time: datetime
7
+ access_token: Annotated[str, Field(examples=["encoded_jwt_token"], description="An encoded JSON web token to use subsequent API requests")]
8
+ token_type: Annotated[str, Field(examples=["bearer"], description='Always "bearer" for Bearer token')]
9
+ username: Annotated[str, Field(examples=["johndoe"], description='The username authenticated with from the form data')]
10
+ expiry_time: Annotated[datetime, Field(examples=["2023-08-01T12:00:00.000000Z"], description="The expiry time of the access token in yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z' format")]
11
+
12
+
13
+ ## Datasets / Dashboards Catalog Response Models
14
+
15
+ name_description = "The name of the dataset / dashboard (usually in snake case)"
16
+ label_description = "The human-friendly display name for the dataset / dashboard"
17
+ description_description = "The description of the dataset / dashboard"
18
+ parameters_path_description = "The API path to the parameters for the dataset / dashboard"
19
+ result_path_description = "The API path to the results for the dataset / dashboard"
20
+
21
+ class DatasetItemModel(BaseModel):
22
+ name: Annotated[str, Field(examples=["mydataset"], description=name_description)]
23
+ label: Annotated[str, Field(examples=["My Dataset"], description=label_description)]
24
+ description: Annotated[str, Field(examples=[""], description=description_description)]
25
+ parameters_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/dataset/mydataset/parameters"], description=parameters_path_description)]
26
+ result_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/dataset/mydataset"], description=result_path_description)]
27
+
28
+ class DashboardItemModel(BaseModel):
29
+ name: Annotated[str, Field(examples=["mydashboard"], description=name_description)]
30
+ label: Annotated[str, Field(examples=["My Dashboard"], description=label_description)]
31
+ description: Annotated[str, Field(examples=[""], description=description_description)]
32
+ parameters_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/dashboard/mydashboard/parameters"], description=parameters_path_description)]
33
+ result_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/dashboard/mydashboard"], description=result_path_description)]
34
+ result_format: Annotated[str, Field(examples=["png", "html"], description="The format of the dashboard's result API response (one of 'png' or 'html')")]
35
+
36
+ class CatalogModel(BaseModel):
37
+ datasets: Annotated[list[DatasetItemModel], Field(description="The list of accessible datasets")]
38
+ dashboards: Annotated[list[DashboardItemModel], Field(description="The list of accessible dashboards")]
11
39
 
12
40
 
13
41
  ## Parameters Response Models
14
42
 
15
43
  class ParameterOptionModel(BaseModel):
16
- id: str
17
- label: str
44
+ id: Annotated[str, Field(examples=["my_option_id"], description="The unique identifier for the option")]
45
+ label: Annotated[str, Field(examples=["My Option"], description="The human-friendly display name for the option")]
18
46
 
19
47
  class ParameterModelBase(BaseModel):
20
- widget_type: str
21
- name: str
22
- label: str
23
- description: str
48
+ widget_type: Annotated[str, Field(examples=["none"], description="The parameter type (set to 'none' for this model)")]
49
+ name: Annotated[str, Field(examples=["my_unique_param_name"], description="The name of the parameter. Use this as the key when providing the API request parameters")]
50
+ label: Annotated[str, Field(examples=["My Parameter"], description="The human-friendly display name for the parameter")]
51
+ description: Annotated[str, Field(examples=[""], description="The description of the parameter")]
52
+
53
+ class NoneParameterModel(ParameterModelBase):
54
+ pass
24
55
 
25
56
  class SelectParameterModel(ParameterModelBase):
26
- options: list[ParameterOptionModel]
27
- trigger_refresh: bool
57
+ options: Annotated[list[ParameterOptionModel], Field(description="The list of dropdown options as JSON objects containing 'id' and 'label' fields")]
58
+ trigger_refresh: Annotated[bool, Field(description="A boolean that's set to true for parent parameters that require a new parameters API call when the selection changes")]
28
59
 
29
60
  class SingleSelectParameterModel(SelectParameterModel):
30
- widget_type: Annotated[str, Field(examples=["single_select"])]
31
- selected_id: Optional[str]
61
+ widget_type: Annotated[str, Field(examples=["single_select"], description="The parameter type (set to 'single_select' for this model)")]
62
+ selected_id: Annotated[str | None, Field(examples=["my_option_id"], description="The ID of the selected / default option")]
32
63
 
33
64
  class MultiSelectParameterModel(SelectParameterModel):
34
- widget_type: Annotated[str, Field(examples=["multi_select"])]
35
- show_select_all: bool
36
- order_matters: bool
37
- selected_ids: list[str]
38
-
39
- class DateParameterModel(ParameterModelBase):
40
- widget_type: Annotated[str, Field(examples=["date"])]
41
- selected_date: date
42
-
43
- class DateRangeParameterModel(ParameterModelBase):
44
- widget_type: Annotated[str, Field(examples=["date_range"])]
45
- selected_start_date: date
46
- selected_end_date: date
47
-
48
- class NumericParameterModel(ParameterModelBase):
49
- min_value: Annotated[float, Field(examples=[0])]
50
- max_value: Annotated[float, Field(examples=[10])]
51
- increment: Annotated[float, Field(examples=[1])]
52
-
53
- class NumberParameterModel(NumericParameterModel):
54
- widget_type: Annotated[str, Field(examples=["number"])]
55
- selected_value: Annotated[float, Field(examples=[2])]
56
-
57
- class NumberRangeParameterModel(NumericParameterModel):
58
- widget_type: Annotated[str, Field(examples=["number_range"])]
59
- selected_lower_value: Annotated[float, Field(examples=[2])]
60
- selected_upper_value: Annotated[float, Field(examples=[8])]
65
+ widget_type: Annotated[str, Field(examples=["multi_select"], description="The parameter type (set to 'multi_select' for this model)")]
66
+ show_select_all: Annotated[bool, Field(description="A boolean for whether there should be a toggle to select all options")]
67
+ order_matters: Annotated[bool, Field(description="A boolean for whether the ordering of the input selections would affect the result of the dataset")]
68
+ selected_ids: Annotated[list[str], Field(examples=[["my_option_id"]], description="A list of ids of the selected / default options")]
69
+
70
+ class _DateTypeParameterModel(ParameterModelBase):
71
+ min_date: Annotated[date | None, Field(examples=["2023-01-01"], description='A string in "yyyy-MM-dd" format for the minimum date')]
72
+ max_date: Annotated[date | None, Field(examples=["2023-12-31"], description='A string in "yyyy-MM-dd" format for the maximum date')]
73
+
74
+ class DateParameterModel(_DateTypeParameterModel):
75
+ widget_type: Annotated[str, Field(examples=["date"], description="The parameter type (set to 'date' for this model)")]
76
+ selected_date: Annotated[date, Field(examples=["2023-01-01"], description='A string in "yyyy-MM-dd" format for the selected / default date')]
77
+
78
+ class DateRangeParameterModel(_DateTypeParameterModel):
79
+ widget_type: Annotated[str, Field(examples=["date_range"], description="The parameter type (set to 'date_range' for this model)")]
80
+ selected_start_date: Annotated[date, Field(examples=["2023-01-01"], description='A string in "yyyy-MM-dd" format for the selected / default start date')]
81
+ selected_end_date: Annotated[date, Field(examples=["2023-12-31"], description='A string in "yyyy-MM-dd" format for the selected / default end date')]
82
+
83
+ class _NumericParameterModel(ParameterModelBase):
84
+ min_value: Annotated[float, Field(examples=[0], description="A number for the lower bound of the selectable number")]
85
+ max_value: Annotated[float, Field(examples=[10], description="A number for the upper bound of the selectable number")]
86
+ increment: Annotated[float, Field(examples=[1], description="A number for the selectable increments between the lower bound and upper bound")]
87
+
88
+ class NumberParameterModel(_NumericParameterModel):
89
+ widget_type: Annotated[str, Field(examples=["number"], description="The parameter type (set to 'number' for this model)")]
90
+ selected_value: Annotated[float, Field(examples=[2], description="A number for the selected / default number")]
91
+
92
+ class NumberRangeParameterModel(_NumericParameterModel):
93
+ widget_type: Annotated[str, Field(examples=["number_range"], description="The parameter type (set to 'number_range' for this model)")]
94
+ selected_lower_value: Annotated[float, Field(examples=[2], description="A number for the selected / default lower number")]
95
+ selected_upper_value: Annotated[float, Field(examples=[8], description="A number for the selected / default upper number")]
61
96
 
62
97
  class TextParameterModel(ParameterModelBase):
63
- widget_type: Annotated[str, Field(examples=["text"])]
64
- entered_text: str
65
- input_type: str
98
+ widget_type: Annotated[str, Field(examples=["text"], description="The parameter type (set to 'text' for this model)")]
99
+ entered_text: Annotated[str, Field(examples=["sushi"], description="A string for the default entered text")]
100
+ input_type: Annotated[str, Field(
101
+ examples=["text", "textarea", "number", "date", "datetime-local", "month", "time", "color", "password"],
102
+ description='A string for the input type (one of "text", "textarea", "number", "date", "datetime-local", "month", "time", "color", or "password")'
103
+ )]
66
104
 
67
105
  class ParametersModel(BaseModel):
68
106
  parameters: list[
69
- Union[
70
- ParameterModelBase, SingleSelectParameterModel, MultiSelectParameterModel, DateParameterModel, DateRangeParameterModel,
71
- NumberParameterModel, NumberRangeParameterModel, TextParameterModel
72
- ]
107
+ NoneParameterModel | SingleSelectParameterModel | MultiSelectParameterModel | DateParameterModel | DateRangeParameterModel |
108
+ NumberParameterModel | NumberRangeParameterModel | TextParameterModel
73
109
  ]
74
110
 
75
111
 
76
112
  ## Dataset Results Response Models
77
113
 
78
114
  class ColumnModel(BaseModel):
79
- name: Annotated[str, Field(examples=["mycol"])]
80
- type: str
115
+ name: Annotated[str, Field(examples=["mycol"], description="Name of column")]
116
+ type: Annotated[str, Field(examples=["string", "number", "integer", "boolean", "datetime"], description='Column type. One of "string", "number", "integer", "boolean", and "datetime"')]
81
117
 
82
118
  class SchemaModel(BaseModel):
83
- fields: list[ColumnModel]
84
- dimensions: Annotated[list[str], Field(examples=[["mycol"]])]
119
+ fields: Annotated[list[ColumnModel], Field(description="A list of JSON objects containing the 'name' and 'type' for each of the columns in the result")]
120
+ dimensions: Annotated[list[str], Field(examples=[["mycol"]], description="A list of column names that are dimensions")]
85
121
 
86
122
  class DatasetResultModel(BaseModel):
87
- data_schema: Annotated[SchemaModel, Field(alias='schema')]
88
- data: Annotated[list[dict], Field(examples=[[{"mycol": "myval"}]])]
123
+ data_schema: Annotated[SchemaModel, Field(alias="schema", description="JSON object describing the schema of the dataset")]
124
+ data: Annotated[list[dict], Field(
125
+ examples=[[{"mycol": "myval"}]],
126
+ description="A list of JSON objects where each object is a row of the tabular results. The keys and values of the object are column names (described in fields) and values of the row."
127
+ )]
89
128
 
90
129
 
91
- ## Catalog Response Models
130
+ ## Project Metadata Response Models
92
131
 
93
132
  class ProjectVersionModel(BaseModel):
94
133
  major_version: int
95
134
  minor_versions: list[int]
96
135
  token_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/token"])]
97
- datasets_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/datasets"])]
136
+ data_catalog_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/datasets"])]
98
137
 
99
138
  class ProjectModel(BaseModel):
100
139
  name: Annotated[str, Field(examples=["myproject"])]
101
140
  label: Annotated[str, Field(examples=["My Project"])]
102
141
  versions: list[ProjectVersionModel]
103
-
104
- class CatalogModel(BaseModel):
105
- projects: list[ProjectModel]
106
-
107
-
108
- ## Datasets Catalog Response Models
109
-
110
- class DatasetInfoModel(BaseModel):
111
- name: Annotated[str, Field(examples=["mydataset"])]
112
- label: Annotated[str, Field(examples=["My Dataset"])]
113
- parameters_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/dataset/mydataset/parameters"])]
114
- result_path: Annotated[str, Field(examples=["/squirrels-v0/myproject/v1/dataset/mydataset"])]
115
-
116
- class DatasetsCatalogModel(BaseModel):
117
- datasets: list[DatasetInfoModel]