diff --git a/README.md b/README.md index 2d98e0c..da84bd6 100644 --- a/README.md +++ b/README.md @@ -77,32 +77,32 @@ API to generate embeddings and works in the same way it works in core Chroma Pyt package tech.amikos; import tech.amikos.chromadb.*; -import tech.amikos.chromadb.Collection; +import tech.amikos.chromadb.CollectionImpl; import tech.amikos.chromadb.embeddings.DefaultEmbeddingFunction; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client(System.getenv("CHROMA_URL")); - client.reset(); - EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); - List> metadata = new ArrayList<>(); - metadata.add(new HashMap() {{ - put("type", "scientist"); - }}); - metadata.add(new HashMap() {{ - put("type", "spy"); - }}); - collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); - System.out.println(qr); - } catch (Exception e) { - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl(System.getenv("CHROMA_URL")); + client.reset(); + EmbeddingFunction ef = new DefaultEmbeddingFunction(); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); + List> metadata = new ArrayList<>(); + metadata.add(new HashMap() {{ + put("type", "scientist"); + }}); + metadata.add(new HashMap() {{ + put("type", "spy"); + }}); + collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); + System.out.println(qr); + } catch (Exception e) { + System.out.println(e); } + } } ``` @@ -116,35 +116,35 @@ our documents. ```java package tech.amikos; -import tech.amikos.chromadb.Client; -import tech.amikos.chromadb.Collection; +import tech.amikos.chromadb.ClientImpl; +import tech.amikos.chromadb.CollectionImpl; import tech.amikos.chromadb.EmbeddingFunction; import tech.amikos.chromadb.embeddings.openai.OpenAIEmbeddingFunction; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client(System.getenv("CHROMA_URL")); - String apiKey = System.getenv("OPENAI_API_KEY"); - EmbeddingFunction ef = new OpenAIEmbeddingFunction(apiKey, "text-embedding-3-small"); - Collection collection = client.createCollection("test-collection", null, true, ef); - List> metadata = new ArrayList<>(); - metadata.add(new HashMap() {{ - put("type", "scientist"); - }}); - metadata.add(new HashMap() {{ - put("type", "spy"); - }}); - collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); - System.out.println(qr); - } catch (Exception e) { - e.printStackTrace(); - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl(System.getenv("CHROMA_URL")); + String apiKey = System.getenv("OPENAI_API_KEY"); + EmbeddingFunction ef = new OpenAIEmbeddingFunction(apiKey, "text-embedding-3-small"); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); + List> metadata = new ArrayList<>(); + metadata.add(new HashMap() {{ + put("type", "scientist"); + }}); + metadata.add(new HashMap() {{ + put("type", "spy"); + }}); + collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); + System.out.println(qr); + } catch (Exception e) { + e.printStackTrace(); + System.out.println(e); } + } } ``` @@ -189,34 +189,34 @@ our documents. package tech.amikos; import tech.amikos.chromadb.*; -import tech.amikos.chromadb.Collection; +import tech.amikos.chromadb.CollectionImpl; import tech.amikos.chromadb.embeddings.cohere.CohereEmbeddingFunction; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client(System.getenv("CHROMA_URL")); - client.reset(); - String apiKey = System.getenv("COHERE_API_KEY"); - EmbeddingFunction ef = new CohereEmbeddingFunction(apiKey); - Collection collection = client.createCollection("test-collection", null, true, ef); - List> metadata = new ArrayList<>(); - metadata.add(new HashMap() {{ - put("type", "scientist"); - }}); - metadata.add(new HashMap() {{ - put("type", "spy"); - }}); - collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); - System.out.println(qr); - } catch (Exception e) { - e.printStackTrace(); - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl(System.getenv("CHROMA_URL")); + client.reset(); + String apiKey = System.getenv("COHERE_API_KEY"); + EmbeddingFunction ef = new CohereEmbeddingFunction(apiKey); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); + List> metadata = new ArrayList<>(); + metadata.add(new HashMap() {{ + put("type", "scientist"); + }}); + metadata.add(new HashMap() {{ + put("type", "spy"); + }}); + collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); + System.out.println(qr); + } catch (Exception e) { + e.printStackTrace(); + System.out.println(e); } + } } ``` @@ -239,32 +239,32 @@ our documents using HuggingFace cloud-based inference API. package tech.amikos; import tech.amikos.chromadb.*; -import tech.amikos.chromadb.Collection; +import tech.amikos.chromadb.CollectionImpl; import tech.amikos.chromadb.embeddings.hf.HuggingFaceEmbeddingFunction; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client("http://localhost:8000"); - String apiKey = System.getenv("HF_API_KEY"); - EmbeddingFunction ef = new HuggingFaceEmbeddingFunction(apiKey); - Collection collection = client.createCollection("test-collection", null, true, ef); - List> metadata = new ArrayList<>(); - metadata.add(new HashMap() {{ - put("type", "scientist"); - }}); - metadata.add(new HashMap() {{ - put("type", "spy"); - }}); - collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); - System.out.println(qr); - } catch (Exception e) { - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl("http://localhost:8000"); + String apiKey = System.getenv("HF_API_KEY"); + EmbeddingFunction ef = new HuggingFaceEmbeddingFunction(apiKey); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); + List> metadata = new ArrayList<>(); + metadata.add(new HashMap() {{ + put("type", "scientist"); + }}); + metadata.add(new HashMap() {{ + put("type", "spy"); + }}); + collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); + System.out.println(qr); + } catch (Exception e) { + System.out.println(e); } + } } ``` @@ -295,33 +295,33 @@ this will ensure the client uses the correct endpoint. package tech.amikos; import tech.amikos.chromadb.*; -import tech.amikos.chromadb.Collection; +import tech.amikos.chromadb.CollectionImpl; import tech.amikos.chromadb.embeddings.hf.HuggingFaceEmbeddingFunction; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client("http://localhost:8000"); - EmbeddingFunction ef = new HuggingFaceEmbeddingFunction( - WithParam.baseAPI("http://localhost:8008"), - new HuggingFaceEmbeddingFunction.WithAPIType(HuggingFaceEmbeddingFunction.APIType.HFEI_API)); - Collection collection = client.createCollection("test-collection", null, true, ef); - List> metadata = new ArrayList<>(); - metadata.add(new HashMap() {{ - put("type", "scientist"); - }}); - metadata.add(new HashMap() {{ - put("type", "spy"); - }}); - collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); - System.out.println(qr); - } catch (Exception e) { - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl("http://localhost:8000"); + EmbeddingFunction ef = new HuggingFaceEmbeddingFunction( + WithParam.baseAPI("http://localhost:8008"), + new HuggingFaceEmbeddingFunction.WithAPIType(HuggingFaceEmbeddingFunction.APIType.HFEI_API)); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); + List> metadata = new ArrayList<>(); + metadata.add(new HashMap() {{ + put("type", "scientist"); + }}); + metadata.add(new HashMap() {{ + put("type", "spy"); + }}); + collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); + System.out.println(qr); + } catch (Exception e) { + System.out.println(e); } + } } ``` @@ -341,31 +341,31 @@ package tech.amikos; import tech.amikos.chromadb.*; import tech.amikos.chromadb.embeddings.ollama.OllamaEmbeddingFunction; -import tech.amikos.chromadb.Collection; +import tech.amikos.chromadb.CollectionImpl; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client(System.getenv("CHROMA_URL")); - client.reset(); - EmbeddingFunction ef = new OllamaEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); - List> metadata = new ArrayList<>(); - metadata.add(new HashMap() {{ - put("type", "scientist"); - }}); - metadata.add(new HashMap() {{ - put("type", "spy"); - }}); - collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); - System.out.println(qr); - } catch (Exception e) { - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl(System.getenv("CHROMA_URL")); + client.reset(); + EmbeddingFunction ef = new OllamaEmbeddingFunction(); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); + List> metadata = new ArrayList<>(); + metadata.add(new HashMap() {{ + put("type", "scientist"); + }}); + metadata.add(new HashMap() {{ + put("type", "spy"); + }}); + collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); + System.out.println(qr); + } catch (Exception e) { + System.out.println(e); } + } } ``` @@ -379,23 +379,22 @@ public class Main { package tech.amikos; import tech.amikos.chromadb.*; -import tech.amikos.chromadb.Collection; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client(System.getenv("CHROMA_URL")); - String encodedString = Base64.getEncoder().encodeToString("admin:admin".getBytes()); - client.setDefaultHeaders(new HashMap<>() {{ - put("Authorization", "Basic " + encodedString); - }}); - // your code here - } catch (Exception e) { - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl(System.getenv("CHROMA_URL")); + String encodedString = Base64.getEncoder().encodeToString("admin:admin".getBytes()); + client.setDefaultHeaders(new HashMap<>() {{ + put("Authorization", "Basic " + encodedString); + }}); + // your code here + } catch (Exception e) { + System.out.println(e); } + } } ``` @@ -405,23 +404,22 @@ public class Main { package tech.amikos; import tech.amikos.chromadb.*; -import tech.amikos.chromadb.Collection; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client(System.getenv("CHROMA_URL")); - String encodedString = Base64.getEncoder().encodeToString("admin:admin".getBytes()); - client.setDefaultHeaders(new HashMap<>() {{ - put("Authorization", "Bearer test-token"); - }}); - // your code here - } catch (Exception e) { - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl(System.getenv("CHROMA_URL")); + String encodedString = Base64.getEncoder().encodeToString("admin:admin".getBytes()); + client.setDefaultHeaders(new HashMap<>() {{ + put("Authorization", "Bearer test-token"); + }}); + // your code here + } catch (Exception e) { + System.out.println(e); } + } } ``` @@ -431,23 +429,22 @@ public class Main { package tech.amikos; import tech.amikos.chromadb.*; -import tech.amikos.chromadb.Collection; import java.util.*; public class Main { - public static void main(String[] args) { - try { - Client client = new Client(System.getenv("CHROMA_URL")); - String encodedString = Base64.getEncoder().encodeToString("admin:admin".getBytes()); - client.setDefaultHeaders(new HashMap<>() {{ - put("X-Chroma-Token", "test-token"); - }}); - // your code here - } catch (Exception e) { - System.out.println(e); - } + public static void main(String[] args) { + try { + ClientImpl client = new ClientImpl(System.getenv("CHROMA_URL")); + String encodedString = Base64.getEncoder().encodeToString("admin:admin".getBytes()); + client.setDefaultHeaders(new HashMap<>() {{ + put("X-Chroma-Token", "test-token"); + }}); + // your code here + } catch (Exception e) { + System.out.println(e); } + } } ``` diff --git a/src/main/java/tech/amikos/chromadb/Client.java b/src/main/java/tech/amikos/chromadb/ClientImpl.java similarity index 76% rename from src/main/java/tech/amikos/chromadb/Client.java rename to src/main/java/tech/amikos/chromadb/ClientImpl.java index 2899737..ff3a3b4 100644 --- a/src/main/java/tech/amikos/chromadb/Client.java +++ b/src/main/java/tech/amikos/chromadb/ClientImpl.java @@ -15,12 +15,12 @@ /** * ChromaDB Client */ -public class Client { +public class ClientImpl { final ApiClient apiClient = new ApiClient(); private int timeout = 60; DefaultApi api; - public Client(String basePath) { + public ClientImpl(String basePath) { apiClient.setBasePath(basePath); api = new DefaultApi(apiClient); apiClient.setHttpClient(apiClient.getHttpClient().newBuilder() @@ -52,15 +52,15 @@ public void setDefaultHeaders(Map headers) { } } - public Collection getCollection(String collectionName, EmbeddingFunction embeddingFunction) throws ApiException { - return new Collection(api, collectionName, embeddingFunction).fetch(); + public CollectionImpl getCollection(String collectionName, EmbeddingFunction embeddingFunction) throws ApiException { + return new CollectionImpl(api, collectionName, embeddingFunction).fetch(); } public Map heartbeat() throws ApiException { return api.heartbeat(); } - public Collection createCollection(String collectionName, Map metadata, Boolean createOrGet, EmbeddingFunction embeddingFunction) throws ApiException { + public CollectionImpl createCollection(String collectionName, Map metadata, Boolean createOrGet, EmbeddingFunction embeddingFunction) throws ApiException { CreateCollection req = new CreateCollection(); req.setName(collectionName); Map _metadata = metadata; @@ -71,17 +71,17 @@ public Collection createCollection(String collectionName, Map me req.setMetadata(_metadata); req.setGetOrCreate(createOrGet); LinkedTreeMap resp = (LinkedTreeMap) api.createCollection(req); - return new Collection(api, (String) resp.get("name"), embeddingFunction).fetch(); + return new CollectionImpl(api, (String) resp.get("name"), embeddingFunction).fetch(); } - public Collection deleteCollection(String collectionName) throws ApiException { - Collection collection = Collection.getInstance(api, collectionName); + public CollectionImpl deleteCollection(String collectionName) throws ApiException { + CollectionImpl collection = CollectionImpl.getInstance(api, collectionName); api.deleteCollection(collectionName); return collection; } - public Collection upsert(String collectionName, EmbeddingFunction ef) throws ApiException { - Collection collection = getCollection(collectionName, ef); + public CollectionImpl upsert(String collectionName, EmbeddingFunction ef) throws ApiException { + CollectionImpl collection = getCollection(collectionName, ef); // collection.upsert(); return collection; } @@ -90,7 +90,7 @@ public Boolean reset() throws ApiException { return api.reset(); } - public List listCollections() throws ApiException { + public List listCollections() throws ApiException { List apiResponse = (List) api.listCollections(); return apiResponse.stream().map((LinkedTreeMap m) -> { try { diff --git a/src/main/java/tech/amikos/chromadb/Collection.java b/src/main/java/tech/amikos/chromadb/CollectionImpl.java similarity index 96% rename from src/main/java/tech/amikos/chromadb/Collection.java rename to src/main/java/tech/amikos/chromadb/CollectionImpl.java index 03d5a60..e82f631 100644 --- a/src/main/java/tech/amikos/chromadb/Collection.java +++ b/src/main/java/tech/amikos/chromadb/CollectionImpl.java @@ -14,7 +14,7 @@ import static java.lang.Thread.sleep; -public class Collection { +public class CollectionImpl { static Gson gson = new Gson(); DefaultApi api; String collectionName; @@ -25,7 +25,7 @@ public class Collection { private EmbeddingFunction embeddingFunction; - public Collection(DefaultApi api, String collectionName, EmbeddingFunction embeddingFunction) { + public CollectionImpl(DefaultApi api, String collectionName, EmbeddingFunction embeddingFunction) { this.api = api; this.collectionName = collectionName; this.embeddingFunction = embeddingFunction; @@ -44,7 +44,7 @@ public Map getMetadata() { return metadata; } - public Collection fetch() throws ApiException { + public CollectionImpl fetch() throws ApiException { try { LinkedTreeMap resp = (LinkedTreeMap) api.getCollection(collectionName); this.collectionName = resp.get("name").toString(); @@ -56,8 +56,8 @@ public Collection fetch() throws ApiException { } } - public static Collection getInstance(DefaultApi api, String collectionName) throws ApiException { - return new Collection(api, collectionName, null); + public static CollectionImpl getInstance(DefaultApi api, String collectionName) throws ApiException { + return new CollectionImpl(api, collectionName, null); } @Override diff --git a/src/main/java/tech/amikos/chromadb/WithParam.java b/src/main/java/tech/amikos/chromadb/WithParam.java new file mode 100644 index 0000000..b07489d --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/WithParam.java @@ -0,0 +1,41 @@ +package tech.amikos.chromadb; + +import java.util.Map; + +public abstract class WithParam { + public abstract void apply(Map params) throws ChromaException; + + public static WithParam baseAPI(String baseApi) { + return new WithBaseAPI(baseApi); + } +} + + +class WithBaseAPI extends WithParam { + private final String baseAPI; + + public WithBaseAPI(String baseAPI) { + this.baseAPI = baseAPI; + } + + @Override + public void apply(Map params) { + params.put(Constants.EF_PARAMS_BASE_API, baseAPI); + } +} + +class WithTimeout extends WithParam { + private final int timeout; + + public WithTimeout(int timeout) { + this.timeout = timeout; + } + + @Override + public void apply(Map params) throws ChromaException { + if (timeout < 0) { + throw new ChromaException("Timeout must be a positive integer"); + } +// params.put(Constants.EF_PARAMS_TIMEOUT, timeout); + } +} diff --git a/src/main/java/tech/amikos/chromadb/api/AddRequest.java b/src/main/java/tech/amikos/chromadb/api/AddRequest.java new file mode 100644 index 0000000..30f596a --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/AddRequest.java @@ -0,0 +1,14 @@ +package tech.amikos.chromadb.api; + +public class AddRequest implements RequestValidator { + + @Override + public void validate() throws Exception { + //TODO + } + + public static class Builder { + + client.createCollection(name, WithMetadata.W + } +} diff --git a/src/main/java/tech/amikos/chromadb/api/ApiClient.java b/src/main/java/tech/amikos/chromadb/api/ApiClient.java new file mode 100644 index 0000000..daec743 --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/ApiClient.java @@ -0,0 +1,29 @@ +package tech.amikos.chromadb.api; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; + +public class ApiClient { + private OkHttpClient httpClient; + private boolean debugging = false; + private HttpLoggingInterceptor loggingInterceptor; + + public ApiClient() { + this.httpClient = new OkHttpClient(); + } + + public ApiClient setDebugging(boolean debugging) { + if (debugging != this.debugging) { + if (debugging) { + loggingInterceptor = new HttpLoggingInterceptor(); + loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + httpClient.interceptors().add(loggingInterceptor); + } else { + httpClient.interceptors().remove(loggingInterceptor); + loggingInterceptor = null; + } + } + this.debugging = debugging; + return this; + } +} diff --git a/src/main/java/tech/amikos/chromadb/api/AuthProvider.java b/src/main/java/tech/amikos/chromadb/api/AuthProvider.java new file mode 100644 index 0000000..c6f1fcd --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/AuthProvider.java @@ -0,0 +1,4 @@ +package tech.amikos.chromadb.api; + +public interface AuthProvider { +} diff --git a/src/main/java/tech/amikos/chromadb/api/Client.java b/src/main/java/tech/amikos/chromadb/api/Client.java new file mode 100644 index 0000000..91ba26b --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/Client.java @@ -0,0 +1,4 @@ +package tech.amikos.chromadb.api; + +public interface Client { +} diff --git a/src/main/java/tech/amikos/chromadb/api/Collection.java b/src/main/java/tech/amikos/chromadb/api/Collection.java new file mode 100644 index 0000000..5bdfee9 --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/Collection.java @@ -0,0 +1,80 @@ +package tech.amikos.chromadb.api; + +public interface Collection { + /** + * The name of the collection. + * @return the name of the collection + */ + String name(); + + /** + * The unique identifier of the collection. + * @return the unique identifier of the collection + */ + String id(); + + /** + * The name of the tenant that owns the collection. + * @return the name of the tenant that owns the collection + */ + String tenant(); + + /** + * The name of the database that contains the collection. + * @return the name of the database that contains the collection + */ + String database(); + + /** + * The metadata of the collection. + * @return the metadata of the collection + */ + CollectionMetadata metadata(); + + /** + * The configuration of the collection. + * @return the configuration of the collection + */ + CollectionConfiguration configuration(); + + /** + * Adds a record to the collection. + */ + void add(); + + /** + * Upserts a record in the collection. + */ + void upsert(); + + /** + * Updates a record in the collection. + */ + void update(); + + /** + * Deletes a record from the collection. + */ + void delete(); + + /** + * Counts the number of records in the collection. + * @return the number of records in the collection + */ + long count(); + + /** + * Renames the collection. + * @param newName the new name of the collection + */ + void rename(String newName); + + /** + * Updates the metadata of the collection. + * @param newMetadata the new metadata of the collection + */ + void updateMetadata(CollectionMetadata newMetadata); + + void get(); + void query(); +} diff --git a/src/main/java/tech/amikos/chromadb/api/CollectionConfiguration.java b/src/main/java/tech/amikos/chromadb/api/CollectionConfiguration.java new file mode 100644 index 0000000..ceea16c --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/CollectionConfiguration.java @@ -0,0 +1,4 @@ +package tech.amikos.chromadb.api; + +public interface CollectionConfiguration { +} diff --git a/src/main/java/tech/amikos/chromadb/api/CollectionMetadata.java b/src/main/java/tech/amikos/chromadb/api/CollectionMetadata.java new file mode 100644 index 0000000..71bd034 --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/CollectionMetadata.java @@ -0,0 +1,96 @@ +package tech.amikos.chromadb.api; + +import java.util.HashMap; +import java.util.Map; + +public interface CollectionMetadata { + String getString(String key); + Integer getInt(String key); + Float getFloat(String key); + Boolean getBoolean(String key); + Map getAsMap(); //TODO immutable map or clone of the original + + class CollectionMetadataImpl implements CollectionMetadata{ + private final Map metadata; + + CollectionMetadataImpl() { + this.metadata = new HashMap<>(); + } + + void put(String key, String value){ + metadata.put(key, value); + } + + void put(String key, int value){ + metadata.put(key, value); + } + + void put(String key, float value){ + metadata.put(key, value); + } + + void put(String key, boolean value){ + metadata.put(key, value); + } + + @Override + public String getString(String key) { + return (String) metadata.get(key); + } + + @Override + public Integer getInt(String key) { + return (Integer) metadata.get(key); + } + + @Override + public Float getFloat(String key) { + return (Float) metadata.get(key); + } + + @Override + public Boolean getBoolean(String key) { + return (Boolean) metadata.get(key); + } + + @Override + public Map getAsMap() { + return metadata; + } + } + + class Builder{ + private final CollectionMetadataImpl metadata; + + private Builder(){ + this.metadata = new CollectionMetadataImpl(); + } + public static Builder New() { + return new Builder(); + } + + public Builder put(String key, String value){ + this.metadata.put(key, value); + return this; + } + + public Builder put(String key, int value){ + this.metadata.put(key, value); + return this; + } + + public Builder put(String key, float value){ + this.metadata.put(key, value); + return this; + } + + public Builder put(String key, boolean value){ + this.metadata.put(key, value); + return this; + } + + public CollectionMetadata build(){ + return metadata; + } + } +} diff --git a/src/main/java/tech/amikos/chromadb/api/Document.java b/src/main/java/tech/amikos/chromadb/api/Document.java new file mode 100644 index 0000000..de5eb4d --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/Document.java @@ -0,0 +1,4 @@ +package tech.amikos.chromadb.api; + +public interface Document { +} diff --git a/src/main/java/tech/amikos/chromadb/api/DocumentMetadata.java b/src/main/java/tech/amikos/chromadb/api/DocumentMetadata.java new file mode 100644 index 0000000..1014811 --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/DocumentMetadata.java @@ -0,0 +1,4 @@ +package tech.amikos.chromadb.api; + +public interface DocumentMetadata { +} diff --git a/src/main/java/tech/amikos/chromadb/api/Embedding.java b/src/main/java/tech/amikos/chromadb/api/Embedding.java new file mode 100644 index 0000000..2a50af7 --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/Embedding.java @@ -0,0 +1,9 @@ +package tech.amikos.chromadb.api; + +import java.util.List; + +public interface Embedding { + Float[] asArray(); + Integer dimensions(); + List asList(); +} diff --git a/src/main/java/tech/amikos/chromadb/api/ID.java b/src/main/java/tech/amikos/chromadb/api/ID.java new file mode 100644 index 0000000..1de2f0b --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/ID.java @@ -0,0 +1,6 @@ +package tech.amikos.chromadb.api; + +public interface ID { + String asString(); + byte[] asBytes(); +} diff --git a/src/main/java/tech/amikos/chromadb/api/Record.java b/src/main/java/tech/amikos/chromadb/api/Record.java new file mode 100644 index 0000000..b2eb74d --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/Record.java @@ -0,0 +1,4 @@ +package tech.amikos.chromadb.api; + +public interface Record { +} diff --git a/src/main/java/tech/amikos/chromadb/api/RecordMetadata.java b/src/main/java/tech/amikos/chromadb/api/RecordMetadata.java new file mode 100644 index 0000000..728dc5a --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/RecordMetadata.java @@ -0,0 +1,4 @@ +package tech.amikos.chromadb.api; + +public interface RecordMetadata { +} diff --git a/src/main/java/tech/amikos/chromadb/api/RequestValidator.java b/src/main/java/tech/amikos/chromadb/api/RequestValidator.java new file mode 100644 index 0000000..15a23bc --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/RequestValidator.java @@ -0,0 +1,6 @@ +package tech.amikos.chromadb.api; + +public interface RequestValidator { + + void validate() throws Exception; +} diff --git a/src/main/java/tech/amikos/chromadb/api/TextID.java b/src/main/java/tech/amikos/chromadb/api/TextID.java new file mode 100644 index 0000000..8546ab5 --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/TextID.java @@ -0,0 +1,20 @@ +package tech.amikos.chromadb.api; + +public class TextID implements ID { + private String id; + + public TextID(String id) { + this.id = id; + } + + + @Override + public String asString() { + return id; + } + + @Override + public byte[] asBytes() { + return id.getBytes(); + } +} diff --git a/src/main/java/tech/amikos/chromadb/api/With.java b/src/main/java/tech/amikos/chromadb/api/With.java new file mode 100644 index 0000000..d68059d --- /dev/null +++ b/src/main/java/tech/amikos/chromadb/api/With.java @@ -0,0 +1,13 @@ +package tech.amikos.chromadb.api; + +import tech.amikos.chromadb.ChromaException; + +import java.util.Map; + +public class With { + + static void IDS(ID ...ids){ + + } + +} diff --git a/src/test/java/tech/amikos/chromadb/TestAPI.java b/src/test/java/tech/amikos/chromadb/TestAPI.java index 0f6172c..7243235 100644 --- a/src/test/java/tech/amikos/chromadb/TestAPI.java +++ b/src/test/java/tech/amikos/chromadb/TestAPI.java @@ -50,14 +50,14 @@ public static void tearDownChromaDB() { @Test public void testHeartbeat() throws ApiException, IOException, InterruptedException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); Map hb = client.heartbeat(); assertTrue(hb.containsKey("nanosecond heartbeat")); } @Test public void testGetCollectionGet() throws ApiException, IOException, EFException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); client.createCollection("test-collection", null, true, ef); @@ -67,16 +67,16 @@ public void testGetCollectionGet() throws ApiException, IOException, EFException @Test public void testCreateCollection() throws ApiException, EFException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); assertEquals(collection.getName(), "test-collection"); } @Test public void testDeleteCollection() throws ApiException, EFException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); client.createCollection("test-collection", null, true, ef); @@ -91,10 +91,10 @@ public void testDeleteCollection() throws ApiException, EFException { @Test public void testCreateUpsert() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -105,10 +105,10 @@ public void testCreateUpsert() throws ApiException, ChromaException { @Test public void testCreateAdd() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -121,26 +121,26 @@ public void testCreateAdd() throws ApiException, ChromaException { @Test public void testQuery() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); }}); collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist."), Arrays.asList("1")); collection.add(null, metadata, Arrays.asList("Hello, my name is Bond. I am a Spy."), Arrays.asList("2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("name is John"), 10, null, null, null); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("name is John"), 10, null, null, null); assertEquals(qr.getIds().get(0).get(0), "1"); //we check that Bond doc is first } @Test public void testQueryExample() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("type", "scientist"); @@ -149,16 +149,16 @@ public void testQueryExample() throws ApiException, ChromaException { put("type", "spy"); }}); collection.add(null, metadata, Arrays.asList("Hello, my name is John. I am a Data Scientist.", "Hello, my name is Bond. I am a Spy."), Arrays.asList("1", "2")); - Collection.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); + CollectionImpl.QueryResponse qr = collection.query(Arrays.asList("Who is the spy"), 10, null, null, null); assertEquals(qr.getIds().get(0).get(0), "2"); //we check that Bond doc is first } @Test public void testReset() throws ApiException, EFException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); client.reset(); @@ -171,7 +171,7 @@ public void testReset() throws ApiException, EFException { @Test public void testListCollections() throws ApiException, EFException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); client.createCollection("test-collection", null, true, ef); @@ -180,10 +180,10 @@ public void testListCollections() throws ApiException, EFException { @Test public void testCollectionCount() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -194,10 +194,10 @@ public void testCollectionCount() throws ApiException, ChromaException { @Test public void testCollectionDeleteIds() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -209,10 +209,10 @@ public void testCollectionDeleteIds() throws ApiException, ChromaException { @Test public void testCollectionDeleteWhere() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -226,10 +226,10 @@ public void testCollectionDeleteWhere() throws ApiException, ChromaException { @Test public void testCollectionDeleteLogicalOrWhere() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key1", "value1"); @@ -251,10 +251,10 @@ public void testCollectionDeleteLogicalOrWhere() throws ApiException, ChromaExce @Test public void testCollectionDeleteWhereNoMatch() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -268,10 +268,10 @@ public void testCollectionDeleteWhereNoMatch() throws ApiException, ChromaExcept @Test public void testCollectionDeleteWhereDocuments() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -286,10 +286,10 @@ public void testCollectionDeleteWhereDocuments() throws ApiException, ChromaExce @Test public void testCollectionDeleteWhereDocumentsNoMatch() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -304,7 +304,7 @@ public void testCollectionDeleteWhereDocumentsNoMatch() throws ApiException, Chr @Test public void testVersion() throws ApiException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); String version = client.version(); assertNotNull(version); @@ -313,10 +313,10 @@ public void testVersion() throws ApiException { @Test public void testUpdateCollection() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -328,10 +328,10 @@ public void testUpdateCollection() throws ApiException, ChromaException { @Test public void testCollectionUpdateEmbeddings() throws ApiException, ChromaException { - Client client = new Client(Utils.getEnvOrProperty("CHROMA_URL")); + ClientImpl client = new ClientImpl(Utils.getEnvOrProperty("CHROMA_URL")); client.reset(); EmbeddingFunction ef = new DefaultEmbeddingFunction(); - Collection collection = client.createCollection("test-collection", null, true, ef); + CollectionImpl collection = client.createCollection("test-collection", null, true, ef); List> metadata = new ArrayList<>(); metadata.add(new HashMap() {{ put("key", "value"); @@ -349,7 +349,7 @@ public void testTimeoutOk() throws ApiException, IOException { .withBody("{\"nanosecond heartbeat\": 123456789}").withFixedDelay(2000))); Utils.loadEnvFile(".env"); - Client client = new Client("http://127.0.0.1:8001"); + ClientImpl client = new ClientImpl("http://127.0.0.1:8001"); client.setTimeout(3); Map hb = client.heartbeat(); assertTrue(hb.containsKey("nanosecond heartbeat")); @@ -363,7 +363,7 @@ public void testTimeoutExpires() throws ApiException, IOException { .withBody("{\"nanosecond heartbeat\": 123456789}").withFixedDelay(2000))); Utils.loadEnvFile(".env"); - Client client = new Client("http://127.0.0.1:8001"); + ClientImpl client = new ClientImpl("http://127.0.0.1:8001"); client.setTimeout(1); try { client.heartbeat(); @@ -382,7 +382,7 @@ public void testClientHeaders() throws ApiException, IOException { .withHeader("Content-Type", "application/json") .withBody("{\"nanosecond heartbeat\": 123456789}"))); Utils.loadEnvFile(".env"); - Client client = new Client("http://127.0.0.1:8001"); + ClientImpl client = new ClientImpl("http://127.0.0.1:8001"); client.setDefaultHeaders(new HashMap() {{ put("Your-Header-Key", "Your-Expected-Header-Value"); }}); @@ -400,7 +400,7 @@ public void testClientAuthorizationBasicHeader() throws ApiException, IOExceptio .withHeader("Content-Type", "application/json") .withBody("{\"nanosecond heartbeat\": 123456789}"))); Utils.loadEnvFile(".env"); - Client client = new Client("http://127.0.0.1:8001"); + ClientImpl client = new ClientImpl("http://127.0.0.1:8001"); String encodedString = Base64.getEncoder().encodeToString("admin:admin".getBytes()); client.setDefaultHeaders(new HashMap() {{ put("Authorization", "Basic " + encodedString); @@ -419,7 +419,7 @@ public void testClientAuthorizationBearerHeader() throws ApiException, IOExcepti .withHeader("Content-Type", "application/json") .withBody("{\"nanosecond heartbeat\": 123456789}"))); Utils.loadEnvFile(".env"); - Client client = new Client("http://127.0.0.1:8001"); + ClientImpl client = new ClientImpl("http://127.0.0.1:8001"); client.setDefaultHeaders(new HashMap() {{ put("Authorization", "Bearer test-token"); }}); @@ -437,7 +437,7 @@ public void testClientXChromaTokenHeader() throws ApiException, IOException { .withHeader("Content-Type", "application/json") .withBody("{\"nanosecond heartbeat\": 123456789}"))); Utils.loadEnvFile(".env"); - Client client = new Client("http://127.0.0.1:8001"); + ClientImpl client = new ClientImpl("http://127.0.0.1:8001"); client.setDefaultHeaders(new HashMap() {{ put("X-Chroma-Token", "test-token"); }});