Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ChromaDB.Client.Tests/ChromaTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task OneTimeSetUp()
{
_container = ConfigureContainer(new ChromaDBBuilder()).Build();
await _container.StartAsync();
_baseConfigurationOptions = new ChromaConfigurationOptions(uri: $"http://{_container.IpAddress}:{_container.GetMappedPublicPort(ChromaDBBuilder.ChromaDBPort)}/api/v1/");
_baseConfigurationOptions = new ChromaConfigurationOptions(uri: $"http://{_container.IpAddress}:{_container.GetMappedPublicPort(ChromaDBBuilder.ChromaDBPort)}/api/v2/");
}

[OneTimeTearDown]
Expand Down
14 changes: 7 additions & 7 deletions ChromaDB.Client/ChromaClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public async Task<List<ChromaCollection>> ListCollections(string? tenant = null,
var requestParams = new RequestQueryParams()
.Insert("{tenant}", tenant)
.Insert("{database}", database);
return await _httpClient.Get<List<ChromaCollection>>("collections?tenant={tenant}&database={database}", requestParams);
return await _httpClient.Get<List<ChromaCollection>>("tenants/{tenant}/databases/{database}/collections", requestParams);
}

public async Task<ChromaCollection> GetCollection(string name, string? tenant = null, string? database = null)
Expand All @@ -49,12 +49,12 @@ public async Task<ChromaCollection> GetCollection(string name, string? tenant =
.Insert("{collectionName}", name)
.Insert("{tenant}", tenant)
.Insert("{database}", database);
return await _httpClient.Get<ChromaCollection>("collections/{collectionName}?tenant={tenant}&database={database}", requestParams);
return await _httpClient.Get<ChromaCollection>("tenants/{tenant}/databases/{database}/collections/{collectionName}", requestParams);
}

public async Task<ChromaHeartbeat> Heartbeat()
{
return await _httpClient.Get<ChromaHeartbeat>("", new RequestQueryParams());
return await _httpClient.Get<ChromaHeartbeat>("heartbeat", new RequestQueryParams());
}

public async Task<ChromaCollection> CreateCollection(string name, Dictionary<string, object>? metadata = null, string? tenant = null, string? database = null)
Expand All @@ -69,7 +69,7 @@ public async Task<ChromaCollection> CreateCollection(string name, Dictionary<str
Name = name,
Metadata = metadata
};
return await _httpClient.Post<CreateCollectionRequest, ChromaCollection>("collections?tenant={tenant}&database={database}", request, requestParams);
return await _httpClient.Post<CreateCollectionRequest, ChromaCollection>("tenants/{tenant}/databases/{database}/collections", request, requestParams);
}

public async Task<ChromaCollection> GetOrCreateCollection(string name, Dictionary<string, object>? metadata = null, string? tenant = null, string? database = null)
Expand All @@ -84,7 +84,7 @@ public async Task<ChromaCollection> GetOrCreateCollection(string name, Dictionar
Name = name,
Metadata = metadata
};
return await _httpClient.Post<GetOrCreateCollectionRequest, ChromaCollection>("collections?tenant={tenant}&database={database}", request, requestParams);
return await _httpClient.Post<GetOrCreateCollectionRequest, ChromaCollection>("tenants/{tenant}/databases/{database}/collections", request, requestParams);
}

public async Task DeleteCollection(string name, string? tenant = null, string? database = null)
Expand All @@ -95,7 +95,7 @@ public async Task DeleteCollection(string name, string? tenant = null, string? d
.Insert("{collectionName}", name)
.Insert("{tenant}", tenant)
.Insert("{database}", database);
await _httpClient.Delete("collections/{collectionName}?tenant={tenant}&database={database}", requestParams);
await _httpClient.Delete("tenants/{tenant}/databases/{database}/collections/{collectionName}", requestParams);
}

public async Task<string> GetVersion()
Expand All @@ -115,6 +115,6 @@ public async Task<int> CountCollections(string? tenant = null, string? database
var requestParams = new RequestQueryParams()
.Insert("{tenant}", tenant)
.Insert("{database}", database);
return await _httpClient.Get<int>("count_collections?tenant={tenant}&database={database}", requestParams);
return await _httpClient.Get<int>("tenants/{tenant}/databases/{database}/collections_count", requestParams);
}
}
40 changes: 31 additions & 9 deletions ChromaDB.Client/ChromaCollectionClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ public class ChromaCollectionClient
{
private readonly ChromaCollection _collection;
private readonly HttpClient _httpClient;
private readonly string _tenant;
private readonly string _database;

public ChromaCollectionClient(ChromaCollection collection, ChromaConfigurationOptions options, HttpClient httpClient)
{
_collection = collection;
_httpClient = httpClient;
_tenant = collection.Tenant ?? options.Tenant ?? ClientConstants.DefaultTenantName;
_database = collection.Database ?? options.Database ?? ClientConstants.DefaultDatabaseName;

if (_httpClient.BaseAddress != options.Uri)
{
Expand All @@ -29,6 +33,8 @@ public ChromaCollectionClient(ChromaCollection collection, ChromaConfigurationOp
public async Task<List<ChromaCollectionEntry>> Get(List<string>? ids = null, ChromaWhereOperator? where = null, ChromaWhereDocumentOperator? whereDocument = null, int? limit = null, int? offset = null, ChromaGetInclude? include = null)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionGetRequest()
{
Expand All @@ -39,7 +45,7 @@ public async Task<List<ChromaCollectionEntry>> Get(List<string>? ids = null, Chr
Offset = offset,
Include = (include ?? ChromaGetInclude.Metadatas | ChromaGetInclude.Documents).ToInclude(),
};
var response = await _httpClient.Post<CollectionGetRequest, CollectionEntriesGetResponse>("collections/{collection_id}/get", request, requestParams);
var response = await _httpClient.Post<CollectionGetRequest, CollectionEntriesGetResponse>("tenants/{tenant}/databases/{database}/collections/{collection_id}/get", request, requestParams);
return response.Map() ?? [];
}

Expand All @@ -49,6 +55,8 @@ public async Task<List<ChromaCollectionQueryEntry>> Query(ReadOnlyMemory<float>
public async Task<List<List<ChromaCollectionQueryEntry>>> Query(List<ReadOnlyMemory<float>> queryEmbeddings, int nResults = 10, ChromaWhereOperator? where = null, ChromaWhereDocumentOperator? whereDocument = null, ChromaQueryInclude? include = null)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionQueryRequest()
{
Expand All @@ -58,13 +66,15 @@ public async Task<List<List<ChromaCollectionQueryEntry>>> Query(List<ReadOnlyMem
WhereDocument = whereDocument?.ToWhereDocument(),
Include = (include ?? ChromaQueryInclude.Metadatas | ChromaQueryInclude.Documents | ChromaQueryInclude.Distances).ToInclude(),
};
var response = await _httpClient.Post<CollectionQueryRequest, CollectionEntriesQueryResponse>("collections/{collection_id}/query", request, requestParams);
var response = await _httpClient.Post<CollectionQueryRequest, CollectionEntriesQueryResponse>("tenants/{tenant}/databases/{database}/collections/{collection_id}/query", request, requestParams);
return response.Map() ?? [];
}

public async Task Add(List<string> ids, List<ReadOnlyMemory<float>>? embeddings = null, List<Dictionary<string, object>>? metadatas = null, List<string>? documents = null)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionAddRequest()
{
Expand All @@ -73,12 +83,14 @@ public async Task Add(List<string> ids, List<ReadOnlyMemory<float>>? embeddings
Metadatas = metadatas,
Documents = documents,
};
await _httpClient.Post("collections/{collection_id}/add", request, requestParams);
await _httpClient.Post("tenants/{tenant}/databases/{database}/collections/{collection_id}/add", request, requestParams);
}

public async Task Update(List<string> ids, List<ReadOnlyMemory<float>>? embeddings = null, List<Dictionary<string, object>>? metadatas = null, List<string>? documents = null)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionUpdateRequest()
{
Expand All @@ -87,12 +99,14 @@ public async Task Update(List<string> ids, List<ReadOnlyMemory<float>>? embeddin
Metadatas = metadatas,
Documents = documents,
};
await _httpClient.Post("collections/{collection_id}/update", request, requestParams);
await _httpClient.Post("tenants/{tenant}/databases/{database}/collections/{collection_id}/update", request, requestParams);
}

public async Task Upsert(List<string> ids, List<ReadOnlyMemory<float>>? embeddings = null, List<Dictionary<string, object>>? metadatas = null, List<string>? documents = null)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionUpsertRequest()
{
Expand All @@ -101,50 +115,58 @@ public async Task Upsert(List<string> ids, List<ReadOnlyMemory<float>>? embeddin
Metadatas = metadatas,
Documents = documents,
};
await _httpClient.Post("collections/{collection_id}/upsert", request, requestParams);
await _httpClient.Post("tenants/{tenant}/databases/{database}/collections/{collection_id}/upsert", request, requestParams);
}

public async Task Delete(List<string> ids, ChromaWhereOperator? where = null, ChromaWhereDocumentOperator? whereDocument = null)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionDeleteRequest()
{
Ids = ids,
Where = where?.ToWhere(),
WhereDocument = whereDocument?.ToWhereDocument(),
};
await _httpClient.Post("collections/{collection_id}/delete", request, requestParams);
await _httpClient.Post("tenants/{tenant}/databases/{database}/collections/{collection_id}/delete", request, requestParams);
}

public async Task<int> Count()
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
return await _httpClient.Get<int>("collections/{collection_id}/count", requestParams);
return await _httpClient.Get<int>("tenants/{tenant}/databases/{database}/collections/{collection_id}/count", requestParams);
}

public async Task<List<ChromaCollectionEntry>> Peek(int limit = 10)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionPeekRequest()
{
Limit = limit,
};
var response = await _httpClient.Post<CollectionPeekRequest, CollectionEntriesGetResponse>("collections/{collection_id}/get", request, requestParams);
var response = await _httpClient.Post<CollectionPeekRequest, CollectionEntriesGetResponse>("tenants/{tenant}/databases/{database}/collections/{collection_id}/get", request, requestParams);
return response.Map() ?? [];
}

public async Task Modify(string? name = null, Dictionary<string, object>? metadata = null)
{
var requestParams = new RequestQueryParams()
.Insert("{tenant}", _tenant)
.Insert("{database}", _database)
.Insert("{collection_id}", _collection.Id);
var request = new CollectionModifyRequest()
{
Name = name,
Metadata = metadata,
};
await _httpClient.Put("collections/{collection_id}", request, requestParams);
await _httpClient.Put("tenants/{tenant}/databases/{database}/collections/{collection_id}", request, requestParams);
}
}
3 changes: 2 additions & 1 deletion ChromaDB.Client/ChromaDB.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>true</IsPackable>
<VersionPrefix>1.0.1</VersionPrefix>
<VersionPrefix>2.0.0</VersionPrefix>
<PackageId>ChromaDB.Client</PackageId>
<PackageDescription>.NET SDK for Chroma database</PackageDescription>
<PackageTags>chroma chromadb vector database</PackageTags>
Expand All @@ -16,6 +16,7 @@
<PackageProjectUrl>https://github.com/ssone95/ChromaDB.Client</PackageProjectUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageReleaseNotes>v2.0.0: Migration to ChromaDB API v2 - Breaking change: Update your configuration URI from /api/v1/ to /api/v2/. See MIGRATION_GUIDE_V2.md for details.</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\" />
Expand Down
2 changes: 1 addition & 1 deletion ChromaDB.Client/Common/ClientConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ internal static class ClientConstants
{
public const string DefaultTenantName = "default_tenant";
public const string DefaultDatabaseName = "default_database";
public const string DefaultUri = "http://localhost:8000/api/v1/";
public const string DefaultUri = "http://localhost:8000/api/v2/";
public const string ChromaTokenHeader = "X-Chroma-Token";

public static ChromaTenant DefaultTenant { get; } = new(DefaultTenantName);
Expand Down
2 changes: 1 addition & 1 deletion ChromaDB.Client/Common/CollectionQueryEntryMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static List<List<ChromaCollectionQueryEntry>> Map(this CollectionEntriesQ
.Select((_, i) => response.Ids[i]
.Select((id, j) => new ChromaCollectionQueryEntry(id)
{
Distance = response.Distances[i].Span[j],
Distance = response.Distances?[i][j] ?? 0f,
Metadata = response.Metadatas?[i][j],
Embeddings = response.Embeddings?[i][j],
Document = response.Documents?[i][j],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ internal class CollectionEntriesGetResponse
public required List<List<string?>?> Uris { get; init; }

[JsonPropertyName("data")]
public required dynamic? Data { get; init; }
public dynamic? Data { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ internal class CollectionEntriesQueryResponse
public required List<List<string>> Ids { get; init; }

[JsonPropertyName("distances")]
public required List<ReadOnlyMemory<float>> Distances { get; init; }
public required List<List<float>>? Distances { get; init; }

[JsonPropertyName("metadatas")]
public required List<List<Dictionary<string, object>>>? Metadatas { get; init; }
Expand All @@ -23,5 +23,5 @@ internal class CollectionEntriesQueryResponse
public required List<List<List<string?>>>? Uris { get; init; }

[JsonPropertyName("data")]
public required dynamic? Data { get; init; }
public dynamic? Data { get; init; }
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ _ChromaDB.Client_ is a .NET SDK that offers a seamless connection to the Chroma
```csharp
using ChromaDB.Client;

var configOptions = new ChromaConfigurationOptions(uri: "http://localhost:8000/api/v1/");
var configOptions = new ChromaConfigurationOptions(uri: "http://localhost:8000/api/v2/");
using var httpClient = new HttpClient();
var client = new ChromaClient(configOptions, httpClient);

Expand Down
2 changes: 1 addition & 1 deletion Samples/ChromaDB.Client.Sample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using ChromaDB.Client;

var configOptions = new ChromaConfigurationOptions(uri: "http://localhost:8000/api/v1/");
var configOptions = new ChromaConfigurationOptions(uri: "http://localhost:8000/api/v2/");
using var httpClient = new HttpClient();
var client = new ChromaClient(configOptions, httpClient);

Expand Down
Loading
Loading