Skip to main content

Python SDK for SmartDecision AI-powered ensemble decision making

Project description

SmartDecision Python SDK

Python Version License PyPI Version

A Python SDK for the SmartDecision AI-powered ensemble decision making API. This SDK provides a simple and intuitive interface for making ensemble decisions using multiple Large Language Models (LLMs) with democratic voting.

Features

  • 🤖 Ensemble Decision Making: Get decisions from multiple LLMs with majority voting
  • 🔐 API Key Authentication: Secure authentication with API keys
  • 📊 Decision History: Track and analyze your decision history
  • 🚀 Async Support: Both synchronous and asynchronous interfaces
  • 🛡️ Comprehensive Error Handling: Detailed error types and messages
  • 📈 Statistics: Get insights into your decision patterns
  • 🔧 Type Safety: Full type hints with Pydantic models
  • 🧪 Well Tested: Comprehensive test coverage

Installation

pip install smartdecision-sdk

Quick Start

from smartdecision_sdk import SmartDecisionClient

# Initialize the client
client = SmartDecisionClient(api_key="your-api-key-here")

# Make an ensemble decision
response = client.make_ensemble_decision(
    question="What is the best programming language for web development?",
    categories=["Python", "JavaScript", "TypeScript", "Go", "Rust"]
)

print(f"Final decision: {response.final_decision}")
print(f"Individual responses: {response.individual_responses}")
print(f"Vote counts: {response.vote_counts}")

# Check ensemble status
status = client.get_ensemble_status()
print(f"Services ready: {status.ready}")
print(f"Available services: {status.available_count}/{status.total_services}")

# Clean up
client.close()

Usage Examples

Basic Usage

from smartdecision_sdk import SmartDecisionClient

client = SmartDecisionClient(api_key="your-api-key-here")

try:
    # Make a decision
    response = client.make_ensemble_decision(
        question="Should I invest in renewable energy stocks?",
        categories=["Yes, invest", "No, avoid", "Wait and research more"]
    )
    
    print(f"Decision: {response.final_decision}")
    print(f"Consensus Score: {response.consensus_score:.2f}")
    
    # Show individual LLM responses
    for vote in response.individual_responses:
        print(f"{vote.llm_name}: {vote.response} (confidence: {vote.confidence:.2f})")
        
finally:
    client.close()

Async Usage

import asyncio
from smartdecision_sdk import SmartDecisionClient

async def main():
    client = SmartDecisionClient(api_key="your-api-key-here")
    
    try:
        # Make decisions concurrently
        tasks = [
            client.make_ensemble_decision_async(
                question="What is the best cloud provider?",
                categories=["AWS", "Google Cloud", "Azure"]
            ),
            client.make_ensemble_decision_async(
                question="Which database should I use?",
                categories=["PostgreSQL", "MySQL", "MongoDB"]
            )
        ]
        
        responses = await asyncio.gather(*tasks)
        
        for i, response in enumerate(responses, 1):
            print(f"Decision {i}: {response.final_decision}")
            
    finally:
        await client.aclose()

asyncio.run(main())

Context Manager Usage

from smartdecision_sdk import SmartDecisionClient

# Automatic cleanup with context manager
with SmartDecisionClient(api_key="your-api-key-here") as client:
    response = client.make_ensemble_decision(
        question="What is the best framework for APIs?",
        categories=["FastAPI", "Django", "Flask", "Express.js"]
    )
    print(f"Decision: {response.final_decision}")

# Async context manager
async def async_example():
    async with SmartDecisionClient(api_key="your-api-key-here").async_context() as client:
        response = await client.make_ensemble_decision_async(
            question="Which mobile framework to choose?",
            categories=["React Native", "Flutter", "Xamarin", "Ionic"]
        )
        print(f"Decision: {response.final_decision}")

Decision History and Statistics

from smartdecision_sdk import SmartDecisionClient

client = SmartDecisionClient(api_key="your-api-key-here")

try:
    # Get decision history
    history = client.get_decision_history(limit=10)
    print(f"Recent decisions: {len(history.decisions)}")
    
    for decision in history.decisions:
        print(f"- {decision.question[:50]}... → {decision.ensemble_decision}")
    
    # Get statistics
    stats = client.get_decision_statistics()
    print(f"Total decisions made: {stats.total_decisions}")
    print(f"Recent decisions: {stats.recent_decisions}")
    
finally:
    client.close()

API Reference

SmartDecisionClient

The main client class for interacting with the SmartDecision API.

Constructor

SmartDecisionClient(
    api_key: str,
    base_url: str = "https://api.smartdec.ai",
    timeout: float = 30.0,
    max_retries: int = 3,
    headers: Optional[Dict[str, str]] = None
)

Parameters:

  • api_key: Your SmartDecision API key (required)
  • base_url: Base URL for the API (default: https://api.smartdec.ai)
  • timeout: Request timeout in seconds (default: 30.0)
  • max_retries: Maximum number of retries (default: 3)
  • headers: Additional headers to include in requests

Methods

make_ensemble_decision(question, categories)

Make an ensemble decision using multiple LLMs.

Parameters:

  • question (str): The question or prompt to send to the models
  • categories (List[str]): List of valid response options (minimum 2)

Returns: EnsembleDecisionResponse

get_ensemble_status()

Get the status of ensemble LLM services.

Returns: EnsembleStatusResponse

get_decision_history(limit=50, offset=0)

Get decision history for the authenticated user.

Parameters:

  • limit (int): Maximum number of decisions to return (max: 100)
  • offset (int): Number of decisions to skip for pagination

Returns: DecisionHistoryResponse

get_decision_statistics()

Get decision statistics for the authenticated user.

Returns: DecisionStatistics

health_check()

Check the health of the API.

Returns: HealthResponse

Response Models

EnsembleDecisionResponse

class EnsembleDecisionResponse:
    ensemble_decision: str          # The final ensemble decision
    vote_details: List[VoteDetail]  # Individual vote details from each LLM
    total_votes: int               # Total number of votes received
    consensus_score: float         # Consensus score (0.0 to 1.0)
    
    # Convenience properties
    final_decision: str            # Alias for ensemble_decision
    individual_responses: List[VoteDetail]  # Alias for vote_details
    vote_counts: Dict[str, int]    # Vote counts for each response option

VoteDetail

class VoteDetail:
    llm_name: str      # Name of the LLM (e.g., "gpt-4o", "gemini-1.5-pro")
    response: str      # The response from this LLM
    confidence: float  # Confidence score (0.0 to 1.0)

Error Handling

The SDK provides specific exception types for different error scenarios:

from smartdecision_sdk import (
    SmartDecisionError,      # Base exception
    AuthenticationError,     # Invalid API key
    ValidationError,         # Invalid request data
    RateLimitError,          # Rate limit exceeded
    ConnectionError,         # Network/connection issues
    APIError                # General API errors
)

try:
    response = client.make_ensemble_decision(
        question="What is the best programming language?",
        categories=["Python", "JavaScript", "Go"]
    )
    
except AuthenticationError as e:
    print(f"Authentication failed: {e.message}")
    
except ValidationError as e:
    print(f"Validation error: {e.message}")
    
except RateLimitError as e:
    print(f"Rate limit exceeded: {e.message}")
    
except ConnectionError as e:
    print(f"Connection error: {e.message}")
    
except APIError as e:
    print(f"API error: {e.message}")
    
except SmartDecisionError as e:
    print(f"SmartDecision error: {e.message}")

Configuration

Environment Variables

You can set your API key as an environment variable:

export SMARTDECISION_API_KEY="your-api-key-here"

Then initialize the client without specifying the API key:

import os
from smartdecision_sdk import SmartDecisionClient

api_key = os.getenv("SMARTDECISION_API_KEY")
if not api_key:
    raise ValueError("SMARTDECISION_API_KEY environment variable is required")

client = SmartDecisionClient(api_key=api_key)

Custom Configuration

client = SmartDecisionClient(
    api_key="your-api-key-here",
    base_url="https://api.smartdec.ai",
    timeout=60.0,  # Longer timeout for complex decisions
    max_retries=5,  # More retries for reliability
    headers={
        "User-Agent": "my-app/1.0.0",
        "X-Custom-Header": "custom-value"
    }
)

Advanced Usage

Batch Processing

import asyncio
from smartdecision_sdk import SmartDecisionClient

async def batch_decisions():
    client = SmartDecisionClient(api_key="your-api-key-here")
    
    questions = [
        {
            "question": "What is the best programming language for data science?",
            "categories": ["Python", "R", "Julia", "Scala"]
        },
        {
            "question": "Which framework is best for web development?",
            "categories": ["React", "Vue.js", "Angular", "Svelte"]
        }
    ]
    
    try:
        # Process all questions concurrently
        tasks = [
            client.make_ensemble_decision_async(**q) for q in questions
        ]
        
        responses = await asyncio.gather(*tasks)
        
        for i, response in enumerate(responses, 1):
            print(f"Question {i}: {response.final_decision}")
            
    finally:
        await client.aclose()

asyncio.run(batch_decisions())

Decision Analysis

from collections import Counter
from smartdecision_sdk import SmartDecisionClient

client = SmartDecisionClient(api_key="your-api-key-here")

try:
    # Get decision history
    history = client.get_decision_history(limit=50)
    
    # Analyze patterns
    all_decisions = [d.ensemble_decision for d in history.decisions]
    decision_counts = Counter(all_decisions)
    
    print("Most common decisions:")
    for decision, count in decision_counts.most_common(5):
        print(f"  {decision}: {count} times")
    
    # Analyze consensus scores
    consensus_scores = [d.consensus_score for d in history.decisions]
    avg_consensus = sum(consensus_scores) / len(consensus_scores)
    print(f"Average consensus score: {avg_consensus:.2f}")
    
finally:
    client.close()

Examples

Check out the examples/ directory for more comprehensive examples:

  • basic_usage.py - Basic synchronous and asynchronous usage
  • advanced_usage.py - Advanced features like batch processing and monitoring
  • error_handling.py - Comprehensive error handling examples

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Changelog

1.0.0 (2024-01-XX)

  • Initial release
  • Ensemble decision making with multiple LLMs
  • API key authentication
  • Decision history and statistics
  • Comprehensive error handling
  • Async support
  • Type safety with Pydantic models

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smartdecision_sdk-1.0.3.tar.gz (24.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smartdecision_sdk-1.0.3-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

Details for the file smartdecision_sdk-1.0.3.tar.gz.

File metadata

  • Download URL: smartdecision_sdk-1.0.3.tar.gz
  • Upload date:
  • Size: 24.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.19

File hashes

Hashes for smartdecision_sdk-1.0.3.tar.gz
Algorithm Hash digest
SHA256 e38580270c5b838efdcb9c2565b10dc0593d555c2c17bb35f1123e1ad4b0d8ab
MD5 0862f009846b876fe1ecb8f6a2b82632
BLAKE2b-256 40f6f3281f9bc4bbf40be1d151ccec32407591c792d7d4da7b55c32a70a47f84

See more details on using hashes here.

File details

Details for the file smartdecision_sdk-1.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for smartdecision_sdk-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ee690ddb53ece8406483dcc56e3784ab06bb23b718175fed8b0fad3ca3c3f0b2
MD5 b14d61f51e76bc992c7be54a30279098
BLAKE2b-256 c29759a4c9ca9cb2d5b2d7788667011dd77bd944e5fed9df28c70295515a0c8b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page