Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions app/config.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rollback the changes in this file, as they are executed before the app is running

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nightcityblade Remember this ☝️

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
Expand Up @@ -268,33 +268,34 @@ def initialize_settings():
tool_settings = ToolSettings()

# Validate required Meta settings
assert (
settings.meta_api_version and settings.meta_api_version.strip()
), "META_API_VERSION is required"
assert (
settings.meta_app_id and settings.meta_app_id.strip()
), "META_APP_ID is required"
assert (
if not (settings.meta_api_version and settings.meta_api_version.strip()):
raise ValueError("META_API_VERSION is required")
if not (settings.meta_app_id and settings.meta_app_id.strip()):
raise ValueError("META_APP_ID is required")
if not (
settings.meta_app_secret and settings.meta_app_secret.get_secret_value().strip()
), "META_APP_SECRET is required"
):
raise ValueError("META_APP_SECRET is required")

# Validate required WhatsApp settings
assert (
if not (
settings.whatsapp_cloud_number_id and settings.whatsapp_cloud_number_id.strip()
), "WHATSAPP_CLOUD_NUMBER_ID is required"
assert (
):
raise ValueError("WHATSAPP_CLOUD_NUMBER_ID is required")
if not (
settings.whatsapp_verify_token
and settings.whatsapp_verify_token.get_secret_value().strip()
), "WHATSAPP_VERIFY_TOKEN is required"
assert (
):
raise ValueError("WHATSAPP_VERIFY_TOKEN is required")
if not (
settings.whatsapp_api_token
and settings.whatsapp_api_token.get_secret_value().strip()
), "WHATSAPP_API_TOKEN is required"
):
raise ValueError("WHATSAPP_API_TOKEN is required")

# Validate other required settings
assert (
settings.database_url and settings.database_url.get_secret_value().strip()
), "DATABASE_URL is required"
if not (settings.database_url and settings.database_url.get_secret_value().strip()):
raise ValueError("DATABASE_URL is required")

return settings, llm_settings, embedding_settings, tool_settings

Expand Down
3 changes: 2 additions & 1 deletion app/services/messaging_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ async def handle_command_message(
self, user: models.User, message: models.Message
) -> JSONResponse:
self.logger.debug(f"Handling command message: {message.content}")
assert message.content is not None
if message.content is None:
raise ValueError("Command message content is unexpectedly None.")
key = message.content.lower()
handler = self._command_handlers.get(key, self._command_unknown)
await handler(user)
Expand Down
3 changes: 2 additions & 1 deletion app/services/onboarding_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ async def process_state(self, user: User):
self.logger.debug(
f"Onboarding user {user.wa_id} with onboarding_state {user.onboarding_state}"
)
assert user.onboarding_state is not None
if user.onboarding_state is None:
raise ValueError("User onboarding_state is unexpectedly None.")
onboarding_handler = self.handlers.get(
user.onboarding_state, self.handle_default
)
Expand Down
9 changes: 6 additions & 3 deletions app/services/rate_limit_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ async def check_rate_limit_and_update_state(

# Check user limit
user_key = RedisKeys.USER_RATE(phone_number)
assert settings.user_message_limit is not None
if settings.user_message_limit is None:
raise ValueError("User message rate limit is unexpectedly None.")
is_exceeded, result = await self._check_rate_limit(
key=user_key,
limit=settings.user_message_limit,
Expand All @@ -122,7 +123,8 @@ async def check_rate_limit_and_update_state(

# Check global limit
global_key = RedisKeys.GLOBAL_RATE
assert settings.global_message_limit is not None
if settings.global_message_limit is None:
raise ValueError("Global message rate limit is unexpectedly None.")
is_exceeded, result = await self._check_rate_limit(
key=global_key,
limit=settings.global_message_limit,
Expand Down Expand Up @@ -167,7 +169,8 @@ async def _check_rate_limit(
if redis is None:
return False, 0

assert settings.time_to_live
if not settings.time_to_live:
raise ValueError("Rate limit TTL is missing or zero.")
pipe = await redis.pipeline()
await pipe.incr(key)
await pipe.expire(key, settings.time_to_live)
Expand Down
30 changes: 22 additions & 8 deletions app/services/state_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def __init__(self):
self.logger = logging.getLogger(__name__)

async def handle_blocked(self, user: User) -> JSONResponse:
assert user.id is not None
if user.id is None:
raise ValueError("User ID is unexpectedly None for blocked state handling.")

blocked_text = strings.get_string(StringCategory.ERROR, "blocked")
last_assistant_message = await db.get_latest_user_message_by_role(
Expand Down Expand Up @@ -57,7 +58,10 @@ async def handle_blocked(self, user: User) -> JSONResponse:
)

async def handle_rate_limited(self, user: User) -> JSONResponse:
assert user.id is not None
if user.id is None:
raise ValueError(
"User ID is unexpectedly None for rate-limited state handling."
)

rate_limit_text = strings.get_string(StringCategory.ERROR, "rate_limited")
last_assistant_message = await db.get_latest_user_message_by_role(
Expand Down Expand Up @@ -184,7 +188,8 @@ async def handle_new_user_registration(
)
await whatsapp_client.send_message(phone_number, response_text)

assert new_user.id is not None
if new_user.id is None:
raise ValueError("New user ID is unexpectedly None after registration.")
await db.create_new_message_by_fields(
user_id=new_user.id,
role=MessageRole.assistant,
Expand All @@ -208,7 +213,8 @@ async def handle_new_user_registration(

async def handle_in_review_user(self, user: User) -> JSONResponse:
"""Handle messages from users in review (not yet approved) users"""
assert user.id is not None
if user.id is None:
raise ValueError("User ID is unexpectedly None for in-review handling.")

pending_text = strings.get_string(
StringCategory.REGISTRATION, "pending_approval"
Expand Down Expand Up @@ -254,7 +260,10 @@ async def handle_new_approved_user(self, user: User) -> JSONResponse:
language_code="en_US",
)

assert user.id is not None
if user.id is None:
raise ValueError(
"User ID is unexpectedly None after approval template send."
)
await db.create_new_message_by_fields(
user_id=user.id,
role=MessageRole.assistant,
Expand All @@ -266,7 +275,10 @@ async def handle_new_approved_user(self, user: User) -> JSONResponse:
await flow_client.send_personal_and_school_info_flow(user)
else:
# In non-production, skip template and flow
assert user.id is not None
if user.id is None:
raise ValueError(
"User ID is unexpectedly None in non-production approval flow."
)
self.logger.info(
f"Skipping template and flow for user {user.wa_id} in {settings.environment} environment"
)
Expand Down Expand Up @@ -314,11 +326,13 @@ async def handle_new_dummy(self, user: User) -> JSONResponse:
# Read the class IDs from the class info
class_ids = await db.get_class_ids_from_class_info(user.class_info)

assert class_ids is not None
if class_ids is None:
raise ValueError("Derived class IDs are unexpectedly None.")

# Update user and create teachers_classes entries
user = await db.update_user(user)
assert user.id is not None
if user.id is None:
raise ValueError("Dummy user ID is unexpectedly None after update.")
await db.assign_teacher_to_classes(user, class_ids)

# Send a welcome message to the user
Expand Down
6 changes: 4 additions & 2 deletions app/tools/tool_code/generate_exercise/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ async def generate_exercise(
try:
# Retrieve the resources for the class
resource_ids = await db.get_class_resources(class_id)
assert resource_ids
if not resource_ids:
raise ValueError(f"No resources found for class {class_id}.")

# Retrieve the relevant content and exercises
retrieved_content = await vector_search(
Expand Down Expand Up @@ -86,7 +87,8 @@ async def generate_exercise(
),
},
)
assert response.content
if not response.content:
raise ValueError("LLM returned empty exercise content.")

# Convert content to string if it's not already
content = response.content
Expand Down
3 changes: 2 additions & 1 deletion app/tools/tool_code/search_knowledge/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ async def search_knowledge(
try:
# Retrieve the resources for the class
resource_ids = await db.get_class_resources(class_id)
assert resource_ids
if not resource_ids:
raise ValueError(f"No resources found for class {class_id}.")

# Retrieve the relevant content
retrieved_content = await vector_search(
Expand Down
Loading