File size: 4,424 Bytes
b729f12
e5b1901
adfc68f
3931752
1eee1c0
5fca79f
9c191f5
a4a8598
 
e00b7f3
 
1eee1c0
e00b7f3
 
 
9c191f5
b09fe29
ff767c9
b09fe29
 
3931752
b09fe29
 
 
 
 
 
 
e5b1901
5fca79f
 
 
e5b1901
5fca79f
 
e5b1901
5fca79f
 
 
b729f12
5fca79f
 
 
 
 
e5b1901
5fca79f
 
 
e5b1901
 
 
 
5fca79f
 
 
 
 
 
 
 
b729f12
5fca79f
 
b729f12
 
 
 
 
 
 
 
 
5fca79f
 
 
 
 
b729f12
5fca79f
 
b729f12
 
 
 
 
 
 
 
e5b1901
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import os

os.environ["HF_HOME"] = "/tmp/huggingface"
os.environ["MPLCONFIGDIR"] = "/tmp/mplconfig"
os.environ["HF_HOME"] = "/tmp"

os.makedirs("/tmp/huggingface", exist_ok=True)
os.makedirs("/tmp/mplconfig", exist_ok=True)

from transformers import AutoTokenizer, AutoModelForTokenClassification

os.environ["HF_HOME"] = "/tmp"
# Load the NER model
tokenizer = AutoTokenizer.from_pretrained("dslim/bert-base-NER")
model = AutoModelForTokenClassification.from_pretrained("dslim/bert-base-NER")



from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import pipeline
from fastapi.responses import StreamingResponse
import matplotlib.pyplot as plt
import requests
import datetime
from io import BytesIO
import logging

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Create FastAPI app
app = FastAPI()

# Load transformers models
try:
    ner_model = pipeline("ner", model="dslim/bert-base-NER", aggregation_strategy="simple")
    sentiment_model = pipeline("sentiment-analysis", model="ProsusAI/finbert")
    logger.info("Models loaded successfully.")
except Exception as e:
    logger.error(f"Model loading failed: {e}")
    ner_model = None
    sentiment_model = None

# Request body schema for sentiment and NER
class TextRequest(BaseModel):
    text: str

# Request body schema for chart
class CoinRequest(BaseModel):
    coin_id: str

@app.get("/")
def home():
    return {"message": "Crypto News API is alive!"}

@app.post("/sentiment")
def analyze_sentiment(req: TextRequest):
    if not sentiment_model:
        raise HTTPException(status_code=503, detail="Sentiment model not available")
    text = req.text.strip()
    if not text:
        raise HTTPException(status_code=400, detail="Text cannot be empty")
    try:
        result = sentiment_model(text[:512])[0]
        return {
            "label": result["label"],
            "score": round(result["score"] * 100, 2)
        }
    except Exception as e:
        logger.error(f"Sentiment analysis error: {e}")
        raise HTTPException(status_code=500, detail="Sentiment analysis failed")

@app.post("/ner")
def analyze_ner(req: TextRequest):
    if not ner_model:
        raise HTTPException(status_code=503, detail="NER model not available")
    text = req.text.strip()
    if not text:
        raise HTTPException(status_code=400, detail="Text cannot be empty")
    try:
        entities = ner_model(text[:512])
        relevant = [e['word'] for e in entities if e.get('entity_group') in ['ORG', 'PERSON', 'MISC', 'PRODUCT', 'GPE']]
        unique_entities = list(dict.fromkeys(relevant))[:5]
        return {"entities": unique_entities}
    except Exception as e:
        logger.error(f"NER analysis error: {e}")
        raise HTTPException(status_code=500, detail="NER analysis failed")

@app.post("/chart")
def generate_chart(req: CoinRequest):
    coin_id = req.coin_id.strip().lower()
    if not coin_id:
        raise HTTPException(status_code=400, detail="coin_id cannot be empty")

    url = f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart"
    params = {"vs_currency": "usd", "days": "1"}

    try:
        res = requests.get(url, params=params)
        if res.status_code != 200:
            logger.error(f"CoinGecko API error: {res.text}")
            raise HTTPException(status_code=502, detail="Failed to fetch coin data from CoinGecko")

        prices = res.json().get("prices", [])
        if not prices:
            raise HTTPException(status_code=404, detail="No price data available")

        times = [datetime.datetime.fromtimestamp(p[0] / 1000) for p in prices]
        values = [p[1] for p in prices]

        plt.figure(figsize=(12, 6))
        plt.fill_between(times, values, color="#1f77b4", alpha=0.3)
        plt.plot(times, values, color="#1f77b4", linewidth=3)
        plt.title(f"{coin_id.capitalize()} Price (24h)", fontsize=20)
        plt.xlabel("Time")
        plt.ylabel("USD Price")
        plt.grid(True, linestyle='--', alpha=0.5)
        plt.tight_layout()

        img_bytes = BytesIO()
        plt.savefig(img_bytes, format="png")
        plt.close()
        img_bytes.seek(0)

        return StreamingResponse(img_bytes, media_type="image/png")
    except Exception as e:
        logger.error(f"Chart generation error: {e}")
        raise HTTPException(status_code=500, detail="Failed to generate chart")