Skip to content

Commit 1e35d53

Browse files
feat: add local/cloud factories and move reset to Client
- Adds `ChromaDB::local()` and `ChromaDB::cloud()` helper methods for easier connection configuration. - Deprecates `ChromaDB::client()` in favor of `ChromaDB::local()->connect()` or `ChromaDB::factory()->connect()`. BREAKING CHANGE: `ChromaDB::reset()` has been removed. Use `$client->reset()` instead.
1 parent 7b6f454 commit 1e35d53

9 files changed

Lines changed: 171 additions & 79 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
*.swp
77
*.swo
88
playground/*
9-
.idea
9+
.idea
10+
.chroma

README.md

Lines changed: 94 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ ChromaDB PHP provides a simple and intuitive interface for interacting with Chro
3131
```php
3232
use Codewithkyrian\ChromaDB\ChromaDB;
3333

34-
$chromaDB = ChromaDB::client();
34+
$chromaDB = ChromaDB::local()->connect();
3535

3636
// Check current ChromaDB version
3737
echo $chromaDB->version();
@@ -81,11 +81,28 @@ echo $queryResponse->ids[0][1]; // test2
8181

8282
In order to use this library, you need to have ChromaDB running somewhere. You can either run it locally or in the
8383
cloud.
84-
(Chroma doesn't support cloud yet, but it will soon.)
8584

86-
For now, ChromaDB can only run in-memory in Python. You can however run it in client/server mode by either running the
87-
python
88-
project or using the docker image (recommended).
85+
### Local
86+
87+
You can run ChromaDB locally using the Chroma CLI or Docker.
88+
89+
#### Chroma CLI
90+
91+
You can install the Chroma CLI globally using cURL:
92+
93+
```bash
94+
curl -sSL https://raw.githubusercontent.com/chroma-core/chroma/main/rust/cli/install/install.sh | bash
95+
```
96+
97+
And then run the server:
98+
99+
```bash
100+
chroma run --path /path/to/data
101+
```
102+
103+
For more installation options and usage details, check the [Chroma CLI Installation Docs](https://docs.trychroma.com/docs/cli/install) and [Run Docs](https://docs.trychroma.com/docs/cli/run).
104+
105+
#### Docker
89106

90107
To run the docker image, you can use the following command:
91108

@@ -128,6 +145,11 @@ ChromaDB.)
128145

129146
Either way, you can now access ChromaDB at `http://localhost:8000`.
130147

148+
### Chroma Cloud
149+
150+
You can sign up for the hosted version of ChromaDB at [Chroma Cloud](https://trychroma.com/). Once you have an account,
151+
you can create a new project and get your API key.
152+
131153
## Installation
132154

133155
```bash
@@ -138,67 +160,95 @@ composer require codewithkyrian/chromadb-php
138160

139161
### Connecting to ChromaDB
140162

163+
#### Local Instance
164+
141165
```php
142166
use Codewithkyrian\ChromaDB\ChromaDB;
143167

144-
$chroma = ChromaDB::client();
168+
$chroma = ChromaDB::local()->connect();
145169

146170
```
147171

148172
By default, ChromaDB will try to connect to `http://localhost:8000` using the default database name `default_database`
149-
and default tenant name `default_tenant`. You can however change these values by constructing the client using the
150-
factory method:
173+
and default tenant name `default_tenant`. You can however change these values by passing them to the `local` method:
151174

152175
```php
153176
use Codewithkyrian\ChromaDB\ChromaDB;
154177

155-
$chroma = ChromaDB::factory()
156-
->withHost('http://localhost')
157-
->withPort(8000)
158-
->withDatabase('new_database')
159-
->withTenant('new_tenant')
160-
->connect();
178+
$chroma = ChromaDB::local(
179+
host: 'http://localhost',
180+
port: 8000,
181+
tenant: 'new_tenant',
182+
database: 'new_database'
183+
)->connect();
184+
185+
$chroma = ChromaDB::local(port: 8030)->connect();
161186
```
162187

163-
If the tenant or database doesn't exist, the package will automatically create them for you.
188+
#### Chroma Cloud
164189

165-
### Authentication
190+
To connect to Chroma Cloud, you can use the `cloud` method and pass in your API key:
166191

167-
ChromaDB supports static token-based authentication. To use it, you need to start the Chroma server passing the required
168-
environment variables as stated in the documentation. If you're using the docker image, you can pass in the environment
169-
variables using the `--env` flag or by using a `.env` file and for the docker-compose file, you can use the `env_file`
170-
option, or pass in the environment variables directly like so:
192+
```php
193+
use Codewithkyrian\ChromaDB\ChromaDB;
171194

172-
```yaml
173-
version: '3.9'
174-
175-
services:
176-
chroma:
177-
image: 'chromadb/chroma'
178-
ports:
179-
- '8000:8000'
180-
environment:
181-
- CHROMA_SERVER_AUTHN_CREDENTIALS=test-token
182-
- CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.token_authn.TokenAuthenticationServerProvider
183-
184-
...
185-
```
186-
187-
You can then connect to ChromaDB using the factory method:
195+
$chroma = ChromaDB::cloud('your-api-key')->connect();
196+
```
197+
198+
You can also specify the tenant and database if needed:
188199

189200
```php
190201
use Codewithkyrian\ChromaDB\ChromaDB;
191202

192-
$chroma = ChromaDB::factory()
193-
->withAuthToken('test-token')
194-
->connect();
203+
$chroma = ChromaDB::cloud(
204+
apiKey: 'your-api-key',
205+
tenant: 'new_tenant',
206+
database: 'new_database'
207+
)->connect();
208+
```
209+
210+
### Configuring the Connection
211+
212+
Both `ChromaDB::local()` and `ChromaDB::cloud()` return a `Factory` instance. This allows you to configure the connection further before establishing it.
213+
214+
#### Setting Host and Port
215+
216+
You can override the host and port using `withHost()` and `withPort()`:
217+
218+
```php
219+
$chroma = ChromaDB::local()
220+
->withHost('http://custom-host')
221+
->withPort(8080)
222+
->connect();
223+
```
224+
225+
#### Setting Database and Tenant
226+
227+
You can specify the database and tenant using `withDatabase()` and `withTenant()`:
228+
229+
```php
230+
$chroma = ChromaDB::local()
231+
->withDatabase('my_db')
232+
->withTenant('my_tenant')
233+
->connect();
234+
```
235+
236+
#### Adding Custom Headers
237+
238+
You can add custom headers to your requests using `withHeader()` or `withHeaders()`. This is useful for passing authentication tokens or other metadata required by your proxy or server.
239+
240+
```php
241+
$chroma = ChromaDB::local()
242+
->withHeader('Authorization', 'Bearer my-token')
243+
->withHeaders(['X-Custom-Header' => 'custom-value'])
244+
->connect();
195245
```
196246

197247
### Getting the version
198248

199249
```php
200250

201-
echo $chroma->version(); // 0.4.0
251+
echo $chroma->version();
202252

203253
```
204254

@@ -564,10 +614,11 @@ $chroma->deleteCollection('test_collection');
564614

565615
## Testing
566616

567-
```
568-
// Run chroma by running the docker compose file in the repo
569-
docker compose up -d
617+
## Testing
618+
619+
To run the tests, make sure you have the Chroma CLI installed and globally accessible. The tests will automatically start the server on port 8000.
570620

621+
```bash
571622
composer test
572623
```
573624

chroma/chroma.sqlite3

-172 KB
Binary file not shown.

src/ChromaDB.php

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,38 @@
66

77
class ChromaDB
88
{
9+
/**
10+
* @deprecated Use ChromaDB::local()->connect() or ChromaDB::factory()->connect() instead.
11+
*/
912
public static function client(): Client
1013
{
1114
return self::factory()->connect();
1215
}
1316

17+
/**
18+
* Creates a new factory instance configured for a local/self-hosted ChromaDB instance.
19+
*/
20+
public static function local(
21+
string $host = 'http://localhost',
22+
?int $port = 8000,
23+
?string $tenant = null,
24+
?string $database = null
25+
): Factory {
26+
$factory = self::factory()
27+
->withHost($host)
28+
->withPort($port);
29+
30+
if ($tenant) {
31+
$factory->withTenant($tenant);
32+
}
33+
34+
if ($database) {
35+
$factory->withDatabase($database);
36+
}
37+
38+
return $factory;
39+
}
40+
1441
/**
1542
* Creates a new factory instance to configure a custom ChromaDB Client
1643
*/
@@ -26,7 +53,7 @@ public static function cloud(string $apiKey, ?string $tenant = null, ?string $da
2653
{
2754
$factory = self::factory()
2855
->withHost('https://api.trychroma.com')
29-
->withPort(8000)
56+
->withPort(null)
3057
->withHeader('X-Chroma-Token', $apiKey);
3158

3259
if ($tenant) {
@@ -39,13 +66,4 @@ public static function cloud(string $apiKey, ?string $tenant = null, ?string $da
3966

4067
return $factory;
4168
}
42-
43-
/**
44-
* Resets the database. This will delete all collections and entries and
45-
* return true if the database was reset successfully.
46-
*/
47-
public static function reset(): bool
48-
{
49-
return (new Factory())->createApi()->reset();
50-
}
5169
}

src/Client.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,9 @@ public function deleteAllCollections(): void
154154
$this->deleteCollection($collection->name);
155155
}
156156
}
157+
158+
public function reset(): bool
159+
{
160+
return $this->api->reset();
161+
}
157162
}

src/Factory.php

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010

1111
class Factory
1212
{
13-
/**
14-
* The base url for the ChromaDB server.
15-
*/
16-
protected string $baseUrl;
17-
1813
/**
1914
* The host where the ChromaDB server is running.
2015
*/
@@ -23,7 +18,7 @@ class Factory
2318
/**
2419
* The port to send requests to.
2520
*/
26-
protected int $port = 8000;
21+
protected ?int $port = 8000;
2722

2823
/**
2924
* The database to use for the instance.
@@ -42,11 +37,6 @@ class Factory
4237
*/
4338
protected array $headers = [];
4439

45-
/**
46-
* The ChromaDB api provider for the instance.
47-
*/
48-
protected Api $api;
49-
5040
/**
5141
* The url of the client to use for the requests.
5242
*/
@@ -59,7 +49,7 @@ public function withHost(string $host): self
5949
/**
6050
* The port of the client to use for the requests.
6151
*/
62-
public function withPort(int $port): self
52+
public function withPort(?int $port): self
6353
{
6454
$this->port = $port;
6555
return $this;
@@ -115,25 +105,20 @@ public function withHeaders(array $headers): self
115105

116106
public function connect(): Client
117107
{
118-
$this->api = $this->createApi();
119-
120-
return new Client($this->api, $this->database, $this->tenant);
121-
}
122-
123-
public function createApi(): Api
124-
{
125-
$this->baseUrl = "$this->host:$this->port";
108+
$baseUrl = $this->port ? "$this->host:$this->port" : $this->host;
126109

127110
$httpClient = Psr18ClientDiscovery::find();
128111
$requestFactory = Psr17FactoryDiscovery::findRequestFactory();
129112
$streamFactory = Psr17FactoryDiscovery::findStreamFactory();
130113

131-
return new Api(
114+
$api = new Api(
132115
$httpClient,
133116
$requestFactory,
134117
$streamFactory,
135-
$this->baseUrl,
118+
$baseUrl,
136119
$this->headers
137120
);
121+
122+
return new Client($api, $this->database, $this->tenant);
138123
}
139124
}

src/Models/Collection.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,6 @@ function validate(
388388
throw new \InvalidArgumentException('Expected IDs to be unique, found duplicates for: ' . implode(', ', $duplicateIds));
389389
}
390390

391-
392391
return [
393392
'ids' => $ids,
394393
'embeddings' => $finalEmbeddings,

0 commit comments

Comments
 (0)