Install
dotnet add package HnswLite.Sdk --version 1.1.2
| Product | Versions |
|---|---|
| .NET |
README
HnswLite C# SDK
C# SDK for the HnswLite REST API. Provides full async coverage of every endpoint for index management, vector operations, and K-nearest-neighbour search.
Installation
dotnet add package HnswLite.Sdk
Or via the NuGet Package Manager:
Install-Package HnswLite.Sdk
Quick Start
using HnswLite.Sdk;
using HnswLite.Sdk.Models;
using HnswLiteClient client = new HnswLiteClient(
baseUrl: "http://localhost:8080",
apiKey: "your-api-key"
);
Usage Examples
Health Check (Ping)
// GET / — unauthenticated health ping
bool isAlive = await client.PingAsync();
Console.WriteLine("Server alive: " + isAlive);
// HEAD / — unauthenticated head ping
bool headOk = await client.HeadPingAsync();
Create an Index
IndexResponse index = await client.CreateIndexAsync(new CreateIndexRequest
{
Name = "my-index",
Dimension = 384,
StorageType = "RAM", // "RAM" or "SQLite"
DistanceFunction = "Cosine", // "Euclidean", "Cosine", or "DotProduct"
M = 16,
MaxM = 32,
EfConstruction = 200
});
Console.WriteLine("Created index: " + index.Name + " (GUID: " + index.GUID + ")");
Get an Index
IndexResponse index = await client.GetIndexAsync("my-index");
Console.WriteLine("Vectors: " + index.VectorCount);
Enumerate Indexes
EnumerationResult<IndexResponse> page = await client.EnumerateIndexesAsync(new EnumerationQuery
{
MaxResults = 25,
Skip = 0,
Ordering = EnumerationOrderEnum.NameAscending,
Prefix = "prod-"
});
foreach (IndexResponse idx in page.Objects)
{
Console.WriteLine(idx.Name + " (" + idx.VectorCount + " vectors)");
}
Console.WriteLine("End of results: " + page.EndOfResults);
Console.WriteLine("Total records: " + page.TotalRecords);
Add a Single Vector
AddVectorRequest echo = await client.AddVectorAsync("my-index", new AddVectorRequest
{
Vector = new List<float> { 0.1f, 0.2f, 0.3f /* ... */ }
});
Console.WriteLine("Added vector GUID: " + echo.GUID);
Add a Batch of Vectors
AddVectorsRequest batchEcho = await client.AddVectorsAsync("my-index", new AddVectorsRequest
{
Vectors = new List<AddVectorRequest>
{
new AddVectorRequest { Vector = new List<float> { 0.1f, 0.2f, 0.3f } },
new AddVectorRequest { Vector = new List<float> { 0.4f, 0.5f, 0.6f } },
new AddVectorRequest { Vector = new List<float> { 0.7f, 0.8f, 0.9f } }
}
});
Console.WriteLine("Added " + batchEcho.Vectors.Count + " vectors");
Search (K-Nearest Neighbours)
SearchResponse result = await client.SearchAsync("my-index", new SearchRequest
{
Vector = new List<float> { 0.1f, 0.2f, 0.3f /* ... */ },
K = 10,
Ef = 200 // optional; null uses server default
});
Console.WriteLine("Search took " + result.SearchTimeMs + " ms");
foreach (VectorSearchResult r in result.Results)
{
Console.WriteLine(" GUID: " + r.GUID + " Distance: " + r.Distance);
}
Enumerate Vectors
// GUIDs only (includeVectors defaults to false)
EnumerationResult<VectorEntryResponse> page = await client.EnumerateVectorsAsync(
"my-index",
new EnumerationQuery { MaxResults = 50 });
Console.WriteLine("Total vectors: " + page.TotalRecords);
foreach (VectorEntryResponse v in page.Objects)
{
Console.WriteLine(" GUID: " + v.GUID);
}
// Include the full vector values
EnumerationResult<VectorEntryResponse> detailed = await client.EnumerateVectorsAsync(
"my-index",
new EnumerationQuery { MaxResults = 10 },
includeVectors: true);
foreach (VectorEntryResponse v in detailed.Objects)
{
Console.WriteLine(" GUID: " + v.GUID + " Dim: " + v.Vector.Count);
}
Get a Single Vector
Guid vectorId = Guid.Parse("...");
VectorEntryResponse entry = await client.GetVectorAsync("my-index", vectorId);
Console.WriteLine("GUID: " + entry.GUID);
Console.WriteLine("Vector: [" + string.Join(", ", entry.Vector) + "]");
Remove a Vector
Guid vectorId = Guid.Parse("...");
await client.RemoveVectorAsync("my-index", vectorId);
Delete an Index
await client.DeleteIndexAsync("my-index");
Error Handling
All non-2xx responses throw HnswLiteApiException:
try
{
IndexResponse index = await client.GetIndexAsync("nonexistent");
}
catch (HnswLiteApiException ex)
{
Console.WriteLine("Status: " + (int)ex.StatusCode); // e.g. 404
Console.WriteLine("Error: " + ex.Error); // e.g. "IndexNotFound"
Console.WriteLine("Detail: " + ex.ApiMessage); // Human-readable message
}
Cancellation
Every async method accepts an optional CancellationToken:
using CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
IndexResponse index = await client.GetIndexAsync("my-index", cts.Token);
Custom API Key Header
The API key header name is configurable (defaults to x-api-key):
using HnswLiteClient client = new HnswLiteClient(
baseUrl: "http://localhost:8080",
apiKey: "your-api-key",
apiKeyHeader: "Authorization"
);
Running the Test Harness
cd sdk/csharp/HnswLite.Sdk.Test
dotnet run -- http://localhost:8080 your-api-key
The test harness exercises every SDK method and prints pass/fail for each. Exit code 0 means all tests passed.
Target Frameworks
- .NET 8.0
- .NET 10.0
Changes from Previous Version
No structural changes between v1.1.1 and v1.1.2.
Adoption Assessment
Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.
No SPDX license expression is published. Review the license text and your organisation's policy before redistribution.Compatibility metadata lists 2 target frameworks; confirm the exact target used by your application.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.