Spaces:
Sleeping
Sleeping
import os | |
import logging | |
from logging.handlers import RotatingFileHandler | |
# Set up logging to console | |
console_handler = logging.StreamHandler() | |
console_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') | |
console_handler.setFormatter(console_formatter) | |
console_handler.setLevel(logging.DEBUG) | |
logging.getLogger().addHandler(console_handler) | |
logging.getLogger().setLevel(logging.DEBUG) | |
from flask import Flask, request, jsonify | |
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity | |
from flask_cors import CORS | |
from dotenv import load_dotenv | |
import openai | |
import yaml | |
import pandas as pd | |
import router_logic | |
load_dotenv() | |
app = Flask(__name__) | |
CORS(app) | |
# Load tool data once when the app starts | |
csv_path = os.path.join(os.path.dirname(__file__), 'ai_tools.csv') | |
print(f"[STARTUP DEBUG] Attempting to load tools from: {csv_path}") | |
logging.getLogger().info(f"[STARTUP DEBUG] Attempting to load tools from: {csv_path}") | |
TOOL_DATA_DF = router_logic.load_tool_data(csv_path) | |
tool_count = len(TOOL_DATA_DF) | |
print(f"[STARTUP DEBUG] Loaded {tool_count} tools from ai_tools.csv.") | |
logging.getLogger().info(f"[STARTUP DEBUG] Loaded {tool_count} tools from ai_tools.csv.") | |
print(f"[STARTUP DEBUG] DataFrame columns: {TOOL_DATA_DF.columns.tolist()}") | |
logging.getLogger().info(f"[STARTUP DEBUG] DataFrame columns: {TOOL_DATA_DF.columns.tolist()}") | |
print(f"[STARTUP DEBUG] Unique MediaType values: {TOOL_DATA_DF['MediaType'].unique()}") | |
logging.getLogger().info(f"[STARTUP DEBUG] Unique MediaType values: {TOOL_DATA_DF['MediaType'].unique()}") | |
if tool_count == 0: | |
print("[STARTUP DEBUG] No tools loaded from ai_tools.csv! File may be missing or unreadable.") | |
logging.getLogger().warning("[STARTUP DEBUG] No tools loaded from ai_tools.csv! File may be missing or unreadable.") | |
app.config['JWT_SECRET_KEY'] = os.environ.get('JWT_SECRET', 'supersecret') | |
jwt = JWTManager(app) | |
openai.api_key = os.environ.get('OPENAI_API_KEY') | |
# In-memory user store (replace with DB for production) | |
USERS = { 'demo': { 'password': 'demo', 'prompts': [] } } | |
def index(): | |
return "Welcome to the Promptified Backend API" | |
def login(): | |
data = request.json | |
username = data.get('username') | |
password = data.get('password') | |
if not username or not password: | |
return jsonify({'error': 'Missing username or password'}), 400 | |
user = USERS.get(username) | |
if not user or user['password'] != password: | |
return jsonify({'error': 'Invalid credentials'}), 401 | |
token = create_access_token(identity=username) | |
return jsonify({'token': token}) | |
def improve_prompt(): | |
data = request.json | |
prompt = data.get('prompt') | |
mode = data.get('mode', 'mode') | |
verbosity = data.get('verbosity', 'concise') | |
if not prompt: | |
return jsonify({'error': 'Missing prompt'}), 400 | |
# Load system prompts from YAML config | |
config_path = os.path.join(os.path.dirname(__file__), 'system_prompts.yaml') | |
try: | |
with open(config_path, 'r', encoding='utf-8') as f: | |
system_prompts = yaml.safe_load(f) | |
app.logger.info(f"[PROMPT IMPROVEMENT] Loaded system prompts: {system_prompts}") | |
except Exception as e: | |
app.logger.error(f"[PROMPT IMPROVEMENT] Error loading system prompts: {str(e)}") | |
system_prompts = {} | |
# Default system prompt (fallback) | |
default_system_prompt = ( | |
"You are an expert at refining prompts for creative AI (image, video, music). " | |
"Given a user prompt and selected mode (e.g., photography, digital art), rewrite the prompt for maximum clarity and creative potential. " | |
"Also, provide a breakdown of what you changed and what could be added for improvement (e.g., camera settings, lighting, subject details)." | |
) | |
# Use mode-specific system prompt if available | |
mode_key = mode.lower() | |
system_prompt = system_prompts.get(mode_key, default_system_prompt) | |
app.logger.info(f"[PROMPT IMPROVEMENT] Using mode: {mode_key}") | |
app.logger.info(f"[PROMPT IMPROVEMENT] System prompt: {system_prompt}") | |
user_content = f"Prompt: {prompt}\nMode: {mode}\nVerbosity: {verbosity}" | |
try: | |
response = openai.chat.completions.create( | |
model="gpt-4.1", | |
messages=[ | |
{"role": "system", "content": system_prompt}, | |
{"role": "user", "content": user_content} | |
], | |
max_tokens=400 | |
) | |
content = response.choices[0].message.content | |
parts = content.split("Improvement Notes:") | |
improved_prompt = parts[0].replace("Improved Prompt:", "").strip() | |
notes = parts[1].strip() if len(parts) > 1 else "" | |
return jsonify({'improvedPrompt': improved_prompt, 'notes': notes}) | |
except Exception as e: | |
return jsonify({'error': str(e)}), 500 | |
def save_prompt(): | |
username = get_jwt_identity() | |
data = request.json | |
prompt = data.get('prompt') | |
if not prompt: | |
return jsonify({'error': 'Missing prompt'}), 400 | |
USERS[username]['prompts'].append(prompt) | |
return jsonify({'success': True}) | |
def get_prompts(): | |
username = get_jwt_identity() | |
prompts = USERS[username]['prompts'] | |
return jsonify({'prompts': prompts}) | |
import logging | |
from logging.handlers import RotatingFileHandler | |
# Set up logging to app.log | |
log_handler = RotatingFileHandler('/tmp/app.log', maxBytes=1024000, backupCount=3) | |
log_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') | |
log_handler.setFormatter(log_formatter) | |
log_handler.setLevel(logging.DEBUG) | |
app.logger.addHandler(log_handler) | |
app.logger.setLevel(logging.DEBUG) | |
#@wt_required() # Remove this decorator if you want the endpoint public | |
def handle_routing_request(): | |
if TOOL_DATA_DF is None: | |
app.logger.error("Tool data not loaded on server") | |
return jsonify({"error": "Tool data not loaded on server"}), 500 | |
import traceback | |
data = request.get_json() | |
app.logger.info(f"[ROUTER DEBUG] Incoming data: {data}") | |
if not data or 'prompt' not in data or 'media_type' not in data: | |
app.logger.warning("[ROUTER DEBUG] Missing prompt or media_type in request body") | |
return jsonify({"error": "Missing 'prompt' or 'media_type' in request body"}), 400 | |
prompt = data.get('prompt') | |
media_type = data.get('media_type') | |
criteria = data.get('criteria', None) # e.g., {"Cost": "Free", "IsOpenSource": True} | |
user_id = data.get('user_id', None) | |
try: | |
app.logger.info(f"[ROUTER DEBUG] prompt={prompt}, media_type={media_type}, criteria={criteria}, user_id={user_id}") | |
selected_tool_details, debug_info = router_logic.universal_router_agent( | |
prompt=prompt, | |
tool_data_df=TOOL_DATA_DF, | |
user_criteria=criteria, | |
media_type=media_type, | |
user_id=user_id, | |
debug=True | |
) | |
app.logger.info(f"[ROUTER DEBUG] Filtered tools: {debug_info.get('filtered_tools')}") | |
app.logger.info(f"[ROUTER DEBUG] Selected tool details: {selected_tool_details}") | |
if selected_tool_details: | |
return jsonify({"selected_tool": selected_tool_details}), 200 | |
else: | |
app.logger.warning("[ROUTER DEBUG] Could not determine a suitable tool") | |
return jsonify({"error": "Could not determine a suitable tool", "debug": debug_info}), 404 | |
except Exception as e: | |
tb_str = traceback.format_exc() | |
app.logger.error(f"[ROUTER ERROR] Exception during routing: {e}\n{tb_str}") | |
# Return the error message in the response for debugging (remove in production) | |
return jsonify({"error": "Internal server error during routing", "details": str(e), "traceback": tb_str}), 500 | |
if __name__ == "__main__": | |
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 7860)), debug=True) | |