Insurance-Claim-Orchestrato.../main.py
2024-10-03 19:49:39 +02:00

214 lines
9.1 KiB
Python

import requests
import time
import os
from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel
import uvicorn
# Load environment variables
load_dotenv()
app = FastAPI()
# Retrieve sensitive data from environment variables
TOKEN_URL = os.getenv('TOKEN_URL')
KVANT_URL = os.getenv('KVANT_URL')
USERNAME = os.getenv('USERNAME')
API_KEY = os.getenv('API_KEY')
MODEL_ID = "meta-llama/llama-3-70b-instruct"
PROJECT_ID = os.getenv('PROJECT_ID')
# Placeholder variables to store token and its expiration time
ACCESS_TOKEN = None
TOKEN_EXPIRATION = 0 # Initialize as expired to trigger refresh on the first request
# Class for Claim Input
class ClaimInput(BaseModel):
description: str
# Function to retrieve the Kvant access token
def get_access_token():
global ACCESS_TOKEN, TOKEN_EXPIRATION
if ACCESS_TOKEN is None or TOKEN_EXPIRATION < time.time():
print("Token expired or not available. Requesting new token.")
headers = {'Content-Type': 'application/json'}
data = {
"username": USERNAME,
"api_key": API_KEY
}
response = requests.post(TOKEN_URL, headers=headers, json=data)
if response.status_code == 200:
token_data = response.json()
ACCESS_TOKEN = token_data.get("token")
expires_in = token_data.get("expires_in", 3600)
TOKEN_EXPIRATION = time.time() + expires_in
print(f"New token retrieved, expires in {expires_in} seconds.")
else:
raise HTTPException(status_code=response.status_code, detail="Failed to retrieve access token.")
else:
print("Using existing valid token.")
return ACCESS_TOKEN
# Function to call the LLM endpoint for all tasks
def call_llm_endpoint(prompt_text):
token = get_access_token()
body = {
"input": prompt_text,
"parameters": {
"decoding_method": "greedy",
"max_new_tokens": 900,
"repetition_penalty": 1
},
"model_id": MODEL_ID,
"project_id": PROJECT_ID
}
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
response = requests.post(KVANT_URL, headers=headers, json=body)
if response.status_code != 200:
raise Exception(f"Non-200 response: {response.text}")
return response.json()['results'][0]['generated_text']
# Function to generate the NER prompt with examples
def getPromptNER(text):
return f"""<|begin_of_text|><|start_header_id|>system<|end_header_id|>
You always answer the questions with markdown formatting using GitHub syntax. The markdown formatting you support: headings, bold, italic, links, tables, lists, code blocks, and blockquotes. You must omit that you answer the questions with markdown.
Any HTML tags must be wrapped in block quotes, for example ```<html>```. You will be penalized for not rendering code in block quotes.
When returning code blocks, specify language.
You are a helpful, respectful, and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.<|eot_id|><|start_header_id|>assistant<|end_header_id|>
Extract the following entities: Car model, Date, Time, and Location from the report below.
Input:
The insured vehicle, a Tesla Model S, was parked outside on April 15th, 2023 when an unexpected and violent hailstorm struck the area. The hailstones caused extensive damage to the vehicle.
Named Entities:
Car= Tesla Model S; Date= April 15th, 2023
Input:
The insured vehicle, a Chevrolet Silverado, was involved in a hit and run accident on September 10th, 2023 at 3:30 PM on Oak Street.
Named Entities:
Car= Chevrolet Silverado; Date= September 10th, 2023; Time= 3:30 PM; Location= Oak Street
Input:
{text}
Named Entities:
"""
# Function to generate the summarization prompt
def getPromptSummary(description):
return f"""<|begin_of_text|><|start_header_id|>system<|end_header_id|>
You always answer the questions with markdown formatting using GitHub syntax. The markdown formatting you support: headings, bold, italic, links, tables, lists, code blocks, and blockquotes. You must omit that you answer the questions with markdown.
Any HTML tags must be wrapped in block quotes, for example ```<html>```. You will be penalized for not rendering code in block quotes.
When returning code blocks, specify language.
You are a helpful, respectful, and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.<|eot_id|><|start_header_id|>assistant<|end_header_id|>
Please summarize the following insurance report in one paragraph.
Report: {description}
Summary:
"""
# Function to generate the next actions prompt with examples
def getPromptNextActions(summary):
return f"""<|begin_of_text|><|start_header_id|>system<|end_header_id|>
You always answer the questions with markdown formatting using GitHub syntax. The markdown formatting you support: headings, bold, italic, links, tables, lists, code blocks, and blockquotes. You must omit that you answer the questions with markdown.
Any HTML tags must be wrapped in block quotes, for example ```<html>```. You will be penalized for not rendering code in block quotes.
When returning code blocks, specify language.
You are a helpful, respectful, and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.<|eot_id|><|start_header_id|>assistant<|end_header_id|>
Based on the summary below, suggest the next actions for this insurance claim.
Input:
A car accident occurred on Jan 1st, 2023 at 5pm at the intersection of Woodbridge. The insured vehicle, a Honda Civic, was hit by another vehicle that ran a red light.
Output:
1. Make a claim with your insurance company.
2. Provide any paperwork required to substantiate the claim.
3. Contact the insurance company and the covered driver.
Input:
The insured vehicle, a Ford RAM, was stolen from Boston on Dec 2nd, 2022. The insured immediately reported the theft to the police and obtained a police report.
Output:
1. Contact the police to file a police report.
2. Provide the insurance company with the police report.
3. Wait for the insurance company to contact you.
Input:
{summary}
Output:
"""
# Extract named entities from the NER result
def getNER_FM(ner_str):
car = ''
loc = ''
date = ''
time = ''
if len(ner_str) > 0:
ner_arr = ner_str.split(';')
for ner in ner_arr:
if '=' in ner:
entity_arr = ner.split('=')
if entity_arr[0].strip() == 'Car':
car = entity_arr[1].strip()
if entity_arr[0].strip() == 'Location':
loc = entity_arr[1].strip()
if entity_arr[0].strip() == 'Date':
date = entity_arr[1].strip()
if entity_arr[0].strip() == 'Time':
time = entity_arr[1].strip()
return car, loc, date, time
# FastAPI route to process the insurance report
@app.post("/process_claim")
async def process_claim(claim: ClaimInput, request: Request):
description = claim.description
# Call NER task
prompt_input_ner = getPromptNER(description)
ner_str = call_llm_endpoint(prompt_input_ner)
car, loc, date, time = getNER_FM(ner_str)
# Call summarization task
prompt_input_summary = getPromptSummary(description)
summary = call_llm_endpoint(prompt_input_summary)
summary = summary.replace('**','')
# Call next actions task
prompt_input_next_actions = getPromptNextActions(summary)
next_actions = call_llm_endpoint(prompt_input_next_actions)
next_actions = next_actions.replace('**','')
return {
"Car Model": car,
"Location": loc,
"Date": date,
"Time": time,
"Summary": summary,
"Next Actions": next_actions
}
# Main block to run the FastAPI app using uvicorn
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8080)