-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
158 lines (135 loc) · 5.4 KB
/
Copy pathapp.py
File metadata and controls
158 lines (135 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import os
from flask import Flask, render_template, request, jsonify
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
app = Flask(__name__)
# User can set API key in .env OR directly below:
# GEMINI_API_KEY = "your_actual_api_key_here"
API_KEY = os.getenv("GEMINI_API_KEY", "").strip()
# Available Gemini Models list (Tested & Verified with active key)
AVAILABLE_MODELS = [
{
"id": "gemini-3.6-flash",
"name": "Gemini 3.6 Flash",
"description": "Next-gen ultra-fast & intelligent model",
"recommended": True
},
{
"id": "gemini-3.5-flash",
"name": "Gemini 3.5 Flash",
"description": "High performance multimodal model"
},
{
"id": "gemini-3.1-flash-lite",
"name": "Gemini 3.1 Flash Lite",
"description": "Lightweight & responsive model"
},
{
"id": "gemini-flash-latest",
"name": "Gemini Flash Latest",
"description": "Latest stable Gemini Flash build"
},
{
"id": "gemini-3-flash-preview",
"name": "Gemini 3 Flash Preview",
"description": "Experimental preview model"
}
]
def get_genai_client():
"""Returns configured google-generativeai module if API key is present."""
key = os.getenv("GEMINI_API_KEY", API_KEY).strip().strip('"').strip("'")
if not key or key == "YOUR_GEMINI_API_KEY_HERE":
return None, "API Key missing. Please enter your GEMINI_API_KEY in .env file or app.py."
try:
import google.generativeai as genai
genai.configure(api_key=key)
return genai, None
except Exception as e:
return None, f"Failed to initialize Google Generative AI client: {str(e)}"
@app.route("/")
def index():
return render_template("index.html")
@app.route("/favicon.ico")
def favicon():
return app.send_static_file("favicon.svg")
@app.route("/api/models", methods=["GET"])
def get_models():
key = os.getenv("GEMINI_API_KEY", API_KEY).strip()
is_key_set = bool(key and key != "YOUR_GEMINI_API_KEY_HERE")
return jsonify({
"models": AVAILABLE_MODELS,
"is_configured": is_key_set,
"active_key_source": ".env / app.py"
})
@app.route("/api/chat", methods=["POST"])
def chat():
genai, err = get_genai_client()
if err:
return jsonify({
"success": False,
"error": err,
"code": "MISSING_KEY"
}), 400
data = request.json or {}
user_message = data.get("message", "").strip()
selected_model = data.get("model", "gemini-3.6-flash")
history = data.get("history", [])
if not user_message:
return jsonify({"success": False, "error": "Message content cannot be empty."}), 400
# Ensure model ID is valid, fallback to gemini-3.6-flash
valid_ids = [m["id"] for m in AVAILABLE_MODELS]
if selected_model not in valid_ids:
selected_model = "gemini-3.6-flash"
try:
# Prepare Generative Model instance
model_instance = genai.GenerativeModel(selected_model)
# Build multi-turn chat history format for google.generativeai
formatted_history = []
for turn in history:
role = turn.get("role")
content = turn.get("content")
if role in ["user", "model", "assistant"] and content:
# Map assistant role to model for SDK
genai_role = "model" if role in ["assistant", "model"] else "user"
formatted_history.append({
"role": genai_role,
"parts": [content]
})
# Start chat session with formatted history
chat_session = model_instance.start_chat(history=formatted_history)
response = chat_session.send_message(user_message)
reply_text = response.text if hasattr(response, 'text') else str(response)
return jsonify({
"success": True,
"reply": reply_text,
"model_used": selected_model
})
except Exception as e:
error_str = str(e)
# Friendly guidance for 401 / Invalid Key errors
if "401" in error_str or "UNSUPPORTED" in error_str or "invalid authentication" in error_str.lower():
return jsonify({
"success": False,
"error": "Invalid API Key format. Please get a free Gemini API key (starts with 'AIzaSy...') from https://aistudio.google.com/app/apikey and set GEMINI_API_KEY on Vercel or in your local .env file.",
"code": "INVALID_KEY"
}), 401
# Attempt fallback to gemini-3.6-flash if model-specific 404 error occurs
if "404" in error_str or "not found" in error_str.lower():
try:
fallback_instance = genai.GenerativeModel("gemini-3.6-flash")
fallback_resp = fallback_instance.generate_content(user_message)
return jsonify({
"success": True,
"reply": fallback_resp.text,
"model_used": "gemini-3.6-flash (fallback)"
})
except Exception as fallback_err:
error_str = f"{error_str} | Fallback failed: {str(fallback_err)}"
return jsonify({
"success": False,
"error": f"Gemini API Error: {error_str}",
"code": "API_ERROR"
}), 500
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5000)