Skip to main content

Python SDK for Valence AI Emotion Detection API - Real-time, Async, and Streaming Support

Project description

Valence SDK for Emotion Detection

valenceai is a Python client library for interacting with the Valence AI APIs for emotion detection. It provides a convenient interface to upload audio files, stream real-time audio, and retrieve detected emotional states.

Features

  • Discrete audio processing - Real-time analysis for short audio clips (4-10s)
  • Asynch audio processing - Multipart parallel upload for long audio files with temporal emotion analysis
  • Streaming API - Real-time WebSocket streaming for live audio
  • Rate limiting - Monitor API usage and limits
  • Environment configuration - Built-in support for environment variables
  • Enhanced logging - Configurable log levels

The emotional classification model used in our APIs is optimized for North American English conversational data. The included model detects four emotions: angry, happy, neutral, and sad. New models coming soon.

API Overview

API Best For Input Output
Discrete Real-time analysis Short audio (4.5-10s) Single emotion prediction
Asynch Pre-recorded files Long audio (up to 1GB) Timeline with emotion changes
Streaming Live audio streams Audio chunks via WebSocket Real-time emotion updates

The DiscreteAPI is built for real-time analysis of emotions in audio data. Small snippets of audio are sent to the API to receive feedback in real-time of what emotions are detected based on tone of voice. This API operates on an approximate per-sentence basis, and audio must be cut to the appropriate size.

The AsynchAPI is built for emotion analysis of pre-recorded audio files. Files of any length, up to 1 GB in size, can be sent to the API to receive a timeline of emotions throughout the file.

The StreamingAPI is built for real-time audio analysis via WebSocket connections. The audio stream is analyzed in real-time and emotions are returned in reference to 5-second chunks of streamed audio.

Audio Input Requirements

Format Specifications

  • Format: WAV only
  • Recommended sampling rate: 44.1 kHz (44100 Hz)
  • Minimum sampling rate: 8 kHz
  • Channel: Mono (single channel)

API-Specific Requirements

  • Discrete API: 4-10 seconds per file
  • Asynch API: Minimum 5 seconds, maximum 1 GB
  • Streaming API: Real-time audio chunks (PCM bytes)

For inquiries about custom microphone specifications or stereo/multi-channel support, please contact us.

Installation

pip install valenceai

Configuration

You can configure the SDK using environment variables or by passing parameters directly:

Environment Variables

export VALENCE_API_KEY="api_key_here"
export VALENCE_API_BASE_URL="https://api.getvalenceai.com" # Optional
export VALENCE_WEBSOCKET_URL="wss://api.getvalenceai.com" # Optional
export VALENCE_LOG_LEVEL="INFO"  # Optional: INFO, DEBUG, ERROR

Client Configuration

client = ValenceClient(
    api_key="your_api_key",           # API key (required)
    base_url="https://custom.api",    # Custom API endpoint (optional)
    websocket_url="wss://custom.api", # Custom WebSocket endpoint (optional)
    part_size=5*1024*1024,            # Upload chunk size (default: 5MB)
    show_progress=True,               # Show upload progress (default: True)
    max_threads=3,                    # Concurrent upload threads (default: 3)
    comprehensive_output=False        # When False: asynch API returns timestamp, main_emotion, confidence only. When True: also includes all_predictions with all emotion confidences (default: False)
)

Asynch API Processing Workflow

The Asynch API uses a multi-step process to handle long audio files. Understanding this workflow is crucial for proper implementation:

1. Upload Phase (Client-Side)

When you call client.asynch.upload(file_path):

  • SDK splits your file into parts (5MB chunks by default)
  • Uploads parts in parallel
  • Returns a request_id - This is a tracking identifier, not a completion signal.
  • At this point: File is uploaded to our server, but NOT processed yet

2. Background Processing (Server-Side)

After upload completes, the server automatically:

  • Checks for new uploads
  • Downloads audio when a new File is detected
  • Splits audio into 5-second segments
  • Processes audio file
  • Invokes machine learning model for emotion detection
  • Stores results in database
  • Updates status to completed

Processing Time: Varies based on file length and server load. Typically 1-2 seconds per minute of audio.

3. Results Retrieval (Client-Side)

When you call client.asynch.emotions(request_id):

  • Polls the status endpoint at regular intervals
  • Waits for status progression:
    • initiated → Upload started
    • upload_completed → File uploaded (processing not started)
    • processing → Background processing in progress
    • completed → Results ready
  • Returns emotion timeline when status is completed

Status Values

Status Meaning What's Happening
initiated Upload started SDK is uploading file parts to S3
upload_completed Upload finished File is in S3, waiting for background processor
processing Processing active Server is analyzing audio with ML model
completed Results ready Emotion timeline is available

Important Notes

  • The request_id is NOT a completion indicator. It's a request tracking ID.
  • upload() completing does not mean results are ready. It means the file is uploaded.
  • Background processing takes time. Processing time varies based on file length and server load.
  • You can check status anytime. The request_id remains valid for retrieving results until databases are cleared (see: DPA).

Installation

pip install valenceai

Quick Start

from valenceai import ValenceClient

# Initialize client (uses VALENCE_API_KEY environment variable)
client = ValenceClient(api_key="your_api_key", comprehensive_output=True)

# Discrete API - Quick emotion detection
result = client.discrete.emotions(file_path="short_audio.wav")
print(f"Emotion: {result['main_emotion']}")

# Asynch API - Long audio with timeline
# Step 1: Upload file (returns tracking ID)
request_id = client.asynch.upload("long_audio.wav")
# Step 2: Wait for server processing and get results (polls until complete)
result = client.asynch.emotions(request_id, max_attempts=30, interval_seconds=10)
# Step 3: Access emotion data from results
emotions = result['emotions']  # List of emotion predictions with timestamps

# Get summary statistics
majority = client.asynch.majority_emotion(request_id)  # Most frequent emotion
counts = client.asynch.emotion_counts(request_id)  # {"happy": 10, "sad": 3, ...}

# Streaming API - Real-time audio
stream = client.streaming.connect()
stream.on_prediction(lambda data: print(data['main_emotion']))
stream.connect()
stream.send_audio(audio_bytes)
stream.disconnect()

# Rate Limit API - Monitor usage
status = client.rate_limit.get_status()
health = client.rate_limit.get_health()

API Reference

Discrete API

For short audio files requiring immediate emotion detection.

# File upload
result = client.discrete.emotions(
    file_path="audio.wav",
)

# In-memory audio array
result = client.discrete.emotions(
    audio_array=[0.1, 0.2, 0.3, ...],
)

Response:

{
    "emotions": {
        "happy": 0.78,
        "sad": 0.12,
        "angry": 0.05,
        "neutral": 0.05
    },
    "main_emotion": "happy"
}

Asynch API

For long audio files with timeline analysis.

Status Progression: initiatedupload_completedprocessingcompleted

Upload Audio

# Upload file
request_id = client.asynch.upload(file_path="long_audio.wav")

Get Emotion Results

# Poll for results until processing completes
result = client.asynch.emotions(
    request_id="abc-123abc-123abc-123abc-123abc-123",
    max_attempts=20,        # Max polling attempts (default: 20, range: 1-100)
    interval_seconds=5      # Polling interval (default: 5, range: 1-60)
)
# This method waits for server processing to complete
# Returns when status is 'completed'

Response:

{
    "emotions": [
        {
            "timestamp": 0.5,
            "start_time": 0.0,
            "end_time": 1.0,
            "emotion": "happy",
            "confidence": 0.9,
            "all_predictions": {"happy": 0.9, "sad": 0.1, ...}
        },
        {
            "timestamp": 1.5,
            "start_time": 1.0,
            "end_time": 2.0,
            "emotion": "neutral",
            "confidence": 0.85,
            "all_predictions": {"neutral": 0.85, "happy": 0.15, ...}
        }
    ],
    "status": "completed"
}

Note: The all_predictions field is only included when comprehensive_output=True is set in the client constructor.

Helper Methods

# Get the most frequently occurring emotion across the entire file
majority = client.asynch.majority_emotion(request_id)
# Returns: "happy"

# Get emotion occurrence counts for the entire file
counts = client.asynch.emotion_counts(request_id)
# Returns: {"happy": 10, "sad": 3, "angry": 8, "neutral": 9}

Streaming API

For real-time emotion detection on live audio streams.

# Create streaming connection
stream = client.streaming.connect()

# Register callbacks
stream.on_prediction(lambda data: print(f"Emotion: {data['main_emotion']}"))
stream.on_error(lambda error: print(f"Error: {error}"))
stream.on_connected(lambda info: print(f"Connected: {info['session_id']}"))

# Connect to WebSocket
stream.connect()

# Send audio chunks (PCM bytes)
stream.send_audio(audio_chunk_bytes)

# Check connection status
if stream.connected:
    print("Streaming active")

# Wait for events (blocking)
stream.wait()

# Disconnect
stream.disconnect()

Prediction Event:

{
    "main_emotion": "happy",
    "confidence": 0.87,
    "all_predictions": {
        "happy": 0.87,
        "sad": 0.05,
        "angry": 0.03,
        "neutral": 0.05
    },
    "timestamp": 1706486400000  # Unix timestamp (UTC) in milliseconds
}

The timestamp is a Unix timestamp (UTC) in milliseconds representing when the server generated the prediction.

Rate Limit API

Monitor your API usage and limits.

# Get rate limit status
status = client.rate_limit.get_status()
print(status)
# {
#     "limits": {
#         "second": {"limit": 10, "remaining": 8, "reset": 1234567890},
#         "minute": {"limit": 100, "remaining": 95, "reset": 1234567890},
#         "hour": {"limit": 1000, "remaining": 950, "reset": 1234567890},
#         "day": {"limit": 10000, "remaining": 9500, "reset": 1234567890}
#     },
#     "current_usage": {
#         "second": 2,
#         "minute": 5,
#         "hour": 50,
#         "day": 500
#     }
# }

# Check API health
health = client.rate_limit.get_health()
print(health)
# {"status": "healthy", "timestamp": 1234567890}

Error Responses

Discrete API Errors

HTTP Status Error Code Description
400 AUDIO_TOO_SHORT Audio duration below minimum (4.5 seconds). Response includes min_duration_seconds and actual_duration_seconds
400 Bad Request Invalid request format or parameters
401 Unauthorized Invalid or missing API key
500 Server Error Internal server error

Asynch API Errors

HTTP Status Error Code Description
400 AUDIO_TOO_SHORT Audio duration below minimum (5 seconds)
400 Bad Request Invalid request format or parameters
401 Unauthorized Invalid or missing API key
404 Not Found Request ID not found
500 Server Error Internal server error

Asynch Status Values:

Status Meaning
initiated Upload in progress
upload_completed Upload finished, awaiting processing
processing Server analyzing audio
completed Results ready
failed Processing failed

Streaming API Errors

Event Description
error Server-side error during streaming
warning Non-fatal warning from server
connect_error WebSocket connection failed
disconnect Connection closed

Rate Limit API Errors

HTTP Status Description
401 Unauthorized - Invalid API key
429 Too Many Requests - Rate limit exceeded
500 Server Error

SDK Exception Classes

from valenceai import ValenceSDKException, AudioTooShortError, UploadError, PredictionError

try:
    result = client.discrete.emotions(file_path="audio.wav")
except AudioTooShortError as e:
    print(f"Audio too short: {e.actual_duration}s (min: {e.min_duration}s)")
except UploadError as e:
    print(f"Upload failed: {e}")
except PredictionError as e:
    print(f"Prediction failed: {e}")
except ValenceSDKException as e:
    print(f"SDK error: {e}")

Additional Examples

Additional usage examples can be found in the Valence docs.

Migration from v0.x

Key Changes in v1.0.0

  1. Environment Variable: VALENCE_API_KEY is now the standard (consistent naming)
  2. Streaming API: New WebSocket-based real-time emotion detection
  3. Rate Limiting: New API for monitoring usage
  4. Timeline Data: Asynch API now returns detailed timestamp information

Updating Your Code

# Old (v0.x)
client = ValenceClient()
result = client.discrete.emotions("file.wav")

# New (v1.0.0) - mostly compatible, with new features
client = ValenceClient(api_key="your_key")
result = client.discrete.emotions(
    file_path="file.wav",
)

# New streaming capability
stream = client.streaming.connect()
stream.on_prediction(callback)
stream.connect()

Support

License

Private License © 2026 Valence Vibrations, Inc, a Delaware public benefit corporation.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

valenceai-1.0.4-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

Details for the file valenceai-1.0.4-py3-none-any.whl.

File metadata

  • Download URL: valenceai-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 15.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.0

File hashes

Hashes for valenceai-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 eb0ee22ef3fbc4fcc453c99231d68fb766900930fe2d54029e011fefff99b286
MD5 0e263349adef39f02c2eb0c50e86e768
BLAKE2b-256 7803a4359b5e5d784b12725b6d28f89361bc23ea737da72b4d259cc1bd1378a1

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