core-lens 0.1.dev183__tar.gz → 0.1.dev184__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.
Files changed (93) hide show
  1. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/PKG-INFO +2 -2
  2. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/_version.py +2 -2
  3. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/aoi.py +4 -2
  4. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/base/entity.py +2 -2
  5. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/utils/polars_utils.py +28 -1
  6. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/utils/spatial.py +3 -2
  7. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/ISSUE_TEMPLATE/blank-proposal.yaml +0 -0
  8. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
  9. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/ISSUE_TEMPLATE/feature-request.yaml +0 -0
  10. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/pull_request_template.md +0 -0
  11. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/workflows/ci.yml +0 -0
  12. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/workflows/gh-pages.yml +0 -0
  13. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/workflows/pre-release.yml +0 -0
  14. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.github/workflows/release.yml +0 -0
  15. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.gitignore +0 -0
  16. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.gitmessage +0 -0
  17. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.pre-commit-config.yaml +0 -0
  18. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/.python-version +0 -0
  19. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/CONTRIBUTING.md +0 -0
  20. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/LICENSE +0 -0
  21. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/README.md +0 -0
  22. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/SKILLS.md +0 -0
  23. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/README.md +0 -0
  24. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_aoi.py +0 -0
  25. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_entity.py +0 -0
  26. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_export.py +0 -0
  27. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_polars_utils.py +0 -0
  28. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_result.py +0 -0
  29. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_schema.py +0 -0
  30. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_season.py +0 -0
  31. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_spatial.py +0 -0
  32. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/bench_view.py +0 -0
  33. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/benchmarks/run_all.sh +0 -0
  34. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/Makefile +0 -0
  35. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/make.bat +0 -0
  36. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/concepts.md +0 -0
  37. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/conf.py +0 -0
  38. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/export.md +0 -0
  39. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/index.rst +0 -0
  40. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/intro.md +0 -0
  41. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/logging.md +0 -0
  42. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/plots.md +0 -0
  43. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/plugins.md +0 -0
  44. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/queries.md +0 -0
  45. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/quickstart.md +0 -0
  46. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/docs/source/stats.md +0 -0
  47. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/examples/demo_mws.py +0 -0
  48. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/examples/demo_tehsil.py +0 -0
  49. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/hooks/mypy.sh +0 -0
  50. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/hooks/no-parquet-outside-fixtures.sh +0 -0
  51. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/hooks/pytest.sh +0 -0
  52. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/pyproject.toml +0 -0
  53. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/__init__.py +0 -0
  54. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/__main__.py +0 -0
  55. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/base/__init__.py +0 -0
  56. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/base/namespaces/__init__.py +0 -0
  57. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/base/namespaces/plot.py +0 -0
  58. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/base/namespaces/stats.py +0 -0
  59. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/base/result.py +0 -0
  60. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/base/view.py +0 -0
  61. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/entities/__init__.py +0 -0
  62. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/entities/mws.py +0 -0
  63. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/entities/tehsil.py +0 -0
  64. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/entities/waterbody.py +0 -0
  65. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/export/__init__.py +0 -0
  66. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/export/formats.py +0 -0
  67. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/py.typed +0 -0
  68. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/schema/__init__.py +0 -0
  69. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/schema/detection.py +0 -0
  70. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/schema/profile.py +0 -0
  71. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/utils/__init__.py +0 -0
  72. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/utils/paths.py +0 -0
  73. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/src/core_lens/utils/season.py +0 -0
  74. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/fixtures/generate_fixtures.py +0 -0
  75. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/conftest.py +0 -0
  76. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_aoi.py +0 -0
  77. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_entities.py +0 -0
  78. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_entity.py +0 -0
  79. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_export.py +0 -0
  80. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_main.py +0 -0
  81. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_plot.py +0 -0
  82. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_polars_utils.py +0 -0
  83. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_profile.py +0 -0
  84. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_result.py +0 -0
  85. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_schema_detection.py +0 -0
  86. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_schema_profile.py +0 -0
  87. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_season.py +0 -0
  88. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_season_config.py +0 -0
  89. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_spatial.py +0 -0
  90. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_stats.py +0 -0
  91. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/tests/unit/test_view.py +0 -0
  92. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/usage.md +0 -0
  93. {core_lens-0.1.dev183 → core_lens-0.1.dev184}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: core-lens
3
- Version: 0.1.dev183
3
+ Version: 0.1.dev184
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.dev183'
22
- __version_tuple__ = version_tuple = (0, 1, 'dev183')
21
+ __version__ = version = '0.1.dev184'
22
+ __version_tuple__ = version_tuple = (0, 1, 'dev184')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -20,7 +20,7 @@ from loguru import logger
20
20
 
21
21
  from core_lens.base.entity import BaseEntity, EntityValidationError
22
22
  from core_lens.utils.paths import is_cloud_uri
23
- from core_lens.utils.polars_utils import cached_read_schema
23
+ from core_lens.utils.polars_utils import cached_read_schema, parquet_scan_path
24
24
 
25
25
  if TYPE_CHECKING:
26
26
  from core_lens.base.view import View
@@ -225,7 +225,9 @@ def _cached_resolve_boundary(
225
225
  geom_col = schema.geometry_col
226
226
  static_path = candidate._resolve(candidate.static_path)
227
227
 
228
- lf = pl.scan_parquet(static_path, storage_options=storage_options or None)
228
+ lf = pl.scan_parquet(
229
+ parquet_scan_path(static_path), storage_options=storage_options or None
230
+ )
229
231
  filter_expr = pl.lit(True)
230
232
  schema_types = cached_read_schema(static_path, storage_options)
231
233
  for col, val in entity_kwargs.items():
@@ -29,7 +29,7 @@ from core_lens.utils.spatial import (
29
29
  build_bbox_index,
30
30
  exact_spatial_filter,
31
31
  )
32
- from core_lens.utils.polars_utils import cached_read_schema
32
+ from core_lens.utils.polars_utils import cached_read_schema, parquet_scan_path
33
33
 
34
34
  if TYPE_CHECKING:
35
35
  import shapely
@@ -475,7 +475,7 @@ class BaseEntity(ABC):
475
475
  )
476
476
 
477
477
  # --- Combine attribute and spatial filters into a single lazy pipeline ---
478
- lf = pl.scan_parquet(static)
478
+ lf = pl.scan_parquet(parquet_scan_path(static))
479
479
 
480
480
  if attr_kwargs:
481
481
  filter_expr = pl.lit(True)
@@ -7,6 +7,8 @@ import functools
7
7
 
8
8
  import polars as pl
9
9
 
10
+ import os
11
+
10
12
  _GPU_AVAILABLE: bool | None = None # None = not yet probed
11
13
 
12
14
 
@@ -16,9 +18,34 @@ def _so_key(storage_options: dict[str, Any] | None) -> tuple[tuple[str, Any], ..
16
18
  return tuple(sorted(storage_options.items()))
17
19
 
18
20
 
21
+ def parquet_scan_path(path: str) -> str:
22
+ """Return a glob-safe path for ``pl.scan_parquet``.
23
+
24
+ When *path* is a directory polars will reject it if the directory contains
25
+ files with mixed extensions (e.g. a ``data_dictionary.csv`` sitting
26
+ alongside Hive-partitioned ``.parquet`` files). This helper coerces a bare
27
+ directory to ``<path>/**/*.parquet`` so only Parquet files are matched.
28
+
29
+ Args:
30
+ path (str): Filesystem path or cloud URI to a Parquet file or directory.
31
+
32
+ Returns:
33
+ str: The original path if it already points to a file, otherwise
34
+ ``<path>/**/*.parquet``.
35
+ """
36
+ if os.path.isdir(path):
37
+ return os.path.join(path, "**", "*.parquet")
38
+ return path
39
+
40
+
19
41
  @functools.cache
20
42
  def _cached_schema_internal(path: str, so_key: tuple[tuple[str, Any], ...]) -> Any:
21
- return pl.scan_parquet(path, storage_options=dict(so_key) or None).collect_schema()
43
+ # Coerce bare directory paths to a *.parquet glob so polars doesn't raise
44
+ # InvalidOperationError when the directory contains mixed-extension files
45
+ # (e.g. data_dictionary.csv alongside Hive-partitioned .parquet files).
46
+ return pl.scan_parquet(
47
+ parquet_scan_path(path), storage_options=dict(so_key) or None
48
+ ).collect_schema()
22
49
 
23
50
 
24
51
  def cached_read_schema(path: str, storage_options: dict[str, Any] | None = None) -> Any:
@@ -12,6 +12,7 @@ import shapely
12
12
  from loguru import logger
13
13
 
14
14
  from core_lens.utils.paths import is_cloud_uri, path_exists, resolve_fs_and_path
15
+ from core_lens.utils.polars_utils import parquet_scan_path
15
16
 
16
17
  if TYPE_CHECKING:
17
18
  pass
@@ -361,7 +362,7 @@ def exact_spatial_filter(
361
362
 
362
363
  # Build a lazy scan and push down an inner join to load only required geometries.
363
364
  full_df = (
364
- pl.scan_parquet(static_path)
365
+ pl.scan_parquet(parquet_scan_path(static_path))
365
366
  .select(key_cols + [geometry_col])
366
367
  .join(candidates.select(key_cols).lazy(), on=key_cols, how="semi")
367
368
  .collect()
@@ -684,7 +685,7 @@ def point_in_entities(
684
685
  static_path: str = entity._resolve(entity.static_path)
685
686
 
686
687
  geom_df = (
687
- pl.scan_parquet(static_path)
688
+ pl.scan_parquet(parquet_scan_path(static_path))
688
689
  .select(key_cols + [geom_col])
689
690
  .join(candidates.select(key_cols).lazy(), on=key_cols, how="semi")
690
691
  .collect()
File without changes
File without changes
File without changes
File without changes
File without changes