NitinBot001's picture
Update app.py
2c63f8e verified
from flask import Flask, request, jsonify, render_template
import os
from flask_cors import CORS
from openai import OpenAI
from translate import Translator
# Load API key and base URL from environment variables
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") or os.getenv("GEMINI_API_KEY")
if not OPENAI_API_KEY:
raise ValueError("OpenAI API Key is missing. Set it in environment variables.")
OPENAI_API_BASE = os.getenv("OPENAI_API_BASE", "https://generativelanguage.googleapis.com/v1beta/openai/") # Default is standard OpenAI
OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gemini-2.5-flash") # Default model
# Configure OpenAI client (supports custom base url for OpenAI-compatible APIs)
client = OpenAI(api_key=OPENAI_API_KEY, base_url=OPENAI_API_BASE)
# Set the static folder path to the "static" folder
STATIC_FOLDER = os.path.join(os.path.dirname(__file__), "static")
# Read the context file from the static folder
CONTEXT_FILE = os.path.join(STATIC_FOLDER, "context.txt")
try:
with open(CONTEXT_FILE, "r", encoding="utf-8") as file:
CONTEXT_DATA = file.read()
except FileNotFoundError:
CONTEXT_DATA = "No context available."
SYSTEM_INSTRUCTION = """
You are Hal, an AI assistant created to help farmers.
Your goal is to analyze the crop data provided in the context file and assist farmers by answering their queries and solving their problems.
Response Rules:
1. Use the context file to answer farmer-related questions.
2. Do not share any personal information.
3. Provide only the information available in the context file.
4. If not found, generate helpful answers from agricultural knowledge.
5. Keep responses simple, clear, and useful.
"""
# Flask app
app = Flask(__name__, template_folder="templates", static_folder="static")
CORS(app)
# Language detection function
def detect_language(text):
"""
Detect language of text using multiple methods
"""
try:
# Method 1: Try langdetect if available
try:
from langdetect import detect
detected = detect(text)
return detected
except ImportError:
pass
except:
pass
# Method 2: Simple heuristic detection
common_words = {
'en': ['the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by', 'is', 'are', 'was', 'were'],
'es': ['el', 'la', 'de', 'que', 'y', 'en', 'un', 'es', 'se', 'no', 'te', 'lo', 'por', 'con', 'del', 'las'],
'fr': ['le', 'de', 'et', 'à', 'un', 'il', 'être', 'en', 'avoir', 'que', 'pour', 'du', 'ce', 'son', 'une'],
'de': ['der', 'die', 'und', 'in', 'den', 'von', 'zu', 'das', 'mit', 'sich', 'des', 'auf', 'für', 'ist'],
'it': ['il', 'di', 'che', 'e', 'la', 'per', 'in', 'un', 'è', 'con', 'non', 'da', 'del', 'sono'],
'pt': ['de', 'a', 'o', 'que', 'e', 'do', 'da', 'em', 'um', 'para', 'é', 'com', 'os', 'uma', 'ser'],
'ru': ['в', 'и', 'не', 'на', 'я', 'быть', 'с', 'а', 'как', 'его', 'к', 'он', 'что', 'то'],
'hi': ['है', 'का', 'के', 'में', 'और', 'को', 'से', 'पर', 'यह', 'वह', 'एक', 'जो'],
'ar': ['في', 'من', 'إلى', 'على', 'هذا', 'هذه', 'التي', 'الذي', 'أن', 'كان', 'مع'],
'zh': ['的', '是', '在', '了', '和', '有', '人', '我', '你', '他', '她', '它'],
}
text_lower = text.lower()
scores = {}
for lang, words in common_words.items():
score = sum(1 for word in words if word in text_lower)
if score > 0:
scores[lang] = score / len(words) # Normalize by word count
if scores:
return max(scores, key=scores.get)
return 'en' # Default to English if detection fails
except Exception:
return 'en' # Default to English
# Translation function with proper language detection
def translate_text(text, target_lang, source_lang=None):
"""
Translate text to desired language using Microsoft Translator
Args:
text (str): Text to translate
target_lang (str): Target language code (e.g., 'es', 'fr', 'de', 'hi', 'zh')
source_lang (str): Source language code (if None, will auto-detect)
Returns:
str: Translated text or original text if translation fails
"""
try:
# Skip translation if target language is English and source appears to be English
if target_lang.lower() == 'en':
return text
# Detect source language if not provided
if source_lang is None or source_lang == 'auto':
source_lang = detect_language(text)
# Skip translation if source and target are the same
if source_lang.lower() == target_lang.lower():
return text
# Create translator instance with detected/specified source language
translator = Translator(to_lang=target_lang, from_lang=source_lang)
translated = translator.translate(text)
# Return translated text if successful
if translated and translated.strip():
return translated
else:
return text # Return original if translation is empty
except Exception as e:
print(f"Translation error: {str(e)}")
# Try fallback translation with English as source
try:
fallback_translator = Translator(to_lang=target_lang, from_lang='en')
fallback_result = fallback_translator.translate(text)
if fallback_result and fallback_result.strip():
return fallback_result
except:
pass
return text # Return original text if all translation attempts fail
# Language code mapping for common languages
LANGUAGE_CODES = {
'english': 'en',
'spanish': 'es',
'french': 'fr',
'german': 'de',
'italian': 'it',
'portuguese': 'pt',
'russian': 'ru',
'chinese': 'zh',
'japanese': 'ja',
'korean': 'ko',
'arabic': 'ar',
'hindi': 'hi',
'dutch': 'nl',
'swedish': 'sv',
'norwegian': 'no',
'danish': 'da',
'finnish': 'fi',
'polish': 'pl',
'czech': 'cs',
'hungarian': 'hu',
'romanian': 'ro',
'turkish': 'tr',
'greek': 'el',
'hebrew': 'he',
'thai': 'th',
'vietnamese': 'vi',
'indonesian': 'id',
'malay': 'ms'
}
@app.route("/", methods=["GET"])
def home():
return render_template("index.html")
@app.route("/chat", methods=["POST"])
def chat():
try:
data = request.get_json()
user_message = data.get("message")
target_lang = data.get("lang", "en")
if not user_message:
return jsonify({"error": "Message is required"}), 400
# Normalize language code (handle full language names)
target_lang = target_lang.lower()
if target_lang in LANGUAGE_CODES:
target_lang = LANGUAGE_CODES[target_lang]
# Translate user message to English for processing if it's not in English
processed_message = user_message
if target_lang != "en":
try:
# Detect source language of user message
detected_source = detect_language(user_message)
print(f"Detected user language: {detected_source}")
# Translate to English only if source is not English
if detected_source != 'en':
english_translator = Translator(to_lang='en', from_lang=detected_source)
processed_message = english_translator.translate(user_message)
if not processed_message or not processed_message.strip():
processed_message = user_message # Fallback to original
print(f"Translated user message to English: {processed_message}")
except Exception as e:
print(f"User message translation error: {str(e)}")
processed_message = user_message # Use original message
messages = [
{"role": "system", "content": SYSTEM_INSTRUCTION},
{"role": "user", "content": f"Context Data:\n{CONTEXT_DATA}\n\nUser Query: {processed_message}"}
]
# Call OpenAI (or OpenAI-compatible) chat API
response = client.chat.completions.create(
model=OPENAI_MODEL,
messages=messages,
temperature=0.7
)
ai_response = response.choices[0].message.content.strip()
# Translate AI response to target language if not English
if target_lang.lower() != "en":
ai_response = translate_text(ai_response, target_lang)
return jsonify({"response": ai_response})
except Exception as e:
error_message = f"Error: {str(e)}"
# Try to translate error message if target language is specified
if 'target_lang' in locals() and target_lang.lower() != "en":
try:
error_message = translate_text(error_message, target_lang)
except:
pass # Use original error message if translation fails
return jsonify({"error": error_message}), 500
@app.route("/languages", methods=["GET"])
def get_languages():
"""Endpoint to get available language codes"""
return jsonify({"languages": LANGUAGE_CODES})
@app.route("/translate", methods=["POST"])
def translate_endpoint():
"""Standalone translation endpoint"""
try:
data = request.get_json()
text = data.get("text")
target_lang = data.get("target_lang", "en")
source_lang = data.get("source_lang") # Remove default 'auto'
if not text:
return jsonify({"error": "Text is required"}), 400
# Normalize language code
target_lang = target_lang.lower()
if target_lang in LANGUAGE_CODES:
target_lang = LANGUAGE_CODES[target_lang]
# Auto-detect source language if not provided
if not source_lang or source_lang.lower() == 'auto':
source_lang = detect_language(text)
translated = translate_text(text, target_lang, source_lang)
return jsonify({
"original_text": text,
"translated_text": translated,
"detected_source_lang": source_lang,
"target_lang": target_lang
})
except Exception as e:
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
print("Starting Flask app with translation support...")
print("Available language codes:", list(LANGUAGE_CODES.keys()))
print("Install dependencies: pip install translate")
app.run(debug=True, host='0.0.0.0', port=7860, threaded=True)