import gradio as gr import requests import pandas as pd from transformers import pipeline import torch import time import threading import os from datetime import datetime, timezone from huggingface_hub import HfApi import plotly.graph_objects as go # --- KONFIGŪRACIJA --- MODEL_NAME = "ProsusAI/finbert" TARGET_DATASET = "Vycka12/Base" HF_TOKEN = os.environ.get("HF_TOKEN") # API Raktas ir URL (Griežtai nustatyti) CRYPTOPANIC_API_KEY = "6c0f988f9e33170ccd183c6a14b34e8c2ad0867f" CRYPTOPANIC_URL = "https://cryptopanic.com/api/developer/v2/posts/" # Globalūs kintamieji news_buffer = [] stats = {"bullish": 0, "bearish": 0, "neutral": 0, "overall": "Inicijuojama...", "status": "Startuoja..."} # Krauname AI print("⌛ Kraunamas AI modelis...") try: sentiment_pipeline = pipeline("sentiment-analysis", model=MODEL_NAME) print("✅ AI paruoštas.") except Exception as e: print(f"❌ AI ERROR: {e}") sentiment_pipeline = None class SentimentSystem: def __init__(self): self.api = HfApi(token=HF_TOKEN) def fetch_and_analyze(self): global news_buffer, stats stats["status"] = "Gaunamos naujienos..." # Pataisyti parametrai - tik būtiniausi params = { "auth_token": CRYPTOPANIC_API_KEY, "kind": "news" } try: resp = requests.get(CRYPTOPANIC_URL, params=params, timeout=20) if resp.status_code == 200: data = resp.json() raw_news = data.get("results", []) if not raw_news: stats["status"] = "⚠️ API grąžino tuščią sąrašą." return temp_news = [] pos, neg, neut = 0, 0, 0 for item in raw_news: title = item.get("title", "") if not title: continue # AI Analizė if sentiment_pipeline: result = sentiment_pipeline(title[:512])[0] label = result['label'] score = result['score'] else: label, score = 'neutral', 0.5 # Emocijos if label == 'positive': status, emo = "🟢 BULLISH", "🚀" pos += 1 elif label == 'negative': status, emo = "🔴 BEARISH", "📉" neg += 1 else: status, emo = "⚪ NEUTRAL", "➖" neut += 1 # Laikas pub_time = item.get("published_at", "")[:16].replace("T", " ") temp_news.append([emo, status, title, f"{round(score*100)}%", pub_time]) stats["bullish"] = pos stats["bearish"] = neg stats["neutral"] = neut total = pos + neg + neut if total > 0: ratio = (pos - neg) / total if ratio > 0.2: stats["overall"] = "OPTIMIZMAS 📈" elif ratio < -0.2: stats["overall"] = "BAIMĖ 📉" else: stats["overall"] = "NEUTRALU ⚖️" news_buffer = temp_news stats["status"] = f"Atnaujinta: {datetime.now().strftime('%H:%M:%S')}" else: stats["status"] = f"❌ API Klaida: {resp.status_code}" except Exception as e: stats["status"] = f"❌ Klaida: {str(e)}" def create_gauge(self): total = stats["bullish"] + stats["bearish"] + stats["neutral"] val = 50 if total > 0: # Formulė: 50 + (teigiami - neigiami) * koeficientas # Jei visi teigiami -> 100, visi neigiami -> 0 net_sentiment = (stats["bullish"] - stats["bearish"]) / total val = 50 + (net_sentiment * 50) fig = go.Figure(go.Indicator( mode = "gauge+number", value = val, title = {'text': f"Rinkos Emocija: {stats['overall']}"}, gauge = { 'axis': {'range': [0, 100]}, 'bar': {'color': "black"}, 'steps': [ {'range': [0, 40], 'color': "#ff4b4b"}, {'range': [40, 60], 'color': "#ffffb2"}, {'range': [60, 100], 'color': "#00cc96"} ], } )) fig.update_layout(height=300, margin=dict(l=20, r=20, t=50, b=20)) return fig sys_analyzer = SentimentSystem() def update_loop(): # Pirmas paleidimas po 10 sek time.sleep(10) sys_analyzer.fetch_and_analyze() while True: # Atnaujiname kas 4 valandas (taupome limitą) time.sleep(14400) sys_analyzer.fetch_and_analyze() def get_ui_data(): gauge = sys_analyzer.create_gauge() cols = ["Emoji", "Verdiktas", "Antraštė", "Pasitikėjimas", "Laikas"] if not news_buffer: df = pd.DataFrame([["-", "-", "Kraunama...", "-", "-"]], columns=cols) else: df = pd.DataFrame(news_buffer, columns=cols) status_text = f"### 📊 Statistika\n**Būsena:** {stats['status']}\n**Geros:** {stats['bullish']} | **Blogos:** {stats['bearish']} | **Viso:** {stats['bullish']+stats['bearish']+stats['neutral']}" return gauge, df, status_text # --- GRADIO UI --- with gr.Blocks(title="Sentiment AI", theme=gr.themes.Soft()) as demo: gr.Markdown("# 🧠 Sentiment AI Analyzer") gr.Markdown("Analizuoja realias crypto naujienas naudodamas ProsusAI FinBERT modelį.") with gr.Row(): with gr.Column(): gauge_output = gr.Plot(label="Nuotaika") with gr.Column(): status_output = gr.Markdown("Laukiama duomenų...") refresh_btn = gr.Button("🔄 Atnaujinti Dabar", variant="primary") gr.Markdown("### 📰 Naujienų srautas ir AI vertinimas") table_output = gr.Dataframe(interactive=False) # Eventai refresh_btn.click(fn=sys_analyzer.fetch_and_analyze).then( fn=get_ui_data, outputs=[gauge_output, table_output, status_output] ) # Auto-start threading.Thread(target=update_loop, daemon=True).start() # UI atnaujinimas (tik vaizdo, ne duomenų siurbimo) demo.load(get_ui_data, outputs=[gauge_output, table_output, status_output]) gr.Timer(5).tick(get_ui_data, outputs=[gauge_output, table_output, status_output]) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)