sxflynn / TeacherGPT

A proposed GPT chatbot for teachers that uses retrieval-augmentation to answer questions about their students.
MIT License
8 stars 1 forks source link

Create robust dependency injection system with Pydantic Settings in FastAPI #2

Open sxflynn opened 7 months ago

sxflynn commented 7 months ago

I consulted with the FastAPI docs on settings and environment variables and was unable to make a full request. await websocket.send_text() messages were not executing after this line in main.py

if relevancy_check(prompt_object.prompt):

indicating that some kind of side effect of implementing a settings object was causing blocking issues.

Here are the steps I took before discovering this issue:

import pydantic_settings and create a BaseSettings inherited class.

class Settings(BaseSettings):
    openai_api_key: str
    anyscale_api_key: str
    togetherai_api_key: str
    default_service: str
    graphql_url: str

Created a settings getter in the global scope of the application

@lru_cache
def get_settings():
    return Settings()

Set up a Depends object as a dependency injection into the main websocket endpoint

@app.websocket("/promptstreaming")
async def run_prompt(websocket: WebSocket, settings: Annotated[Settings, Depends(get_settings)]):

Replaced all code related to os.getenv with settings

Somehow, even though I could access the settings variables, like settings.graphql_url, the code was getting blocked as soon as I entered a non-async function, the first being relevancy_check.

I'd like to implement a proper dependency injection system and pydantic_settings system working, but until then, I will just use os.getenv

sxflynn commented 7 months ago

Update: I've identified the line that blocks the Websockets process

config.py

inside the Config() initializer

# existing line that works, imports from environment variables
self.key = os.getenv(f'{provider_name.upper()}_API_KEY', 'none')

# proposed replacement line, imports from settings instance, currently blocks async websockets
self.key = getattr(settings,f'{provider_name}_api_key','none')