Files
clm-system/PLANNING/asyncio_event_loop_fix.md

1.9 KiB

Asyncio Event Loop Issue with Streamlit

Problem

Error: There is no current event loop in thread 'ScriptRunner.scriptThread'

This occurs because:

  1. Google's langchain integration uses asyncio internally
  2. Streamlit runs scripts in a separate thread (ScriptRunner.scriptThread)
  3. This thread doesn't have an asyncio event loop by default
  4. When embed_query() is called, it tries to use async operations but fails

Solution

Add event loop handling in the model factory:

import asyncio
import threading

def _create_google_embeddings() -> GoogleGenerativeAIEmbeddings:
    """Create Google embeddings with validation"""
    if not config.GOOGLE_API_KEY:
        raise ValueError("GOOGLE_API_KEY not configured")
    
    # Ensure event loop exists for current thread
    try:
        loop = asyncio.get_event_loop()
    except RuntimeError:
        # Create new event loop for this thread
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
    
    embeddings = GoogleGenerativeAIEmbeddings(
        model=config.GOOGLE_EMBEDDING_MODEL,
        google_api_key=config.GOOGLE_API_KEY
    )
    
    # Rest of validation...

Option 2: Use nest_asyncio (Simple but less clean)

Install and apply nest_asyncio at app startup:

import nest_asyncio
nest_asyncio.apply()

Option 3: Synchronous Wrapper

Create a synchronous wrapper for async operations:

def sync_embed_query(embeddings, text):
    """Synchronous wrapper for async embed_query"""
    try:
        loop = asyncio.get_event_loop()
    except RuntimeError:
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
    
    return loop.run_until_complete(embeddings.aembed_query(text))

Update model_factory.py in the _create_google_embeddings method to handle the event loop properly.