squirrels 0.5.0b2__py3-none-any.whl → 0.5.0b4__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 (96) hide show
  1. dateutils/__init__.py +6 -460
  2. dateutils/_enums.py +25 -0
  3. dateutils/_implementation.py +409 -0
  4. dateutils/types.py +6 -0
  5. squirrels/__init__.py +9 -13
  6. squirrels/_api_routes/__init__.py +5 -0
  7. squirrels/_api_routes/auth.py +262 -0
  8. squirrels/_api_routes/base.py +154 -0
  9. squirrels/_api_routes/dashboards.py +142 -0
  10. squirrels/_api_routes/data_management.py +103 -0
  11. squirrels/_api_routes/datasets.py +242 -0
  12. squirrels/_api_routes/oauth2.py +300 -0
  13. squirrels/_api_routes/project.py +214 -0
  14. squirrels/_api_server.py +145 -748
  15. squirrels/_arguments/__init__.py +0 -0
  16. squirrels/{arguments → _arguments}/init_time_args.py +7 -2
  17. squirrels/{arguments → _arguments}/run_time_args.py +4 -26
  18. squirrels/_auth.py +646 -93
  19. squirrels/_connection_set.py +5 -5
  20. squirrels/_constants.py +7 -1
  21. squirrels/{_dashboards_io.py → _dashboards.py} +87 -6
  22. squirrels/_data_sources.py +564 -0
  23. squirrels/_exceptions.py +9 -37
  24. squirrels/_initializer.py +31 -26
  25. squirrels/_manifest.py +5 -5
  26. squirrels/_model_builder.py +1 -1
  27. squirrels/_model_configs.py +2 -2
  28. squirrels/_model_queries.py +1 -1
  29. squirrels/_models.py +40 -27
  30. squirrels/{package_data → _package_data}/base_project/.env +1 -0
  31. squirrels/{package_data → _package_data}/base_project/.env.example +1 -0
  32. squirrels/{package_data → _package_data}/base_project/dashboards/dashboard_example.py +4 -4
  33. squirrels/{package_data → _package_data}/base_project/dashboards/dashboard_example.yml +2 -2
  34. squirrels/_package_data/base_project/macros/macros_example.sql +17 -0
  35. squirrels/{package_data → _package_data}/base_project/models/builds/build_example.py +2 -2
  36. squirrels/{package_data → _package_data}/base_project/models/builds/build_example.sql +1 -1
  37. squirrels/{package_data → _package_data}/base_project/models/dbviews/dbview_example.sql +1 -1
  38. squirrels/_package_data/base_project/models/federates/federate_example.py +41 -0
  39. squirrels/_package_data/base_project/models/federates/federate_example.sql +25 -0
  40. squirrels/{package_data → _package_data}/base_project/models/federates/federate_example.yml +6 -6
  41. squirrels/{package_data → _package_data}/base_project/parameters.yml +9 -8
  42. squirrels/_package_data/base_project/pyconfigs/connections.py +14 -0
  43. squirrels/{package_data → _package_data}/base_project/pyconfigs/context.py +14 -16
  44. squirrels/_package_data/base_project/pyconfigs/parameters.py +106 -0
  45. squirrels/_package_data/base_project/pyconfigs/user.py +51 -0
  46. squirrels/_package_data/templates/dataset_results.html +112 -0
  47. squirrels/_package_data/templates/oauth_login.html +271 -0
  48. squirrels/_parameter_configs.py +35 -35
  49. squirrels/_parameter_options.py +348 -0
  50. squirrels/_parameter_sets.py +47 -37
  51. squirrels/_parameters.py +1664 -0
  52. squirrels/_project.py +76 -32
  53. squirrels/_py_module.py +3 -2
  54. squirrels/_schemas/__init__.py +0 -0
  55. squirrels/_schemas/auth_models.py +144 -0
  56. squirrels/_schemas/query_param_models.py +67 -0
  57. squirrels/{_api_response_models.py → _schemas/response_models.py} +12 -8
  58. squirrels/_utils.py +38 -4
  59. squirrels/arguments.py +2 -0
  60. squirrels/auth.py +1 -0
  61. squirrels/connections.py +1 -0
  62. squirrels/dashboards.py +1 -82
  63. squirrels/data_sources.py +8 -563
  64. squirrels/parameter_options.py +8 -348
  65. squirrels/parameters.py +9 -1266
  66. squirrels/types.py +11 -0
  67. {squirrels-0.5.0b2.dist-info → squirrels-0.5.0b4.dist-info}/METADATA +4 -1
  68. squirrels-0.5.0b4.dist-info/RECORD +94 -0
  69. squirrels/package_data/base_project/macros/macros_example.sql +0 -15
  70. squirrels/package_data/base_project/models/federates/federate_example.py +0 -44
  71. squirrels/package_data/base_project/models/federates/federate_example.sql +0 -17
  72. squirrels/package_data/base_project/pyconfigs/connections.py +0 -14
  73. squirrels/package_data/base_project/pyconfigs/parameters.py +0 -93
  74. squirrels/package_data/base_project/pyconfigs/user.py +0 -23
  75. squirrels-0.5.0b2.dist-info/RECORD +0 -70
  76. /squirrels/{dataset_result.py → _dataset_types.py} +0 -0
  77. /squirrels/{package_data → _package_data}/base_project/assets/expenses.db +0 -0
  78. /squirrels/{package_data → _package_data}/base_project/assets/weather.db +0 -0
  79. /squirrels/{package_data → _package_data}/base_project/connections.yml +0 -0
  80. /squirrels/{package_data → _package_data}/base_project/docker/.dockerignore +0 -0
  81. /squirrels/{package_data → _package_data}/base_project/docker/Dockerfile +0 -0
  82. /squirrels/{package_data → _package_data}/base_project/docker/compose.yml +0 -0
  83. /squirrels/{package_data → _package_data}/base_project/duckdb_init.sql +0 -0
  84. /squirrels/{package_data/base_project/.gitignore → _package_data/base_project/gitignore} +0 -0
  85. /squirrels/{package_data → _package_data}/base_project/models/builds/build_example.yml +0 -0
  86. /squirrels/{package_data → _package_data}/base_project/models/dbviews/dbview_example.yml +0 -0
  87. /squirrels/{package_data → _package_data}/base_project/models/sources.yml +0 -0
  88. /squirrels/{package_data → _package_data}/base_project/seeds/seed_categories.csv +0 -0
  89. /squirrels/{package_data → _package_data}/base_project/seeds/seed_categories.yml +0 -0
  90. /squirrels/{package_data → _package_data}/base_project/seeds/seed_subcategories.csv +0 -0
  91. /squirrels/{package_data → _package_data}/base_project/seeds/seed_subcategories.yml +0 -0
  92. /squirrels/{package_data → _package_data}/base_project/squirrels.yml.j2 +0 -0
  93. /squirrels/{package_data → _package_data}/base_project/tmp/.gitignore +0 -0
  94. {squirrels-0.5.0b2.dist-info → squirrels-0.5.0b4.dist-info}/WHEEL +0 -0
  95. {squirrels-0.5.0b2.dist-info → squirrels-0.5.0b4.dist-info}/entry_points.txt +0 -0
  96. {squirrels-0.5.0b2.dist-info → squirrels-0.5.0b4.dist-info}/licenses/LICENSE +0 -0
@@ -4,8 +4,8 @@ from sqlalchemy import Engine
4
4
  import time, polars as pl
5
5
 
6
6
  from . import _utils as u, _constants as c, _py_module as pm
7
- from .arguments.init_time_args import ConnectionsArgs
8
- from ._manifest import ManifestConfig, ConnectionProperties, ConnectionType
7
+ from ._arguments.init_time_args import ConnectionsArgs
8
+ from ._manifest import ManifestConfig, ConnectionProperties, ConnectionTypeEnum
9
9
 
10
10
 
11
11
  @dataclass
@@ -31,11 +31,11 @@ class ConnectionSet:
31
31
  def run_sql_query_from_conn_name(self, query: str, conn_name: str, placeholders: dict = {}) -> pl.DataFrame:
32
32
  conn = self.get_connection(conn_name)
33
33
  try:
34
- if isinstance(conn, ConnectionProperties) and (conn.type == ConnectionType.CONNECTORX or conn.type == ConnectionType.ADBC):
34
+ if isinstance(conn, ConnectionProperties) and (conn.type == ConnectionTypeEnum.CONNECTORX or conn.type == ConnectionTypeEnum.ADBC):
35
35
  if len(placeholders) > 0:
36
36
  raise u.ConfigurationError(f"Connection '{conn_name}' is a ConnectorX or ADBC connection, which does not support placeholders")
37
37
  df = pl.read_database_uri(query, conn.uri, engine=conn.type.value)
38
- elif isinstance(conn, ConnectionProperties) and conn.type == ConnectionType.SQLALCHEMY:
38
+ elif isinstance(conn, ConnectionProperties) and conn.type == ConnectionTypeEnum.SQLALCHEMY:
39
39
  with conn.engine.connect() as connection:
40
40
  df = pl.read_database(query, connection, execute_options={"parameters": placeholders})
41
41
  else:
@@ -52,7 +52,7 @@ class ConnectionSet:
52
52
  if isinstance(conn, Engine):
53
53
  conn.dispose()
54
54
  elif isinstance(conn, ConnectionProperties):
55
- if conn.type == ConnectionType.SQLALCHEMY:
55
+ if conn.type == ConnectionTypeEnum.SQLALCHEMY:
56
56
  conn.engine.dispose()
57
57
  elif hasattr(conn, 'close'):
58
58
  conn.close()
squirrels/_constants.py CHANGED
@@ -13,6 +13,7 @@ SQRL_SECRET_ADMIN_PASSWORD = 'SQRL_SECRET__ADMIN_PASSWORD'
13
13
 
14
14
  SQRL_AUTH_DB_FILE_PATH = 'SQRL_AUTH__DB_FILE_PATH'
15
15
  SQRL_AUTH_TOKEN_EXPIRE_MINUTES = 'SQRL_AUTH__TOKEN_EXPIRE_MINUTES'
16
+ SQRL_AUTH_CREDENTIAL_ORIGINS = 'SQRL_AUTH__ALLOWED_ORIGINS_FOR_COOKIES'
16
17
 
17
18
  SQRL_PARAMETERS_CACHE_SIZE = 'SQRL_PARAMETERS__CACHE_SIZE'
18
19
  SQRL_PARAMETERS_CACHE_TTL_MINUTES = 'SQRL_PARAMETERS__CACHE_TTL_MINUTES'
@@ -33,7 +34,7 @@ SQRL_CONNECTIONS_DEFAULT_NAME_USED = 'SQRL_CONNECTIONS__DEFAULT_NAME_USED'
33
34
  SQRL_DUCKDB_VENV_DB_FILE_PATH = 'SQRL_DUCKDB_VENV__DB_FILE_PATH'
34
35
 
35
36
  # Folder/File names
36
- PACKAGE_DATA_FOLDER = 'package_data'
37
+ PACKAGE_DATA_FOLDER = '_package_data'
37
38
  BASE_PROJECT_FOLDER = 'base_project'
38
39
 
39
40
  GLOBAL_ENV_FOLDER = '.squirrels'
@@ -114,3 +115,8 @@ MAIN_FUNC = "main"
114
115
  # Regex
115
116
  DATE_REGEX = r"^\d{4}\-\d{2}\-\d{2}$"
116
117
  COLOR_REGEX = r"^#[0-9a-fA-F]{6}$"
118
+
119
+ # OAuth2
120
+ SUPPORTED_SCOPES = ['read']
121
+ SUPPORTED_GRANT_TYPES = ['authorization_code', 'refresh_token']
122
+ SUPPORTED_RESPONSE_TYPES = ['code']
@@ -2,15 +2,96 @@ from typing import Type, TypeVar, Callable, Coroutine, Any
2
2
  from enum import Enum
3
3
  from dataclasses import dataclass
4
4
  from pydantic import BaseModel, Field
5
- import os, time
5
+ import matplotlib.figure as figure
6
+ import os, time, io, abc, typing
6
7
 
7
- from .arguments.run_time_args import DashboardArgs
8
+ from ._arguments.run_time_args import DashboardArgs
8
9
  from ._py_module import PyModule
9
10
  from ._manifest import AnalyticsOutputConfig
10
11
  from ._exceptions import InvalidInputError, ConfigurationError, FileExecutionError
11
- from . import _constants as c, _utils as u, dashboards as d
12
+ from . import _constants as c, _utils as u
12
13
 
13
- T = TypeVar('T', bound=d.Dashboard)
14
+
15
+ class Dashboard(metaclass=abc.ABCMeta):
16
+ """
17
+ Abstract parent class for all Dashboard classes.
18
+ """
19
+
20
+ @property
21
+ @abc.abstractmethod
22
+ def _content(self) -> bytes | str:
23
+ pass
24
+
25
+ @property
26
+ @abc.abstractmethod
27
+ def _format(self) -> str:
28
+ pass
29
+
30
+
31
+ class PngDashboard(Dashboard):
32
+ """
33
+ Instantiate a Dashboard in PNG format from a matplotlib figure or bytes
34
+ """
35
+
36
+ def __init__(self, content: figure.Figure | io.BytesIO | bytes) -> None:
37
+ """
38
+ Constructor for PngDashboard
39
+
40
+ Arguments:
41
+ content: The content of the dashboard as a matplotlib.figure.Figure or bytes
42
+ """
43
+ if isinstance(content, figure.Figure):
44
+ buffer = io.BytesIO()
45
+ content.savefig(buffer, format=c.PNG)
46
+ content = buffer.getvalue()
47
+
48
+ if isinstance(content, io.BytesIO):
49
+ content = content.getvalue()
50
+
51
+ self.__content = content
52
+
53
+ @property
54
+ def _content(self) -> bytes:
55
+ return self.__content
56
+
57
+ @property
58
+ def _format(self) -> typing.Literal['png']:
59
+ return c.PNG
60
+
61
+ def _repr_png_(self):
62
+ return self._content
63
+
64
+
65
+ class HtmlDashboard(Dashboard):
66
+ """
67
+ Instantiate a Dashboard from an HTML string
68
+ """
69
+
70
+ def __init__(self, content: io.StringIO | str) -> None:
71
+ """
72
+ Constructor for HtmlDashboard
73
+
74
+ Arguments:
75
+ content: The content of the dashboard as HTML string
76
+ """
77
+ if isinstance(content, io.StringIO):
78
+ content = content.getvalue()
79
+
80
+ self.__content = content
81
+
82
+ @property
83
+ def _content(self) -> str:
84
+ return self.__content
85
+
86
+ @property
87
+ def _format(self) -> typing.Literal['html']:
88
+ return c.HTML
89
+
90
+ def _repr_html_(self):
91
+ return self._content
92
+
93
+
94
+ T = TypeVar('T', bound=Dashboard)
14
95
 
15
96
 
16
97
  class DashboardFormat(Enum):
@@ -34,7 +115,7 @@ class DashboardDefinition:
34
115
  config: DashboardConfig
35
116
 
36
117
  @property
37
- def dashboard_func(self) -> Callable[[DashboardArgs], Coroutine[Any, Any, d.Dashboard]]:
118
+ def dashboard_func(self) -> Callable[[DashboardArgs], Coroutine[Any, Any, Dashboard]]:
38
119
  if not hasattr(self, '_dashboard_func'):
39
120
  module = PyModule(self.filepath)
40
121
  self._dashboard_func = module.get_func_or_class(c.MAIN_FUNC)
@@ -43,7 +124,7 @@ class DashboardDefinition:
43
124
  def get_dashboard_format(self) -> str:
44
125
  return self.config.format.value
45
126
 
46
- async def get_dashboard(self, args: DashboardArgs, *, dashboard_type: Type[T] = d.Dashboard) -> T:
127
+ async def get_dashboard(self, args: DashboardArgs, *, dashboard_type: Type[T] = Dashboard) -> T:
47
128
  try:
48
129
  dashboard = await self.dashboard_func(args)
49
130
  assert isinstance(dashboard, dashboard_type), f"Function does not return expected Dashboard type: {dashboard_type}"