core-lens 0.1.dev160__tar.gz → 0.1.dev162__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 (91) hide show
  1. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/PKG-INFO +1 -1
  2. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/pyproject.toml +15 -0
  3. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/_version.py +2 -2
  4. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/base/namespaces/plot.py +28 -12
  5. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/export/formats.py +1 -1
  6. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/utils/spatial.py +1 -1
  7. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/ISSUE_TEMPLATE/blank-proposal.yaml +0 -0
  8. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
  9. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/ISSUE_TEMPLATE/feature-request.yaml +0 -0
  10. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/pull_request_template.md +0 -0
  11. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/workflows/ci.yml +0 -0
  12. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/workflows/gh-pages.yml +0 -0
  13. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/workflows/pre-release.yml +0 -0
  14. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.github/workflows/release.yml +0 -0
  15. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.gitignore +0 -0
  16. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.gitmessage +0 -0
  17. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.pre-commit-config.yaml +0 -0
  18. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/.python-version +0 -0
  19. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/CONTRIBUTING.md +0 -0
  20. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/LICENSE +0 -0
  21. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/README.md +0 -0
  22. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/SKILLS.md +0 -0
  23. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/README.md +0 -0
  24. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_aoi.py +0 -0
  25. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_export.py +0 -0
  26. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_polars_utils.py +0 -0
  27. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_result.py +0 -0
  28. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_schema.py +0 -0
  29. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_season.py +0 -0
  30. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_spatial.py +0 -0
  31. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/bench_view.py +0 -0
  32. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/benchmarks/run_all.sh +0 -0
  33. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/Makefile +0 -0
  34. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/make.bat +0 -0
  35. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/concepts.md +0 -0
  36. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/conf.py +0 -0
  37. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/export.md +0 -0
  38. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/index.rst +0 -0
  39. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/intro.md +0 -0
  40. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/logging.md +0 -0
  41. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/plots.md +0 -0
  42. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/plugins.md +0 -0
  43. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/queries.md +0 -0
  44. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/quickstart.md +0 -0
  45. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/docs/source/stats.md +0 -0
  46. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/examples/demo_mws.py +0 -0
  47. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/examples/demo_tehsil.py +0 -0
  48. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/hooks/mypy.sh +0 -0
  49. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/hooks/no-parquet-outside-fixtures.sh +0 -0
  50. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/hooks/pytest.sh +0 -0
  51. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/__init__.py +0 -0
  52. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/__main__.py +0 -0
  53. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/aoi.py +0 -0
  54. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/base/__init__.py +0 -0
  55. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/base/entity.py +0 -0
  56. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/base/namespaces/__init__.py +0 -0
  57. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/base/namespaces/stats.py +0 -0
  58. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/base/result.py +0 -0
  59. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/base/view.py +0 -0
  60. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/entities/__init__.py +0 -0
  61. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/entities/mws.py +0 -0
  62. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/entities/tehsil.py +0 -0
  63. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/entities/waterbody.py +0 -0
  64. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/export/__init__.py +0 -0
  65. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/py.typed +0 -0
  66. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/schema/__init__.py +0 -0
  67. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/schema/detection.py +0 -0
  68. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/schema/profile.py +0 -0
  69. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/utils/__init__.py +0 -0
  70. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/utils/paths.py +0 -0
  71. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/utils/polars_utils.py +0 -0
  72. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/src/core_lens/utils/season.py +0 -0
  73. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/fixtures/generate_fixtures.py +0 -0
  74. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/conftest.py +0 -0
  75. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_aoi.py +0 -0
  76. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_entities.py +0 -0
  77. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_entity.py +0 -0
  78. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_export.py +0 -0
  79. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_main.py +0 -0
  80. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_plot.py +0 -0
  81. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_polars_utils.py +0 -0
  82. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_profile.py +0 -0
  83. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_result.py +0 -0
  84. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_schema_detection.py +0 -0
  85. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_schema_profile.py +0 -0
  86. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_season.py +0 -0
  87. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_season_config.py +0 -0
  88. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_spatial.py +0 -0
  89. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_stats.py +0 -0
  90. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/tests/unit/test_view.py +0 -0
  91. {core_lens-0.1.dev160 → core_lens-0.1.dev162}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: core-lens
3
- Version: 0.1.dev160
3
+ Version: 0.1.dev162
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
@@ -122,3 +122,18 @@ cudf-polars-cu13 = { index = "nvidia" }
122
122
 
123
123
  [tool.coverage.run]
124
124
  source = ["src/core_lens"]
125
+
126
+ [tool.ruff.lint]
127
+ select = [
128
+ "E",
129
+ "F", # Default rules (Error and Pyflakes)
130
+ "S", # Enable all flake8-bandit security rules
131
+ ]
132
+ ignore = [
133
+ "E501", # line too long
134
+ "S101", # use of assert
135
+ ]
136
+
137
+ [tool.ruff.lint.per-file-ignores]
138
+ "tests/*" = ["S"]
139
+ "examples/*" = ["S"]
@@ -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.dev160'
22
- __version_tuple__ = version_tuple = (0, 1, 'dev160')
21
+ __version__ = version = '0.1.dev162'
22
+ __version_tuple__ = version_tuple = (0, 1, 'dev162')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -157,7 +157,7 @@ def _wkb_to_arrow_table(
157
157
  if b"ARROW:extension:metadata" in ext_meta:
158
158
  try:
159
159
  geo_meta = json.loads(ext_meta[b"ARROW:extension:metadata"].decode("utf-8"))
160
- except Exception:
160
+ except Exception: # noqa: S110
161
161
  pass
162
162
  geo_meta["crs"] = "EPSG:4326"
163
163
  ext_meta[b"ARROW:extension:metadata"] = json.dumps(geo_meta).encode("utf-8")
@@ -561,11 +561,19 @@ class PlotNamespace:
561
561
  color=color,
562
562
  size=5,
563
563
  )
564
- elif key_col in pdf.columns:
565
- for i, entity in enumerate(pdf[key_col].unique()):
566
- row = pdf[pdf[key_col] == entity]
564
+ elif key_col in df.columns:
565
+ entities = df.get_column(key_col).unique().to_list()
566
+ for i, entity in enumerate(entities):
567
+ entity_df = df.filter(pl.col(key_col) == entity)
568
+ source_data = {}
569
+ for c in hover_cols:
570
+ if c in entity_df.columns:
571
+ lst = entity_df.get_column(c).to_list()
572
+ if entity_df.schema[c].is_numeric():
573
+ lst = [float("nan") if v is None else v for v in lst]
574
+ source_data[c] = lst
575
+ source = ColumnDataSource(source_data) # type: ignore[arg-type]
567
576
  color = _color_for(i)
568
- source = _src(row)
569
577
  fig.line(
570
578
  x=x,
571
579
  y=y_col,
@@ -676,8 +684,6 @@ class PlotNamespace:
676
684
  entities = unique_entities.limit(top_n).to_list()
677
685
  df = df.join(pl.DataFrame({key_col: entities}), on=key_col, how="inner")
678
686
 
679
- df_pd = df.to_pandas()
680
-
681
687
  def _make_scatter(y_col: str) -> "BokehFigure":
682
688
  from bokeh.models import ColumnDataSource
683
689
 
@@ -689,11 +695,21 @@ class PlotNamespace:
689
695
  tools="pan,wheel_zoom,box_zoom,reset,save,hover",
690
696
  tooltips=[(c, f"@{{{c}}}") for c in hover_cols],
691
697
  )
692
- for i, entity in enumerate(df_pd[key_col].unique()):
693
- row = df_pd[df_pd[key_col] == entity]
694
- source = ColumnDataSource(
695
- {c: row[c].tolist() for c in hover_cols if c in row.columns}
696
- )
698
+
699
+ entities = df.get_column(key_col).unique().to_list()
700
+ for i, entity in enumerate(entities):
701
+ row = df.filter(pl.col(key_col) == entity)
702
+
703
+ # Replace None with NaN for numeric columns to prevent Bokeh JS rendering crashes
704
+ source_data = {}
705
+ for c in hover_cols:
706
+ if c in row.columns:
707
+ lst = row.get_column(c).to_list()
708
+ if row.schema[c].is_numeric():
709
+ lst = [float("nan") if v is None else v for v in lst]
710
+ source_data[c] = lst
711
+
712
+ source = ColumnDataSource(source_data) # type: ignore[arg-type]
697
713
  fig.scatter(
698
714
  x=x,
699
715
  y=y_col,
@@ -159,7 +159,7 @@ def geoparquet(result: "Result", path: str | pathlib.Path, **kwargs: Any) -> Non
159
159
  SELECT {select_clause}
160
160
  FROM df
161
161
  ) TO '{path_str}' ({options_str});
162
- """
162
+ """ # noqa: S608
163
163
  conn.execute(query)
164
164
 
165
165
 
@@ -59,7 +59,7 @@ def _bbox_sidecar_path(static_path: str) -> pathlib.Path | None:
59
59
  # Fallback to user cache dir.
60
60
  import hashlib
61
61
 
62
- fingerprint = hashlib.sha1(static_path.encode()).hexdigest()[:16]
62
+ fingerprint = hashlib.sha256(static_path.encode()).hexdigest()[:16]
63
63
  _CACHE_DIR.mkdir(parents=True, exist_ok=True)
64
64
  sidecar = _CACHE_DIR / (fingerprint + _SIDECAR_SUFFIX)
65
65
  return sidecar
File without changes
File without changes
File without changes
File without changes