hoangthiencm commited on
Commit
1d7f30d
·
verified ·
1 Parent(s): b419497

Update server.py

Browse files
Files changed (1) hide show
  1. server.py +88 -72
server.py CHANGED
@@ -1,107 +1,123 @@
1
  import os
2
  import random
3
  import logging
4
- from flask import Flask, request, jsonify
 
 
 
 
 
 
5
  import google.generativeai as genai
6
- from flask_cors import CORS
7
  from dotenv import load_dotenv
 
8
 
9
- # Load environment variables (dùng cho chạy local, trên HF nó tự load từ Settings)
10
  load_dotenv()
11
 
12
- app = Flask(__name__)
13
- CORS(app)
14
 
15
- # Cấu hình Logging
16
- logging.basicConfig(level=logging.INFO)
17
- logger = logging.getLogger(__name__)
 
 
 
 
 
18
 
19
- # --- CẤU HÌNH TỪ BIẾN MÔI TRƯỜNG ---
20
 
21
- # 1. Lấy danh sách API KEYS
22
- # Trên Hugging Face, bạn vào Settings -> Variables/Secrets tạo biến tên GEMINI_API_KEYS
23
- # Giá trị là các key cách nhau bằng dấu phẩy: key1,key2,key3
24
  api_keys_env = os.getenv("GEMINI_API_KEYS", "")
25
- API_KEYS = [k.strip() for k in api_keys_env.split(",") if k.strip()]
26
-
27
- if not API_KEYS:
28
- logger.warning("CHÚ Ý: Chưa tìm thấy GEMINI_API_KEYS trong biến môi trường! Server sẽ không hoạt động đúng.")
29
 
30
  # 2. Lấy danh sách MODELS
31
- # Tạo biến GEMINI_MODELS, giá trị ví dụ: gemini-2.5-flash,gemini-1.5-pro
32
  models_env = os.getenv("GEMINI_MODELS", "gemini-2.0-flash-exp,gemini-1.5-pro,gemini-1.5-flash")
33
- GEMINI_MODELS = [m.strip() for m in models_env.split(",") if m.strip()]
34
-
35
- @app.route('/')
36
- def home():
37
- return jsonify({
38
- "status": "online",
39
- "message": "HT MATH Server is running",
40
- "models_available": GEMINI_MODELS,
41
- "keys_count": len(API_KEYS)
42
- })
43
 
44
- @app.route('/api/models', methods=['GET'])
45
- def get_models():
46
- """API trả về danh sách model để Client (main.py) cập nhật vào ComboBox"""
47
- return jsonify({"models": GEMINI_MODELS})
 
48
 
49
- @app.route('/api/generate', methods=['POST'])
50
- def generate_content():
51
- if not API_KEYS:
52
- return jsonify({'error': 'Server chưa cấu hình API Key'}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  try:
55
- data = request.json
56
- if not data:
57
- return jsonify({'error': 'No data provided'}), 400
58
-
59
- prompt = data.get('prompt', '')
60
- image_data = data.get('image') # Base64 string
61
- model_name = data.get('model', GEMINI_MODELS[0]) # Mặc định lấy model đầu tiên nếu client không gửi
62
-
63
- if not prompt and not image_data:
64
- return jsonify({'error': 'Cần cung cấp nội dung hoặc hình ảnh'}), 400
65
-
66
- # --- RANDOM KEY SELECTION ---
67
- # Chọn ngẫu nhiên 1 key để tránh rate limit
68
- current_key = random.choice(API_KEYS)
69
  genai.configure(api_key=current_key)
70
 
71
- # Log (ẩn bớt key để bảo mật)
72
- masked_key = current_key[:5] + "..." + current_key[-3:]
73
- logger.info(f"Processing request with Model: {model_name} using Key: {masked_key}")
74
-
75
- # Khởi tạo model
76
  model = genai.GenerativeModel(model_name)
77
 
78
- # Xử input (Text + Image hoặc Text only)
79
- content_parts = [prompt]
80
-
81
- if image_data:
 
82
  try:
83
- import base64
84
- from io import BytesIO
85
- from PIL import Image
86
-
87
- image_bytes = base64.b64decode(image_data)
88
  image = Image.open(BytesIO(image_bytes))
89
  content_parts.append(image)
90
  except Exception as e:
91
- logger.error(f"Lỗi xử lý ảnh: {str(e)}")
92
- return jsonify({'error': f'Lỗi xử lý ảnh: {str(e)}'}), 400
93
 
94
- # Gọi Google Gemini
95
  response = model.generate_content(content_parts)
96
 
97
  if response.text:
98
- return jsonify({'result': response.text})
99
  else:
100
- return jsonify({'result': 'Không phản hồi từ Gemini'}), 500
101
 
102
  except Exception as e:
103
- logger.error(f"Lỗi Server: {str(e)}")
104
- return jsonify({'error': str(e)}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
- if __name__ == '__main__':
107
- app.run(host='0.0.0.0', port=7860)
 
 
1
  import os
2
  import random
3
  import logging
4
+ import base64
5
+ from io import BytesIO
6
+ from typing import Optional, List
7
+
8
+ from fastapi import FastAPI, HTTPException, UploadFile, File, Form, Body
9
+ from fastapi.middleware.cors import CORSMiddleware
10
+ from pydantic import BaseModel
11
  import google.generativeai as genai
 
12
  from dotenv import load_dotenv
13
+ from PIL import Image
14
 
15
+ # --- LOAD BIẾN MÔI TRƯỜNG ---
16
  load_dotenv()
17
 
18
+ # --- CẤU HÌNH SERVER ---
19
+ app = FastAPI(title="HT MATH UNIFIED SERVER")
20
 
21
+ # Cấu hình CORS (Cho phép cả Web và Desktop App gọi vào)
22
+ app.add_middleware(
23
+ CORSMiddleware,
24
+ allow_origins=["*"], # Cho phép tất cả các nguồn (Web, App Desktop)
25
+ allow_credentials=True,
26
+ allow_methods=["*"],
27
+ allow_headers=["*"],
28
+ )
29
 
30
+ # --- PHẦN 1: CẤU HÌNH CHO DESKTOP APP (Key Rotation & Models) ---
31
 
32
+ # 1. Lấy danh sách API KEYS từ biến môi trường
33
+ # Format trên HuggingFace: Key1,Key2,Key3
 
34
  api_keys_env = os.getenv("GEMINI_API_KEYS", "")
35
+ DESKTOP_API_KEYS = [k.strip() for k in api_keys_env.split(",") if k.strip()]
 
 
 
36
 
37
  # 2. Lấy danh sách MODELS
 
38
  models_env = os.getenv("GEMINI_MODELS", "gemini-2.0-flash-exp,gemini-1.5-pro,gemini-1.5-flash")
39
+ DESKTOP_MODELS = [m.strip() for m in models_env.split(",") if m.strip()]
 
 
 
 
 
 
 
 
 
40
 
41
+ # Model dữ liệu nhận từ Desktop App
42
+ class DesktopGenerateRequest(BaseModel):
43
+ prompt: str
44
+ model: Optional[str] = "gemini-1.5-flash"
45
+ image: Optional[str] = None # Base64 string
46
 
47
+ @app.get("/")
48
+ async def root():
49
+ return {
50
+ "status": "online",
51
+ "server": "HT MATH UNIFIED SERVER",
52
+ "desktop_keys_loaded": len(DESKTOP_API_KEYS),
53
+ "web_support": "Active"
54
+ }
55
+
56
+ # --- API 1: Lấy danh sách Model (Cho Desktop App) ---
57
+ @app.get("/api/models")
58
+ async def get_models_desktop():
59
+ return {"models": DESKTOP_MODELS}
60
+
61
+ # --- API 2: Xử lý AI (Cho Desktop App - Có xoay vòng Key) ---
62
+ @app.post("/api/generate")
63
+ async def generate_content_desktop(req: DesktopGenerateRequest):
64
+ if not DESKTOP_API_KEYS:
65
+ raise HTTPException(status_code=500, detail="Server chưa cấu hình GEMINI_API_KEYS")
66
 
67
  try:
68
+ # 1. Chọn ngẫu nhiên 1 Key (Load Balancing)
69
+ current_key = random.choice(DESKTOP_API_KEYS)
 
 
 
 
 
 
 
 
 
 
 
 
70
  genai.configure(api_key=current_key)
71
 
72
+ # 2. Chọn Model
73
+ # Nếu model client gửi lên không có trong danh sách hỗ trợ, dùng model mặc định
74
+ model_name = req.model if req.model in DESKTOP_MODELS else DESKTOP_MODELS[0]
 
 
75
  model = genai.GenerativeModel(model_name)
76
 
77
+ # 3. Chuẩn bị nội dung gửi đi
78
+ content_parts = [req.prompt]
79
+
80
+ # 4. Xử lý ảnh (nếu có)
81
+ if req.image:
82
  try:
83
+ # Desktop App gửi ảnh dạng Base64 string
84
+ image_bytes = base64.b64decode(req.image)
 
 
 
85
  image = Image.open(BytesIO(image_bytes))
86
  content_parts.append(image)
87
  except Exception as e:
88
+ raise HTTPException(status_code=400, detail=f"Lỗi xử lý ảnh base64: {str(e)}")
 
89
 
90
+ # 5. Gọi Google Gemini
91
  response = model.generate_content(content_parts)
92
 
93
  if response.text:
94
+ return {"result": response.text}
95
  else:
96
+ raise HTTPException(status_code=500, detail="Gemini không trả về nội dung text.")
97
 
98
  except Exception as e:
99
+ print(f"Lỗi Desktop API: {e}")
100
+ raise HTTPException(status_code=500, detail=str(e))
101
+
102
+
103
+ # ==============================================================================
104
+ # --- PHẦN 2: KHU VỰC CỦA WEB APP (COPY CODE CŨ VÀO DƯỚI ĐÂY) ---
105
+ # ==============================================================================
106
+
107
+ # Bạn hãy dán các hàm xử lý của Web App vào đây.
108
+ # Ví dụ: import supabase, các hàm convert_file, login, signup...
109
+ # Đảm bảo giữ nguyên logic cũ của Web App.
110
+
111
+ # Ví dụ mẫu (Nếu bạn dùng Supabase):
112
+ # from supabase import create_client, Client
113
+ # url: str = os.environ.get("SUPABASE_URL")
114
+ # key: str = os.environ.get("SUPABASE_KEY")
115
+ # supabase: Client = create_client(url, key)
116
+
117
+ # @app.post("/convert")
118
+ # async def convert_file(...):
119
+ # ... code cũ của bạn ...
120
 
121
+ if __name__ == "__main__":
122
+ import uvicorn
123
+ uvicorn.run(app, host="0.0.0.0", port=7860)