import os from dataclasses import dataclass from datetime import date from temporalio import common from temporalio.client import WithStartWorkflowOperation, WorkflowUpdateFailedError 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 sourceAccount: str targetAccount: str @dataclass class TxResult: transactionId: str status: 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("email_address_or_account_ID") amount = args.get("amount") loan_status: dict = await start_workflow(amount=amount, account_name=account_key) if loan_status.get("error") is None: return { "status": loan_status.get("loan_application_status"), "detailed_status": loan_status.get("application_details"), "next_step": loan_status.get("advisement"), "confirmation_id": loan_status.get("transaction_id"), } else: print(loan_status) return loan_status # Async function to start workflow async def start_workflow( amount: str, account_name: str, ) -> dict: 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 return { "loan_application_status": "applied", "application_details": "loan application is submitted and initial validation is complete", "transaction_id": "APPLICATION" + account_name, "advisement": "You'll receive a confirmation for final approval in three business days", } else: # START_REAL_WORKFLOW = True # Connect to Temporal client = await get_temporal_client() # Define the workflow ID and task queue workflow_id = ( "LOAN_APPLICATION-" + account_name + "-" + date.today().strftime("%Y-%m-%d") ) task_queue = "LatencyOptimizationTEST" # Create a TransactionRequest (matching the Java workflow's expected input) tx_request = TransactionRequest( amount=float(amount), targetAccount=account_name, sourceAccount=account_name, ) start_op = WithStartWorkflowOperation( "TransactionWorkflowLocalBeforeUpdate", tx_request, id=workflow_id, id_conflict_policy=common.WorkflowIDConflictPolicy.USE_EXISTING, task_queue=task_queue, ) try: print("trying update-with-start") tx_result = TxResult( await client.execute_update_with_start_workflow( "returnInitResult", start_workflow_operation=start_op, ) ) except WorkflowUpdateFailedError: print("aww man got exception WorkflowUpdateFailedError") tx_result = None return_msg = "Loan could not be processed for " + account_name return {"error": return_msg} workflow_handle = await start_op.workflow_handle() print(f"Workflow started with ID: {workflow_handle.id}") print(tx_result) print( f"Update result: Transaction ID = {tx_result.transactionId}, Message = {tx_result.status}" ) # 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}") # 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 { "loan_application_status": "applied", "application_details": "loan application is submitted and initial validation is complete", "transaction_id": tx_result.transactionId, "advisement": "You'll receive a confirmation for final approval in three business days", }