1.9 KiB
1.9 KiB
Asyncio Event Loop Issue with Streamlit
Problem
Error: There is no current event loop in thread 'ScriptRunner.scriptThread'
This occurs because:
- Google's langchain integration uses asyncio internally
- Streamlit runs scripts in a separate thread (ScriptRunner.scriptThread)
- This thread doesn't have an asyncio event loop by default
- When
embed_query()is called, it tries to use async operations but fails
Solution
Option 1: Create Event Loop for Thread (Recommended)
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))
Recommended Fix
Update model_factory.py in the _create_google_embeddings method to handle the event loop properly.