Spaces:
Sleeping
Sleeping
Commit ·
e5b1901
1
Parent(s): 7b2857c
Initial push to Hugging Face Space
Browse files- app.py +56 -6
- requirements.txt +2 -0
app.py
CHANGED
|
@@ -1,20 +1,26 @@
|
|
| 1 |
from fastapi import FastAPI, HTTPException
|
| 2 |
from pydantic import BaseModel
|
| 3 |
from transformers import pipeline
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
import logging
|
| 5 |
import os
|
|
|
|
|
|
|
| 6 |
os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf_cache"
|
| 7 |
os.environ["HF_HOME"] = "/tmp/hf_cache"
|
| 8 |
|
|
|
|
| 9 |
logging.basicConfig(level=logging.INFO)
|
| 10 |
logger = logging.getLogger(__name__)
|
| 11 |
|
|
|
|
| 12 |
app = FastAPI()
|
| 13 |
|
| 14 |
-
#
|
| 15 |
-
os.environ["TRANSFORMERS_CACHE"] = "/tmp/huggingface"
|
| 16 |
-
|
| 17 |
-
# Load models once on startup with error handling
|
| 18 |
try:
|
| 19 |
ner_model = pipeline("ner", model="dslim/bert-base-NER", aggregation_strategy="simple")
|
| 20 |
sentiment_model = pipeline("sentiment-analysis", model="ProsusAI/finbert")
|
|
@@ -24,9 +30,14 @@ except Exception as e:
|
|
| 24 |
ner_model = None
|
| 25 |
sentiment_model = None
|
| 26 |
|
|
|
|
| 27 |
class TextRequest(BaseModel):
|
| 28 |
text: str
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
@app.get("/")
|
| 31 |
def home():
|
| 32 |
return {"message": "Crypto News API is alive!"}
|
|
@@ -57,11 +68,50 @@ def analyze_ner(req: TextRequest):
|
|
| 57 |
raise HTTPException(status_code=400, detail="Text cannot be empty")
|
| 58 |
try:
|
| 59 |
entities = ner_model(text[:512])
|
| 60 |
-
# Filter relevant entity groups
|
| 61 |
relevant = [e['word'] for e in entities if e.get('entity_group') in ['ORG', 'PERSON', 'MISC', 'PRODUCT', 'GPE']]
|
| 62 |
-
# Remove duplicates preserving order, limit to 5 entities
|
| 63 |
unique_entities = list(dict.fromkeys(relevant))[:5]
|
| 64 |
return {"entities": unique_entities}
|
| 65 |
except Exception as e:
|
| 66 |
logger.error(f"NER analysis error: {e}")
|
| 67 |
raise HTTPException(status_code=500, detail="NER analysis failed")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from fastapi import FastAPI, HTTPException
|
| 2 |
from pydantic import BaseModel
|
| 3 |
from transformers import pipeline
|
| 4 |
+
from fastapi.responses import StreamingResponse
|
| 5 |
+
import matplotlib.pyplot as plt
|
| 6 |
+
import requests
|
| 7 |
+
import datetime
|
| 8 |
+
from io import BytesIO
|
| 9 |
import logging
|
| 10 |
import os
|
| 11 |
+
|
| 12 |
+
# Set environment variables for Hugging Face cache
|
| 13 |
os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf_cache"
|
| 14 |
os.environ["HF_HOME"] = "/tmp/hf_cache"
|
| 15 |
|
| 16 |
+
# Configure logging
|
| 17 |
logging.basicConfig(level=logging.INFO)
|
| 18 |
logger = logging.getLogger(__name__)
|
| 19 |
|
| 20 |
+
# Create FastAPI app
|
| 21 |
app = FastAPI()
|
| 22 |
|
| 23 |
+
# Load transformers models
|
|
|
|
|
|
|
|
|
|
| 24 |
try:
|
| 25 |
ner_model = pipeline("ner", model="dslim/bert-base-NER", aggregation_strategy="simple")
|
| 26 |
sentiment_model = pipeline("sentiment-analysis", model="ProsusAI/finbert")
|
|
|
|
| 30 |
ner_model = None
|
| 31 |
sentiment_model = None
|
| 32 |
|
| 33 |
+
# Request body schema for sentiment and NER
|
| 34 |
class TextRequest(BaseModel):
|
| 35 |
text: str
|
| 36 |
|
| 37 |
+
# Request body schema for chart
|
| 38 |
+
class CoinRequest(BaseModel):
|
| 39 |
+
coin_id: str
|
| 40 |
+
|
| 41 |
@app.get("/")
|
| 42 |
def home():
|
| 43 |
return {"message": "Crypto News API is alive!"}
|
|
|
|
| 68 |
raise HTTPException(status_code=400, detail="Text cannot be empty")
|
| 69 |
try:
|
| 70 |
entities = ner_model(text[:512])
|
|
|
|
| 71 |
relevant = [e['word'] for e in entities if e.get('entity_group') in ['ORG', 'PERSON', 'MISC', 'PRODUCT', 'GPE']]
|
|
|
|
| 72 |
unique_entities = list(dict.fromkeys(relevant))[:5]
|
| 73 |
return {"entities": unique_entities}
|
| 74 |
except Exception as e:
|
| 75 |
logger.error(f"NER analysis error: {e}")
|
| 76 |
raise HTTPException(status_code=500, detail="NER analysis failed")
|
| 77 |
+
|
| 78 |
+
@app.post("/chart")
|
| 79 |
+
def generate_chart(req: CoinRequest):
|
| 80 |
+
coin_id = req.coin_id.strip().lower()
|
| 81 |
+
if not coin_id:
|
| 82 |
+
raise HTTPException(status_code=400, detail="coin_id cannot be empty")
|
| 83 |
+
|
| 84 |
+
url = f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart"
|
| 85 |
+
params = {"vs_currency": "usd", "days": "1"}
|
| 86 |
+
|
| 87 |
+
try:
|
| 88 |
+
res = requests.get(url, params=params)
|
| 89 |
+
if res.status_code != 200:
|
| 90 |
+
logger.error(f"CoinGecko API error: {res.text}")
|
| 91 |
+
raise HTTPException(status_code=502, detail="Failed to fetch coin data from CoinGecko")
|
| 92 |
+
|
| 93 |
+
prices = res.json().get("prices", [])
|
| 94 |
+
if not prices:
|
| 95 |
+
raise HTTPException(status_code=404, detail="No price data available")
|
| 96 |
+
|
| 97 |
+
times = [datetime.datetime.fromtimestamp(p[0] / 1000) for p in prices]
|
| 98 |
+
values = [p[1] for p in prices]
|
| 99 |
+
|
| 100 |
+
plt.figure(figsize=(12, 6))
|
| 101 |
+
plt.fill_between(times, values, color="#1f77b4", alpha=0.3)
|
| 102 |
+
plt.plot(times, values, color="#1f77b4", linewidth=3)
|
| 103 |
+
plt.title(f"{coin_id.capitalize()} Price (24h)", fontsize=20)
|
| 104 |
+
plt.xlabel("Time")
|
| 105 |
+
plt.ylabel("USD Price")
|
| 106 |
+
plt.grid(True, linestyle='--', alpha=0.5)
|
| 107 |
+
plt.tight_layout()
|
| 108 |
+
|
| 109 |
+
img_bytes = BytesIO()
|
| 110 |
+
plt.savefig(img_bytes, format="png")
|
| 111 |
+
plt.close()
|
| 112 |
+
img_bytes.seek(0)
|
| 113 |
+
|
| 114 |
+
return StreamingResponse(img_bytes, media_type="image/png")
|
| 115 |
+
except Exception as e:
|
| 116 |
+
logger.error(f"Chart generation error: {e}")
|
| 117 |
+
raise HTTPException(status_code=500, detail="Failed to generate chart")
|
requirements.txt
CHANGED
|
@@ -2,3 +2,5 @@ fastapi
|
|
| 2 |
uvicorn[standard]
|
| 3 |
transformers
|
| 4 |
torch
|
|
|
|
|
|
|
|
|
| 2 |
uvicorn[standard]
|
| 3 |
transformers
|
| 4 |
torch
|
| 5 |
+
matplotlib
|
| 6 |
+
requests
|