import hashlib
import json
from .schemas import FlowInput
def normalize_flow(flow: FlowInput) -> dict:
"""
Normalize flow for idempotency:
- Sort nodes by ID
- Sort edges by (from, to, label)
"""
flow_dict = flow.model_dump(exclude_none=True, by_alias=True)
# Sort nodes
flow_dict['nodes'].sort(key=lambda x: x['id'])
# Sort edges
# Use empty string for None values in sort key to avoid type errors
flow_dict['edges'].sort(key=lambda x: (
x['from'],
x['to'],
x.get('label', '') or ''
))
return flow_dict
def calculate_flow_hash(flow: FlowInput) -> str:
"""Calculate SHA256 of normalized flow"""
normalized = normalize_flow(flow)
json_str = json.dumps(normalized, sort_keys=True)
return hashlib.sha256(json_str.encode('utf-8')).hexdigest()