Skip to content

Commit 4234eeb

Browse files
ChromaDB
1 parent 6fe748b commit 4234eeb

File tree

3 files changed

+61
-68
lines changed

3 files changed

+61
-68
lines changed

docs/modules/chromadb.md

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,48 @@
1-
# ChromaDB Module
2-
3-
[ChromaDB](https://www.trychroma.com/) is an AI-native open-source embedding database.
1+
# ChromaDB
42

53
## Install
64

75
```bash
86
npm install @testcontainers/chromadb --save-dev
97
```
108

11-
## Resources
9+
## Examples
1210

13-
* [GitHub](https://github.com/chroma-core/chroma)
14-
* [Node.js Client](https://www.npmjs.com/package/chromadb)
15-
* [Docs](https://docs.trychroma.com)
16-
* [Discord](https://discord.gg/MMeYNTmh3x)
17-
* [Cookbook](https://cookbook.chromadb.dev)
11+
These examples use the following libraries:
1812

19-
## Examples
13+
- [chromadb](https://www.npmjs.com/package/chromadb)
2014

21-
<!--codeinclude-->
22-
[Connect to Chroma:](../../packages/modules/chromadb/src/chromadb-container.test.ts)
23-
inside_block:simpleConnect
24-
<!--/codeinclude-->
15+
npm install chromadb
16+
17+
- [ollama](https://www.npmjs.com/package/ollama)
18+
19+
npm install ollama
20+
21+
---
22+
23+
Choose an image from [Docker Hub](https://hub.docker.com/r/chromadb/chroma) and substitute `IMAGE`.
24+
25+
### Create/query collection
2526

2627
<!--codeinclude-->
27-
[Create Collection:](../../packages/modules/chromadb/src/chromadb-container.test.ts)
28-
inside_block:createCollection
28+
[](../../packages/modules/chromadb/src/chromadb-container.test.ts) inside_block:chromaCreateCollection
2929
<!--/codeinclude-->
3030

31+
### Embedding function
32+
3133
<!--codeinclude-->
32-
[Query Collection with Embedding Function:](../../packages/modules/chromadb/src/chromadb-container.test.ts)
33-
inside_block:queryCollectionWithEmbeddingFunction
34+
[](../../packages/modules/chromadb/src/chromadb-container.test.ts) inside_block:queryCollectionWithEmbeddingFunction
3435
<!--/codeinclude-->
3536

37+
### Persistent directory
38+
3639
<!--codeinclude-->
37-
[Work with persistent directory:](../../packages/modules/chromadb/src/chromadb-container.test.ts)
38-
inside_block:persistentData
40+
[](../../packages/modules/chromadb/src/chromadb-container.test.ts) inside_block:persistentData
3941
<!--/codeinclude-->
4042

43+
### Authentication
44+
4145
<!--codeinclude-->
42-
[Work with authentication:](../../packages/modules/chromadb/src/chromadb-container.test.ts) inside_block:auth
46+
[](../../packages/modules/chromadb/src/chromadb-container.test.ts) inside_block:chromaAuth
4347
<!--/codeinclude-->
44-
48+

docs/quickstart/logging.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Testcontainers writes logs using the [debug](https://www.npmjs.com/package/debug
55
The following namespaces are available:
66

77
- `testcontainers*`: Show all logs
8-
- `testcontainers`: Show Testcontainers core logs
8+
- `testcontainers`: Show core logs
99
- `testcontainers:containers`: Show logs from containers
1010
- `testcontainers:compose`: Show logs from Docker Compose
1111
- `testcontainers:build`: Show build logs

packages/modules/chromadb/src/chromadb-container.test.ts

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,53 @@ import os from "node:os";
44
import path from "node:path";
55
import { GenericContainer } from "testcontainers";
66
import { getImage } from "../../../testcontainers/src/utils/test-helper";
7-
import { ChromaDBContainer, StartedChromaDBContainer } from "./chromadb-container";
7+
import { ChromaDBContainer } from "./chromadb-container";
88

99
const IMAGE = getImage(__dirname);
1010

1111
describe("ChromaDB", { timeout: 360_000 }, () => {
12-
// startContainer {
1312
it("should connect", async () => {
1413
await using container = await new ChromaDBContainer(IMAGE).start();
15-
const client = await connectTo(container);
14+
const client = new ChromaClient({ path: container.getHttpUrl() });
1615
expect(await client.heartbeat()).toBeDefined();
17-
// Do something with the client
1816
});
19-
// }
2017

21-
// simpleConnect {
22-
async function connectTo(container: StartedChromaDBContainer) {
23-
const client = new ChromaClient({
24-
path: container.getHttpUrl(),
25-
});
26-
const hb = await client.heartbeat();
27-
expect(hb).toBeDefined();
28-
return client;
29-
}
30-
// }
31-
32-
// createCollection {
3318
it("should create collection and get data", async () => {
19+
// chromaCreateCollection {
3420
await using container = await new ChromaDBContainer(IMAGE).start();
35-
const client = await connectTo(container);
21+
22+
const client = new ChromaClient({ path: container.getHttpUrl() });
3623
const collection = await client.createCollection({ name: "test", metadata: { "hnsw:space": "cosine" } });
3724
expect(collection.name).toBe("test");
38-
expect(collection.metadata).toBeDefined();
39-
expect(collection.metadata?.["hnsw:space"]).toBe("cosine");
25+
4026
await collection.add({ ids: ["1"], embeddings: [[1, 2, 3]], documents: ["my doc"], metadatas: [{ key: "value" }] });
4127
const getResults = await collection.get({ ids: ["1"] });
4228
expect(getResults.ids[0]).toBe("1");
4329
expect(getResults.documents[0]).toStrictEqual("my doc");
4430
expect(getResults.metadatas).toBeDefined();
4531
expect(getResults.metadatas?.[0]?.key).toStrictEqual("value");
32+
// }
4633
});
47-
// }
4834

49-
// queryCollectionWithEmbeddingFunction {
5035
it("should create collection and query", async () => {
36+
// queryCollectionWithEmbeddingFunction {
5137
await using container = await new ChromaDBContainer(IMAGE).start();
38+
5239
const ollama = await new GenericContainer("ollama/ollama").withExposedPorts(11434).start();
5340
await ollama.exec(["ollama", "pull", "nomic-embed-text"]);
54-
const client = await connectTo(container);
41+
const client = new ChromaClient({ path: container.getHttpUrl() });
5542
const embedder = new OllamaEmbeddingFunction({
5643
url: `http://${ollama.getHost()}:${ollama.getMappedPort(11434)}/api/embeddings`,
5744
model: "nomic-embed-text",
5845
});
46+
5947
const collection = await client.createCollection({
6048
name: "test",
6149
metadata: { "hnsw:space": "cosine" },
6250
embeddingFunction: embedder,
6351
});
6452
expect(collection.name).toBe("test");
53+
6554
await collection.add({
6655
ids: ["1", "2"],
6756
documents: [
@@ -73,38 +62,38 @@ describe("ChromaDB", { timeout: 360_000 }, () => {
7362
expect(results).toBeDefined();
7463
expect(results.ids[0]).toEqual(["1"]);
7564
expect(results.ids[0][0]).toBe("1");
65+
// }
7666
});
7767

78-
// persistentData {
7968
it("should reconnect with volume and persistence data", async () => {
80-
const sourcePath = fs.mkdtempSync(path.join(os.tmpdir(), "chroma-temp"));
81-
await using container = await new ChromaDBContainer(IMAGE)
82-
.withBindMounts([{ source: sourcePath, target: "/data" }])
83-
.start();
84-
const client = await connectTo(container);
85-
const collection = await client.createCollection({ name: "test", metadata: { "hnsw:space": "cosine" } });
86-
expect(collection.name).toBe("test");
87-
expect(collection.metadata).toBeDefined();
88-
expect(collection.metadata?.["hnsw:space"]).toBe("cosine");
89-
await collection.add({ ids: ["1"], embeddings: [[1, 2, 3]], documents: ["my doc"] });
90-
const getResults = await collection.get({ ids: ["1"] });
91-
expect(getResults.ids[0]).toBe("1");
92-
expect(getResults.documents[0]).toStrictEqual("my doc");
93-
expect(fs.existsSync(`${sourcePath}/chroma.sqlite3`)).toBe(true);
9469
try {
95-
fs.rmSync(sourcePath, { force: true, recursive: true });
96-
} catch (e) {
97-
// Ignore clean up, when have no access on fs.
98-
console.log(e);
70+
// persistentData {
71+
const sourcePath = fs.mkdtempSync(path.join(os.tmpdir(), "chroma-temp"));
72+
await using container = await new ChromaDBContainer(IMAGE)
73+
.withBindMounts([{ source: sourcePath, target: "/data" }])
74+
.start();
75+
76+
const client = new ChromaClient({ path: container.getHttpUrl() });
77+
const collection = await client.createCollection({ name: "test", metadata: { "hnsw:space": "cosine" } });
78+
expect(collection.name).toBe("test");
79+
80+
await collection.add({ ids: ["1"], embeddings: [[1, 2, 3]], documents: ["my doc"] });
81+
const getResults = await collection.get({ ids: ["1"] });
82+
expect(getResults.ids[0]).toBe("1");
83+
expect(getResults.documents[0]).toStrictEqual("my doc");
84+
expect(fs.existsSync(`${sourcePath}/chroma.sqlite3`)).toBe(true);
85+
// }
86+
} finally {
87+
fs.rmSync(path.join(os.tmpdir(), "chroma-temp"), { force: true, recursive: true });
9988
}
10089
});
101-
// }
10290

103-
// auth {
10491
it("should use auth", async () => {
92+
// chromaAuth {
10593
const tenant = "test-tenant";
10694
const key = "test-key";
10795
const database = "test-db";
96+
10897
await using container = await new ChromaDBContainer(IMAGE)
10998
.withEnvironment({
11099
CHROMA_SERVER_AUTHN_CREDENTIALS: key,
@@ -139,6 +128,6 @@ describe("ChromaDB", { timeout: 360_000 }, () => {
139128

140129
const collection = await dbClient.createCollection({ name: "test-collection" });
141130
expect(collection.name).toBe("test-collection");
131+
// }
142132
});
143-
// }
144133
});

0 commit comments

Comments
 (0)