core_lens.base.entity#
Base entity contract for core_lens.
All entities — built-in or plugin — must subclass BaseEntity and
implement its abstract interface. Concrete implementations live in
core_lens.entities.* (built-ins) or in third-party packages (plugins).
Plugin authors import from the public surface:
from core_lens.base import BaseEntity
Exceptions#
Raised when an entity fails validation at |
Classes#
Abstract base class for every entity in the core_lens plugin system. |
Module Contents#
- class core_lens.base.entity.BaseEntity(data_root: str | pathlib.Path | None = None, storage_options: dict[str, Any] | None = None)#
Bases:
abc.ABCAbstract base class for every entity in the core_lens plugin system.
An entity represents a geospatial primitive (e.g. microwatershed, village, district) backed by one or more Parquet/GeoParquet files. Entities are descriptors — they carry path and schema metadata but hold no per-row state themselves. Row-level data lives in
ViewandResult.Subclasses must implement:
key_cols— column(s) that uniquely identify one entity instancegeometry_col— geometry column name in the static GeoParquet filestatic_path— path to the static GeoParquet file (mandatory).May be relative; resolved against
data_rootwhen the entity is instantiated byAoI.
Subclasses may override:
annual_path— path to the annual time-series Parquet filesub_annual_path— path to the sub_annual time-series Parquet fileschema_profile— override auto-detection by returning anexplicit
SchemaProfile
where,spatial_filter,spatial_join, andschema_profileare all implemented on this base class. Subclasses only need to declare paths and keys.Plugin example:
from core_lens.base import BaseEntity class ForestEntity(BaseEntity): key_cols = [\"forest_patch_id\"] geometry_col = \"geometry\" static_path = \"forest/static.geoparquet\" # relative to AoI data_root annual_path = \"forest/annual.parquet\" AoI.register(ForestEntity)
Validation rules enforced at
AoI()instantiation time (relative paths) or atAoI.register()time (absolute paths):static_pathexists and is readable.key_colsare present and unique in the static file.geometry_colis present and contains valid geometries.annual_pathandsub_annual_pathexist if declared.
Any failure raises
EntityValidationError.- property key_cols: list[str]#
- Abstractmethod:
Columns that uniquely identify one instance of this entity.
For built-in entities this is always a single-element list (e.g.
[\"mws_id\"]), but the contract allows composite keys for plugins.- Returns:
A list of column name strings present in the static file.
- Return type:
list[str]
- property geometry_col: str#
- Abstractmethod:
Name of the geometry column in the static GeoParquet file.
The column must contain a geometry type understood by GeoPandas (WKB bytes, WKT string, or a native geometry column).
- Returns:
The column name as a string.
- Return type:
str
- property static_path: str#
- Abstractmethod:
Absolute filesystem path to the static GeoParquet file.
The path must be absolute. If a relative path is provided it is resolved against the current working directory at first use. A
FileNotFoundErroris raised if the file does not exist.- Returns:
A path string.
- Return type:
str
- property annual_path: str | None#
Path to the annual time-series Parquet file, or
None.Override in subclasses that carry annual temporal data. If declared, the file must exist at
AoI.register()time orEntityValidationErroris raised.- Returns:
A path string, or
Noneif the entity has no annual data.- Return type:
str | None
- property sub_annual_path: str | None#
Path to the sub_annual time-series Parquet file, or
None.Override in subclasses that carry sub_annual temporal data. If declared, the file must exist at
AoI.register()time orEntityValidationErroris raised.- Returns:
A path string, or
Noneif the entity has no sub_annual data.- Return type:
str | None
- property schema_profile: core_lens.schema.profile.SchemaProfile#
Validated schema descriptor for this entity’s data files.
Auto-detected from Parquet file metadata on first access. The result is cached at two levels:
Instance level —
_schema_profileattribute set onselfso that repeated property access within the same instance is a bare attribute lookup with no dict overhead.Process level —
_cached_detect()(backed byfunctools.cache) keyed on the resolved paths and entity configuration. DifferentAoI()calls that point at the same data directory share oneSchemaProfileobject, avoiding redundantcollect_schema()I/O.
Override in subclasses to provide an explicit profile instead of relying on detection.
- Returns:
A fully-validated
SchemaProfile.- Return type:
- property geometry_lazy: polars.LazyFrame#
A cached LazyFrame representing the geometry of this entity.
Contains only the key columns and the geometry column. Used to avoid repeatedly scanning and selecting geometries in downstream operations.
- where(**kwargs: Any) core_lens.base.view.View#
Return a lazy
Viewfiltered by attributes.Each keyword argument is interpreted attribute-first: if the kwarg key exists as a column in the static file the filter is applied directly. If a kwarg key does not exist as a column it is resolved as a registered entity name and the matching entity’s geometry is used for a spatial filter (e.g.
district="Shimla"finds all MWS whose centroid falls within Shimla district).Multiple attribute kwargs are AND-ed. Multiple spatial-entity kwargs are AND-ed via sequential spatial filters.
- spatial_filter(geometry: shapely.Geometry | None = None, bbox: tuple[float, float, float, float] | None = None, relationship: str = 'centroid', threshold: float = 0.5) core_lens.base.view.View#
Return a lazy
Viewfiltered by geometry.Uses the in-memory bbox index for a fast rectangular pre-filter, then refines with a Shapely STRtree exact-relationship check.
- Parameters:
geometry (shapely.Geometry | None, optional) – A Shapely geometry representing the spatial extent.
bbox (tuple[float, float, float, float] | None, optional) – Bounding box as
(minx, miny, maxx, maxy)in WGS-84. Converted to ashapely.geometry.boxinternally.relationship (str, optional) –
Spatial relationship mode.
"centroid"(default) — entity centroid must lie within the geometry."area"— intersection area / entity area must exceedthreshold.
threshold (float, optional) – Area coverage threshold for
"area"mode (0–1). Default 0.5.
- Returns:
A lazy
Viewscoped to the given spatial extent.- Return type:
- Raises:
ValueError – If neither
geometrynorbboxis provided.
- spatial_join(other: BaseEntity, agg: dict[str, str]) core_lens.base.view.View#
Return a lazy
Viewwith a cross-entity join pending.The join is recorded in the View’s
join_specand computed only at materialisation time (.static,.annual, or.sub_annual). Joined columns are namespaced as{entity_name}_{column_name}.- Parameters:
other (BaseEntity) – The secondary
BaseEntitywhose columns will be joined and aggregated ontoself.agg (dict[str, str]) – Mapping of
{column: aggregation}specifying which columns fromotherto bring in and how to aggregate them. Valid aggregation strings are\"area\",\"count\",\"mean\",\"sum\",\"min\", and\"max\".
- Returns:
A lazy
Viewwith the join spec recorded for deferred execution.- Return type:
- exception core_lens.base.entity.EntityValidationError#
Bases:
ExceptionRaised when an entity fails validation at
AoI.register()time.The message will describe exactly which check failed (missing file, absent key column, invalid geometry column, etc.) to give plugin authors actionable feedback.