Enhance Dev Experience and Code Quality (#41)

* Format codebase to satisfy linters

* fixing pylance and ruff-checked files

* contributing md, and type and formatting fixes

* setup file capitalization

* test fix
This commit is contained in:
Steve Androulakis
2025-06-01 08:54:59 -07:00
committed by GitHub
parent e35181b5ad
commit eb06cf5c8d
52 changed files with 1282 additions and 1105 deletions

View File

@@ -1,24 +1,31 @@
from pathlib import Path
import json
from pathlib import Path
# this is made to demonstrate functionality but it could just as durably be an API call
# called as part of a temporal activity with automatic retries
def check_account_valid(args: dict) -> dict:
email = args.get("email")
account_id = args.get("account_id")
file_path = Path(__file__).resolve().parent.parent / "data" / "customer_account_data.json"
file_path = (
Path(__file__).resolve().parent.parent / "data" / "customer_account_data.json"
)
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
account_list = data["accounts"]
for account in account_list:
if account["email"] == email or account["account_id"] == account_id:
return{"status": "account valid"}
return_msg = "Account not found with email address " + email + " or account ID: " + account_id
return {"error": return_msg}
return {"status": "account valid"}
return_msg = (
"Account not found with email address "
+ email
+ " or account ID: "
+ account_id
)
return {"error": return_msg}

View File

@@ -1,23 +1,33 @@
from pathlib import Path
import json
from pathlib import Path
# this is made to demonstrate functionality but it could just as durably be an API call
# this assumes it's a valid account - use check_account_valid() to verify that first
def get_account_balance(args: dict) -> dict:
account_key = args.get("email_address_or_account_ID")
file_path = Path(__file__).resolve().parent.parent / "data" / "customer_account_data.json"
file_path = (
Path(__file__).resolve().parent.parent / "data" / "customer_account_data.json"
)
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
account_list = data["accounts"]
for account in account_list:
if account["email"] == account_key or account["account_id"] == account_key:
return{ "name": account["name"], "email": account["email"], "account_id": account["account_id"], "checking_balance": account["checking_balance"], "savings_balance": account["savings_balance"], "bitcoin_balance": account["bitcoin_balance"], "account_creation_date": account["account_creation_date"] }
return {
"name": account["name"],
"email": account["email"],
"account_id": account["account_id"],
"checking_balance": account["checking_balance"],
"savings_balance": account["savings_balance"],
"bitcoin_balance": account["bitcoin_balance"],
"account_creation_date": account["account_creation_date"],
}
return_msg = "Account not found with for " + account_key
return {"error": return_msg}
return {"error": return_msg}

View File

@@ -1,16 +1,12 @@
import os
from pathlib import Path
import json
from temporalio.client import Client
import os
from dataclasses import dataclass
from typing import Optional
import asyncio
from pathlib import Path
from temporalio.exceptions import WorkflowAlreadyStartedError
from shared.config import get_temporal_client
from enum import Enum, auto
# enums for the java enum
# class ExecutionScenarios(Enum):
# HAPPY_PATH = 0
@@ -32,7 +28,6 @@ class MoneyMovementWorkflowParameterObj:
# this is made to demonstrate functionality but it could just as durably be an API call
# this assumes it's a valid account - use check_account_valid() to verify that first
async def move_money(args: dict) -> dict:
account_key = args.get("email_address_or_account_ID")
account_type: str = args.get("accounttype")
amount = args.get("amount")
@@ -101,7 +96,6 @@ async def move_money(args: dict) -> dict:
async def start_workflow(
amount_cents: int, from_account_name: str, to_account_name: str
) -> str:
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
@@ -128,7 +122,7 @@ async def start_workflow(
task_queue="MoneyTransferJava", # Task queue name
)
return handle.id
except WorkflowAlreadyStartedError as e:
except WorkflowAlreadyStartedError:
existing_handle = client.get_workflow_handle(workflow_id=workflow_id)
return existing_handle.id
else:

View File

@@ -1,18 +1,10 @@
from datetime import date, timedelta
import os
from pathlib import Path
import json
from temporalio.client import (
Client,
WithStartWorkflowOperation,
WorkflowHandle,
WorkflowUpdateFailedError,
)
from temporalio import common
from dataclasses import dataclass
from typing import Optional
import asyncio
from temporalio.exceptions import WorkflowAlreadyStartedError
from datetime import date
from temporalio import common
from temporalio.client import WithStartWorkflowOperation, WorkflowUpdateFailedError
from shared.config import get_temporal_client
@@ -24,39 +16,55 @@ class TransactionRequest:
sourceAccount: str
targetAccount: str
@dataclass
class TxResult:
transactionId: str
status: str
#demonstrate starting a workflow and early return pattern while the workflow continues
# 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)
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")}
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:
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", }
# 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
# 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')
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)
@@ -83,21 +91,27 @@ async def start_workflow(amount: str, account_name: str, )-> dict:
)
)
except WorkflowUpdateFailedError:
print("aww man got exception 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}")
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", }
# 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",
}