-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
102 lines (81 loc) · 3.13 KB
/
main.py
File metadata and controls
102 lines (81 loc) · 3.13 KB
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
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import yfinance as yf
from dotenv import load_dotenv
from typing import Literal
from langchain_groq import ChatGroq
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
load_dotenv()
app = FastAPI(title="Mini Disruptor Scoring Endpoint (LangChain v1 + Tools)")
class TickerRequest(BaseModel):
ticker: str
class DisruptorScore(BaseModel):
summary: str
risk_score: Literal[1, 2, 3, 4, 5]
opportunity_score: Literal[1, 2, 3, 4, 5]
# LangChain model
llm = ChatGroq(model="llama-3.1-8b-instant", temperature=0.7)
# -----------------------
# Tool 1: Validate ticker
# -----------------------
def validate_ticker(ticker: str) -> bool:
try:
tk = yf.Ticker(ticker)
info = tk.info
return "longName" in info and info["longName"] != ""
except Exception:
return False
# -----------------------
# Tool 2: Get company info
# -----------------------
def get_company_info(ticker: str) -> dict:
tk = yf.Ticker(ticker)
info = tk.info
return {
"name": info.get("longName", ""),
"sector": info.get("sector", ""),
"industry": info.get("industry", ""),
"marketCap": info.get("marketCap", 0),
"summary": info.get("longBusinessSummary", "")
}
# -----------------------
# API Endpoint
# -----------------------
@app.post("/score-company")
async def score_company(request: TickerRequest):
ticker = request.ticker.upper().strip()
# Step 1: Validate ticker
if not ticker.isalpha() or len(ticker) > 5:
raise HTTPException(status_code=400, detail="Invalid ticker format")
if not validate_ticker(ticker):
raise HTTPException(status_code=404, detail="Ticker not found")
# Step 2: Get company info
company_info = get_company_info(ticker)
# Step 3: Build prompt and parser
prompt = ChatPromptTemplate.from_messages([
("system", "You are a financial analyst and expert in disruptive companies."),
("human", "Here is some company info:\n"
"Name: {name}\n"
"Sector: {sector}\n"
"Industry: {industry}\n"
"MarketCap: {marketCap}\n"
"Summary: {summary}\n\n"
"Based on this info, give me a simple 3-sentence summary of why {ticker} might be considered a disruptor. "
"Respond in JSON with fields: summary, risk_score (1–5), opportunity_score (1–5).")
])
# Use structured output with Pydantic
parser = PydanticOutputParser(pydantic_object=DisruptorScore)
prompt_with_parser = prompt | llm | parser
try:
result = prompt_with_parser.invoke({
"ticker": ticker,
"name": company_info["name"],
"sector": company_info["sector"],
"industry": company_info["industry"],
"marketCap": company_info["marketCap"],
"summary": company_info["summary"]
})
return {"ticker": ticker, **result.dict()}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))