API reference
Client SDKs
Install the Kiwi Fabric client for .NET, Java, Node.js or Python, authenticate, and run a query or saga.
Official client libraries wrap the Kiwi Fabric REST API for .NET, Java, Node.js and Python. They cover federated queries, distributed sagas, data sources, capabilities, templates, virtual tables, access control, telemetry, version history, lineage, AI generation, files and administrative export and import.
Choose your language in any sample below. The choice applies to every sample on the site and is remembered in your browser.
| Language | Package | Requires |
|---|---|---|
| .NET | Kiwify.Kiwi.Fabric.Client |
.NET Standard 2.1 or later |
| Java | com.kiwify:kiwifabric-client |
Java 17 |
| Node.js | kiwifabric (ESM and CommonJS, no runtime dependencies) |
Node.js 18 |
| Python | kiwifabric |
Python with pip |
Note
The SDKs are not yet published to the public package registries. Build them from source as shown below, or ask Kiwify Labs for access.
The SDKs use the REST surface only. The PostgreSQL wire and Arrow Flight SQL surfaces are served by Kiwi Fabric directly. See Network surfaces.
Install#
# from your project, reference the client project (build it from the Kiwi Fabric source)
dotnet add reference path/to/Clients/DotNet/Kiwify.Kiwi.Fabric.Client/Kiwify.Kiwi.Fabric.Client.csproj
# from Clients/Java: build and install into your local Maven cache
mvn install
# then depend on com.kiwify:kiwifabric-client:0.1.0 from your own pom.xml
# from Clients/Node: build the package, then link it from your project
npm install
npm run build
# from Clients/Python
pip install -e .
Connect and authenticate#
Use an API key, or log in with a user name and password. Keep keys in a secret store, never in source control.
using Kiwify.Kiwi.Fabric.Client;
// with an API key
using var client = new KiwiFabricClient("http://localhost:8080", apiKey);
// or with a user name and password: the session token is used as the key
using var login = new KiwiFabricClient("http://localhost:8080");
var session = await login.LoginAsync("admin", password);
using var client2 = new KiwiFabricClient("http://localhost:8080", session.Token);
import com.kiwify.fabric.client.KiwiFabricClient;
// with an API key
KiwiFabricClient client = new KiwiFabricClient("http://localhost:8080", apiKey);
// or with a user name and password: the client keeps the session and re-logs in once if it expires
KiwiFabricClient loggedIn = new KiwiFabricClient("http://localhost:8080");
loggedIn.login("admin", password);
import { KiwiFabricClient } from "kiwifabric";
// with an API key
const client = new KiwiFabricClient("http://localhost:8080", apiKey);
// or with a user name and password: the client keeps the session and re-logs in once if it expires
const loggedIn = new KiwiFabricClient("http://localhost:8080");
await loggedIn.login("admin", password);
from kiwifabric import KiwiFabricClient
# with an API key
with KiwiFabricClient("http://localhost:8080", api_key=api_key) as client:
...
# or with a user name and password
client = KiwiFabricClient("http://localhost:8080")
client.login("admin", password)
client.close()
Bootstrap a new server#
On a server that has no users yet, create the first user and its API key once. This only works while no user exists.
using var bootstrap = new KiwiFabricClient("http://localhost:8080");
var setup = await bootstrap.SetupAsync("admin", password);
// store the initial API key now: it is shown once
KiwiFabricClient bootstrap = new KiwiFabricClient("http://localhost:8080");
var setup = bootstrap.setup("admin", password);
// store setup.rawKey() now: it is shown once
const bootstrap = new KiwiFabricClient("http://localhost:8080");
const setup = await bootstrap.setup("admin", password);
// store setup.rawKey now: it is shown once
setup = KiwiFabricClient.setup("http://localhost:8080", "admin", password)
# store the initial API key now: it is shown once
Run a query#
var result = await client.QueryAsync(
"SELECT * FROM orders WHERE total > @minTotal",
new Dictionary<string, object?> { ["minTotal"] = 100 });
Console.WriteLine($"{result.RowCount} rows in {result.TotalMs}ms");
QueryResponse result = client.query(
"SELECT * FROM orders WHERE total > @minTotal", Map.of("minTotal", 100));
System.out.println(result.rowCount() + " rows in " + result.totalMs() + "ms");
const result = await client.query("SELECT * FROM orders WHERE total > @minTotal", { minTotal: 100 });
console.log(`${result.rowCount} rows in ${result.totalMs}ms`);
result = client.query("SELECT * FROM orders WHERE total > @minTotal", {"minTotal": 100})
print(f"{result.row_count} rows in {result.total_ms}ms")
df = result.to_pandas()
See Run federated queries for a multi-source example and Run distributed transactions for sagas.
What the clients cover#
Each client has one area per group of REST endpoints.
| Area | Covers |
|---|---|
| Authentication | Users, API keys, password administration |
| Access control | Groups, roles, permissions and Kerberos linking |
| Data sources | Registration, schema introspection |
| Capabilities | Table and stored-procedure read and write configuration |
| Sagas | Execution, status, and compensation gap reports |
| Templates | Saved, parameterised sagas |
| Virtual tables | Saved queries |
| Telemetry | Request log, latency series, per-user summaries |
| Versions and lineage | Version history, diff and publish; dependency and impact analysis |
| AI | LLM configuration, SQL and saga generation |
| Files and administration | Managed files; encrypted export and import (superadmin) |
In .NET the operations are methods on KiwiFabricClient. In Java and Node.js they are properties such as client.sagas, client.dataSources and client.lineage. In Python they are sub-clients such as client.sagas, client.sources and client.rbac.
Behaviour to know#
- Calls are synchronous in Java and Python. The .NET and Node.js clients are asynchronous.
- Rows come back as plain maps in Java and Node.js. In Python the result is an Arrow table, with
to_pandas()andto_polars()helpers. - Pagination is uniform. Paged endpoints return one paged-result type in Java and Node.js.