| Crates.io | greentic-distributor-client |
| lib.rs | greentic-distributor-client |
| version | 0.4.26 |
| created_at | 2025-12-06 21:21:51.135345+00 |
| updated_at | 2026-01-17 11:40:57.388879+00 |
| description | WIT-based client for the greentic:distributor-api@1.0.0 distributor resolver. |
| homepage | https://gihub.com/greentic |
| repository | https://github.com/greentic/greentic-distributor-client |
| max_upload_size | |
| id | 1970775 |
| size | 316,378 |
WIT-based client for the greentic:distributor-api@1.0.0 world. Provides:
DistributorClient async trait for resolving components, querying pack status, and warming packs.WitDistributorClient adapter that translates DTOs to greentic-interfaces-guest distributor-api bindings; use GeneratedDistributorApiBindings on WASM targets to call the distributor imports.http-runtime feature for JSON endpoints that mirror the runtime API.greentic-dist CLI (feature dist-cli) for resolving/pulling components into a shared cache, plus a library DistClient API for pack/runner integration.Uses DTOs from greentic-types.
use greentic_distributor_client::{
DistributorApiBindings, DistributorClient, DistributorEnvironmentId, EnvId,
GeneratedDistributorApiBindings, ResolveComponentRequest, TenantCtx, TenantId,
WitDistributorClient,
};
use serde_json::json;
let bindings = GeneratedDistributorApiBindings::default();
let client = WitDistributorClient::new(bindings);
let resp = client.resolve_component(ResolveComponentRequest {
tenant: TenantCtx::new(
EnvId::try_from("prod").unwrap(),
TenantId::try_from("tenant-a").unwrap(),
),
environment_id: DistributorEnvironmentId::from("env-1"),
pack_id: "pack-123".into(),
component_id: "component-x".into(),
version: "1.0.0".into(),
extra: json!({}),
}).await?;
println!("artifact: {:?}", resp.artifact);
if let Some(reqs) = resp.secret_requirements.as_ref() {
println!("secret requirements: {:?}", reqs);
}
GeneratedDistributorApiBindings calls the distributor imports on WASM targets. On non-WASM targets it returns an error; consumers can provide their own bindings implementation for testing.
secret_requirements is present when talking to distributor versions that support it; otherwise it is None. When requirements are returned, run greentic-secrets init --pack <pack-id> ahead of time so secrets are available to the runtime.
http-runtime)Enable the feature and construct HttpDistributorClient:
[dependencies]
greentic-distributor-client = { version = "0.4", features = ["http-runtime"] }
use greentic_distributor_client::{
DistributorClient, DistributorClientConfig, DistributorEnvironmentId, EnvId, HttpDistributorClient,
ResolveComponentRequest, TenantCtx, TenantId,
};
use serde_json::json;
let config = DistributorClientConfig {
base_url: Some("https://distributor.example.com".into()),
environment_id: DistributorEnvironmentId::from("env-1"),
tenant: TenantCtx::new(EnvId::try_from("prod").unwrap(), TenantId::try_from("tenant-a").unwrap()),
auth_token: Some("token123".into()),
extra_headers: None,
request_timeout: None,
};
let client = HttpDistributorClient::new(config)?;
let resp = client.resolve_component(ResolveComponentRequest {
tenant: TenantCtx::new(
EnvId::try_from("prod").unwrap(),
TenantId::try_from("tenant-a").unwrap(),
),
environment_id: DistributorEnvironmentId::from("env-1"),
pack_id: "pack-123".into(),
component_id: "component-x".into(),
version: "1.0.0".into(),
extra: json!({}),
}).await?;
println!("artifact: {:?}", resp.artifact);
if let Some(reqs) = resp.secret_requirements.as_ref() {
println!("secret requirements: {:?}", reqs);
}
Fetch typed pack status (includes secret requirements):
let status = client
.get_pack_status_v2(
&TenantCtx::new(EnvId::try_from("prod")?, TenantId::try_from("tenant-a")?),
&DistributorEnvironmentId::from("env-1"),
"pack-123",
)
.await?;
println!(
"status: {}, secrets: {:?}",
status.status, status.secret_requirements
);
dist-cli)Build with the CLI feature to get the greentic-dist binary:
cargo run --features dist-cli --bin greentic-dist -- resolve ghcr.io/greentic-ai/components/templates:latest
Commands:
resolve <REF>: print digest (use --json for structured output).pull <REF>: ensure cached; prints path. Use --lock <pack.lock> to pull all components from a lockfile.cache ls|rm|gc: list/remove/gc cache entries.auth login <target>: stub for future store/repo auth.Control cache location with --cache-dir or GREENTIC_DIST_CACHE_DIR; defaults to ${XDG_CACHE_HOME:-~/.cache}/greentic/components/<sha256>/component.wasm. Set GREENTIC_SILENCE_DEPRECATION_WARNINGS=1 to silence the temporary greentic-distributor-client shim binary warning.
Exit codes:
0 success2 invalid input (bad ref/lockfile/missing args)3 not found (cache miss)4 offline blocked (network needed)5 auth required/not implemented (repo://, store://)10 internal errordist-client)Use DistClient to reuse the same resolution and cache logic programmatically. The dist-client feature also includes the OCI pack fetcher APIs (fetch_pack, OciPackFetcher):
use greentic_distributor_client::dist::{DistClient, DistOptions};
let client = DistClient::new(DistOptions::default());
let resolved = client.ensure_cached("file:///tmp/my-component.wasm").await?;
println!("digest: {}, path: {}", resolved.digest, resolved.cache_path.unwrap().display());
greentic-dist resolve oci://ghcr.io/greentic-ai/components/hello-world:1greentic-dist pull --lock pack.lock.jsongreentic-dist pull --lock pack.lock.json then greentic-runner run mypack.gtpack --offlineResolve configuration in your host binary with greentic-config and map it into the distributor client with DistributorClientConfig::from_greentic:
use greentic_config_types::GreenticConfig;
use greentic_distributor_client::{DistributorClientConfig, DistributorEnvironmentId, DistributorClient, TenantCtx, TenantId};
let cfg: GreenticConfig = /* resolved in the host via greentic-config */;
let tenant = TenantCtx::new(cfg.environment.env_id.clone(), TenantId::try_from("tenant-a")?);
let mut client_cfg = DistributorClientConfig::from_greentic(&cfg, tenant)
.with_base_url("https://distributor.example.com"); // host still provides the endpoint/auth
// pass client_cfg to your chosen DistributorClient implementation
Use the companion greentic-distributor-dev crate to serve packs/components from a local directory, useful for greentic-dev and conformance tests:
use greentic_distributor_client::{ChainedDistributorSource, DistributorSource, PackId, Version};
use greentic_distributor_dev::{DevConfig, DevDistributorSource};
let dev_source = DevDistributorSource::new(DevConfig::default());
let sources = ChainedDistributorSource::new(vec![Box::new(dev_source)]);
let pack_bytes = sources.fetch_pack(&PackId::try_from("dev.local.hello-flow")?, &Version::parse("0.1.0")?);
println!("Loaded {} bytes", pack_bytes.len());