diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ad1ed2d --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +# LearnSphere Environment Configuration +# Copy this file to .env and fill in your actual values. +# NEVER commit .env to version control. + +# Google Gemini AI API Key +# Get your key at: https://makersuite.google.com/app/apikey +GEMINI_API_KEY=your_gemini_api_key_here + +# Flask Configuration +# Set to "true" only during local development — NEVER in production +FLASK_DEBUG=false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96fa0a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# LearnSphere – .gitignore + +# ───────────────────────────────────────────── +# Environment & Secrets (NEVER commit these) +# ───────────────────────────────────────────── +.env +*.env +.env.local +.env.production + +# ───────────────────────────────────────────── +# Python +# ───────────────────────────────────────────── +__pycache__/ +*.py[cod] +*.pyo +*.pyd +*.pyc +*.egg +*.egg-info/ +dist/ +build/ +venv/ +env/ +.venv/ +pip-log.txt +pip-delete-this-directory.txt + +# ───────────────────────────────────────────── +# Node.js +# ───────────────────────────────────────────── +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.npm/ +.yarn/ + +# ───────────────────────────────────────────── +# OS & Editor +# ───────────────────────────────────────────── +.DS_Store +Thumbs.db +desktop.ini +.vscode/ +.idea/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# ───────────────────────────────────────────── +# Logs +# ───────────────────────────────────────────── +logs/ +*.log + +# ───────────────────────────────────────────── +# Misc +# ───────────────────────────────────────────── +*.bak +*.tmp +*.swp +launch.json diff --git a/chatbot.py b/chatbot.py index 39e3f7d..75b0659 100644 --- a/chatbot.py +++ b/chatbot.py @@ -1,45 +1,69 @@ -import os -from flask import Flask, request, jsonify, render_template -from flask_cors import CORS -import google.generativeai as genai - -# Secure API Key -API_KEY = "AIzaSyCHaO_fHrrnttwyuWjSFznVrDAwGmB2xUo" -genai.configure(api_key=API_KEY) - -app = Flask(__name__, template_folder="templates", static_folder="static") -CORS(app) - -def format_response(text): - """Formats chatbot response for better readability""" - formatted_text = text.replace("**", "").replace("*", "").replace("\n", "
") - return formatted_text.strip() - -@app.route("/") -def home(): - return render_template("index.html") - -@app.route("/chat", methods=["POST"]) -def chat(): - user_input = request.json.get("message") - - if not user_input: - return jsonify({"error": "No message provided"}), 400 - - try: - model = genai.GenerativeModel("gemini-1.5-pro") # Updated model - response = model.generate_content(user_input) - - if response and response.candidates: - reply = format_response(response.candidates[0].content.parts[0].text) - else: - reply = "I'm not sure how to respond to that. Can you try rephrasing?" - - except Exception as e: - return jsonify({"reply": f"Error: {str(e)}"}), 500 - - return jsonify({"reply": reply}) - -if __name__ == "__main__": - app.run(debug=True) - +import os +from flask import Flask, request, jsonify, render_template +from flask_cors import CORS +import google.generativeai as genai + +# Load API Key securely from environment variable +# Never hardcode secrets in source code. +# Set your key with: export GEMINI_API_KEY="your_key_here" (Linux/Mac) +# set GEMINI_API_KEY=your_key_here (Windows) +API_KEY = os.environ.get("GEMINI_API_KEY") + +if not API_KEY: + raise EnvironmentError( + "GEMINI_API_KEY environment variable is not set. " + "Please set it before running the application. " + "See .env.example for guidance." + ) + +genai.configure(api_key=API_KEY) + +app = Flask(__name__, template_folder="templates", static_folder="static") +CORS(app) + + +def format_response(text): + """Formats chatbot response for better readability.""" + # Safely convert markdown-like bold to HTML + formatted_text = text.replace("**", "").replace("*", "").replace("\n", "
") + return formatted_text.strip() + + +@app.route("/") +def home(): + return render_template("index.html") + + +@app.route("/chat", methods=["POST"]) +def chat(): + data = request.get_json(silent=True) + + if not data or "message" not in data: + return jsonify({"error": "No message provided"}), 400 + + user_input = data["message"] + + if not user_input or not user_input.strip(): + return jsonify({"error": "Message cannot be empty"}), 400 + + try: + model = genai.GenerativeModel("gemini-1.5-pro") + response = model.generate_content(user_input) + + if response and response.candidates: + reply = format_response(response.candidates[0].content.parts[0].text) + else: + reply = "I'm not sure how to respond to that. Can you try rephrasing?" + + except Exception as e: + # Log internally but don't expose raw exception to the client + print(f"[ERROR] Chatbot error: {e}") + return jsonify({"reply": "An error occurred while processing your request. Please try again later."}), 500 + + return jsonify({"reply": reply}) + + +if __name__ == "__main__": + # Disable debug mode in production + debug_mode = os.environ.get("FLASK_DEBUG", "false").lower() == "true" + app.run(debug=debug_mode)