squirrels 0.5.0b2__tar.gz → 0.5.0b4__tar.gz
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-0.5.0b2 → squirrels-0.5.0b4}/.gitignore +2 -1
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/PKG-INFO +4 -1
- squirrels-0.5.0b4/dateutils/__init__.py +6 -0
- squirrels-0.5.0b4/dateutils/_enums.py +25 -0
- squirrels-0.5.0b2/dateutils/__init__.py → squirrels-0.5.0b4/dateutils/_implementation.py +56 -107
- squirrels-0.5.0b4/dateutils/types.py +6 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/pyproject.toml +4 -1
- squirrels-0.5.0b4/squirrels/__init__.py +19 -0
- squirrels-0.5.0b4/squirrels/_api_routes/__init__.py +5 -0
- squirrels-0.5.0b4/squirrels/_api_routes/auth.py +262 -0
- squirrels-0.5.0b4/squirrels/_api_routes/base.py +154 -0
- squirrels-0.5.0b4/squirrels/_api_routes/dashboards.py +142 -0
- squirrels-0.5.0b4/squirrels/_api_routes/data_management.py +103 -0
- squirrels-0.5.0b4/squirrels/_api_routes/datasets.py +242 -0
- squirrels-0.5.0b4/squirrels/_api_routes/oauth2.py +300 -0
- squirrels-0.5.0b4/squirrels/_api_routes/project.py +214 -0
- squirrels-0.5.0b4/squirrels/_api_server.py +301 -0
- squirrels-0.5.0b4/squirrels/_arguments/__init__.py +0 -0
- {squirrels-0.5.0b2/squirrels/arguments → squirrels-0.5.0b4/squirrels/_arguments}/init_time_args.py +7 -2
- {squirrels-0.5.0b2/squirrels/arguments → squirrels-0.5.0b4/squirrels/_arguments}/run_time_args.py +4 -26
- squirrels-0.5.0b4/squirrels/_auth.py +1004 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_connection_set.py +5 -5
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_constants.py +7 -1
- squirrels-0.5.0b2/squirrels/_dashboards_io.py → squirrels-0.5.0b4/squirrels/_dashboards.py +87 -6
- squirrels-0.5.0b2/squirrels/data_sources.py → squirrels-0.5.0b4/squirrels/_data_sources.py +56 -55
- squirrels-0.5.0b4/squirrels/_exceptions.py +29 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_initializer.py +31 -26
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_manifest.py +5 -5
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_model_builder.py +1 -1
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_model_configs.py +2 -2
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_model_queries.py +1 -1
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_models.py +40 -27
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/.env +1 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/.env.example +1 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/dashboards/dashboard_example.py +4 -4
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/dashboards/dashboard_example.yml +2 -2
- squirrels-0.5.0b4/squirrels/_package_data/base_project/macros/macros_example.sql +17 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/models/builds/build_example.py +2 -2
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/models/builds/build_example.sql +1 -1
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/models/dbviews/dbview_example.sql +1 -1
- squirrels-0.5.0b4/squirrels/_package_data/base_project/models/federates/federate_example.py +41 -0
- squirrels-0.5.0b4/squirrels/_package_data/base_project/models/federates/federate_example.sql +25 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/models/federates/federate_example.yml +6 -6
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/parameters.yml +9 -8
- squirrels-0.5.0b4/squirrels/_package_data/base_project/pyconfigs/connections.py +14 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/pyconfigs/context.py +14 -16
- squirrels-0.5.0b4/squirrels/_package_data/base_project/pyconfigs/parameters.py +106 -0
- squirrels-0.5.0b4/squirrels/_package_data/base_project/pyconfigs/user.py +51 -0
- squirrels-0.5.0b4/squirrels/_package_data/templates/dataset_results.html +112 -0
- squirrels-0.5.0b4/squirrels/_package_data/templates/oauth_login.html +271 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_parameter_configs.py +35 -35
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_parameter_sets.py +47 -37
- squirrels-0.5.0b2/squirrels/parameters.py → squirrels-0.5.0b4/squirrels/_parameters.py +552 -154
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_project.py +76 -32
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_py_module.py +3 -2
- squirrels-0.5.0b4/squirrels/_schemas/__init__.py +0 -0
- squirrels-0.5.0b4/squirrels/_schemas/auth_models.py +144 -0
- squirrels-0.5.0b4/squirrels/_schemas/query_param_models.py +67 -0
- squirrels-0.5.0b2/squirrels/_api_response_models.py → squirrels-0.5.0b4/squirrels/_schemas/response_models.py +12 -8
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_utils.py +38 -4
- squirrels-0.5.0b4/squirrels/arguments.py +2 -0
- squirrels-0.5.0b4/squirrels/auth.py +1 -0
- squirrels-0.5.0b4/squirrels/connections.py +1 -0
- squirrels-0.5.0b4/squirrels/dashboards.py +1 -0
- squirrels-0.5.0b4/squirrels/data_sources.py +8 -0
- squirrels-0.5.0b4/squirrels/parameter_options.py +8 -0
- squirrels-0.5.0b4/squirrels/parameters.py +9 -0
- squirrels-0.5.0b4/squirrels/types.py +11 -0
- squirrels-0.5.0b2/squirrels/__init__.py +0 -23
- squirrels-0.5.0b2/squirrels/_api_server.py +0 -904
- squirrels-0.5.0b2/squirrels/_auth.py +0 -451
- squirrels-0.5.0b2/squirrels/_exceptions.py +0 -57
- squirrels-0.5.0b2/squirrels/dashboards.py +0 -82
- squirrels-0.5.0b2/squirrels/package_data/base_project/macros/macros_example.sql +0 -15
- squirrels-0.5.0b2/squirrels/package_data/base_project/models/federates/federate_example.py +0 -44
- squirrels-0.5.0b2/squirrels/package_data/base_project/models/federates/federate_example.sql +0 -17
- squirrels-0.5.0b2/squirrels/package_data/base_project/pyconfigs/connections.py +0 -14
- squirrels-0.5.0b2/squirrels/package_data/base_project/pyconfigs/parameters.py +0 -93
- squirrels-0.5.0b2/squirrels/package_data/base_project/pyconfigs/user.py +0 -23
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/LICENSE +0 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/README.md +0 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_command_line.py +0 -0
- /squirrels-0.5.0b2/squirrels/dataset_result.py → /squirrels-0.5.0b4/squirrels/_dataset_types.py +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/assets/expenses.db +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/assets/weather.db +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/connections.yml +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/docker/.dockerignore +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/docker/Dockerfile +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/docker/compose.yml +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/duckdb_init.sql +0 -0
- /squirrels-0.5.0b2/squirrels/package_data/base_project/.gitignore → /squirrels-0.5.0b4/squirrels/_package_data/base_project/gitignore +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/models/builds/build_example.yml +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/models/dbviews/dbview_example.yml +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/models/sources.yml +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/seeds/seed_categories.csv +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/seeds/seed_categories.yml +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/seeds/seed_subcategories.csv +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/seeds/seed_subcategories.yml +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/squirrels.yml.j2 +0 -0
- {squirrels-0.5.0b2/squirrels/package_data → squirrels-0.5.0b4/squirrels/_package_data}/base_project/tmp/.gitignore +0 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_package_loader.py +0 -0
- /squirrels-0.5.0b2/squirrels/parameter_options.py → /squirrels-0.5.0b4/squirrels/_parameter_options.py +0 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_seeds.py +0 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_sources.py +0 -0
- {squirrels-0.5.0b2 → squirrels-0.5.0b4}/squirrels/_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: squirrels
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.0b4
|
|
4
4
|
Summary: Squirrels - API Framework for Data Analytics
|
|
5
5
|
Project-URL: Homepage, https://squirrels-analytics.github.io
|
|
6
6
|
Project-URL: Repository, https://github.com/squirrels-analytics/squirrels
|
|
@@ -13,15 +13,18 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
|
13
13
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
14
|
Classifier: Typing :: Typed
|
|
15
15
|
Requires-Python: ~=3.10
|
|
16
|
+
Requires-Dist: authlib<2,>=1.5.2
|
|
16
17
|
Requires-Dist: bcrypt<5,>=4.0.1
|
|
17
18
|
Requires-Dist: cachetools<6,>=5.3.2
|
|
18
19
|
Requires-Dist: duckdb<2,>=1.1.3
|
|
19
20
|
Requires-Dist: fastapi<1,>=0.112.1
|
|
20
21
|
Requires-Dist: gitpython<4,>=3.1.41
|
|
21
22
|
Requires-Dist: inquirer<4,>=3.2.1
|
|
23
|
+
Requires-Dist: itsdangerous<3,>=2.2.0
|
|
22
24
|
Requires-Dist: jinja2<4,>=3.1.3
|
|
23
25
|
Requires-Dist: libpass<2,>=1.9.0
|
|
24
26
|
Requires-Dist: matplotlib<4,>=3.8.3
|
|
27
|
+
Requires-Dist: mcp>=1.9.2
|
|
25
28
|
Requires-Dist: networkx<4,>=3.2.1
|
|
26
29
|
Requires-Dist: pandas<3,>=2.1.4
|
|
27
30
|
Requires-Dist: polars<2,>=1.14.0
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from ._enums import DayOfWeekEnum, MonthEnum
|
|
2
|
+
from ._implementation import (
|
|
3
|
+
DayIdxOfMonthsCycle, DayIdxOfYear, DayIdxOfQuarter, DayIdxOfMonth, DayIdxOfWeek,
|
|
4
|
+
OffsetYears, OffsetMonths, OffsetWeeks, OffsetDays,
|
|
5
|
+
DateModPipeline, DateStringModifier, TimestampModifier
|
|
6
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DayOfWeekEnum(Enum):
|
|
5
|
+
Sunday = 0
|
|
6
|
+
Monday = 1
|
|
7
|
+
Tuesday = 2
|
|
8
|
+
Wednesday = 3
|
|
9
|
+
Thursday = 4
|
|
10
|
+
Friday = 5
|
|
11
|
+
Saturday = 6
|
|
12
|
+
|
|
13
|
+
class MonthEnum(Enum):
|
|
14
|
+
January = 1
|
|
15
|
+
February = 2
|
|
16
|
+
March = 3
|
|
17
|
+
April = 4
|
|
18
|
+
May = 5
|
|
19
|
+
June = 6
|
|
20
|
+
July = 7
|
|
21
|
+
August = 8
|
|
22
|
+
September = 9
|
|
23
|
+
October = 10
|
|
24
|
+
November = 11
|
|
25
|
+
December = 12
|
|
@@ -3,31 +3,8 @@ from dataclasses import dataclass
|
|
|
3
3
|
from datetime import date as Date, datetime
|
|
4
4
|
from dateutil.relativedelta import relativedelta
|
|
5
5
|
from abc import ABCMeta, abstractmethod
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class DayOfWeek(Enum):
|
|
10
|
-
Sunday = 0
|
|
11
|
-
Monday = 1
|
|
12
|
-
Tuesday = 2
|
|
13
|
-
Wednesday = 3
|
|
14
|
-
Thursday = 4
|
|
15
|
-
Friday = 5
|
|
16
|
-
Saturday = 6
|
|
17
|
-
|
|
18
|
-
class Month(Enum):
|
|
19
|
-
January = 1
|
|
20
|
-
February = 2
|
|
21
|
-
March = 3
|
|
22
|
-
April = 4
|
|
23
|
-
May = 5
|
|
24
|
-
June = 6
|
|
25
|
-
July = 7
|
|
26
|
-
August = 8
|
|
27
|
-
September = 9
|
|
28
|
-
October = 10
|
|
29
|
-
November = 11
|
|
30
|
-
December = 12
|
|
6
|
+
|
|
7
|
+
from ._enums import DayOfWeekEnum, MonthEnum
|
|
31
8
|
|
|
32
9
|
|
|
33
10
|
class DateModifier(metaclass=ABCMeta):
|
|
@@ -52,20 +29,21 @@ class DateModifier(metaclass=ABCMeta):
|
|
|
52
29
|
return datetype(year, month, day)
|
|
53
30
|
|
|
54
31
|
|
|
55
|
-
|
|
32
|
+
@dataclass
|
|
33
|
+
class DayIdxOfCalendarUnit(DateModifier):
|
|
56
34
|
"""
|
|
57
35
|
Interface for adjusting a date to some day of calendar unit
|
|
58
36
|
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
37
|
+
idx: int
|
|
38
|
+
|
|
39
|
+
def __post_init__(self) -> None:
|
|
62
40
|
if self.idx == 0:
|
|
63
41
|
raise ValueError(f"For constructors of class names that start with DayIdxOf_, idx cannot be zero")
|
|
64
42
|
self.incr = self.idx - 1 if self.idx > 0 else self.idx
|
|
65
43
|
|
|
66
44
|
|
|
67
45
|
@dataclass
|
|
68
|
-
class DayIdxOfMonthsCycle(
|
|
46
|
+
class DayIdxOfMonthsCycle(DayIdxOfCalendarUnit):
|
|
69
47
|
"""
|
|
70
48
|
DateModifier class to get the idx-th day of a cycle of months for an input date
|
|
71
49
|
|
|
@@ -74,23 +52,21 @@ class DayIdxOfMonthsCycle(_DayIdxOfCalendarUnit):
|
|
|
74
52
|
num_months_in_cycle: 2 for one 6th of year, 3 for Quarter, 4 for one 3rd of year, 6 for half year, 12 for full year. Must fit evenly in 12
|
|
75
53
|
first_month_of_cycle: The first month of months cycle of year. Default is January
|
|
76
54
|
"""
|
|
77
|
-
|
|
78
|
-
|
|
55
|
+
num_months_in_cycle: int
|
|
56
|
+
first_month_of_cycle: MonthEnum = MonthEnum.January
|
|
79
57
|
|
|
80
|
-
def
|
|
81
|
-
super().
|
|
82
|
-
self.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
raise ValueError(f"Value X must fit evenly in 12")
|
|
86
|
-
self.first_month_of_first_cycle = (self._first_month_of_cycle.value - 1) % self._num_months_in_cycle + 1
|
|
58
|
+
def __post_init__(self) -> None:
|
|
59
|
+
super().__post_init__()
|
|
60
|
+
if 12 % self.num_months_in_cycle != 0:
|
|
61
|
+
raise ValueError(f"Argument 'num_months_in_cycle' must fit evenly in 12")
|
|
62
|
+
self.first_month_of_first_cycle = (self.first_month_of_cycle.value - 1) % self.num_months_in_cycle + 1
|
|
87
63
|
|
|
88
64
|
def modify(self, date: Date) -> Date:
|
|
89
|
-
current_cycle = (date.month - self.first_month_of_first_cycle) % 12 // self.
|
|
90
|
-
first_month_of_curr_cycle = current_cycle * self.
|
|
65
|
+
current_cycle = (date.month - self.first_month_of_first_cycle) % 12 // self.num_months_in_cycle
|
|
66
|
+
first_month_of_curr_cycle = current_cycle * self.num_months_in_cycle + self.first_month_of_first_cycle
|
|
91
67
|
year = date.year if date.month >= first_month_of_curr_cycle else date.year - 1
|
|
92
68
|
first_day = self._get_date(type(date), year, first_month_of_curr_cycle, 1)
|
|
93
|
-
ref_date = first_day if self.idx > 0 else first_day + relativedelta(months=self.
|
|
69
|
+
ref_date = first_day if self.idx > 0 else first_day + relativedelta(months=self.num_months_in_cycle)
|
|
94
70
|
return ref_date + relativedelta(days=self.incr)
|
|
95
71
|
|
|
96
72
|
|
|
@@ -104,7 +80,7 @@ class DayIdxOfYear(DayIdxOfMonthsCycle):
|
|
|
104
80
|
first_month_of_year: The first month of year. Default is January
|
|
105
81
|
"""
|
|
106
82
|
|
|
107
|
-
def __init__(self, idx: int, first_month_of_year:
|
|
83
|
+
def __init__(self, idx: int, first_month_of_year: MonthEnum = MonthEnum.January):
|
|
108
84
|
super().__init__(idx, num_months_in_cycle=12, first_month_of_cycle=first_month_of_year)
|
|
109
85
|
|
|
110
86
|
|
|
@@ -118,12 +94,12 @@ class DayIdxOfQuarter(DayIdxOfMonthsCycle):
|
|
|
118
94
|
first_month_of_quarter: The first month of first quarter. Default is January
|
|
119
95
|
"""
|
|
120
96
|
|
|
121
|
-
def __init__(self, idx: int, first_month_of_quarter:
|
|
97
|
+
def __init__(self, idx: int, first_month_of_quarter: MonthEnum = MonthEnum.January):
|
|
122
98
|
super().__init__(idx, num_months_in_cycle=3, first_month_of_cycle=first_month_of_quarter)
|
|
123
99
|
|
|
124
100
|
|
|
125
101
|
@dataclass
|
|
126
|
-
class DayIdxOfMonth(
|
|
102
|
+
class DayIdxOfMonth(DayIdxOfCalendarUnit):
|
|
127
103
|
"""
|
|
128
104
|
DateModifier class to get the idx-th day of month of an input date
|
|
129
105
|
|
|
@@ -131,9 +107,6 @@ class DayIdxOfMonth(_DayIdxOfCalendarUnit):
|
|
|
131
107
|
idx: 1 for first, 2 for second, etc. Or, -1 for last, -2 for second last, etc. Must not be 0
|
|
132
108
|
"""
|
|
133
109
|
|
|
134
|
-
def __init__(self, idx: int) -> None:
|
|
135
|
-
super().__init__(idx)
|
|
136
|
-
|
|
137
110
|
def modify(self, date: Date) -> Date:
|
|
138
111
|
first_day = self._get_date(type(date), date.year, date.month, 1)
|
|
139
112
|
ref_date = first_day if self.idx > 0 else first_day + relativedelta(months=1)
|
|
@@ -141,7 +114,7 @@ class DayIdxOfMonth(_DayIdxOfCalendarUnit):
|
|
|
141
114
|
|
|
142
115
|
|
|
143
116
|
@dataclass
|
|
144
|
-
class DayIdxOfWeek(
|
|
117
|
+
class DayIdxOfWeek(DayIdxOfCalendarUnit):
|
|
145
118
|
"""
|
|
146
119
|
DateModifier class to get the idx-th day of week of an input date
|
|
147
120
|
|
|
@@ -149,12 +122,11 @@ class DayIdxOfWeek(_DayIdxOfCalendarUnit):
|
|
|
149
122
|
idx: 1 for first, 2 for second, etc. Or, -1 for last, -2 for second last, etc. Must not be 0
|
|
150
123
|
first_day_of_week: The day of week identified as the "first". Default is Monday
|
|
151
124
|
"""
|
|
152
|
-
|
|
125
|
+
first_day_of_week: DayOfWeekEnum = DayOfWeekEnum.Monday
|
|
153
126
|
|
|
154
|
-
def
|
|
155
|
-
super().
|
|
156
|
-
self.
|
|
157
|
-
self.first_dow_num = self._first_day_of_week.value
|
|
127
|
+
def __post_init__(self) -> None:
|
|
128
|
+
super().__post_init__()
|
|
129
|
+
self.first_dow_num = self.first_day_of_week.value
|
|
158
130
|
|
|
159
131
|
def modify(self, date: Date) -> Date:
|
|
160
132
|
distance_from_first_day = (1 + date.weekday() - self.first_dow_num) % 7
|
|
@@ -162,17 +134,16 @@ class DayIdxOfWeek(_DayIdxOfCalendarUnit):
|
|
|
162
134
|
return date + relativedelta(days=total_incr)
|
|
163
135
|
|
|
164
136
|
|
|
165
|
-
|
|
137
|
+
@dataclass
|
|
138
|
+
class OffsetUnits(DateModifier):
|
|
166
139
|
"""
|
|
167
140
|
Abstract DateModifier class to offset an input date by some number of some calendar unit
|
|
168
141
|
"""
|
|
169
|
-
|
|
170
|
-
super().__init__()
|
|
171
|
-
self.offset = offset
|
|
142
|
+
offset: int
|
|
172
143
|
|
|
173
144
|
|
|
174
145
|
@dataclass
|
|
175
|
-
class OffsetYears(
|
|
146
|
+
class OffsetYears(OffsetUnits):
|
|
176
147
|
"""
|
|
177
148
|
DateModifier class to offset an input date by some number of years
|
|
178
149
|
|
|
@@ -180,15 +151,12 @@ class OffsetYears(_OffsetUnits):
|
|
|
180
151
|
offset: The number of years to offset the input date.
|
|
181
152
|
"""
|
|
182
153
|
|
|
183
|
-
def __init__(self, offset: int) -> None:
|
|
184
|
-
super().__init__(offset)
|
|
185
|
-
|
|
186
154
|
def modify(self, date: Date) -> Date:
|
|
187
155
|
return date + relativedelta(years=self.offset)
|
|
188
156
|
|
|
189
157
|
|
|
190
158
|
@dataclass
|
|
191
|
-
class OffsetMonths(
|
|
159
|
+
class OffsetMonths(OffsetUnits):
|
|
192
160
|
"""
|
|
193
161
|
DateModifier class to offset an input date by some number of months
|
|
194
162
|
|
|
@@ -196,15 +164,12 @@ class OffsetMonths(_OffsetUnits):
|
|
|
196
164
|
offset: The number of months to offset the input date.
|
|
197
165
|
"""
|
|
198
166
|
|
|
199
|
-
def __init__(self, offset: int) -> None:
|
|
200
|
-
super().__init__(offset)
|
|
201
|
-
|
|
202
167
|
def modify(self, date: Date) -> Date:
|
|
203
168
|
return date + relativedelta(months=self.offset)
|
|
204
169
|
|
|
205
170
|
|
|
206
171
|
@dataclass
|
|
207
|
-
class OffsetWeeks(
|
|
172
|
+
class OffsetWeeks(OffsetUnits):
|
|
208
173
|
"""
|
|
209
174
|
DateModifier class to offset an input date by some number of weeks
|
|
210
175
|
|
|
@@ -212,15 +177,12 @@ class OffsetWeeks(_OffsetUnits):
|
|
|
212
177
|
offset: The number of weeks to offset the input date.
|
|
213
178
|
"""
|
|
214
179
|
|
|
215
|
-
def __init__(self, offset: int) -> None:
|
|
216
|
-
super().__init__(offset)
|
|
217
|
-
|
|
218
180
|
def modify(self, date: Date) -> Date:
|
|
219
181
|
return date + relativedelta(weeks=self.offset)
|
|
220
182
|
|
|
221
183
|
|
|
222
184
|
@dataclass
|
|
223
|
-
class OffsetDays(
|
|
185
|
+
class OffsetDays(OffsetUnits):
|
|
224
186
|
"""
|
|
225
187
|
DateModifier class to offset an input date by some number of days
|
|
226
188
|
|
|
@@ -228,9 +190,6 @@ class OffsetDays(_OffsetUnits):
|
|
|
228
190
|
offset: The number of days to offset the input date.
|
|
229
191
|
"""
|
|
230
192
|
|
|
231
|
-
def __init__(self, offset: int) -> None:
|
|
232
|
-
super().__init__(offset)
|
|
233
|
-
|
|
234
193
|
def modify(self, date: Date) -> Date:
|
|
235
194
|
return date + relativedelta(days=self.offset)
|
|
236
195
|
|
|
@@ -243,14 +202,10 @@ class DateModPipeline(DateModifier):
|
|
|
243
202
|
Attributes:
|
|
244
203
|
modifiers: The list of DateModifier's to apply in sequence.
|
|
245
204
|
"""
|
|
246
|
-
|
|
205
|
+
date_modifiers: Sequence[DateModifier]
|
|
247
206
|
|
|
248
|
-
def __init__(self, date_modifiers: Sequence[DateModifier]) -> None:
|
|
249
|
-
super().__init__()
|
|
250
|
-
self._date_modifiers = tuple(date_modifiers)
|
|
251
|
-
|
|
252
207
|
def modify(self, date: Date) -> Date:
|
|
253
|
-
for modifier in self.
|
|
208
|
+
for modifier in self.date_modifiers:
|
|
254
209
|
date = modifier.modify(date)
|
|
255
210
|
return date
|
|
256
211
|
|
|
@@ -265,7 +220,7 @@ class DateModPipeline(DateModifier):
|
|
|
265
220
|
Returns:
|
|
266
221
|
A new sequence of DateModifier
|
|
267
222
|
"""
|
|
268
|
-
joined_modifiers = tuple(self.
|
|
223
|
+
joined_modifiers = tuple(self.date_modifiers) + tuple(date_modifiers)
|
|
269
224
|
return joined_modifiers
|
|
270
225
|
|
|
271
226
|
def with_more_modifiers(self, date_modifiers: Sequence[DateModifier]):
|
|
@@ -298,7 +253,7 @@ class DateModPipeline(DateModifier):
|
|
|
298
253
|
Returns:
|
|
299
254
|
A list of datetime objects
|
|
300
255
|
"""
|
|
301
|
-
assert isinstance(step,
|
|
256
|
+
assert isinstance(step, OffsetUnits)
|
|
302
257
|
if step.offset == 0:
|
|
303
258
|
raise ValueError(f"The length of 'step' must not be zero")
|
|
304
259
|
|
|
@@ -313,12 +268,15 @@ class DateModPipeline(DateModifier):
|
|
|
313
268
|
return output
|
|
314
269
|
|
|
315
270
|
|
|
316
|
-
|
|
271
|
+
@dataclass
|
|
272
|
+
class DateRepresentationModifier(metaclass=ABCMeta):
|
|
317
273
|
"""
|
|
318
274
|
Abstract class for modifying other representations of dates (such as string or unix timestemp)
|
|
319
275
|
"""
|
|
320
|
-
|
|
321
|
-
|
|
276
|
+
date_modifiers: Sequence[DateModifier]
|
|
277
|
+
|
|
278
|
+
def __post_init__(self) -> None:
|
|
279
|
+
self.date_mod_pipeline = DateModPipeline(self.date_modifiers)
|
|
322
280
|
|
|
323
281
|
@abstractmethod
|
|
324
282
|
def with_more_modifiers(self, date_modifiers: Sequence[DateModifier]):
|
|
@@ -326,7 +284,7 @@ class _DateRepresentationModifier(metaclass=ABCMeta):
|
|
|
326
284
|
|
|
327
285
|
|
|
328
286
|
@dataclass
|
|
329
|
-
class DateStringModifier(
|
|
287
|
+
class DateStringModifier(DateRepresentationModifier):
|
|
330
288
|
"""
|
|
331
289
|
Class to modify a string representation of a date given a DateModifier
|
|
332
290
|
|
|
@@ -334,12 +292,7 @@ class DateStringModifier(_DateRepresentationModifier):
|
|
|
334
292
|
date_modifier: The DateModifier to apply on datetime objects
|
|
335
293
|
date_format: Format of the output date string. Default is '%Y-%m-%d'
|
|
336
294
|
"""
|
|
337
|
-
|
|
338
|
-
_date_format: str
|
|
339
|
-
|
|
340
|
-
def __init__(self, date_modifiers: Sequence[DateModifier], date_format: str = '%Y-%m-%d'):
|
|
341
|
-
super().__init__(date_modifiers)
|
|
342
|
-
self._date_format = date_format
|
|
295
|
+
date_format: str = '%Y-%m-%d'
|
|
343
296
|
|
|
344
297
|
def with_more_modifiers(self, date_modifiers: Sequence[DateModifier]):
|
|
345
298
|
"""
|
|
@@ -351,11 +304,11 @@ class DateStringModifier(_DateRepresentationModifier):
|
|
|
351
304
|
Returns:
|
|
352
305
|
A new DateStringModifier
|
|
353
306
|
"""
|
|
354
|
-
joined_modifiers = self.
|
|
355
|
-
return DateStringModifier(joined_modifiers, self.
|
|
307
|
+
joined_modifiers = self.date_mod_pipeline.get_joined_modifiers(date_modifiers)
|
|
308
|
+
return DateStringModifier(joined_modifiers, self.date_format)
|
|
356
309
|
|
|
357
310
|
def _get_input_date_obj(self, date_str: str, input_format: str | None = None) -> Date:
|
|
358
|
-
input_format = self.
|
|
311
|
+
input_format = self.date_format if input_format is None else input_format
|
|
359
312
|
return datetime.strptime(date_str, input_format).date()
|
|
360
313
|
|
|
361
314
|
def modify(self, date_str: str, input_format: str | None = None) -> str:
|
|
@@ -370,7 +323,7 @@ class DateStringModifier(_DateRepresentationModifier):
|
|
|
370
323
|
The resulting date string
|
|
371
324
|
"""
|
|
372
325
|
date_obj = self._get_input_date_obj(date_str, input_format)
|
|
373
|
-
return self.
|
|
326
|
+
return self.date_mod_pipeline.modify(date_obj).strftime(self.date_format)
|
|
374
327
|
|
|
375
328
|
def get_date_list(self, start_date_str: str, step: DateModifier, input_format: str | None = None) -> Sequence[str]:
|
|
376
329
|
"""
|
|
@@ -390,14 +343,14 @@ class DateStringModifier(_DateRepresentationModifier):
|
|
|
390
343
|
Returns:
|
|
391
344
|
A list of date strings
|
|
392
345
|
"""
|
|
393
|
-
assert isinstance(step,
|
|
346
|
+
assert isinstance(step, OffsetUnits)
|
|
394
347
|
curr_date = self._get_input_date_obj(start_date_str, input_format)
|
|
395
|
-
output = self.
|
|
396
|
-
return [x.strftime(self.
|
|
348
|
+
output = self.date_mod_pipeline.get_date_list(curr_date, step)
|
|
349
|
+
return [x.strftime(self.date_format) for x in output]
|
|
397
350
|
|
|
398
351
|
|
|
399
352
|
@dataclass
|
|
400
|
-
class TimestampModifier(
|
|
353
|
+
class TimestampModifier(DateRepresentationModifier):
|
|
401
354
|
"""
|
|
402
355
|
Class to modify a numeric representation of a date (as Unix/Epoch/POSIX timestamp) given a DateModifier
|
|
403
356
|
|
|
@@ -405,10 +358,6 @@ class TimestampModifier(_DateRepresentationModifier):
|
|
|
405
358
|
date_modifier: The DateModifier to apply on datetime objects
|
|
406
359
|
date_format: Format of the date string. Default is '%Y-%m-%d'
|
|
407
360
|
"""
|
|
408
|
-
_date_modifiers: Sequence[DateModifier]
|
|
409
|
-
|
|
410
|
-
def __init__(self, date_modifiers: Sequence[DateModifier]):
|
|
411
|
-
super().__init__(date_modifiers)
|
|
412
361
|
|
|
413
362
|
def with_more_modifiers(self, date_modifiers: Sequence[DateModifier]):
|
|
414
363
|
"""
|
|
@@ -420,7 +369,7 @@ class TimestampModifier(_DateRepresentationModifier):
|
|
|
420
369
|
Returns:
|
|
421
370
|
A new TimestampModifier
|
|
422
371
|
"""
|
|
423
|
-
joined_modifiers = self.
|
|
372
|
+
joined_modifiers = self.date_mod_pipeline.get_joined_modifiers(date_modifiers)
|
|
424
373
|
return TimestampModifier(joined_modifiers)
|
|
425
374
|
|
|
426
375
|
def modify(self, timestamp: float) -> float:
|
|
@@ -434,7 +383,7 @@ class TimestampModifier(_DateRepresentationModifier):
|
|
|
434
383
|
The resulting timestamp
|
|
435
384
|
"""
|
|
436
385
|
date_obj = datetime.fromtimestamp(timestamp).date()
|
|
437
|
-
modified_date = self.
|
|
386
|
+
modified_date = self.date_mod_pipeline.modify(date_obj)
|
|
438
387
|
modified_datetime = datetime.combine(modified_date, datetime.min.time())
|
|
439
388
|
return modified_datetime.timestamp()
|
|
440
389
|
|
|
@@ -456,5 +405,5 @@ class TimestampModifier(_DateRepresentationModifier):
|
|
|
456
405
|
A list of timestamp as floats
|
|
457
406
|
"""
|
|
458
407
|
curr_date = datetime.fromtimestamp(start_timestamp).date()
|
|
459
|
-
output = self.
|
|
408
|
+
output = self.date_mod_pipeline.get_date_list(curr_date, step)
|
|
460
409
|
return [datetime.combine(x, datetime.min.time()).timestamp() for x in output]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "squirrels"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.0b4"
|
|
4
4
|
description = "Squirrels - API Framework for Data Analytics"
|
|
5
5
|
authors = [{ name = "Tim Huang", email = "tim.yuting@hotmail.com" }]
|
|
6
6
|
requires-python = "~=3.10"
|
|
@@ -34,6 +34,9 @@ dependencies = [
|
|
|
34
34
|
"bcrypt>=4.0.1,<5",
|
|
35
35
|
"python-dotenv>=1.0.1,<2",
|
|
36
36
|
"libpass>=1.9.0,<2",
|
|
37
|
+
"authlib>=1.5.2,<2",
|
|
38
|
+
"itsdangerous>=2.2.0,<3",
|
|
39
|
+
"mcp>=1.9.2",
|
|
37
40
|
]
|
|
38
41
|
|
|
39
42
|
[project.urls]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from ._version import __version__
|
|
2
|
+
|
|
3
|
+
from .arguments import *
|
|
4
|
+
|
|
5
|
+
from .auth import *
|
|
6
|
+
|
|
7
|
+
from .connections import *
|
|
8
|
+
|
|
9
|
+
from .parameter_options import *
|
|
10
|
+
|
|
11
|
+
from .parameters import *
|
|
12
|
+
|
|
13
|
+
from .data_sources import *
|
|
14
|
+
|
|
15
|
+
from .dashboards import *
|
|
16
|
+
|
|
17
|
+
from .types import *
|
|
18
|
+
|
|
19
|
+
from ._project import SquirrelsProject
|