File size: 3,962 Bytes
988c3f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
from fastapi import FastAPI, HTTPException, UploadFile, File
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, StreamingResponse
from pydantic import BaseModel
import os

from prediction_helper import predict
from advisor_bot import generate_advice
from chatbot_advisor import ask_chatbot
from utility import STT, TTS

app = FastAPI()

# ---------------- CORS ---------------- #
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# ---------------- MODELS ---------------- #

class CreditRiskInput(BaseModel):
    age: int
    income: float
    loan_amount: float
    loan_tenure_months: int
    avg_dpd_per_delinquency: float
    delinquency_ratio: float
    credit_utilization_ratio: float
    num_open_accounts: int
    residence_type: str
    loan_purpose: str
    loan_type: str


class CreditRiskOutput(BaseModel):
    probability: float
    credit_score: int
    rating: str
    advisor_response: str | None = None


class ChatMessage(BaseModel):
    thread_id: str
    message: str
    probability: float
    credit_score: int
    rating: str
    advisor_reply: str


class TTSRequest(BaseModel):
    text: str


# ---------------- BASIC ROUTES ---------------- #

@app.get("/")
def root():
    return {"message": "Hello world!!"}


@app.get("/home")
def home():
    return {"message": "Credit Risk API is running."}


# ---------------- CREDIT RISK ---------------- #

@app.post("/predict_credit_risk", response_model=CreditRiskOutput)
def predict_credit_risk(input_data: CreditRiskInput):
    try:
        probability, credit_score, rating = predict(
            input_data.age,
            input_data.income,
            input_data.loan_amount,
            input_data.loan_tenure_months,
            input_data.avg_dpd_per_delinquency,
            input_data.delinquency_ratio,
            input_data.credit_utilization_ratio,
            input_data.num_open_accounts,
            input_data.residence_type,
            input_data.loan_purpose,
            input_data.loan_type
        )

        advisor_reply = generate_advice(
            probability=probability,
            credit_score=credit_score,
            rating=rating
        )

        return CreditRiskOutput(
            probability=probability,
            credit_score=credit_score,
            rating=rating,
            advisor_response=advisor_reply
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# ---------------- CHAT STREAM ---------------- #

@app.post("/chat")
async def chat(message_data: ChatMessage):

    async def event_generator():
        for chunk in ask_chatbot(
            message_data.probability,
            message_data.credit_score,
            message_data.rating,
            message_data.advisor_reply,
            message_data.message,
            message_data.thread_id
        ):
            yield chunk

    return StreamingResponse(event_generator(), media_type="text/plain")


# ---------------- TTS ---------------- #

@app.post("/tts")
async def generate_tts(request: TTSRequest):
    try:
        if not request.text.strip():
            raise HTTPException(status_code=400, detail="Text is empty")

        audio_path = await TTS(text=request.text)

        if not os.path.exists(audio_path):
            raise HTTPException(status_code=500, detail="Audio file not created")

        return FileResponse(
            path=audio_path,
            media_type="audio/mpeg",
            filename="speech.mp3"
        )

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# ---------------- STT ---------------- #

@app.post("/stt")
async def transcribe_audio(file: UploadFile = File(...)):
    try:
        return await STT(file)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))