Metadata-Version: 2.4
Name: traceAI-lancedb
Version: 0.1.2
Summary: OpenTelemetry instrumentation for LanceDB vector database
License: Apache-2.0
Keywords: opentelemetry,lancedb,vector-database,tracing,observability,rag,traceai,futureagi,llm
Author: Future AGI
Author-email: no-reply@futureagi.com
Requires-Python: >=3.10,<3.14
Classifier: Framework :: OpenTelemetry
Classifier: Framework :: OpenTelemetry :: Instrumentations
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Monitoring
Requires-Dist: fi-instrumentation-otel (>=1.2.2)
Requires-Dist: lancedb (>=0.25.0)
Requires-Dist: wrapt (>=1.0.0)
Project-URL: Changelog, https://github.com/future-agi/traceAI/blob/dev/python/frameworks/lancedb/CHANGELOG.md
Project-URL: Documentation, https://docs.futureagi.com/docs/tracing
Project-URL: Homepage, https://futureagi.com
Project-URL: Issues, https://github.com/future-agi/traceAI/issues
Project-URL: Repository, https://github.com/future-agi/traceAI/tree/dev/python/frameworks/lancedb
Description-Content-Type: text/markdown

# traceAI-lancedb

Trace LanceDB query execution and table operations with OpenTelemetry. The same instrumentor supports local and remote tables and LanceDB's synchronous and asynchronous APIs.

## Install

```bash
pip install traceAI-lancedb
```

Requires Python 3.10–3.13, LanceDB 0.25.0 or newer and `fi-instrumentation-otel` 1.2.2 or newer. Older LanceDB releases are not supported; upgrade them before enabling this instrumentor.

## Trace a local search

Set `FI_API_KEY` and `FI_SECRET_KEY` in your application environment. For self-hosted Future AGI, set `FI_BASE_URL` to your collector origin.

```python
import lancedb
from fi_instrumentation import register
from fi_instrumentation.fi_types import ProjectType
from traceai_lancedb import LanceDBInstrumentor

provider = register(project_type=ProjectType.OBSERVE, project_name="lancedb-search")
instrumentor = LanceDBInstrumentor()
instrumentor.instrument(tracer_provider=provider)

try:
    db = lancedb.connect("./lancedb-demo")
    table = db.create_table(
        "documents",
        data=[
            {"id": 1, "vector": [1.0, 0.0], "text": "violet flower"},
            {"id": 2, "vector": [0.0, 1.0], "text": "blue sea"},
        ],
        mode="overwrite",
    )
    results = table.search([1.0, 0.0]).limit(2).to_list()
    print(results)
finally:
    provider.force_flush()
```

Open **Observe** in Future AGI and select `lancedb-search`. The example produces a `lancedb create_table` span and one `lancedb search` span. Calling `to_list()` does not create extra spans for the `to_arrow()` and `to_batches()` calls it makes internally.

To use your application's existing OpenTelemetry setup instead, pass its tracer provider to `instrument(tracer_provider=provider)`. Register one provider per process.

## Supported operations

| API | Span |
| --- | --- |
| Vector, full-text, hybrid and scan query materialization | `lancedb search` |
| `add`, `update`, `delete` on local, remote or async tables | `lancedb add`, `lancedb update`, `lancedb delete` |
| `create_table`, `open_table`, `drop_table` on local, remote or async connections | `lancedb create_table`, `lancedb open_table`, `lancedb drop_table` |

Query materialization includes `to_list`, `to_arrow`, `to_batches`, `to_pandas`, `to_df`, `to_pydantic` and `to_polars` where available in your LanceDB version. Building a query with `search()`, `query()`, `where()` or `limit()` does not itself execute a query or create a span. Index creation, maintenance and SQL execution APIs are not instrumented.

### Streaming batches

The span stays open while you consume a batch reader. Consume it to exhaustion or close it when you stop early:

```python
with table.search([1.0, 0.0]).limit(2).to_batches() as batches:
    for batch in batches:
        print(batch.num_rows)
```

The reader remains lazy and supports Arrow's C stream interface. Completed readers report the number of returned rows. Early close or garbage collection ends the span with the count consumed so far and an unset status, rather than claiming successful completion. Errors and async cancellation end the span with error status. The span is current only during database work, not while your application processes each batch.

Async queries use the same setup:

```python
import asyncio

async def search_async():
    db = await lancedb.connect_async("./lancedb-demo")
    table = await db.open_table("documents")
    reader = await table.vector_search([1.0, 0.0]).limit(2).to_batches()
    try:
        async for batch in reader:
            print(batch.num_rows)
    finally:
        await reader.aclose()

asyncio.run(search_async())
provider.force_flush()
```

## Recorded data

Spans include the operation, table name when available, output format, result count and query limit when exposed by the SDK. They do not capture vectors, query text, SQL filters, row contents, connection credentials or exception messages/stack traces. Error status and exception type are retained. Table names are metadata; avoid including sensitive information in them. To redact recognized PII patterns in metadata before spans reach OpenTelemetry samplers, processors or exporters, set `FI_PII_REDACTION=true` before calling `instrument()`, or pass an explicit configuration:

```python
from fi_instrumentation import TraceConfig

instrumentor.instrument(
    tracer_provider=provider,
    config=TraceConfig(pii_redaction=True),
)
```

Choose the configuration when first enabling instrumentation (or uninstrument before changing it). Explicit options override environment defaults. Redaction is opt-in and pattern-based, not a guarantee that arbitrary secrets are detected. It does not enable content capture: vectors, row contents, filters and exception details remain excluded even when error-detail hiding is disabled.

These limits apply to this instrumentor's spans. Other instrumentors and your application may capture additional information.

## Disable instrumentation

```python
instrumentor.uninstrument()
```

This restores the patched methods. Readers already in progress finish their existing spans when consumed or closed. Calling `instrument()` again enables tracing without stacking duplicate patches.

## License

Apache License 2.0

