SwisperStudio SDK Upgrade to v0.5.1¶
For Swisper Team
Date: 2025-11-26
Priority: ๐ด CRITICAL (Production Fix)
๐จ Problem Summary¶
SDK v0.5.0 can hang Swisper indefinitely when: - Redis is misconfigured - Redis is unreachable - SwisperStudio is not running
This happened in production because initialize_redis_publisher() has no timeout and blocks forever on connection attempts.
โ Solution¶
SDK v0.5.1 introduces completely safe initialization that: - NEVER blocks indefinitely (all operations have timeouts) - NEVER raises exceptions - NEVER crashes Swisper - Gracefully disables tracing if Redis unavailable
๐ Required Changes in Swisper¶
Step 1: Update SDK Version¶
File: backend/pyproject.toml (or requirements.txt)
Step 2: Update Initialization Code¶
File: apps/backend/app/main.py
Find this code (around line 118-151):
# Initialize SwisperStudio observability (SDK v0.5.0)
# SDK installed from GitHub Releases as proper pip package
if settings.SWISPER_STUDIO_ENABLED:
try:
from swisper_studio_sdk import initialize_redis_publisher, wrap_llm_adapter
# Initialize Redis Streams publisher for observability
await initialize_redis_publisher(
redis_url=settings.SWISPER_STUDIO_REDIS_URL,
stream_name=settings.SWISPER_STUDIO_STREAM_NAME,
project_id=settings.SWISPER_STUDIO_PROJECT_ID,
verify_consumer=True, # Check if SwisperStudio consumer is running
)
logger.info("โ
SwisperStudio observability initialized (Redis Streams)")
logger.info(f" Redis: {settings.SWISPER_STUDIO_REDIS_URL}")
logger.info(f" Stream: {settings.SWISPER_STUDIO_STREAM_NAME}")
logger.info(f" Project ID: {settings.SWISPER_STUDIO_PROJECT_ID}")
# Enable LLM prompt capture (includes streaming support)
try:
wrap_llm_adapter()
logger.info("โ
LLM prompt capture enabled (structured + streaming)")
except Exception as e:
logger.warning(f"โ ๏ธ LLM prompt capture disabled: {e}")
logger.warning(" State capture will still work")
except ImportError:
logger.warning("โ ๏ธ SwisperStudio SDK not installed - observability disabled")
logger.warning(" Install with: pip install swisper-studio-sdk==0.5.0")
except Exception as e:
logger.warning(f"โ ๏ธ SwisperStudio observability initialization failed: {e}")
logger.warning(
" Continuing without observability - events will queue in Redis"
)
Replace with:
# Initialize SwisperStudio observability (SDK v0.5.1)
# SDK v0.5.1: ROBUST - safe_initialize() NEVER blocks or crashes Swisper
if settings.SWISPER_STUDIO_ENABLED:
try:
from swisper_studio_sdk import safe_initialize, wrap_llm_adapter
# safe_initialize() is completely safe:
# - NEVER raises exceptions
# - NEVER blocks indefinitely (has timeouts)
# - Returns status dict instead of raising
# - If Redis unavailable, tracing is silently disabled
status = await safe_initialize(
redis_url=settings.SWISPER_STUDIO_REDIS_URL,
project_id=settings.SWISPER_STUDIO_PROJECT_ID,
stream_name=settings.SWISPER_STUDIO_STREAM_NAME,
verify_consumer=True,
connection_timeout=5.0, # Max 5 seconds to connect
)
if status.get("initialized"):
logger.info("โ
SwisperStudio observability initialized (Redis Streams)")
logger.info(f" Redis: {settings.SWISPER_STUDIO_REDIS_URL}")
logger.info(f" Project ID: {settings.SWISPER_STUDIO_PROJECT_ID}")
# Enable LLM prompt capture (includes streaming support)
try:
wrap_llm_adapter()
logger.info("โ
LLM prompt capture enabled (structured + streaming)")
except Exception as e:
logger.debug(f"LLM prompt capture skipped: {e}")
else:
logger.warning("โ ๏ธ SwisperStudio tracing disabled (Swisper continues normally)")
if not status.get("redis"):
logger.warning(" Reason: Redis connection failed or timed out")
elif not status.get("write"):
logger.warning(" Reason: Redis write permission denied")
except ImportError:
logger.warning("โ ๏ธ SwisperStudio SDK not installed - observability disabled")
logger.warning(" Install with: pip install swisper-studio-sdk==0.5.1")
except Exception as e:
# This should NEVER happen with safe_initialize, but just in case
logger.warning(f"โ ๏ธ SwisperStudio unexpected error: {e}")
logger.warning(" Continuing without observability")
๐ Key API Changes¶
| v0.5.0 (OLD) | v0.5.1 (NEW) | Behavior |
|---|---|---|
initialize_redis_publisher() |
safe_initialize() |
Never blocks, never raises |
| Raises on error | Returns {"initialized": False} |
Safe for production |
| No timeout | 5s connection timeout | Configurable |
New Function: safe_initialize()¶
status = await safe_initialize(
redis_url: str, # Required: Redis URL
project_id: str, # Required: Project ID
stream_name: str = "...", # Optional: Stream name
verify_consumer: bool = True, # Optional: Check consumer
connection_timeout: float = 5.0, # Optional: Max connect time
)
# Returns dict (NEVER raises):
{
"enabled": True, # Was initialization attempted
"redis": True/False, # Redis connectivity OK
"write": True/False, # Write permission OK
"consumer": True/False, # Consumer detected
"initialized": True/False, # Overall success
}
๐งช Testing the Fix¶
You can test that the new SDK handles misconfiguration gracefully:
# Test with WRONG Redis URL (simulates misconfiguration)
python -c "
import asyncio
from swisper_studio_sdk import safe_initialize
async def test():
status = await safe_initialize(
redis_url='redis://nonexistent:6379', # Wrong URL
project_id='test',
connection_timeout=3.0
)
print(f'Status: {status}')
print(f'Initialized: {status[\"initialized\"]}') # Should be False
print('โ
Swisper would continue normally!')
asyncio.run(test())
"
Expected output:
โ ๏ธ Redis connection timed out after 3.0s
Tracing will be DISABLED (Swisper continues normally)
Status: {'enabled': True, 'redis': False, 'write': False, 'consumer': False, 'initialized': False}
Initialized: False
โ
Swisper would continue normally!
๐ฆ Deployment Steps¶
- Wait for SDK v0.5.1 to be published (SwisperStudio team will tag and publish)
- Update Swisper's SDK version in
pyproject.toml - Update initialization code in
main.pyas shown above - Test locally with the test script above
- Deploy to production
๐ก๏ธ What's Fixed in SDK v0.5.1¶
| Issue | Fix |
|---|---|
ping() hangs forever on unreachable Redis |
All operations have timeouts (default 3s) |
| Exceptions crash Swisper | safe_initialize() never raises |
| No way to recover from failed init | Tracing silently disabled, Swisper continues |
| Mid-operation disconnects cause hangs | Health checks before every Redis operation |
๐ Questions?¶
Contact SwisperStudio team or check:
- SDK CHANGELOG: swisper_studio/sdk/CHANGELOG.md
- SDK source: swisper_studio/sdk/swisper_studio_sdk/
Document Owner: SwisperStudio Team
Created: 2025-11-26