core-lens 0.1.dev86__tar.gz → 0.1.dev89__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.
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/PKG-INFO +1 -1
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/_version.py +2 -2
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/aoi.py +1 -1
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/base/result.py +2 -2
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/utils/season.py +20 -1
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_season.py +30 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.github/pull_request_template.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.github/workflows/ci.yml +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.github/workflows/gh-pages.yml +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.github/workflows/pre-release.yml +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.github/workflows/release.yml +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.gitignore +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.gitmessage +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.pre-commit-config.yaml +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/.python-version +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/CONTRIBUTING.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/LICENSE +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/README.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/SKILLS.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/Makefile +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/make.bat +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/concepts.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/conf.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/index.rst +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/intro.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/plots.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/plugins.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/queries.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/quickstart.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/docs/source/stats.md +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/examples/demo_mws.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/examples/demo_tehsil.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/hooks/mypy.sh +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/hooks/no-parquet-outside-fixtures.sh +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/hooks/pytest.sh +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/pyproject.toml +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/__init__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/__main__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/base/__init__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/base/entity.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/base/namespaces/__init__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/base/namespaces/plot.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/base/namespaces/stats.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/base/view.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/entities/__init__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/entities/mws.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/entities/tehsil.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/export/__init__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/export/formats.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/py.typed +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/schema/__init__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/schema/detection.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/schema/profile.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/utils/__init__.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/utils/polars_utils.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/src/core_lens/utils/spatial.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/fixtures/generate_fixtures.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/conftest.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_aoi.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_entities.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_entity.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_export.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_main.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_plot.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_polars_utils.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_profile.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_result.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_schema_detection.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_schema_profile.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_season_config.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_spatial.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_stats.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/tests/unit/test_view.py +0 -0
- {core_lens-0.1.dev86 → core_lens-0.1.dev89}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: core-lens
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.dev89
|
|
4
4
|
Summary: Query, analyse, and visualise CoreStack's microwatershed and Earth science data through a clean, composable Python API.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ApoorvaKashyap/core-lens
|
|
6
6
|
Project-URL: Issues, https://github.com/ApoorvaKashyap/core-lens/issues
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.1.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1, '
|
|
21
|
+
__version__ = version = '0.1.dev89'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 'dev89')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -235,12 +235,12 @@ class Result:
|
|
|
235
235
|
)
|
|
236
236
|
|
|
237
237
|
if by is None:
|
|
238
|
-
new_data = self.data.group_by(self.key_cols).agg(exprs)
|
|
238
|
+
new_data = self.data.group_by(self.key_cols).agg(*exprs)
|
|
239
239
|
else:
|
|
240
240
|
# Temporal grouping columns are expected to already exist on the
|
|
241
241
|
# frame (added by the materialisation layer from the time column).
|
|
242
242
|
group_cols = self.key_cols + [by]
|
|
243
|
-
new_data = self.data.group_by(group_cols).agg(exprs)
|
|
243
|
+
new_data = self.data.group_by(group_cols).agg(*exprs)
|
|
244
244
|
|
|
245
245
|
return self._replace(data=new_data)
|
|
246
246
|
|
|
@@ -81,7 +81,26 @@ def _date_range_expr(time_col: str, start: str, end: str) -> pl.Expr:
|
|
|
81
81
|
start_date = datetime.date.fromisoformat(start)
|
|
82
82
|
end_date = datetime.date.fromisoformat(end)
|
|
83
83
|
col = pl.col(time_col)
|
|
84
|
-
|
|
84
|
+
|
|
85
|
+
# We use cast to string to avoid ComputeError when the column is an integer,
|
|
86
|
+
# but still allow exact date comparison.
|
|
87
|
+
# For integer year columns (e.g., 2020), cast to string yields "2020".
|
|
88
|
+
# For date columns, cast to string yields "2020-01-01".
|
|
89
|
+
# So we compare strings directly! Lexicographical string comparison works perfectly for ISO-8601 dates and 4-digit years.
|
|
90
|
+
# For year integers, "2020" >= "2020-01-01" is False.
|
|
91
|
+
# Wait, "2020" < "2020-01-01". So if it's an integer, "2020" will not be between "2020-01-01" and "2023-12-31" because "2020" is less than "2020-01-01".
|
|
92
|
+
# To fix this, we can extract the year for the integer comparison using a regex or length check.
|
|
93
|
+
# Better: check the length of the casted string. If 4, it's a year.
|
|
94
|
+
s_col = col.cast(pl.String)
|
|
95
|
+
is_year_int = s_col.str.len_bytes() == 4
|
|
96
|
+
|
|
97
|
+
# Use strict=False so "2020-01-01" casts to null instead of raising ComputeError
|
|
98
|
+
year_expr = s_col.cast(pl.Int32, strict=False).is_between(
|
|
99
|
+
start_date.year, end_date.year
|
|
100
|
+
)
|
|
101
|
+
date_expr = s_col.is_between(pl.lit(start), pl.lit(end))
|
|
102
|
+
|
|
103
|
+
return pl.when(is_year_int).then(year_expr).otherwise(date_expr)
|
|
85
104
|
|
|
86
105
|
|
|
87
106
|
def _season_expr(
|
|
@@ -31,6 +31,36 @@ class TestResolveTimeFilter:
|
|
|
31
31
|
assert "date" in str(expr)
|
|
32
32
|
# We can't strictly assert string contents, but we know it's built successfully
|
|
33
33
|
|
|
34
|
+
def test_date_range_evaluation_on_types(self, season_config: SeasonConfig) -> None:
|
|
35
|
+
df = pl.DataFrame(
|
|
36
|
+
{
|
|
37
|
+
"year_int": [2019, 2020, 2021],
|
|
38
|
+
"date_col": [
|
|
39
|
+
datetime.date(2019, 6, 1),
|
|
40
|
+
datetime.date(2020, 1, 15),
|
|
41
|
+
datetime.date(2021, 1, 1),
|
|
42
|
+
],
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Test integer year column
|
|
47
|
+
expr_int = resolve_time_filter(
|
|
48
|
+
{"start": "2020-01-01", "end": "2020-12-31"},
|
|
49
|
+
time_col="year_int",
|
|
50
|
+
season_config=season_config,
|
|
51
|
+
)
|
|
52
|
+
res_int = df.filter(expr_int)
|
|
53
|
+
assert res_int["year_int"].to_list() == [2020]
|
|
54
|
+
|
|
55
|
+
# Test Date column
|
|
56
|
+
expr_date = resolve_time_filter(
|
|
57
|
+
{"start": "2020-01-01", "end": "2020-12-31"},
|
|
58
|
+
time_col="date_col",
|
|
59
|
+
season_config=season_config,
|
|
60
|
+
)
|
|
61
|
+
res_date = df.filter(expr_date)
|
|
62
|
+
assert res_date["year_int"].to_list() == [2020]
|
|
63
|
+
|
|
34
64
|
def test_season_no_year(self, season_config: SeasonConfig) -> None:
|
|
35
65
|
expr = resolve_time_filter(
|
|
36
66
|
{"season": "kharif"},
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|