diff --git a/tools/fin/submit_loan_application.py b/tools/fin/submit_loan_application.py new file mode 100644 index 0000000..4aa1e83 --- /dev/null +++ b/tools/fin/submit_loan_application.py @@ -0,0 +1,94 @@ +from datetime import timedelta +import os +from pathlib import Path +import json +from temporalio.client import Client, WorkflowHandle +from dataclasses import dataclass +from typing import Optional +import asyncio +from temporalio.exceptions import WorkflowAlreadyStartedError +from shared.config import get_temporal_client + + +# Define data structures to match the Java workflow's expected input/output +# see https://github.com/temporal-sa/temporal-latency-optimization-scenarios for more details +@dataclass +class TransactionRequest: + amount: float + account_id: str + +@dataclass +class TxResult: + transaction_id: str + message: str + +#demonstrate starting a workflow and early return pattern while the workflow continues +async def submit_loan_application(args: dict) -> dict: + account_key = args.get("accountkey") + amount = args.get("amount") + + loan_status: dict = await start_workflow(amount=amount,account_name=account_key) + + return {'status': loan_status.get("loan_status"), 'detailed_status': loan_status.get("results"), 'next_step': loan_status.get("advisement"), 'confirmation_id': loan_status.get("workflowID")} + + +# Async function to start workflow +async def start_workflow(amount: str, account_name: str, )-> dict: + + # Connect to Temporal + client = await get_temporal_client() + start_real_workflow = os.getenv("FIN_START_REAL_WORKFLOW") + if start_real_workflow is not None and start_real_workflow.lower() == "false": + START_REAL_WORKFLOW = False + else: + START_REAL_WORKFLOW = True + + if START_REAL_WORKFLOW: + + # Define the workflow ID and task queue + workflow_id = "APPLICATION-"+account_name + task_queue = "LatencyOptimizationTEST" + + # Create a TransactionRequest (matching the Java workflow's expected input) + tx_request = TransactionRequest( + amount=float(amount), + account_id=account_name + ) + + #try: + # Use update-with-start to start the workflow and call the update method + handle: WorkflowHandle = await client.start_workflow( + "TransactionWorkflowLocalBeforeUpdate.processTransaction", # Workflow name + tx_request, # Input to the processTransaction method + id=workflow_id, + task_queue=task_queue, + execution_timeout=timedelta(minutes=5), + # Specify the update to call immediately after starting + update="returnInitResult", + update_args=[] # No arguments needed for returnInitResult + ) + + # Wait for the update result (returnInitResult) + update_result = await handle.result_of_update("returnInitResult") + + # Since the result is a RawValue, we need to deserialize it + # For simplicity, assuming the result is TxResult (adjust based on actual serialization) + #result_dict = update_result.payloads[0].decode() # Simplified; use proper deserialization + tx_result = TxResult( + transaction_id=result_dict.get("transaction_id", ""), + message=result_dict.get("message", "") + ) + + print(f"Update result: Transaction ID = {tx_result.transaction_id}, Message = {tx_result.message}") + + # Optionally, wait for the workflow to complete and get the final result + # final_result = await handle.result() + # print(f"Workflow completed with result: {final_result}") + + #except Exception as e: + # print(f"Error executing workflow: {e}") + + + # return {'status': loan_status.get("loan_status"), 'detailed_status': loan_status.get("results"), 'next_step': loan_status.get("advisement"), 'confirmation_id': loan_status.get("workflowID")} + return {'status': "status", 'detailed_status': "loan application is submitted and initial validation is complete",'confirmation id': "11358", 'next_step': "You'll receive a confirmation for final approval in three business days", } + \ No newline at end of file