|
|
"""
|
|
|
Idea House Blueprint - Flask Blueprint for analyzing data fields using Coze API
|
|
|
"""
|
|
|
|
|
|
from flask import Blueprint, render_template, request, jsonify, session as flask_session
|
|
|
import os
|
|
|
import sys
|
|
|
from cozepy import Coze, TokenAuth, Message, ChatStatus, MessageContentType
|
|
|
from cozepy import COZE_CN_BASE_URL
|
|
|
import json
|
|
|
|
|
|
# Create blueprint
|
|
|
idea_house_bp = Blueprint('idea_house', __name__, url_prefix='/idea-house')
|
|
|
|
|
|
@idea_house_bp.route('/')
|
|
|
def idea_house():
|
|
|
"""Idea house page"""
|
|
|
return render_template('idea_house.html')
|
|
|
|
|
|
@idea_house_bp.route('/api/process-fields', methods=['POST'])
|
|
|
def process_fields():
|
|
|
"""Process selected data fields using Coze API"""
|
|
|
try:
|
|
|
# Get the selected fields from request
|
|
|
data = request.get_json()
|
|
|
selected_fields = data.get('selected_fields', {})
|
|
|
coze_api_token = data.get('coze_api_token')
|
|
|
workflow_id = data.get('workflow_id')
|
|
|
dataset_description = data.get('dataset_description', '')
|
|
|
|
|
|
print("=" * 60)
|
|
|
print("🚀 COZE API REQUEST INITIATED")
|
|
|
print("=" * 60)
|
|
|
print(f"📋 Selected Fields Count: {len(selected_fields)}")
|
|
|
print(f"🔑 API Token (last 10 chars): ...{coze_api_token[-10:] if coze_api_token else 'None'}")
|
|
|
print(f"⚙️ Workflow ID: {workflow_id}")
|
|
|
print("=" * 60)
|
|
|
|
|
|
if not selected_fields:
|
|
|
print("❌ ERROR: No fields selected")
|
|
|
return jsonify({'error': 'No fields selected'}), 400
|
|
|
|
|
|
if not coze_api_token:
|
|
|
print("❌ ERROR: Coze API token is required")
|
|
|
return jsonify({'error': 'Coze API token is required'}), 400
|
|
|
|
|
|
if not workflow_id:
|
|
|
print("❌ ERROR: Workflow ID is required")
|
|
|
return jsonify({'error': 'Workflow ID is required'}), 400
|
|
|
|
|
|
# Prepare the input string from selected fields
|
|
|
# Format: "field_id (description, unit)"
|
|
|
input_lines = []
|
|
|
for field_id, description in selected_fields.items():
|
|
|
input_lines.append(f"{field_id} ({description})")
|
|
|
|
|
|
input_string = "\n".join(input_lines)
|
|
|
|
|
|
# Append dataset description if available
|
|
|
if dataset_description:
|
|
|
input_string = f"Dataset Description: {dataset_description}\n\nSelected Fields:\n{input_string}"
|
|
|
|
|
|
print("📤 PREPARING COZE API REQUEST:")
|
|
|
print(f" Input String: {input_string[:100]}..." if len(input_string) > 100 else f" Input String: {input_string}")
|
|
|
|
|
|
# Setup Coze API
|
|
|
coze_api_base = COZE_CN_BASE_URL
|
|
|
print(f"🌐 Using Coze API Base URL: {coze_api_base}")
|
|
|
|
|
|
# Initialize Coze client
|
|
|
print("🔧 Initializing Coze client...")
|
|
|
coze = Coze(auth=TokenAuth(token=coze_api_token), base_url=coze_api_base)
|
|
|
|
|
|
# Prepare parameters
|
|
|
parameters = {
|
|
|
"input": input_string
|
|
|
}
|
|
|
|
|
|
print("📊 Request Parameters:")
|
|
|
print(f" {json.dumps(parameters, indent=2)}")
|
|
|
|
|
|
# Call the workflow with retries
|
|
|
workflow_result = None
|
|
|
error_message = None
|
|
|
|
|
|
print("🔄 Starting workflow execution with retries...")
|
|
|
for attempt in range(3):
|
|
|
try:
|
|
|
print(f" Attempt {attempt + 1}/3: Calling Coze workflow...")
|
|
|
workflow = coze.workflows.runs.create(
|
|
|
workflow_id=workflow_id,
|
|
|
parameters=parameters
|
|
|
)
|
|
|
workflow_result = workflow
|
|
|
print(f" ✅ Attempt {attempt + 1} succeeded!")
|
|
|
print(f" 📥 Workflow Response Type: {type(workflow_result)}")
|
|
|
if hasattr(workflow_result, 'data'):
|
|
|
print(f" 📥 Response Data Length: {len(str(workflow_result.data)) if workflow_result.data else 0}")
|
|
|
break
|
|
|
except Exception as e:
|
|
|
error_message = f"Attempt {attempt + 1} failed with error: {str(e)}"
|
|
|
print(f" ❌ {error_message}")
|
|
|
continue
|
|
|
|
|
|
if workflow_result is None:
|
|
|
print("💥 WORKFLOW EXECUTION FAILED AFTER ALL RETRIES")
|
|
|
print(f" Last Error: {error_message}")
|
|
|
return jsonify({
|
|
|
'error': 'Failed to run workflow after 3 attempts',
|
|
|
'details': error_message
|
|
|
}), 500
|
|
|
|
|
|
print("✅ WORKFLOW EXECUTION SUCCESSFUL")
|
|
|
print("🔍 Processing workflow result...")
|
|
|
|
|
|
# Process the result
|
|
|
try:
|
|
|
# Try to extract output from workflow data
|
|
|
if hasattr(workflow_result, 'data') and workflow_result.data:
|
|
|
print(" 📊 Workflow data found, processing...")
|
|
|
# Try to evaluate the data if it's a string
|
|
|
try:
|
|
|
result_data = eval(workflow_result.data) if isinstance(workflow_result.data, str) else workflow_result.data
|
|
|
output = result_data.get('output', '')
|
|
|
print(f" 📄 Extracted output length: {len(str(output))}")
|
|
|
except:
|
|
|
# If eval fails, use the data as is
|
|
|
output = str(workflow_result.data)
|
|
|
print(f" 📄 Using raw data as output (length: {len(output)})")
|
|
|
else:
|
|
|
output = "No data returned from the workflow"
|
|
|
print(" ⚠️ No data returned from workflow")
|
|
|
|
|
|
print("=" * 60)
|
|
|
print("🎉 COZE API REQUEST COMPLETED SUCCESSFULLY")
|
|
|
print(f"📊 Final Output Preview: {str(output)[:150]}..." if len(str(output)) > 150 else f"📊 Final Output: {str(output)}")
|
|
|
print("=" * 60)
|
|
|
|
|
|
return jsonify({
|
|
|
'success': True,
|
|
|
'output': output,
|
|
|
'parameters': parameters,
|
|
|
'selected_fields': selected_fields
|
|
|
})
|
|
|
|
|
|
except Exception as parse_error:
|
|
|
print(f"💥 ERROR PARSING WORKFLOW RESULT: {str(parse_error)}")
|
|
|
print(f" Raw workflow.data: {workflow_result.data if hasattr(workflow_result, 'data') else 'No data attribute'}")
|
|
|
|
|
|
return jsonify({
|
|
|
'error': 'Error parsing workflow result',
|
|
|
'details': str(parse_error),
|
|
|
'raw_data': str(workflow_result.data) if hasattr(workflow_result, 'data') else None
|
|
|
}), 500
|
|
|
|
|
|
except Exception as e:
|
|
|
print(f"💥 PROCESS FIELDS ERROR: {str(e)}")
|
|
|
print("=" * 60)
|
|
|
return jsonify({'error': str(e)}), 500
|
|
|
|
|
|
@idea_house_bp.route('/api/get-datafields-proxy', methods=['GET'])
|
|
|
def get_datafields_proxy():
|
|
|
"""Proxy endpoint to get data fields from main app's BRAIN API endpoint"""
|
|
|
try:
|
|
|
from flask import current_app
|
|
|
|
|
|
# Use the test client to make an internal request
|
|
|
with current_app.test_client() as client:
|
|
|
# Copy headers from the original request
|
|
|
headers = {
|
|
|
'Session-ID': request.headers.get('Session-ID') or flask_session.get('brain_session_id')
|
|
|
}
|
|
|
|
|
|
# Copy query parameters
|
|
|
params = request.args.to_dict()
|
|
|
|
|
|
# Make internal request to the main app's datafields endpoint
|
|
|
response = client.get('/api/datafields', headers=headers, query_string=params)
|
|
|
|
|
|
# Return the response data and status
|
|
|
return response.get_json(), response.status_code
|
|
|
|
|
|
except Exception as e:
|
|
|
print(f"Datafields proxy error: {str(e)}")
|
|
|
return jsonify({'error': str(e)}), 500
|
|
|
|
|
|
@idea_house_bp.route('/api/get-dataset-description', methods=['GET'])
|
|
|
def get_dataset_description():
|
|
|
"""Proxy endpoint to get dataset description from main app's BRAIN API endpoint"""
|
|
|
print("\n" + "="*60)
|
|
|
print("🔍 DATASET DESCRIPTION PROXY ENDPOINT CALLED")
|
|
|
print("="*60)
|
|
|
|
|
|
try:
|
|
|
from flask import current_app
|
|
|
|
|
|
# Use the test client to make an internal request
|
|
|
with current_app.test_client() as client:
|
|
|
# Copy headers from the original request
|
|
|
headers = {
|
|
|
'Session-ID': request.headers.get('Session-ID') or flask_session.get('brain_session_id')
|
|
|
}
|
|
|
|
|
|
# Copy query parameters
|
|
|
params = request.args.to_dict()
|
|
|
|
|
|
print(f"📊 Proxying request with params: {params}")
|
|
|
print(f"📌 Session ID: {headers.get('Session-ID')}")
|
|
|
|
|
|
# Make internal request to the main app's dataset description endpoint
|
|
|
response = client.get('/api/dataset-description', headers=headers, query_string=params)
|
|
|
|
|
|
print(f"📥 Proxy response status: {response.status_code}")
|
|
|
|
|
|
# Return the response data and status
|
|
|
return response.get_json(), response.status_code
|
|
|
|
|
|
except Exception as e:
|
|
|
print(f"💥 Dataset description proxy error: {str(e)}")
|
|
|
print("="*60 + "\n")
|
|
|
return jsonify({'error': str(e)}), 500 |