Skip to content

Commit

Permalink
Merge pull request #206 from Anushka-Pote/main
Browse files Browse the repository at this point in the history
Enhanced Error Handling for API Calls and API Key Validation #201
  • Loading branch information
kom-senapati authored Oct 28, 2024
2 parents 03273c8 + 7cb8406 commit 43e5fec
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 54 deletions.
121 changes: 71 additions & 50 deletions app/ai.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,91 @@
import os
import logging
from groq import Groq
from dotenv import load_dotenv
from typing import List, Dict
from openai import OpenAI
import google.generativeai as genai
from anthropic import Anthropic


load_dotenv()

# Set up logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)

def chat_with_chatbot(messages: List[Dict[str, str]], apiKey: str, engine: str) -> str:
if engine == "groq":
content = chat_with_groq(messages, apiKey)
return content
elif engine == "openai":
content = chat_with_openai(messages, apiKey)
return content
elif engine == "anthropic":
content = chat_with_anthropic(messages, apiKey)
return content
elif engine == "gemini":
content = chat_with_gemini(messages, apiKey)
if not apiKey:
logger.error("API key is missing.")
raise ValueError("API key is required for making API requests.")

try:
if engine == "groq":
content = chat_with_groq(messages, apiKey)
elif engine == "openai":
content = chat_with_openai(messages, apiKey)
elif engine == "anthropic":
content = chat_with_anthropic(messages, apiKey)
elif engine == "gemini":
content = chat_with_gemini(messages, apiKey)
else:
logger.error(f"Unsupported engine: {engine}")
raise ValueError(f"Unsupported engine: {engine}")
logger.info(f"Request to {engine} API was successful.")
return content
else:
raise ValueError(f"Unsupported engine: {engine}")

except Exception as e:
logger.error(f"Error in chat_with_chatbot function with engine {engine}: {e}")
raise

def chat_with_groq(messages: List[Dict[str, str]], apiKey: str) -> str:
client = Groq(api_key=apiKey)
chat_completion = client.chat.completions.create(
messages=messages,
model="llama3-8b-8192",
)
return chat_completion.choices[0].message.content

try:
client = Groq(api_key=apiKey)
chat_completion = client.chat.completions.create(
messages=messages,
model="llama3-8b-8192",
)
return chat_completion.choices[0].message.content
except Exception as e:
logger.error(f"Error in chat_with_groq: {e}")
raise

def chat_with_openai(messages: List[Dict[str, str]], apiKey: str) -> str:
client = OpenAI(api_key=apiKey)
chat_completion = client.chat.completions.create(
messages=messages,
model="gpt-3.5-turbo",
)
return chat_completion.choices[0].message.content

try:
client = OpenAI(api_key=apiKey)
chat_completion = client.chat.completions.create(
messages=messages,
model="gpt-3.5-turbo",
)
return chat_completion.choices[0].message.content
except Exception as e:
logger.error(f"Error in chat_with_openai: {e}")
raise

def chat_with_anthropic(messages: List[Dict[str, str]], apiKey: str) -> str:
client = Anthropic(api_key=apiKey)
chat_completion = client.messages.create(
max_tokens=1024,
messages=messages,
model="claude-3-5-sonnet-latest",
)
return chat_completion.content

try:
client = Anthropic(api_key=apiKey)
chat_completion = client.messages.create(
max_tokens=1024,
messages=messages,
model="claude-3-5-sonnet-latest",
)
return chat_completion.content
except Exception as e:
logger.error(f"Error in chat_with_anthropic: {e}")
raise

def chat_with_gemini(messages: List[Dict[str, str]], apiKey: str) -> str:
genai.configure(api_key=apiKey)
model = genai.GenerativeModel("gemini-1.5-flash")
formatted_messages = [
{
"role": (
message["role"] if message["role"] == "user" else "model"
), # User or assistant
"parts": [message["content"]], # Wrap the content in a list
}
for message in messages
]
response = model.generate_content(formatted_messages)
return response.text
try:
genai.configure(api_key=apiKey)
model = genai.GenerativeModel("gemini-1.5-flash")
formatted_messages = [
{
"role": message["role"] if message["role"] == "user" else "model",
"parts": [message["content"]],
}
for message in messages
]
response = model.generate_content(formatted_messages)
return response.text
except Exception as e:
logger.error(f"Error in chat_with_gemini: {e}")
raise
18 changes: 18 additions & 0 deletions app/constants.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import logging
from typing import Union, List, Optional, Dict
from urllib.parse import urlparse

# Set up logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)

USER_AVATAR_API = "https://ui-avatars.com/api"
BOT_AVATAR_API = "https://robohash.org"
IMAGE_GEN_API = "https://image.pollinations.ai/prompt"

# Validate URLs
for api_url in [USER_AVATAR_API, BOT_AVATAR_API, IMAGE_GEN_API]:
parsed_url = urlparse(api_url)
if not all([parsed_url.scheme, parsed_url.netloc]):
logger.error(f"Invalid API URL: {api_url}")

DEFAULT_CHATBOTS: List[Dict[str, Union[str, Optional[int], bool]]] = [
{
"name": "supportgpt",
Expand Down Expand Up @@ -107,3 +119,9 @@
"public": False,
},
]

# Check chatbot configurations for required fields
required_fields = {"name", "prompt", "generated_by", "user_id", "public"}
for bot in DEFAULT_CHATBOTS:
if not all(field in bot for field in required_fields):
logger.error(f"Missing fields in chatbot configuration: {bot.get('name', 'Unknown')}")
17 changes: 15 additions & 2 deletions app/data_fetcher.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import logging
from sqlalchemy import func
from .models import User, Chatbot, Chat, Image
from typing import Union, List, Optional, Dict

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
handler = logging.FileHandler("contribution_data_fetch.log")
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)

def fetch_contribution_data(db):
users = db.session.query(User).order_by(User.contribution_score.desc()).all()
return users
"""Fetch user data sorted by contribution score, and log details."""

try:
users = db.session.query(User).order_by(User.contribution_score.desc()).all()
logger.info("Fetched user contribution data successfully.")
return users
except Exception as e:
logger.error(f"Error fetching contribution data: {str(e)}")
return []
19 changes: 17 additions & 2 deletions app/helpers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
from flask import flash
from .models import Chatbot
from .constants import BOT_AVATAR_API, DEFAULT_CHATBOTS
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
handler = logging.FileHandler("chatbot_creation.log")
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)

def create_default_chatbots(db):
"""Create default chatbots if none exist."""

if Chatbot.query.count() == 0:
try:
for bot_data in DEFAULT_CHATBOTS:
required_fields = ["name", "prompt", "generated_by"]
for field in required_fields:
if field not in bot_data:
logger.error(f"Missing required field '{field}' in bot_data: {bot_data}")
continue

avatar = f"{BOT_AVATAR_API}/{bot_data['name']}"
chatbot = Chatbot(
name=bot_data["name"],
Expand All @@ -20,6 +32,9 @@ def create_default_chatbots(db):
)
db.session.add(chatbot)
db.session.commit()
logger.info("Default chatbots created successfully.")
except Exception as e:
db.session.rollback()
flash(f"Error creating default chatbots: {str(e)}", "error")
error_message = f"Error creating default chatbots: {str(e)}"
flash(error_message, "error")
logger.error(error_message)

0 comments on commit 43e5fec

Please sign in to comment.