llm-cost-ops-sdk

Crates.iollm-cost-ops-sdk
lib.rsllm-cost-ops-sdk
version0.1.0
created_at2025-11-16 08:14:25.726612+00
updated_at2025-11-16 08:14:25.726612+00
descriptionClient SDK for LLM Cost Ops
homepagehttps://github.com/globalbusinessadvisors/llm-cost-ops
repositoryhttps://github.com/globalbusinessadvisors/llm-cost-ops
max_upload_size
id1935325
size168,847
GBA (globalbusinessadvisors)

documentation

https://docs.rs/llm-cost-ops-sdk

README

LLM Cost Ops - SDK

Crates.io Documentation License

Rust SDK client for LLM Cost Ops platform

A production-ready Rust client library for interacting with the LLM Cost Ops API, providing type-safe access to cost tracking, analytics, and reporting features.

Features

  • Type-Safe API Client - Fully typed request/response models
  • Async/Await Support - Built on tokio for high-performance async operations
  • Authentication - JWT and API key authentication support
  • Error Handling - Comprehensive error types with context
  • Retry Logic - Automatic retry with exponential backoff
  • Telemetry - Built-in metrics and tracing
  • Pagination - Helper methods for paginated endpoints
  • Rate Limiting - Client-side rate limiting support

Quick Start

Add to your Cargo.toml:

[dependencies]
llm-cost-ops-sdk = "0.1"
tokio = { version = "1", features = ["full"] }

Basic Usage

use llm_cost_ops_sdk::{Client, ClientConfig, AuthMethod};
use chrono::{Utc, Duration};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create client with API key
    let config = ClientConfig {
        base_url: "https://api.example.com".to_string(),
        auth: AuthMethod::ApiKey {
            key: "your-api-key".to_string(),
        },
        timeout_secs: 30,
        max_retries: 3,
    };

    let client = Client::new(config)?;

    // Submit usage record
    let usage = client
        .usage()
        .create()
        .provider("openai")
        .model("gpt-4")
        .organization_id("org-123")
        .prompt_tokens(1500)
        .completion_tokens(500)
        .submit()
        .await?;

    println!("Usage recorded: {}", usage.id);

    Ok(())
}

JWT Authentication

use llm_cost_ops_sdk::{Client, ClientConfig, AuthMethod};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create client with JWT token
    let config = ClientConfig {
        base_url: "https://api.example.com".to_string(),
        auth: AuthMethod::Jwt {
            token: "your-jwt-token".to_string(),
        },
        timeout_secs: 30,
        max_retries: 3,
    };

    let client = Client::new(config)?;

    // Refresh token automatically
    let refreshed_client = client.refresh_token().await?;

    Ok(())
}

Query Costs

use llm_cost_ops_sdk::Client;
use chrono::{Utc, Duration};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(config)?;

    // Query costs for last 30 days
    let end_date = Utc::now();
    let start_date = end_date - Duration::days(30);

    let costs = client
        .costs()
        .query()
        .organization_id("org-123")
        .date_range(start_date, end_date)
        .group_by("provider")
        .execute()
        .await?;

    for cost in costs.data {
        println!("{}: ${}", cost.provider, cost.total_cost);
    }

    Ok(())
}

Generate Reports

use llm_cost_ops_sdk::{Client, ReportType, ExportFormat};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(config)?;

    // Generate cost report
    let report = client
        .reports()
        .generate()
        .report_type(ReportType::Cost)
        .organization_id("org-123")
        .format(ExportFormat::Csv)
        .email_to("finance@example.com")
        .submit()
        .await?;

    println!("Report generated: {}", report.id);

    // Download report
    let data = client
        .reports()
        .download(&report.id)
        .await?;

    std::fs::write("report.csv", data)?;

    Ok(())
}

Usage Analytics

use llm_cost_ops_sdk::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(config)?;

    // Get usage analytics
    let analytics = client
        .analytics()
        .usage()
        .organization_id("org-123")
        .group_by("model")
        .top(10)
        .execute()
        .await?;

    for item in analytics.data {
        println!("{}: {} tokens", item.model, item.total_tokens);
    }

    Ok(())
}

Forecasting

use llm_cost_ops_sdk::{Client, ForecastHorizon};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(config)?;

    // Get cost forecast
    let forecast = client
        .forecasting()
        .cost_forecast()
        .organization_id("org-123")
        .horizon(ForecastHorizon::Days30)
        .confidence_level(0.95)
        .execute()
        .await?;

    println!("Forecast for next 30 days: ${}", forecast.predicted_cost);
    println!("Confidence interval: ${} - ${}",
        forecast.lower_bound, forecast.upper_bound);

    Ok(())
}

Pagination

use llm_cost_ops_sdk::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(config)?;

    // Paginate through usage records
    let mut page = 1;
    loop {
        let response = client
            .usage()
            .list()
            .organization_id("org-123")
            .page(page)
            .per_page(100)
            .execute()
            .await?;

        println!("Page {}: {} records", page, response.data.len());

        if !response.has_more {
            break;
        }
        page += 1;
    }

    Ok(())
}

Error Handling

use llm_cost_ops_sdk::{Client, SdkError};

#[tokio::main]
async fn main() {
    let client = Client::new(config).unwrap();

    match client.usage().list().execute().await {
        Ok(response) => {
            println!("Success: {} records", response.data.len());
        }
        Err(SdkError::Authentication(msg)) => {
            eprintln!("Authentication failed: {}", msg);
        }
        Err(SdkError::RateLimited { retry_after }) => {
            eprintln!("Rate limited, retry after {} seconds", retry_after);
        }
        Err(SdkError::Network(err)) => {
            eprintln!("Network error: {}", err);
        }
        Err(err) => {
            eprintln!("Error: {}", err);
        }
    }
}

Configuration

Environment Variables

export COST_OPS_API_URL="https://api.example.com"
export COST_OPS_API_KEY="your-api-key"
export COST_OPS_TIMEOUT=30
export COST_OPS_MAX_RETRIES=3

Configuration File

use llm_cost_ops_sdk::ClientConfig;

let config = ClientConfig::from_env()?;
let client = Client::new(config)?;

Features

  • Automatic Retries - Failed requests are automatically retried with exponential backoff
  • Connection Pooling - Efficient HTTP connection reuse
  • Timeout Handling - Configurable request timeouts
  • Custom Headers - Add custom headers to all requests
  • Telemetry - OpenTelemetry integration for distributed tracing
  • Mock Server - Built-in mock server for testing

Testing

use llm_cost_ops_sdk::testing::MockServer;

#[tokio::test]
async fn test_usage_creation() {
    let mock = MockServer::start().await;

    mock.expect_usage_create()
        .with_provider("openai")
        .respond_with_id("usage-123")
        .await;

    let client = Client::new(mock.client_config())?;
    let usage = client.usage().create().provider("openai").submit().await?;

    assert_eq!(usage.id, "usage-123");
}

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Links

Commit count: 0

cargo fmt