feat(bindings): expose new IndexConfig fields in Python and Node.js (#3534)

## Summary

Surfaces the rich per-index metadata added in #3497 to the Python and
Node.js language bindings. Closes #3495.

New optional fields exposed on `IndexConfig` in both bindings:

- `index_uuid` / `indexUuid` — UUID of the first index segment
- `type_url` / `typeUrl` — protobuf type URL for the index
- `created_at` / `createdAt` — creation timestamp (milliseconds since
Unix epoch)
- `num_indexed_rows` / `numIndexedRows` — rows covered by the index
- `num_unindexed_rows` / `numUnindexedRows` — rows not yet indexed
- `size_bytes` / `sizeBytes` — total index file size in bytes
- `num_segments` / `numSegments` — number of index segments
- `index_version` / `indexVersion` — on-disk format version
- `index_details` / `indexDetails` — type-specific JSON details string

All fields are `None`/`undefined` for remote tables (which don't yet
surface this metadata through the server response).

## Changes

- `python/src/index.rs`: extend `IndexConfig` pyclass; update `From`
impl; update `__getitem__`
- `python/python/lancedb/_lancedb.pyi`: add type hints for new fields
- `python/python/tests/test_table.py`: new `test_index_config_fields`
test
- `nodejs/src/table.rs`: extend `IndexConfig` napi struct; update `From`
impl
- `nodejs/__test__/table.test.ts`: new test; update existing `toEqual`
assertions to `expect.objectContaining` to accommodate new fields

## Test plan

- [x] Python: `uv run --extra tests pytest
python/tests/test_table.py::test_index_config_fields`
- [x] Node.js: `pnpm test __test__/table.test.ts`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Will Jones
2026-06-11 13:37:39 -07:00
committed by GitHub
parent 40f3e22600
commit f8caef3aca
10 changed files with 359 additions and 45 deletions

View File

@@ -3,6 +3,8 @@
use std::collections::HashMap;
use chrono::{DateTime, Utc};
use lancedb::ipc::{ipc_file_to_batches, ipc_file_to_schema};
use lancedb::table::{
AddDataMode, ColumnAlteration as LanceColumnAlteration, Duration,
@@ -602,6 +604,43 @@ pub struct IndexConfig {
/// Currently this is always an array of size 1. In the future there may
/// be more columns to represent composite indices.
pub columns: Vec<String>,
/// The UUID of the first segment of the index.
///
/// `undefined` for remote tables, which do not yet surface this.
pub index_uuid: Option<String>,
/// The protobuf type URL, a precise type identifier for the index.
///
/// `undefined` for remote tables.
pub type_url: Option<String>,
/// When the index was created.
///
/// `undefined` for remote tables or indices created before timestamps were tracked.
pub created_at: Option<DateTime<Utc>>,
/// The number of rows indexed, across all segments.
///
/// `undefined` for remote tables.
pub num_indexed_rows: Option<i64>,
/// The number of rows not yet covered by this index.
///
/// `undefined` for remote tables.
pub num_unindexed_rows: Option<i64>,
/// The total size in bytes of all index files across all segments.
///
/// `undefined` for remote tables or indices without size tracking.
pub size_bytes: Option<i64>,
/// The number of segments that make up the index.
///
/// `undefined` for remote tables.
pub num_segments: Option<i32>,
/// The on-disk index format version.
///
/// `undefined` for remote tables.
pub index_version: Option<i32>,
/// Index-type-specific details parsed as a JavaScript object.
///
/// Falls back to a raw string if JSON parsing fails. `undefined` for
/// remote tables or when details are unavailable.
pub index_details: Option<serde_json::Value>,
}
impl From<lancedb::index::IndexConfig> for IndexConfig {
@@ -611,6 +650,17 @@ impl From<lancedb::index::IndexConfig> for IndexConfig {
index_type,
columns: value.columns,
name: value.name,
index_uuid: value.index_uuid,
type_url: value.type_url,
created_at: value.created_at,
num_indexed_rows: value.num_indexed_rows.map(|n| n as i64),
num_unindexed_rows: value.num_unindexed_rows.map(|n| n as i64),
size_bytes: value.size_bytes.map(|n| n as i64),
num_segments: value.num_segments.map(|n| n as i32),
index_version: value.index_version,
index_details: value
.index_details
.and_then(|s| serde_json::from_str(&s).ok()),
}
}
}