callix

Crates.iocallix
lib.rscallix
version0.1.1
created_at2025-12-15 20:32:45.069713+00
updated_at2025-12-29 18:03:13.909301+00
descriptionA flexible HTTP client library for calling various AI APIs or somthing with configuration and templating support
homepage
repositoryhttps://github.com/naseridev/callix
max_upload_size
id1986686
size185,276
Nima Naseri (naseridev)

documentation

https://docs.rs/callix

README

Callix

A flexible, configuration-driven HTTP client library for Rust, designed for seamless integration with AI APIs and RESTful services.

Features

  • Configuration-Driven - Define providers and endpoints in YAML for easy management
  • Auto Retry - Built-in retry mechanism with configurable delays and exponential backoff
  • Template Engine - Dynamic variable substitution in URLs, headers, and request bodies
  • Multi-Provider Support - Pre-configured for OpenAI, Gemini, Claude, and more
  • Type-Safe - Full Rust type safety with serde integration
  • Zero Config - Works out of the box with default configurations for popular AI services
  • Async/Await - Built on Tokio and Reqwest for high-performance async operations

Table of Contents

Installation

Add Callix to your Cargo.toml:

[dependencies]
callix = "0.1.0"
tokio = { version = "1", features = ["full"] }
serde_json = "1.0"

Step-by-Step Setup

  1. Create a new Rust project:

    cargo new my_callix_project
    cd my_callix_project
    
  2. Add dependencies using cargo add (Rust 1.62+):

    cargo add callix
    cargo add tokio --features full
    cargo add serde_json
    

    Or manually in Cargo.toml:

    [dependencies]
    callix = "0.1.0"
    tokio = { version = "1", features = ["full"] }
    serde_json = "1.0"
    
  3. Write your first code in src/main.rs:

    use callix::CallixBuilder;
    use std::time::Duration;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let callix = CallixBuilder::new()
            .timeout(Duration::from_secs(60))
            .build()?;
    
        println!("Callix is ready!");
        Ok(())
    }
    
  4. Run your project:

    cargo run
    

Optional: Environment Variables Setup

For secure API key management, create a .env file:

# .env
OPENAI_API_KEY=sk-your-key-here
GEMINI_API_KEY=your-key-here
ANTHROPIC_API_KEY=sk-ant-your-key-here

Add the dotenv crate:

cargo add dotenv

Load environment variables in your code:

use dotenv::dotenv;
use std::env;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    dotenv().ok();
    let api_key = env::var("OPENAI_API_KEY")?;
    // Use api_key...
    Ok(())
}

Quick Start

Basic Usage

use callix::CallixBuilder;
use serde_json::json;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a client
    let callix = CallixBuilder::new()
        .timeout(Duration::from_secs(60))
        .retries(3)
        .retry_delay(Duration::from_secs(1))
        .build()?;

    // Make a request to Gemini
    let response = callix
        .request("gemini", "generate")?
        .var("API_KEY", "your-api-key")
        .var("model", "gemini-2.0-flash-exp")
        .var("prompt", "Hello, world!")
        .send()
        .await?;

    // Handle the response
    if response.is_success() {
        let body = response.text().await?;
        println!("Response: {}", body);
    }

    Ok(())
}

OpenAI Example

use serde_json::json;

let response = callix
    .request("openai", "chat")?
    .var("API_KEY", "sk-...")
    .var("model", "gpt-4")
    .var("messages", json!([
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain Rust ownership in simple terms"}
    ]))
    .send()
    .await?;

let json: serde_json::Value = response.json().await?;
println!("{}", json["choices"][0]["message"]["content"]);

Anthropic Claude Example

let response = callix
    .request("anthropic", "messages")?
    .var("API_KEY", "sk-ant-...")
    .var("model", "claude-3-5-sonnet-20241022")
    .var("max_tokens", 1024)
    .var("messages", json!([
        {"role": "user", "content": "Explain quantum computing"}
    ]))
    .send()
    .await?;

Configuration

Default Configuration

Callix includes pre-configured settings for popular AI providers:

  • OpenAI - GPT-4, GPT-3.5 Turbo
  • Google Gemini - Gemini Pro, Gemini Flash
  • Anthropic Claude - Claude 3.5 Sonnet, Opus, Haiku

Custom Configuration

Create a config.yaml file to define your own API endpoints:

providers:
  my_api:
    base_url: "https://api.example.com"
    headers:
      Authorization: "Bearer {{API_KEY}}"
      Content-Type: "application/json"
    timeout: 30  # seconds (optional)
    endpoints:
      predict:
        path: "/v1/predict"
        method: "POST"
        body_template: |
          {
            "input": "{{text}}",
            "model": "{{model}}",
            "temperature": {{temperature}}
          }
        query_params:
          version: "{{api_version}}"

Use your custom configuration:

let callix = CallixBuilder::new()
    .config("config.yaml")
    .build()?;

let response = callix
    .request("my_api", "predict")?
    .var("API_KEY", "secret")
    .var("text", "Hello")
    .var("model", "v2")
    .var("temperature", 0.7)
    .var("api_version", "latest")
    .send()
    .await?;

Examples

Custom Headers

let response = callix
    .request("openai", "chat")?
    .var("API_KEY", "sk-...")
    .var("model", "gpt-4")
    .var("messages", json!([
        {"role": "user", "content": "Hello"}
    ]))
    .header("X-Custom-Header", "value")
    .header("X-Request-ID", "12345")
    .send()
    .await?;

Retry Configuration

let callix = CallixBuilder::new()
    .retries(5)
    .retry_delay(Duration::from_secs(2))
    .timeout(Duration::from_secs(120))
    .build()?;

Error Handling

match response.status() {
    200..=299 => {
        let json: serde_json::Value = response.json().await?;
        println!("Success: {:#?}", json);
    }
    400 => println!("Bad Request - check your input"),
    401 => println!("Unauthorized - verify your API key"),
    429 => println!("Rate Limited - please retry later"),
    500..=599 => println!("Server Error - try again"),
    _ => println!("Unexpected status: {}", response.status()),
}

Batch Processing

let prompts = vec![
    "Explain machine learning",
    "What is quantum computing?",
    "Describe neural networks"
];

for prompt in prompts {
    let response = callix
        .request("openai", "chat")?
        .var("API_KEY", api_key)
        .var("model", "gpt-3.5-turbo")
        .var("messages", json!([
            {"role": "user", "content": prompt}
        ]))
        .send()
        .await?;

    // Process response
    let json: serde_json::Value = response.json().await?;
    println!("{}: {}", prompt, json["choices"][0]["message"]["content"]);

    // Rate limiting
    tokio::time::sleep(Duration::from_millis(500)).await;
}

Concurrent Requests

use futures::future::join_all;

let prompts = vec!["Prompt 1", "Prompt 2", "Prompt 3"];

let futures: Vec<_> = prompts.iter().map(|&prompt| {
    let callix = callix.clone();
    let api_key = api_key.clone();
    async move {
        callix
            .request("openai", "chat")?
            .var("API_KEY", api_key)
            .var("model", "gpt-3.5-turbo")
            .var("messages", json!([
                {"role": "user", "content": prompt}
            ]))
            .send()
            .await
    }
}).collect();

let results = join_all(futures).await;

Documentation

Running Examples

cargo run --example openai
cargo run --example gemini
cargo run --example anthropic

Feature Flags

Customize Callix with feature flags:

[dependencies]
callix = { version = "0.1", features = ["rustls-tls", "gzip"] }

Available Features

Feature Description Default
native-tls Use system's native TLS
rustls-tls Use Rustls (pure Rust TLS)
blocking Blocking HTTP client support
cookies Cookie store support
gzip Gzip compression
brotli Brotli compression
stream Streaming response support

Architecture

Component Overview

CallixBuilder → Callix → RequestBuilder → HTTP Request → CallixResponse
                  ↓           ↓
               Config    TemplateEngine

Core Modules

  • client - Main client implementation and HTTP method parsing
  • config - Configuration management and provider definitions
  • request - Request building and execution with retry logic
  • response - Response handling and parsing utilities
  • template - Variable substitution and template rendering
  • error - Comprehensive error types and conversions

Minimum Supported Rust Version (MSRV)

Callix requires Rust 1.75 or higher.

Contributing

Contributions are welcome! Here's how to get started:

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

Development Setup

git clone https://github.com/naseridev/callix.git
cd callix
cargo build
cargo test

Guidelines

  • Follow Rust naming conventions and idioms
  • Add tests for new features
  • Update documentation
  • Run cargo fmt and cargo clippy before committing

Security

  • Never hardcode API keys - Use environment variables
  • Validate all user input - Sanitize before sending requests
  • Use HTTPS - All default configurations use secure connections
  • Rotate keys regularly - Follow security best practices

Acknowledgments

Built with these amazing Rust crates:

Support

Commit count: 0

cargo fmt