Skip to content

Commit 9ebafcc

Browse files
authored
Update namespace and SDK docs (#167)
* Update namespace docs * Fix formatting * Fix issues with namespace examples * Fix failing test snippets * Fix broken link
1 parent fcb34bc commit 9ebafcc

File tree

14 files changed

+267
-144
lines changed

14 files changed

+267
-144
lines changed

docs/api-reference/index.mdx

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
title: Client SDKs
2+
title: SDKs and REST API Reference
33
sidebarTitle: "SDKs"
4-
description: "SDK & REST API reference for LanceDB"
4+
description: "SDK and REST API reference for LanceDB Enterprise and OSS."
55

66
---
77

@@ -15,20 +15,35 @@ If you're looking for conceptual and practical namespace guidance before diving
1515

1616
## Supported SDKs
1717

18-
Python, Typescript and Rust SDKs are officially supported by LanceDB.
18+
Python, Typescript and Rust SDKs are officially supported by LanceDB. You can use these SDKs to interact with both LanceDB OSS and Enterprise deployments.
1919

20-
| SDK Reference | Description |
20+
| Reference | Description |
2121
|:--------------|-------------------|
22-
| [Python SDK](https://lancedb.github.io/lancedb/python/python/) | Full-featured Python client with pandas & numpy integration |
23-
| [Typescript SDK](https://lancedb.github.io/lancedb/js/) | A TypeScript wrapper around the Rust library, built with `napi-rs`
24-
| [Rust SDK](https://docs.rs/lancedb/latest/lancedb/index.html) | Native Rust library with persistent-storage and high performance |
22+
| <Icon icon="python" /> [Python](https://lancedb.github.io/lancedb/python/python/) | Full-featured Python client with pandas & numpy integration |
23+
| <Icon icon="square-js" /> [Typescript](https://lancedb.github.io/lancedb/js/) | A TypeScript wrapper around the Rust library, built with `napi-rs`
24+
| <Icon icon="rust" /> [Rust](https://docs.rs/lancedb/latest/lancedb/index.html) | Native Rust library with persistent-storage and high performance |
2525

26-
## Examples in other languages
26+
## REST API SDKs
2727

28-
Other language SDKs are available through examples or third-party contributions.
28+
<Badge color="red">Enterprise</Badge>
2929

30-
| SDK Examples | Description |
30+
REST API-based SDKs provide a convenient way to interact with LanceDB Cloud and Enterprise deployments using the Lance REST Namespace API.
31+
32+
| Reference | Description |
33+
|:--------------|-------------------|
34+
| <Icon icon="java" /> [Java](https://lancedb.github.io/lancedb/java/java/)| REST API Enterprise SDK in Java |
35+
36+
## Community-driven SDKs
37+
38+
In addition to the officially supported SDKs, the LanceDB community may contribute SDKs in other languages.
39+
These SDKs may not have the same level of support or feature parity as the official ones supported by LanceDB, but they can be an option
40+
for users working in languages other than those listed above.
41+
42+
| Reference | Description |
3143
|:--------------|-------------------|
32-
| [Java API Quickstart]https://lancedb.github.io/lancedb/java/java/)| Streamline REST API interactions in Java|
44+
| <Icon icon="golang" /> [Go](https://pkg.go.dev/github.com/lancedb/lancedb-go/pkg/lancedb) | Community-contributed Go SDK for LanceDB |
45+
| <Icon icon="gem" /> [Ruby](https://github.com/scientist-labs/lancelot) | Community-contributed Ruby bindings for LanceDB |
46+
| <Icon icon="swift" /> [Swift](https://github.com/RyanLisse/LanceDbSwiftKit) | Community-contributed Swift SDK for LanceDB |
47+
| <Icon icon="R" /> [R](https://github.com/CathalByrneGit/lancedb) | Community-contributed R package for LanceDB |
48+
| <Icon icon="flutter" /> [Flutter](https://github.com/Alexcn/flutter_lancedb) | Community-contributed Flutter bindings for LanceDB |
3349

34-
{/* TODO: Add Go bindings reference page here */}

docs/namespaces.mdx

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,61 +23,90 @@ A namespace can contain a collection of tables, and it can also contain namespac
2323

2424
![](/static/assets/images/namespaces/lance-namespace.png)
2525

26-
## Root namespace and the familiar `data/` layout
26+
Before diving into examples, it helps to keep two terms in mind: the **namespace client** is the abstraction that presents a consistent namespace API, while the **namespace implementation** is the concrete backend that resolves namespaces and table locations (for example, a local directory or an external catalog).
27+
If you want to go deeper, see the Lance format [namespace documentation](https://lance.org/format/namespace/).
28+
29+
## Directory namespaces
2730

2831
The simplest namespace model in LanceDB is a single root namespace, often represented by one
2932
directory:
3033

3134
```bash
32-
/data/ # root namespace
33-
├─ users.lance # table ["users"] in root
34-
└─ orders.lance # table ["orders"] in root
35+
./local_lancedb (root)
36+
└── prod
37+
└── search
38+
└── user (table)
39+
└── data (table)
3540
```
3641

37-
As a user of LanceDB, you might never notice namespaces at first, because LanceDB exposes the single-level
38-
hierarchy shown above, with the data stored in the `data/` directory, where the root namespace
39-
is implicit. In alternative setups, you could have multiple namespaces that we won't cover here,
40-
but you can learn more about them in the [namespace documentation](https://lance.org/format/namespace/) for the Lance format.
42+
As a user of LanceDB OSS, you might never notice namespaces at first, because LanceDB exposes the single-level hierarchy shown above, with the data stored in the `data/` directory, where the root namespace is implicit. Connecting to this namespace is as simple as connecting to the catalog root:
4143

42-
## Best-practice guidance
44+
```python Python icon="python"
45+
import lancedb
4346

44-
- Use the default, single-level root namespace in LanceDB for locally stored, single-application, or early-stage projects.
45-
- For remote storage locations, introduce explicit namespaces when multiple teams, environments, or domains share the same catalog.
46-
- Treat namespace paths as stable identifiers (for example `"prod/search"`, `"staging/recs"`).
47-
- Avoid hard-coding object-store table paths in application code -- instead, prefer catalog identifiers + namespaces.
47+
# Connect to the directory namespace root
48+
db = lancedb.connect("./local_lancedb")
49+
```
4850

49-
See the Python example below for how to use namespaces in practice.
51+
This will create the default namespace directory (`data/`) under the specified root path:
52+
53+
You can also explicitly connect to a namespace using `lancedb.connect_namespace(...)` with the directory namespace implementation:
5054

5155
```python Python icon="python"
5256
import lancedb
5357

5458
# Local namespace-backed catalog root (DirectoryNamespace)
55-
db = lancedb.connect_namespace("dir", {"root": "./namespace_test"})
56-
57-
# Business identifier + namespace path (stable app-level IDs)
58-
namespace = ["prod", "recommendations"]
59-
table_name = "user_profiles"
60-
61-
# Create namespace hierarchy sequentially
62-
for i in range(1, len(namespace) + 1):
63-
db.create_namespace(namespace[:i], mode="exist_ok")
64-
65-
# Good: resolve table through catalog + namespace
66-
table = db.create_table(
67-
table_name,
68-
data=[{"id": 1, "vector": [0.1, 0.2], "name": "alice"}],
69-
namespace=namespace,
70-
mode="overwrite",
71-
)
59+
# See https://lance.org/format/namespace/dir/catalog-spec/
60+
db = lancedb.connect_namespace("dir", {"root": "./local_lancedb"})
61+
62+
table_name = "user"
63+
data = [{"id": 1, "vector": [0.1, 0.2], "name": "alice"}]
64+
65+
table = db.create_table(table_name, data=data, mode="create")
66+
print(f"Created table: {table.name}")
67+
# Created table: user
68+
```
7269

73-
# Bad: Avoid hard-coded physical object-store table paths
74-
# (it's bad for maintainability reasons)
75-
# table = lancedb.connect(
76-
# "s3://my-lakehouse/catalog/prod/recommendations/user_profiles.lance"
77-
# )
70+
<Info>
71+
- For simple use cases in LanceDB OSS, you don't need to go too deep into namespaces.
72+
- To integrate LanceDB with external catalogs and to use it as a true **multimodal lakehouse**, it's useful to understant the different namespace implementations and how to use them in your organization's setup.
73+
</Info>
74+
75+
## Remote or external catalog namespaces
76+
77+
The example above showed local directory-baed namespaces. LanceDB also supports namespaces backed by remote object stores and external catalogs, via the REST namespace implementation.
78+
79+
For remote object stores with central metadata/catalog services (either commercial or open source), use the REST namespace implementation,
80+
This is backed by REST routes
81+
(for example `POST /v1/namespace/{id}/create` and `GET /v1/namespace/{id}/list`) and server-provided table locations.
82+
83+
For authentication, any property prefixed with `headers` is forwarded as an HTTP header
84+
(for example `headers.Authorization` becomes `Authorization`, and `headers.X-API-Key` becomes `X-API-Key`).
85+
86+
```python Python icon="python"
87+
import os
88+
import lancedb
89+
90+
# Remote namespace-backed catalog root (RestNamespace)
91+
# See https://lance.org/format/namespace/rest/catalog-spec/
92+
db = lancedb.connect_namespace(
93+
"rest",
94+
{
95+
"uri": "https://<your_catalog>.internal.<your_org>.com",
96+
"headers.x-api-key": os.environ["API_KEY"],
97+
# or:
98+
# "headers.Authorization": f"Bearer {os.environ['REST_AUTH_TOKEN']}",
99+
},
100+
)
78101
```
102+
[LanceDB Enterprise](/enterprise) operates a REST namespace server on top of the Lance format, so any REST client that can speak the REST namespace API
103+
contract can be used to interact with it. For authentication examples in LanceDB Enterprise, visit
104+
the [Namespaces in SDKs](/tables/namespaces#namespaces-in-lancedb-enterprise) page.
79105

80-
## SDK usage
106+
## Best practices
81107

82-
1. For language-specific examples of `namespace` usage across Python, TypeScript, and Rust, see "[Using namespaces in SDKs](/tables/namespaces)".
83-
2. For REST-level operations, see the [REST API Reference](/api-reference/rest).
108+
Below, we list some best practices for working with namespaces:
109+
- For simple use cases and single, stand-alone applications, the directory-based root namespace is sufficient and requires no special configuration.
110+
- For remote storage locations, introduce explicit namespaces when multiple teams, environments, or domains share the same catalog.
111+
- Treat namespace paths as stable identifiers (for example `"prod/search"`, `"staging/recs"`).
112+
- For maintainability reasons, avoid hard-coding object-store table paths in application code -- instead, prefer catalog identifiers + namespaces.

docs/snippets/connection.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@ export const PyConnectObjectStorage = "import lancedb\n\nuri = \"s3://your-bucke
1212

1313
export const PyConnectObjectStorageAsync = "import lancedb\n\nuri = \"s3://your-bucket/path\"\n# You can also use \"gs://your-bucket/path\" or \"az://your-container/path\".\nasync_db = await lancedb.connect_async(uri)\n";
1414

15-
export const PyNamespaceAdminOps = "import lancedb\n\ndb = lancedb.connect_namespace(\"dir\", {\"root\": \"./data/sample-lancedb\"})\nnamespace = [\"prod\", \"search\"]\n\nfor i in range(1, len(namespace) + 1):\n db.create_namespace(namespace[:i], mode=\"exist_ok\")\n\nchild_namespaces = db.list_namespaces(namespace=[\"prod\"]).namespaces\nmetadata = db.describe_namespace([\"prod\", \"search\"])\n\ndb.drop_namespace([\"prod\", \"search\"], mode=\"skip\")\ndb.drop_namespace([\"prod\"], mode=\"skip\")\n";
15+
export const PyNamespaceAdminOps = "import lancedb\n\ndb = lancedb.connect_namespace(\"dir\", {\"root\": \"./local_lancedb\"})\nnamespace = [\"prod\", \"search\"]\n\ndb.create_namespace([\"prod\"])\ndb.create_namespace([\"prod\", \"search\"])\n\nchild_namespaces = db.list_namespaces(namespace=[\"prod\"]).namespaces\nprint(f\"Child namespaces under {namespace}: {child_namespaces}\")\n# Child namespaces under ['prod', 'search']: ['search']\n\nmetadata = db.describe_namespace([\"prod\", \"search\"])\nprint(f\"Metadata for namespace {namespace}: {metadata}\")\n# Metadata for namespace ['prod', 'search']: properties=None\n\ndb.drop_namespace([\"prod\", \"search\"], mode=\"skip\")\ndb.drop_namespace([\"prod\"], mode=\"skip\")\n";
1616

17-
export const PyNamespaceTableOps = "import lancedb\n\ndb = lancedb.connect_namespace(\"dir\", {\"root\": \"./data/sample-lancedb\"})\nnamespace = [\"prod\", \"search\"]\n\nfor i in range(1, len(namespace) + 1):\n db.create_namespace(namespace[:i], mode=\"exist_ok\")\n\ndb.create_table(\n \"users\",\n data=[{\"id\": 1, \"vector\": [0.1, 0.2], \"name\": \"alice\"}],\n mode=\"overwrite\",\n namespace=namespace,\n)\n\ntable = db.open_table(\"users\", namespace=namespace)\ntables = db.list_tables(namespace=namespace).tables\n\ndb.drop_table(\"users\", namespace=namespace)\n# drop_all_tables is namespace-aware as well:\n# db.drop_all_tables(namespace=namespace)\n";
17+
export const PyNamespaceTableOps = "import lancedb\n\ndb = lancedb.connect_namespace(\"dir\", {\"root\": \"./local_lancedb\"})\n\n# Create namespace tree: prod/search\ndb.create_namespace([\"prod\"], mode=\"exist_ok\")\ndb.create_namespace([\"prod\", \"search\"], mode=\"exist_ok\")\ndb.create_namespace([\"prod\", \"recommendations\"], mode=\"exist_ok\")\n\ndb.create_table(\n \"user\",\n data=[{\"id\": 1, \"vector\": [0.1, 0.2], \"name\": \"alice\"}],\n namespace=[\"prod\", \"search\"],\n mode=\"create\", # use \"overwrite\" only if you want to replace existing table\n)\n\ndb.create_table(\n \"user\",\n data=[{\"id\": 2, \"vector\": [0.3, 0.4], \"name\": \"bob\"}],\n namespace=[\"prod\", \"recommendations\"],\n mode=\"create\", # use \"overwrite\" only if you want to replace existing table\n)\n\n# Verify\nprint(db.list_namespaces()) # ['prod']\nprint(db.list_namespaces(namespace=[\"prod\"])) # ['recommendations', 'search']\nprint(db.list_tables(namespace=[\"prod\", \"search\"])) # ['user']\nprint(db.list_tables(namespace=[\"prod\", \"recommendations\"])) # ['user']\n";
1818

1919
export const TsConnect = "import * as lancedb from \"@lancedb/lancedb\";\n\nasync function connectExample(uri: string) {\n const db = await lancedb.connect(uri);\n return db;\n}\n";
2020

2121
export const TsConnectCloud = "const uri = \"db://your-database-uri\";\nconst apiKey = \"your-api-key\";\nconst region = \"us-east-1\";\n";
2222

2323
export const TsConnectObjectStorage = "async function connectObjectStorageExample() {\n const uri = \"s3://your-bucket/path\";\n // You can also use \"gs://your-bucket/path\" or \"az://your-container/path\".\n const db = await lancedb.connect(uri);\n return db;\n}\n";
2424

25-
export const TsNamespaceTableOps = "const db = await lancedb.connect(uri);\nconst namespace = [\"prod\", \"search\"];\n\nawait db.createTable(\n \"users\",\n [{ id: 1, name: \"alice\" }],\n namespace,\n { mode: \"overwrite\" },\n);\n\nconst table = await db.openTable(\"users\", namespace);\nconst tableNames = await db.tableNames(namespace);\n\nawait db.dropTable(\"users\", namespace);\n// dropAllTables is namespace-aware as well:\n// await db.dropAllTables(namespace);\n";
26-
2725
export const RsConnect = "async fn connect_example(uri: &str) {\n let db = connect(uri).execute().await.unwrap();\n let _ = db;\n}\n";
2826

2927
export const RsConnectCloud = "let uri = \"db://your-database-uri\";\nlet api_key = \"your-api-key\";\nlet region = \"us-east-1\";\n";
3028

3129
export const RsConnectObjectStorage = "let uri = \"s3://your-bucket/path\";\n// You can also use \"gs://your-bucket/path\" or \"az://your-container/path\".\n";
3230

33-
export const RsNamespaceTableOps = "let conn = connect(uri).execute().await?;\nlet namespace = vec![\"prod\".to_string(), \"search\".to_string()];\n\nlet schema = std::sync::Arc::new(arrow_schema::Schema::new(vec![\n arrow_schema::Field::new(\"id\", arrow_schema::DataType::Int64, false),\n]));\n\nconn.create_empty_table(\"users\", schema)\n .namespace(namespace.clone())\n .execute()\n .await?;\n\nlet _table = conn\n .open_table(\"users\")\n .namespace(namespace.clone())\n .execute()\n .await?;\nlet _table_names = conn\n .table_names()\n .namespace(namespace.clone())\n .execute()\n .await?;\n\nconn.drop_table(\"users\", &namespace).await?;\n// drop_all_tables is namespace-aware as well:\n// conn.drop_all_tables(&namespace).await?;\n";
31+
export const RsNamespaceAdminOps = "let mut properties = std::collections::HashMap::new();\nproperties.insert(\"root\".to_string(), \"./local_lancedb\".to_string());\nlet db = lancedb::connect_namespace(\"dir\", properties).execute().await?;\nlet namespace = vec![\"prod\".to_string(), \"search\".to_string()];\n\ndb.create_namespace(lancedb::database::CreateNamespaceRequest {\n namespace: vec![\"prod\".to_string()],\n})\n.await?;\ndb.create_namespace(lancedb::database::CreateNamespaceRequest {\n namespace: namespace.clone(),\n})\n.await?;\n\nlet child_namespaces = db\n .list_namespaces(lancedb::database::ListNamespacesRequest {\n namespace: vec![\"prod\".to_string()],\n ..Default::default()\n })\n .await?;\nprintln!(\n \"Child namespaces under {:?}: {:?}\",\n namespace, child_namespaces\n);\n// Child namespaces under [\"prod\", \"search\"]: [\"search\"]\n\ndb.drop_namespace(lancedb::database::DropNamespaceRequest {\n namespace: namespace.clone(),\n})\n.await?;\ndb.drop_namespace(lancedb::database::DropNamespaceRequest {\n namespace: vec![\"prod\".to_string()],\n})\n.await?;\n";
32+
33+
export const RsNamespaceTableOps = "let conn = connect(uri).execute().await?;\nlet search_namespace = vec![\"prod\".to_string(), \"search\".to_string()];\nlet recommendations_namespace = vec![\"prod\".to_string(), \"recommendations\".to_string()];\n\nlet schema = std::sync::Arc::new(arrow_schema::Schema::new(vec![\n arrow_schema::Field::new(\"id\", arrow_schema::DataType::Int64, false),\n]));\n\nconn.create_empty_table(\"user\", schema.clone())\n .namespace(search_namespace.clone())\n .execute()\n .await?;\n\nconn.create_empty_table(\"user\", schema)\n .namespace(recommendations_namespace.clone())\n .execute()\n .await?;\n\nlet search_table_names = conn\n .table_names()\n .namespace(search_namespace)\n .execute()\n .await?;\nlet recommendation_table_names = conn\n .table_names()\n .namespace(recommendations_namespace)\n .execute()\n .await?;\n\nprintln!(\"{search_table_names:?}\"); // [\"user\"]\nprintln!(\"{recommendation_table_names:?}\"); // [\"user\"]\n";
3434

docs/snippets/multimodal.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{/* Auto-generated by scripts/mdx_snippets_gen.py. Do not edit manually. */}
22

3-
export const PyBlobApiIngest = "import lancedb\nimport lance\n\ndb = lancedb.connect(db_path_factory(\"blob_db\"))\n \n# Create sample data\ndata = [\n {\"id\": 1, \"video\": b\"fake_video_bytes_1\"},\n {\"id\": 2, \"video\": b\"fake_video_bytes_2\"}\n]\n \n# Create the table\ntbl = db.create_table(\"videos\", data=data, schema=schema)\n";
3+
export const PyBlobApiIngest = "import lancedb\n\ndb = lancedb.connect(db_path_factory(\"blob_db\"))\n \n# Create sample data\ndata = [\n {\"id\": 1, \"video\": b\"fake_video_bytes_1\"},\n {\"id\": 2, \"video\": b\"fake_video_bytes_2\"}\n]\n \n# Create the table\ntbl = db.create_table(\"videos\", data=data, schema=schema)\n";
44

55
export const PyBlobApiSchema = "import pyarrow as pa\n\n# Define schema with Blob API metadata for lazy loading\nschema = pa.schema([\n pa.field(\"id\", pa.int64()),\n pa.field(\n \"video\", \n pa.large_binary(), \n metadata={\"lance-encoding:blob\": \"true\"} # Enable Blob API\n ),\n])\n";
66

0 commit comments

Comments
 (0)