Skip to content

Commit 3eae010

Browse files
author
marwan37
committed
run format script
1 parent 9bb2937 commit 3eae010

File tree

1 file changed

+57
-35
lines changed

1 file changed

+57
-35
lines changed

credit-scorer/src/steps/deployment/approve.py

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,103 +48,121 @@ def approve_deployment(
4848
"""
4949
# Timestamp for record-keeping
5050
timestamp = datetime.now().isoformat()
51-
51+
5252
print("\n" + "=" * 60)
5353
print(" HUMAN OVERSIGHT REQUIRED (EU AI Act Article 14) ")
5454
print("=" * 60)
55-
55+
5656
# Extract metrics for display
5757
metrics = evaluation_results.get("metrics", {})
5858
fairness_data = evaluation_results.get("fairness", {})
5959
fairness_metrics = fairness_data.get("fairness_metrics", {})
6060
bias_flag = fairness_data.get("bias_flag", False)
61-
61+
6262
# Performance metrics summary
6363
print("\n📊 PERFORMANCE METRICS:")
6464
print(f" • Accuracy: {metrics.get('accuracy', 'N/A'):.4f}")
6565
print(f" • Precision: {metrics.get('precision', 'N/A'):.4f}")
6666
print(f" • Recall: {metrics.get('recall', 'N/A'):.4f}")
6767
print(f" • F1 Score: {metrics.get('f1_score', 'N/A'):.4f}")
6868
print(f" • AUC-ROC: {metrics.get('auc_roc', 'N/A'):.4f}")
69-
print(f" • Average Precision: {metrics.get('average_precision', 'N/A'):.4f}")
70-
print(f" • Balanced Accuracy: {metrics.get('balanced_accuracy', 'N/A'):.4f}")
71-
69+
print(
70+
f" • Average Precision: {metrics.get('average_precision', 'N/A'):.4f}"
71+
)
72+
print(
73+
f" • Balanced Accuracy: {metrics.get('balanced_accuracy', 'N/A'):.4f}"
74+
)
75+
7276
# Financial impact metrics
7377
print("\n💰 FINANCIAL IMPACT:")
74-
print(f" • Optimal Threshold: {metrics.get('optimal_threshold', 'N/A'):.4f}")
78+
print(
79+
f" • Optimal Threshold: {metrics.get('optimal_threshold', 'N/A'):.4f}"
80+
)
7581
print(f" • Normalized Cost: {metrics.get('normalized_cost', 'N/A'):.4f}")
76-
77-
# Fairness summary (aggregated, not per-group)
82+
83+
# Fairness summary (aggregated, not per-group)
7884
print(f"\n⚖️ FAIRNESS ASSESSMENT:")
7985
if bias_flag:
8086
print(" 🚨 BIAS DETECTED - Requires careful review")
81-
87+
8288
# Show worst disparity without listing all groups
8389
max_disparity = 0
8490
worst_attribute = None
85-
91+
8692
for attribute, attr_metrics in fairness_metrics.items():
8793
disparity = abs(attr_metrics.get("selection_rate_disparity", 0))
8894
if disparity > max_disparity:
8995
max_disparity = disparity
9096
worst_attribute = attribute
91-
97+
9298
if worst_attribute:
93-
print(f" • Highest disparity: {max_disparity:.3f} ({worst_attribute})")
94-
99+
print(
100+
f" • Highest disparity: {max_disparity:.3f} ({worst_attribute})"
101+
)
102+
95103
print(f" • Protected attributes analyzed: {len(fairness_metrics)}")
96104
else:
97105
print(" ✅ No significant bias detected across protected groups")
98106
print(f" • Protected attributes analyzed: {len(fairness_metrics)}")
99-
107+
100108
# Risk assessment
101109
print(f"\n⚠️ RISK ASSESSMENT:")
102110
print(f" • Overall Risk Score: {risk_scores.get('overall', 0):.3f}")
103111
print(f" • Risk Level: {risk_scores.get('risk_level', 'Unknown')}")
104-
112+
105113
high_risk_count = len(risk_scores.get("high_risk_factors", []))
106114
if high_risk_count > 0:
107115
print(f" • High-risk factors identified: {high_risk_count}")
108-
116+
109117
# Approval criteria check
110118
threshold_checks = {
111-
"Performance": metrics.get("accuracy", 0) >= approval_thresholds.get("accuracy", 0.7),
119+
"Performance": metrics.get("accuracy", 0)
120+
>= approval_thresholds.get("accuracy", 0.7),
112121
"Fairness": not bias_flag,
113-
"Risk": risk_scores.get("overall", 1) <= approval_thresholds.get("risk_score", 0.8),
122+
"Risk": risk_scores.get("overall", 1)
123+
<= approval_thresholds.get("risk_score", 0.8),
114124
}
115-
125+
116126
print(f"\n🔍 APPROVAL CRITERIA:")
117127
all_passed = True
118128
for check_name, passed in threshold_checks.items():
119129
status = "✅ PASS" if passed else "❌ FAIL"
120130
print(f" • {check_name}: {status}")
121131
if not passed:
122132
all_passed = False
123-
124-
print(f"\n📝 RECOMMENDATION: {'✅ APPROVE' if all_passed else '⚠️ REVIEW REQUIRED'}")
125-
133+
134+
print(
135+
f"\n📝 RECOMMENDATION: {'✅ APPROVE' if all_passed else '⚠️ REVIEW REQUIRED'}"
136+
)
137+
126138
# Get decision
127139
decision = os.getenv("DEPLOY_APPROVAL")
128-
140+
129141
if decision is None:
130142
if bias_flag:
131143
print("\n⚠️ WARNING: Review fairness implications before approval")
132-
133-
decision = input(f"\nApprove deployment? ({'Y/n' if all_passed else 'y/N'}): ").strip().lower()
144+
145+
decision = (
146+
input(
147+
f"\nApprove deployment? ({'Y/n' if all_passed else 'y/N'}): "
148+
)
149+
.strip()
150+
.lower()
151+
)
134152
approver = os.getenv("USER", input("Approver name: ").strip())
135153
rationale = input("Decision rationale: ").strip()
136154
decision_mode = "interactive"
137155
else:
138156
approver = os.getenv("APPROVER", "automated")
139157
rationale = os.getenv("APPROVAL_RATIONALE", "Automated approval")
140158
decision_mode = "automated"
141-
159+
142160
# Handle default approval logic
143161
if decision == "":
144162
approved = all_passed # Default to approve only if all criteria pass
145163
else:
146164
approved = decision in ["y", "yes"]
147-
165+
148166
# Create approval record
149167
approval_record = {
150168
"approval_id": f"approval_{timestamp.replace(':', '-')}",
@@ -163,17 +181,21 @@ def approve_deployment(
163181
"risk_score": risk_scores.get("overall"),
164182
},
165183
"protected_attributes_count": len(fairness_metrics),
166-
"max_bias_disparity": max([
167-
abs(attr_metrics.get("selection_rate_disparity", 0))
168-
for attr_metrics in fairness_metrics.values()
169-
]) if fairness_metrics else 0,
184+
"max_bias_disparity": max(
185+
[
186+
abs(attr_metrics.get("selection_rate_disparity", 0))
187+
for attr_metrics in fairness_metrics.values()
188+
]
189+
)
190+
if fairness_metrics
191+
else 0,
170192
}
171-
193+
172194
# Final status
173195
if approved:
174196
print(f"\n✅ DEPLOYMENT APPROVED by {approver}")
175197
else:
176198
print(f"\n❌ DEPLOYMENT REJECTED by {approver}")
177199
raise RuntimeError(f"Deployment rejected by {approver}: {rationale}")
178-
179-
return approved, approval_record
200+
201+
return approved, approval_record

0 commit comments

Comments
 (0)