Skip to content

Commit b9aa4d5

Browse files
authored
New Features (#6)
* feat: Added support for reset * fix: Improved delete Collection test case. * feat: Cohere support Refs: #1 * feat: Added integration tests in a separate workflow - Release workflow now is only triggered upon new release and it bumps version to tag name * fix: Added reset after each test to ensure test are not failing due to what previous tests have done. * feat: List collections - Improvements of how Collections are handled Refs: #3 * feat: Full feature parity with the Python API (except for raw SQL execution) Refs: #2, #3, #4
1 parent c1f4c9e commit b9aa4d5

13 files changed

Lines changed: 856 additions & 105 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Integration test
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
integration-test:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v3
16+
- name: Set up JDK 8
17+
uses: actions/setup-java@v3
18+
with:
19+
java-version: '8'
20+
distribution: 'adopt'
21+
cache: maven
22+
23+
- name: Install Helm
24+
uses: azure/setup-helm@v1
25+
with:
26+
version: v3.4.0
27+
28+
- name: start minikube
29+
id: minikube
30+
uses: medyagh/setup-minikube@latest
31+
with:
32+
kubernetes-version: 1.27.3
33+
- name: Add helm repo
34+
run: |
35+
set -e
36+
helm repo add chromadb https://amikos-tech.github.io/chromadb-chart/
37+
helm repo update
38+
- name: Install chromadb
39+
run: |
40+
set -e
41+
helm install chromadb chromadb/chromadb --set chromadb.allowReset=true
42+
- name: Wait for deployment to be ready
43+
id: wait-and-set
44+
run: |
45+
set -e
46+
kubectl wait \
47+
--for=condition=ready pod \
48+
--selector=app.kubernetes.io/name=chromadb \
49+
--timeout=120s
50+
echo "chroma-url=$(minikube service chromadb --url)" >> $GITHUB_OUTPUT
51+
- name: Hearthbeat
52+
run: |
53+
set -e
54+
kubectl get svc -A
55+
curl $(minikube service chromadb --url)/api/v1
56+
- name: Test with Maven
57+
run: mvn clean test
58+
env:
59+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
60+
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
61+
CHROMA_URL: ${{steps.wait-and-set.outputs.chroma-url}}

.github/workflows/release.yml

Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
name: release
22

33
on:
4-
push:
5-
branches: [ "main" ]
6-
pull_request:
4+
release:
5+
types: [created]
76
branches: [ "main" ]
87

98
jobs:
@@ -20,65 +19,37 @@ jobs:
2019
server-id: ossrh
2120
server-username: MAVEN_USERNAME
2221
server-password: MAVEN_PASSWORD
23-
24-
- name: Install Helm
25-
uses: azure/setup-helm@v1
26-
with:
27-
version: v3.4.0
28-
29-
- name: start minikube
30-
id: minikube
31-
uses: medyagh/setup-minikube@latest
32-
with:
33-
kubernetes-version: 1.27.3
34-
- name: Add helm repo
35-
run: |
36-
set -e
37-
helm repo add chromadb https://amikos-tech.github.io/chromadb-chart/
38-
helm repo update
39-
- name: Install chromadb
40-
run: |
41-
set -e
42-
helm install chromadb chromadb/chromadb
43-
- name: Wait for deployment to be ready
44-
id: wait-and-set
45-
run: |
46-
set -e
47-
kubectl wait \
48-
--for=condition=ready pod \
49-
--selector=app.kubernetes.io/name=chromadb \
50-
--timeout=120s
51-
echo "chroma-url=$(minikube service chromadb --url)" >> $GITHUB_OUTPUT
52-
- name: Hearthbeat
53-
run: |
54-
set -e
55-
kubectl get svc -A
56-
curl $(minikube service chromadb --url)/api/v1
57-
- name: Build with Maven
58-
run: mvn clean package
59-
env:
60-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
61-
CHROMA_URL: ${{steps.wait-and-set.outputs.chroma-url}}
62-
# - name: Publish package
63-
# run: mvn --batch-mode deploy
64-
# env:
65-
# MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
66-
# MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
6722
- id: install-secret-key
6823
name: Install gpg secret key
6924
run: |
7025
# Install gpg secret key
71-
cat <(echo -e "${{ secrets.AMIKOS_OSS_GPG_SECRET_KEY }}") | gpg --batch --import
26+
cat <(echo -e "${GPG_KEY}") | gpg --batch --import
7227
# Verify gpg secret key
7328
gpg --list-secret-keys --keyid-format LONG
29+
env:
30+
GPG_KEY: ${{ secrets.AMIKOS_OSS_GPG_SECRET_KEY }}
31+
- name: Version bump
32+
run: |
33+
mvn \
34+
--no-transfer-progress \
35+
--batch-mode \
36+
-Dgpg.skip=true \
37+
-DskipTests \
38+
versions:set \
39+
-DnewVersion=${{ github.ref_name }}
40+
git config --local user.email "action@github.com"
41+
git config --local user.name "GitHub Action"
42+
git add pom.xml
43+
git commit -m "Increment version to ${{ github.ref_name }}" -a
44+
git push
7445
- name: Publish package
7546
run: |
7647
mvn \
7748
--no-transfer-progress \
7849
--batch-mode \
7950
-Dgpg.passphrase=${GPG_PASSPHRASE} \
8051
-DskipTests \
81-
clean deploy
52+
clean package deploy
8253
env:
8354
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8455
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}

README.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,43 @@
22

33
This is a very basic/naive implementation in Java of the Chroma Vector Database API.
44

5-
| Important: For now it only supports OpenAI embeddings.
5+
This client works with Chroma Version `0.4.3`
6+
7+
## Features
8+
9+
### Embeddings Support
10+
11+
- [x] OpenAI API
12+
- [x] Cohere API (including Multi-language support)
13+
- [ ] Sentence Transformers
14+
- [ ] PaLM API
15+
- [ ] Custom Embedding Function
16+
17+
### Feature Parity with ChromaDB API
18+
19+
- [x] Reset
20+
- [x] Heartbeat
21+
- [x] List Collections
22+
- [ ] Raw SQL
23+
- [x] Get Version
24+
- [x] Create Collection
25+
- [x] Delete Collection
26+
- [x] Collection Add
27+
- [x] Collection Get (partial without additional parameters)
28+
- [x] Collection Count
29+
- [x] Collection Query
30+
- [x] Collection Modify
31+
- [x] Collection Update
32+
- [x] Collection Upsert
33+
- [x] Collection Create Index
34+
- [x] Collection Delete - delete documents in collection
635

736
## TODO
837

938
- [ ] Add support for other embedding functions
10-
- [ ] Push the package to Maven Central - https://docs.github.com/en/actions/publishing-packages/publishing-java-packages-with-maven
39+
- [ ] Push the package to Maven
40+
Central - https://docs.github.com/en/actions/publishing-packages/publishing-java-packages-with-maven
41+
- [ ] Fluent API - make it easier for users to make use of the library
1142

1243
## Usage
1344

pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.github.amikos-tech</groupId>
88
<artifactId>chromadb-java-client</artifactId>
9-
<version>0.1.0-SNAPSHOT</version>
9+
<version>0.1.1-SNAPSHOT</version>
1010
<description>
1111
Chroma Vector DB Java Client
1212
</description>
@@ -357,6 +357,11 @@
357357
</execution>
358358
</executions>
359359
</plugin>
360+
<plugin>
361+
<groupId>org.codehaus.mojo</groupId>
362+
<artifactId>versions-maven-plugin</artifactId>
363+
<version>2.8.1</version> <!-- Use the latest version available -->
364+
</plugin>
360365
</plugins>
361366
</build>
362367

src/main/java/tech/amikos/chromadb/Client.java

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
import tech.amikos.chromadb.model.CreateCollection;
88

99
import java.math.BigDecimal;
10+
import java.util.List;
1011
import java.util.Map;
12+
import java.util.stream.Collectors;
1113

1214
/**
1315
* ChromaDB Client
@@ -22,8 +24,8 @@ public Client(String basePath) {
2224
api = new DefaultApi(apiClient);
2325
}
2426

25-
public Collection getCollection(String collectionName, EmbeddingFunction embeddingFunction) {
26-
return new Collection(api, collectionName, embeddingFunction);
27+
public Collection getCollection(String collectionName, EmbeddingFunction embeddingFunction) throws ApiException {
28+
return new Collection(api, collectionName, embeddingFunction).fetch();
2729
}
2830

2931
public Map<String, BigDecimal> heartbeat() throws ApiException {
@@ -33,21 +35,46 @@ public Map<String, BigDecimal> heartbeat() throws ApiException {
3335
public Collection createCollection(String collectionName, Map<String, String> metadata, Boolean createOrGet, EmbeddingFunction embeddingFunction) throws ApiException {
3436
CreateCollection req = new CreateCollection();
3537
req.setName(collectionName);
36-
req.setMetadata(metadata);
38+
Map<String, String> _metadata = metadata;
39+
if (metadata == null || metadata.isEmpty() || !metadata.containsKey("embedding_function")) {
40+
_metadata = new LinkedTreeMap<>();
41+
_metadata.put("embedding_function", embeddingFunction.getClass().getName());
42+
}
43+
req.setMetadata(_metadata);
3744
req.setGetOrCreate(createOrGet);
3845
LinkedTreeMap resp = (LinkedTreeMap) api.createCollection(req);
39-
return new Collection(api, (String) resp.get("name"), embeddingFunction);
46+
return new Collection(api, (String) resp.get("name"), embeddingFunction).fetch();
4047
}
4148

4249
public Collection deleteCollection(String collectionName) throws ApiException {
43-
Collection collection = Collection.getInstance(api,collectionName);
44-
collection.delete();
50+
Collection collection = Collection.getInstance(api, collectionName);
51+
api.deleteCollection(collectionName);
4552
return collection;
4653
}
4754

48-
public Collection upsert(String collectionName, EmbeddingFunction ef) {
55+
public Collection upsert(String collectionName, EmbeddingFunction ef) throws ApiException {
4956
Collection collection = getCollection(collectionName, ef);
5057
// collection.upsert();
5158
return collection;
5259
}
60+
61+
public Boolean reset() throws ApiException {
62+
return api.reset();
63+
}
64+
65+
public List<Collection> listCollections() throws ApiException {
66+
List<LinkedTreeMap> apiResponse = (List<LinkedTreeMap>) api.listCollections();
67+
return apiResponse.stream().map((LinkedTreeMap m) -> {
68+
try {
69+
return getCollection((String) m.get("name"), null);
70+
} catch (ApiException e) {
71+
e.printStackTrace(); //this is not great as we're swallowing the exception
72+
}
73+
return null;
74+
}).collect(Collectors.toList());
75+
}
76+
77+
public String version() throws ApiException {
78+
return api.version();
79+
}
5380
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package tech.amikos.chromadb;
2+
3+
import tech.amikos.cohere.CohereClient;
4+
import tech.amikos.cohere.CreateEmbeddingRequest;
5+
import tech.amikos.cohere.CreateEmbeddingResponse;
6+
7+
import java.util.Arrays;
8+
import java.util.List;
9+
import java.util.stream.Collectors;
10+
11+
public class CohereEmbeddingFunction implements EmbeddingFunction {
12+
13+
private final String cohereAPIKey;
14+
15+
public CohereEmbeddingFunction(String cohereAPIKey) {
16+
this.cohereAPIKey = cohereAPIKey;
17+
18+
}
19+
20+
@Override
21+
public List<List<Float>> createEmbedding(List<String> documents) {
22+
CohereClient client = new CohereClient(this.cohereAPIKey);
23+
CreateEmbeddingResponse response = client.createEmbedding(new CreateEmbeddingRequest().texts(documents.toArray(new String[0])));
24+
return response.getEmbeddings();
25+
}
26+
}

0 commit comments

Comments
 (0)