From 2a1409dd4a0d973976a0f290e60c7a7fe70e7e5e Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 9 Jun 2024 13:37:57 -0700 Subject: [PATCH] Add global df variable and have frontend home only start when backend is ready --- api/app.py | 34 +++++++++++--- api/requirements.txt | 5 ++- src/components/chatbot/chatbot.tsx | 4 +- src/pages/views/homeView.tsx | 72 +++++++++++++++++------------- 4 files changed, 75 insertions(+), 40 deletions(-) diff --git a/api/app.py b/api/app.py index cd6d6ba8..89741bd2 100644 --- a/api/app.py +++ b/api/app.py @@ -20,19 +20,23 @@ load_dotenv() app = Flask(__name__) +CORS(app, resources={r"/*": {"origins": "http://localhost:3000"}}) server_thread = None -CORS(app) # Permite todas as origens por padrão (não recomendado para produção) openai.api_key = os.getenv('OPEN_AI_KEY') log = logging.getLogger('werkzeug') log.disabled = True +selectedFile = None app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True data_processer = DataProcesser() + loop = asyncio.get_event_loop() +df = None + def run_flask_app(): app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=False) @@ -44,6 +48,22 @@ def shutdown_server(): def hello_world(): return jsonify("Hello, world!") + +@app.route('/receive', methods=['POST']) +def receive_file(): + global df + + if 'file' not in request.files: + return jsonify({'error': 'No file part'}), 400 + file = request.files['file'] + if file.filename == '': + return jsonify({'error': 'No selected file'}), 400 + if file: + df = pd.read_csv(file) + return jsonify({'message': 'File uploaded successfully'}), 200 + + + @app.route('/classify', methods=["POST"]) def upload_file(): received_data = request.get_json() @@ -184,8 +204,13 @@ def cancel_training(): except Exception as e: return jsonify({'error': str(e)}), 500 -@app.route('/api/chat', methods=['POST']) +@app.route('/chat', methods=['POST']) def chat(): + global df + if df is not None: + # run rag + print(df.head(1)) + else: data = request.get_json() user_message = data.get('message') chat_history = data.get('history', []) @@ -203,8 +228,7 @@ def chat(): max_tokens=200 ) bot_reply = response.choices[0].message.content.strip() - - print(bot_reply) + return jsonify(reply=bot_reply) except Exception as e: print(f"Error: {e}") @@ -218,4 +242,4 @@ def chat(): } with open('training_progress.json', 'w') as file: json.dump(training_progress, file) - app.run(host='0.0.0.0', port=5000, debug=False) \ No newline at end of file + app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file diff --git a/api/requirements.txt b/api/requirements.txt index 06510281..39164791 100644 --- a/api/requirements.txt +++ b/api/requirements.txt @@ -4,4 +4,7 @@ Flask-Cors==4.0.0 pandas==2.0.3 nltk==3.8.1 scikit-learn==1.3.0 -numpy==1.26.4 \ No newline at end of file +numpy==1.26.4 +python-dotenv==1.0.1 +openai==1.33.0 +flask_sse==1.0.0 \ No newline at end of file diff --git a/src/components/chatbot/chatbot.tsx b/src/components/chatbot/chatbot.tsx index 857d9a0c..b05ac811 100644 --- a/src/components/chatbot/chatbot.tsx +++ b/src/components/chatbot/chatbot.tsx @@ -28,9 +28,9 @@ const ChatBot: React.FC = () => { setChatHistory(prevHistory => [...prevHistory, newMessage]); try { - const response = await axios.post('http://localhost:5000/api/chat', { + const response = await axios.post('http://localhost:5000/chat', { message, - history: [...chatHistory, newMessage] // Enviar o histórico completo + history: [...chatHistory, newMessage] }); const botResponse: Message = { text: response.data.reply, origin: 'bot' }; diff --git a/src/pages/views/homeView.tsx b/src/pages/views/homeView.tsx index f14fa2c6..4876eefb 100644 --- a/src/pages/views/homeView.tsx +++ b/src/pages/views/homeView.tsx @@ -12,15 +12,15 @@ export default function HomeView() { const [classifiers, setClassifiers] = useState<{ [key: string]: string }>({}); const [result, setResult] = useState<{ [key: string]: any }>({}); const [isLoading, setIsLoading] = useState(false); + const [isBackendAvailable, setIsBackendAvailable] = useState(false); useEffect(() => { const fetchClassifiers = async () => { while (true) { try { - const response = await axios.get( - "http://localhost:5000/get-classifiers" - ); + const response = await axios.get("http://localhost:5000/get-classifiers"); setClassifiers(response.data); + setIsBackendAvailable(true); break; } catch (error) { console.error("Error fetching classifiers, retrying...", error); @@ -32,6 +32,27 @@ export default function HomeView() { fetchClassifiers(); }, []); + useEffect(() => { + const sendSelectedFileToBackend = async () => { + if (selectedFile) { + const formData = new FormData(); + formData.append("file", selectedFile); + + try { + await axios.post("http://localhost:5000/receive", formData, { + headers: { + "Content-Type": "multipart/form-data", + }, + }); + } catch (error) { + console.error("Error uploading file", error); + } + } + }; + + sendSelectedFileToBackend(); + }, [selectedFile]); + const handleChangeSelectedColumn = (event: React.ChangeEvent) => { setSelectedColumn(Number(event.target.value)); }; @@ -43,14 +64,12 @@ export default function HomeView() { const handleSubmit = async () => { setIsLoading(true); let selectedData = data.map((row) => row[selectedColumn]); - const response = await axios - .post("http://localhost:5000/classify", { - data: selectedData, - classifier: selectedClassifier, - }) - .catch((error) => { - console.error(error.response.data); - }); + const response = await axios.post("http://localhost:5000/classify", { + data: selectedData, + classifier: selectedClassifier, + }).catch((error) => { + console.error(error.response.data); + }); if (response && response.data) { const parsedData = JSON.parse(response.data.result); @@ -66,7 +85,7 @@ export default function HomeView() { console.log(result); setResult(result); } else { - console.error("Os arrays 'input' e 'output' tem tamanhos diferentes."); + console.error("Os arrays 'input' e 'output' têm tamanhos diferentes."); } } @@ -75,14 +94,9 @@ export default function HomeView() { const handleDownloadOutputCSV = async () => { const finalHeader = header.concat(`${selectedClassifier}_output`); - const finalData = data.map((row) => - row.concat(result[row[selectedColumn]]) - ); + const finalData = data.map((row) => row.concat(result[row[selectedColumn]])); - const csv = finalHeader - .join(",") - .concat("\n") - .concat(finalData.map((row) => row.join(",")).join("\n")); + const csv = finalHeader.join(",").concat("\n").concat(finalData.map((row) => row.join(",")).join("\n")); const csvFile = new Blob([csv], { type: "text/csv" }); const csvURL = window.URL.createObjectURL(csvFile); @@ -92,8 +106,12 @@ export default function HomeView() { tempLink.click(); }; + if (!isBackendAvailable) { + return
Carregando backend...
; + } + return ( -
+
- {header.length > 0 && @@ -137,12 +150,7 @@ export default function HomeView() { className="w-full border-2 border-gray-500 rounded-xl py-2 px-4 hover:bg-gray-100 focus:outline-none h-14" onChange={handleChangeSelectedClassifier} > - {Object.entries(classifiers).map(([value, label]) => (