Spaces:
Running
Running
Commit ·
2bdf9a9
1
Parent(s): 0367d20
Refactor datetime logging to use timezone-aware timestamps and comment out unused transaction_date field in TransactionParser
Browse files
app.py
CHANGED
|
@@ -7,7 +7,7 @@ import json
|
|
| 7 |
from langgraph.graph import StateGraph, END
|
| 8 |
from typing import TypedDict, Annotated
|
| 9 |
import operator
|
| 10 |
-
from langchain_core.messages import SystemMessage,
|
| 11 |
# from langgraph.pregel import RetryPolicy
|
| 12 |
from langgraph.types import RetryPolicy
|
| 13 |
import json
|
|
@@ -19,6 +19,7 @@ from datetime import datetime
|
|
| 19 |
from fastapi import HTTPException
|
| 20 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
| 21 |
from opik.integrations.langchain import OpikTracer
|
|
|
|
| 22 |
|
| 23 |
# Load environment variables - for local development
|
| 24 |
from dotenv import load_dotenv
|
|
@@ -39,7 +40,7 @@ class TransactionParser(BaseModel):
|
|
| 39 |
dr_or_cr: str = Field(description="Identify if the transaction was debit (spent) or credit (received). Strictly choose one of the values - Debit or Credit")
|
| 40 |
receiver: str = Field(description="The recipient of the transaction. Identify the Merchant Name from the message text.")
|
| 41 |
category: str = Field(description="The category of the transaction. The category of the transaction is linked to the Merchant Name. Strictly choose from one the of values - Shopping,EMI,Education,Miscellaneous,Grocery,Utility,House Help,Travel,Transport,Food")
|
| 42 |
-
transaction_date: str = Field(description="Use today's date strictly in yyyy-mm-dd format.")
|
| 43 |
transaction_origin: str = Field(description="The origin of the transaction. Provide the card or account number as well.")
|
| 44 |
|
| 45 |
class AgentState(TypedDict):
|
|
@@ -64,17 +65,17 @@ class Agent:
|
|
| 64 |
self.model = model
|
| 65 |
|
| 66 |
def classify_txn_type(self, state: AgentState) -> AgentState:
|
| 67 |
-
print(f"{datetime.now()}: Classifying transaction type...")
|
| 68 |
messages = state["messages"]
|
| 69 |
if self.system:
|
| 70 |
messages = [SystemMessage(content=self.system)] + messages
|
| 71 |
|
| 72 |
message = self.model.invoke(messages)
|
| 73 |
-
print(f"{datetime.now()}: Classifying transaction type completed.")
|
| 74 |
return {"messages": [message]}
|
| 75 |
|
| 76 |
def parse_message(self, state: AgentState) -> AgentState:
|
| 77 |
-
print(f"{datetime.now()}: Parsing transaction message...")
|
| 78 |
message = state["messages"][0]#.content
|
| 79 |
system = """
|
| 80 |
You are a helpful assistant skilled at parsing transaction messages and providing structured responses.
|
|
@@ -84,12 +85,12 @@ class Agent:
|
|
| 84 |
prompt = ChatPromptTemplate.from_messages([("system", system), ("human", human)])
|
| 85 |
chain = prompt | self.model.with_structured_output(TransactionParser)
|
| 86 |
result = chain.invoke({"topic": message})
|
| 87 |
-
print(f"{datetime.now()}: Parsing transaction message completed.")
|
| 88 |
|
| 89 |
return {"messages": [result]}
|
| 90 |
|
| 91 |
def write_message(self, state: AgentState) -> AgentState:
|
| 92 |
-
print(f"{datetime.now()}: Writing transaction message to Google Sheets...")
|
| 93 |
result = state["messages"][-1]
|
| 94 |
|
| 95 |
SCOPES = ('https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive')
|
|
@@ -106,10 +107,10 @@ class Agent:
|
|
| 106 |
wk.update_value(f'B{nrows+2}', result.dr_or_cr)
|
| 107 |
wk.update_value(f'C{nrows+2}', result.receiver)
|
| 108 |
wk.update_value(f'D{nrows+2}', result.category)
|
| 109 |
-
wk.update_value(f'E{nrows+2}', datetime.now().strftime("%Y-%m-%d")) #result.transaction_date)
|
| 110 |
wk.update_value(f'F{nrows+2}', result.transaction_origin)
|
| 111 |
wk.update_value(f'G{nrows+2}', state["messages"][0])
|
| 112 |
-
print(f"{datetime.now()}: Writing transaction message to Google Sheets completed.")
|
| 113 |
return {"messages": ["Transaction Completed"]}
|
| 114 |
|
| 115 |
def check_txn_and_decide(self, state: AgentState):
|
|
@@ -120,14 +121,7 @@ class Agent:
|
|
| 120 |
|
| 121 |
return result == "Transaction"
|
| 122 |
|
| 123 |
-
|
| 124 |
-
You will be penalized heavily for incorrect classification. \
|
| 125 |
-
Your task is to classify the message into one of the following categories: \
|
| 126 |
-
Transaction, OTP, Promotional, Scheduled, Non-Transaction. \
|
| 127 |
-
Consider Salary Credit, Interest Credit, Redemtions as non-transactional messages.
|
| 128 |
-
Output the classification in a structured format like below. \
|
| 129 |
-
{"classification": "OTP"} \
|
| 130 |
-
"""
|
| 131 |
app = FastAPI()
|
| 132 |
|
| 133 |
@app.get("/")
|
|
@@ -139,6 +133,15 @@ def write_message(data: dict, header: str = Header()):
|
|
| 139 |
if header != HF_TOKEN:
|
| 140 |
raise HTTPException(status_code=400, detail="Invalid header")
|
| 141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
message = data['message']
|
| 143 |
|
| 144 |
try:
|
|
|
|
| 7 |
from langgraph.graph import StateGraph, END
|
| 8 |
from typing import TypedDict, Annotated
|
| 9 |
import operator
|
| 10 |
+
from langchain_core.messages import SystemMessage, AnyMessage
|
| 11 |
# from langgraph.pregel import RetryPolicy
|
| 12 |
from langgraph.types import RetryPolicy
|
| 13 |
import json
|
|
|
|
| 19 |
from fastapi import HTTPException
|
| 20 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
| 21 |
from opik.integrations.langchain import OpikTracer
|
| 22 |
+
from pytz import timezone
|
| 23 |
|
| 24 |
# Load environment variables - for local development
|
| 25 |
from dotenv import load_dotenv
|
|
|
|
| 40 |
dr_or_cr: str = Field(description="Identify if the transaction was debit (spent) or credit (received). Strictly choose one of the values - Debit or Credit")
|
| 41 |
receiver: str = Field(description="The recipient of the transaction. Identify the Merchant Name from the message text.")
|
| 42 |
category: str = Field(description="The category of the transaction. The category of the transaction is linked to the Merchant Name. Strictly choose from one the of values - Shopping,EMI,Education,Miscellaneous,Grocery,Utility,House Help,Travel,Transport,Food")
|
| 43 |
+
# transaction_date: str = Field(description="Use today's date strictly in yyyy-mm-dd format.")
|
| 44 |
transaction_origin: str = Field(description="The origin of the transaction. Provide the card or account number as well.")
|
| 45 |
|
| 46 |
class AgentState(TypedDict):
|
|
|
|
| 65 |
self.model = model
|
| 66 |
|
| 67 |
def classify_txn_type(self, state: AgentState) -> AgentState:
|
| 68 |
+
print(f"{datetime.now(timezone("Asia/Kolkata"))}: Classifying transaction type...")
|
| 69 |
messages = state["messages"]
|
| 70 |
if self.system:
|
| 71 |
messages = [SystemMessage(content=self.system)] + messages
|
| 72 |
|
| 73 |
message = self.model.invoke(messages)
|
| 74 |
+
print(f"{datetime.now(timezone("Asia/Kolkata"))}: Classifying transaction type completed.")
|
| 75 |
return {"messages": [message]}
|
| 76 |
|
| 77 |
def parse_message(self, state: AgentState) -> AgentState:
|
| 78 |
+
print(f"{datetime.now(timezone("Asia/Kolkata"))}: Parsing transaction message...")
|
| 79 |
message = state["messages"][0]#.content
|
| 80 |
system = """
|
| 81 |
You are a helpful assistant skilled at parsing transaction messages and providing structured responses.
|
|
|
|
| 85 |
prompt = ChatPromptTemplate.from_messages([("system", system), ("human", human)])
|
| 86 |
chain = prompt | self.model.with_structured_output(TransactionParser)
|
| 87 |
result = chain.invoke({"topic": message})
|
| 88 |
+
print(f"{datetime.now(timezone("Asia/Kolkata"))}: Parsing transaction message completed.")
|
| 89 |
|
| 90 |
return {"messages": [result]}
|
| 91 |
|
| 92 |
def write_message(self, state: AgentState) -> AgentState:
|
| 93 |
+
print(f"{datetime.now(timezone("Asia/Kolkata"))}: Writing transaction message to Google Sheets...")
|
| 94 |
result = state["messages"][-1]
|
| 95 |
|
| 96 |
SCOPES = ('https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive')
|
|
|
|
| 107 |
wk.update_value(f'B{nrows+2}', result.dr_or_cr)
|
| 108 |
wk.update_value(f'C{nrows+2}', result.receiver)
|
| 109 |
wk.update_value(f'D{nrows+2}', result.category)
|
| 110 |
+
wk.update_value(f'E{nrows+2}', datetime.now(timezone("Asia/Kolkata")).strftime("%Y-%m-%d")) #result.transaction_date)
|
| 111 |
wk.update_value(f'F{nrows+2}', result.transaction_origin)
|
| 112 |
wk.update_value(f'G{nrows+2}', state["messages"][0])
|
| 113 |
+
print(f"{datetime.now(timezone("Asia/Kolkata"))}: Writing transaction message to Google Sheets completed.")
|
| 114 |
return {"messages": ["Transaction Completed"]}
|
| 115 |
|
| 116 |
def check_txn_and_decide(self, state: AgentState):
|
|
|
|
| 121 |
|
| 122 |
return result == "Transaction"
|
| 123 |
|
| 124 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
app = FastAPI()
|
| 126 |
|
| 127 |
@app.get("/")
|
|
|
|
| 133 |
if header != HF_TOKEN:
|
| 134 |
raise HTTPException(status_code=400, detail="Invalid header")
|
| 135 |
|
| 136 |
+
prompt = """You are a smart assistant adept at classifying different messages. \
|
| 137 |
+
You will be penalized heavily for incorrect classification. \
|
| 138 |
+
Your task is to classify the message into one of the following categories: \
|
| 139 |
+
Transaction, OTP, Promotional, Scheduled, Non-Transaction. \
|
| 140 |
+
Consider Salary Credit, Interest Credit, Redemptions as non-transactional messages.
|
| 141 |
+
Output the classification in a structured format like below. \
|
| 142 |
+
{"classification": "OTP"} \
|
| 143 |
+
"""
|
| 144 |
+
|
| 145 |
message = data['message']
|
| 146 |
|
| 147 |
try:
|