Skip to main content

A Python SDK for monitoring and analyzing AI API interactions with LLM services

Project description

Coolhand Python

PyPI version

Monitor and log LLM API calls from OpenAI, Anthropic, Google Gemini, GitHub Copilot, and more to the Coolhand analytics platform.

Python 3.8 and 3.9 support deprecated: As of v0.4.0, coolhand requires Python 3.10 or later. Python 3.8 reached end-of-life in October 2024 and 3.9 in October 2025. If you are on an older Python version, pin to coolhand<0.4.0.

Installation

pip install coolhand

Getting Started

  1. Get API Key: Visit coolhandlabs.com to create a free account
  2. Install: pip install coolhand
  3. Configure: Set COOLHAND_API_KEY and import coolhand in your app
  4. Deploy: Your AI calls are now automatically monitored!

Quick Start

Automatic Global Monitoring

Set it and forget it! Monitor ALL AI API calls across your entire application with minimal configuration.

import coolhand  # Auto-initializes and starts monitoring

# That's it! ALL AI API calls are now automatically monitored:
# ✅ OpenAI SDK calls
# ✅ Anthropic API calls
# ✅ Google Gemini API calls
# ✅ GitHub Copilot SDK calls
# ✅ ANY library making AI API calls via httpx

# Your existing code works unchanged:
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello!"}]
)
# The request and response have been automatically logged to Coolhand!

Why Automatic Monitoring:

  • Zero refactoring - No code changes to existing services
  • Complete coverage - Monitors all AI libraries using httpx automatically
  • Security built-in - Automatic credential sanitization
  • Performance optimized - Negligible overhead via async logging
  • Future-proof - Automatically captures new AI calls added by your team

Configuration

Environment Variables

Variable Required Default Description
COOLHAND_API_KEY Yes - Your Coolhand API key for authentication
COOLHAND_BASE_URL No https://coolhandlabs.com Override the API host (self-hosted deployments)
COOLHAND_SILENT No true Set to false for verbose logging output

Manual Configuration

from coolhand import Coolhand

coolhand_client = Coolhand(
    api_key='your-api-key',
    silent=False,  # Enable verbose logging
)

Excluding API Patterns

Some endpoints — batch jobs, health checks, internal metrics — generate high-volume traffic that isn't useful to log. Use exclude_api_patterns to skip them:

from coolhand import Coolhand

coolhand_client = Coolhand(
    api_key='your-api-key',
    exclude_api_patterns=[
        '/health',
        '/metrics',
        '/batchPredictionJobs/',
    ],
)

Any request whose URL contains one of the listed substrings is passed through without logging. The default list (DEFAULT_EXCLUDE_API_PATTERNS) excludes /batchPredictionJobs/; setting exclude_api_patterns replaces the default entirely.

from coolhand import DEFAULT_EXCLUDE_API_PATTERNS

# Extend the defaults rather than replace them
coolhand_client = Coolhand(
    api_key='your-api-key',
    exclude_api_patterns=DEFAULT_EXCLUDE_API_PATTERNS + ['/health'],
)

Self-Hosted Deployments

If you run your own Coolhand-compatible backend (e.g. for compliance or data-residency requirements), point the SDK at your host with base_url:

from coolhand import Coolhand

coolhand_client = Coolhand(
    api_key='your-api-key',
    base_url='https://feedback.example.com',  # must use https://
)

Or via environment variable (useful for 12-factor deployments):

export COOLHAND_API_KEY=your-api-key
export COOLHAND_BASE_URL=https://feedback.example.com
import coolhand  # picks up COOLHAND_BASE_URL automatically

The SDK rejects non-https:// URLs by default. http://localhost and http://127.0.0.1 are allowed for local development only.

Usage Examples

With OpenAI

import coolhand
from openai import OpenAI

client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
# Request automatically logged to Coolhand!

With Anthropic

import coolhand
from anthropic import Anthropic

client = Anthropic()
response = client.messages.create(
    model="claude-3-opus-20240229",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}]
)
print(response.content[0].text)
# Request automatically logged to Coolhand!

With Google Gemini

import coolhand
import google.generativeai as genai

genai.configure(api_key="your-gemini-api-key")
model = genai.GenerativeModel("gemini-pro")
response = model.generate_content("Hello!")
print(response.text)
# Request automatically logged to Coolhand!

With GitHub Copilot SDK

import coolhand
# GitHub Copilot SDK calls are automatically intercepted
# via JsonRpcClient patching — no additional setup needed.

With Streaming

import coolhand
from openai import OpenAI

client = OpenAI()
stream = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Tell me a story"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
# Complete streamed response automatically logged to Coolhand!

What Gets Logged

The monitor captures:

  • Request Data: Method, URL, headers, request body
  • Response Data: Status code, headers, response body
  • Timing: Request timestamp, response timestamp, duration
  • LLM-Specific: Model used, token counts, streaming status

Headers containing API keys are automatically sanitized for security.

Supported Libraries

Coolhand intercepts AI API calls through two mechanisms:

httpx patching (covers any library built on httpx):

  • OpenAI Python SDK
  • Anthropic Python SDK
  • Google Gemini (google-generativeai / google-genai)
  • GitHub Models via Azure (models.inference.ai.azure.com)
  • Any other library using httpx for HTTP requests

requests patching (covers any library built on requests):

  • azure-ai-inference, azure-openai, and other azure-core-based SDKs
  • Any other library using requests for HTTP requests (requests is optional — patch is skipped if not installed)

JSON-RPC patching (direct protocol interception):

  • GitHub Copilot SDK (JsonRpcClient)

How It Works

  1. When you import coolhand, it automatically patches httpx, requests.Session.send (if installed), and the GitHub Copilot JsonRpcClient
  2. Requests to AI APIs are intercepted (OpenAI, Anthropic, Gemini, GitHub Models, GitHub Copilot, and more)
  3. Request and response data are captured (credentials and sensitive URL parameters sanitized)
  4. Data is sent to Coolhand asynchronously
  5. Your application continues without interruption

For non-LLM endpoints, requests pass through unchanged with zero overhead.

Feedback Service

Collect user feedback on LLM responses to improve your AI outputs. The FeedbackService lets you capture sentiment ratings, explanations, and corrections.

Frontend Feedback Widget: For browser-based feedback collection, see coolhand-js - an accessible, lightweight JavaScript widget that leverages best UX practices to capture actionable user feedback on any AI output.

Basic Usage

from coolhand import Coolhand

# Initialize with your API key
ch = Coolhand(api_key='your-api-key')

# Submit positive feedback
ch.create_feedback({
    'llm_request_log_id': 12345,  # From Coolhand logs
    'sentiment': 'like',
    'explanation': 'Very helpful response!'
})

# Using original output for fuzzy matching
ch.create_feedback({
    'original_output': 'The capital of France is London.',
    'sentiment': 'dislike',
    'revised_output': 'The capital of France is Paris.'
})

Feedback Fields

All fields are optional. At least one matching field (marked *) is recommended to link feedback to the original LLM request.

Field Type Description
sentiment str Preferred. "like", "dislike", or "neutral"
like bool Deprecated — use sentiment instead. Auto-converted and stripped from the wire payload. Emits DeprecationWarning.
llm_request_log_id int * Coolhand log ID (exact match)
llm_provider_unique_id str * Provider's x-request-id (exact match)
original_output str * Original response text (fuzzy match)
client_unique_id str * Your internal identifier
explanation str Why the response was good/bad
revised_output str User's corrected version
creator_unique_id str ID of user providing feedback
workload_hashid str Associate feedback with a specific workload
collector str Override the SDK-generated collector string

Troubleshooting

Enable Debug Output

from coolhand import Coolhand

Coolhand(
    api_key='your-api-key',
    silent=False  # Enable verbose logging
)

Or via environment variable:

export COOLHAND_SILENT=false

API Key

Sign up for free at coolhandlabs.com to get your API key and start monitoring your LLM usage.

What you get:

  • Complete LLM request and response logging
  • Usage analytics and insights
  • No credit card required to start

Security

  • API keys in request headers are automatically redacted
  • Sensitive URL query parameters (key, api_key, token, etc.) are automatically redacted
  • No sensitive data is exposed in logs
  • All data is sent via HTTPS to Coolhand servers

Related Packages

  • Frontend (Feedback Collection Widget): coolhand-js - Frontend feedback widget for collecting user feedback on AI outputs
  • Ruby: coolhand gem - Coolhand monitoring for Ruby applications
  • Node.js: coolhand-node package - Coolhand monitoring for Node.js applications

Community

License

Apache-2.0

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

coolhand-0.4.1.tar.gz (65.2 kB view details)

Uploaded Source

Built Distribution

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

coolhand-0.4.1-py3-none-any.whl (25.8 kB view details)

Uploaded Python 3

File details

Details for the file coolhand-0.4.1.tar.gz.

File metadata

  • Download URL: coolhand-0.4.1.tar.gz
  • Upload date:
  • Size: 65.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for coolhand-0.4.1.tar.gz
Algorithm Hash digest
SHA256 37e01c910a8ea4f43a3d1823a985a7b0af103e56b20fde120aeb36e7e37b81dc
MD5 dfa9b68bf9d35a53966cc05f3e8562fc
BLAKE2b-256 6b9cfed979a9aafe32ef60e1d417339d96ce6eeab276c1955893b9d1e4020811

See more details on using hashes here.

File details

Details for the file coolhand-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: coolhand-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 25.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for coolhand-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b234d7761d650be49c4790d4f2bfd417dd26789d910c8f967ffe89de62cff6d0
MD5 2f109d2c470646a6a5cbb70547c9305a
BLAKE2b-256 3a6905b5a1ffde4f120468c6ca2ea630b633924769240d34ad6b2faee27d128c

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