Atualizar app/app.py
This commit is contained in:
+166
@@ -1,3 +1,169 @@
|
||||
import os
|
||||
import json
|
||||
import requests
|
||||
from functools import wraps
|
||||
|
||||
from flask import Flask, request, jsonify, redirect, session, url_for
|
||||
from authlib.integrations.flask_client import OAuth
|
||||
|
||||
from config import Config
|
||||
|
||||
# All comments are in English.
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(Config)
|
||||
|
||||
# Configure session secret key.
|
||||
app.secret_key = app.config["SECRET_KEY"]
|
||||
|
||||
# Configure OAuth with Google.
|
||||
oauth = OAuth(app)
|
||||
google = oauth.register(
|
||||
name="google",
|
||||
client_id=app.config["GOOGLE_CLIENT_ID"],
|
||||
client_secret=app.config["GOOGLE_CLIENT_SECRET"],
|
||||
access_token_url="https://oauth2.googleapis.com/token",
|
||||
access_token_params=None,
|
||||
authorize_url="https://accounts.google.com/o/oauth2/v2/auth",
|
||||
authorize_params={
|
||||
"access_type": "offline",
|
||||
"prompt": "consent",
|
||||
},
|
||||
api_base_url="https://www.googleapis.com/oauth2/v2/",
|
||||
client_kwargs={"scope": "openid email profile"},
|
||||
)
|
||||
|
||||
|
||||
def login_required(f):
|
||||
"""Decorator to ensure the user is authenticated via Google OAuth."""
|
||||
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
# Check if user info is stored in session.
|
||||
if "user" not in session:
|
||||
# Redirect to login if not authenticated.
|
||||
return redirect(url_for("login"))
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@app.route("/login")
|
||||
def login():
|
||||
"""Start Google OAuth login flow."""
|
||||
redirect_uri = app.config["GOOGLE_REDIRECT_URI"]
|
||||
# Use the configured redirect URI for OAuth callback.
|
||||
return google.authorize_redirect(redirect_uri)
|
||||
|
||||
|
||||
@app.route("/oauth/callback")
|
||||
def oauth_callback():
|
||||
"""Handle Google OAuth callback and store user session."""
|
||||
# Exchange authorization code for tokens.
|
||||
token = google.authorize_access_token()
|
||||
# Fetch user info from Google.
|
||||
resp = google.get("userinfo")
|
||||
user_info = resp.json()
|
||||
|
||||
# Store minimal user info in session.
|
||||
session["user"] = {
|
||||
"email": user_info.get("email"),
|
||||
"name": user_info.get("name"),
|
||||
}
|
||||
|
||||
# Redirect to a simple home or API docs page.
|
||||
return redirect(url_for("home"))
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def home():
|
||||
"""Simple home endpoint explaining the service."""
|
||||
# This endpoint is intentionally simple and easy to understand.
|
||||
return jsonify(
|
||||
{
|
||||
"message": "Ollama Gateway is running.",
|
||||
"auth": "Google OAuth required for /api/* endpoints.",
|
||||
"endpoints": {
|
||||
"health": "/health",
|
||||
"generate": "/api/generate",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@app.route("/health")
|
||||
def health():
|
||||
"""Health check endpoint."""
|
||||
return jsonify({"status": "ok"})
|
||||
|
||||
|
||||
@app.route("/api/generate", methods=["POST"])
|
||||
@login_required
|
||||
def generate():
|
||||
"""Generate text using a selected Ollama model.
|
||||
|
||||
Expected JSON body:
|
||||
{
|
||||
"model": "llama3.2",
|
||||
"prompt": "Your prompt here"
|
||||
}
|
||||
"""
|
||||
data = request.get_json(silent=True) or {}
|
||||
|
||||
# Extract model and prompt from request.
|
||||
model_name = data.get("model", "llama3.2")
|
||||
prompt = data.get("prompt")
|
||||
|
||||
if not prompt:
|
||||
return jsonify({"error": "Missing 'prompt' field."}), 400
|
||||
|
||||
# Map user-facing model name to Ollama model identifier.
|
||||
model_id = app.config["MODEL_MAP"].get(model_name)
|
||||
if not model_id:
|
||||
return jsonify({"error": f"Unsupported model '{model_name}'."}), 400
|
||||
|
||||
# Prepare request to Ollama API.
|
||||
ollama_url = f"{app.config['OLLAMA_BASE_URL']}/api/generate"
|
||||
payload = {
|
||||
"model": model_id,
|
||||
"prompt": prompt,
|
||||
# You can add more Ollama-specific parameters here if needed.
|
||||
}
|
||||
|
||||
try:
|
||||
# Call Ollama HTTP API.
|
||||
response = requests.post(ollama_url, json=payload, timeout=60)
|
||||
response.raise_for_status()
|
||||
except requests.RequestException as e:
|
||||
# Handle network or API errors gracefully.
|
||||
return jsonify({"error": "Failed to call Ollama API.", "details": str(e)}), 502
|
||||
|
||||
# Parse Ollama response.
|
||||
try:
|
||||
ollama_data = response.json()
|
||||
except json.JSONDecodeError:
|
||||
return jsonify({"error": "Invalid JSON response from Ollama."}), 502
|
||||
|
||||
# Extract output text (this depends on Ollama's response format).
|
||||
output_text = ollama_data.get("response") or ollama_data.get("output") or ""
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
"model": model_name,
|
||||
"output": output_text,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# This block is mainly for local debugging.
|
||||
# In production, Gunicorn will run the app.
|
||||
app.run(host="0.0.0.0", port=8000)
|
||||
|
||||
|
||||
# ***
|
||||
|
||||
|
||||
from flask import Flask, request, jsonify
|
||||
from flask_cors import CORS
|
||||
from db import Base, engine
|
||||
|
||||
Reference in New Issue
Block a user