-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathADD_TO_VISUALIZATION_PY.txt
More file actions
79 lines (73 loc) · 3.64 KB
/
Copy pathADD_TO_VISUALIZATION_PY.txt
File metadata and controls
79 lines (73 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# Budget Amendments API Endpoints
# Add this code to visualization.py after line 1312 (after budget_column_mapping_api)
# ===== BUDGET AMENDMENTS (FY 2026) ENDPOINTS =====
_amendments_cache = None
def load_amendments_data():
"""Load FY 2026 budget amendments data from JSON"""
global _amendments_cache
if _amendments_cache is not None:
return _amendments_cache
json_path = DATA_ROOT / "budget_amendments_2026.json"
if not json_path.exists():
return None
with open(json_path, 'r', encoding='utf-8') as f:
_amendments_cache = json.load(f)
return _amendments_cache
@app.get("/api/budget/amendments/summary")
async def budget_amendments_summary():
"""Get FY 2026 budget amendments summary statistics"""
try:
data = load_amendments_data()
if not data:
return JSONResponse({"success": False, "error": "Data not available"}, status_code=404)
return JSONResponse({"success": True, **data['metadata']})
except Exception as e:
return JSONResponse({"success": False, "error": str(e)}, status_code=500)
@app.get("/api/budget/amendments/departments")
async def budget_amendments_departments():
"""Get all departments with budget amendment summary"""
try:
data = load_amendments_data()
if not data:
return JSONResponse({"success": False, "error": "Data not available"}, status_code=404)
departments = sorted(data['departments'], key=lambda d: d.get('original_amount', 0), reverse=True)
return JSONResponse({"success": True, "departments": departments, "metadata": data['metadata']})
except Exception as e:
return JSONResponse({"success": False, "error": str(e)}, status_code=500)
@app.get("/api/budget/amendments/department/{dept_id}")
async def budget_amendments_department_details(dept_id: str):
"""Get programs within a department"""
try:
data = load_amendments_data()
if not data:
return JSONResponse({"success": False, "error": "Data not available"}, status_code=404)
department = next((d for d in data['departments'] if d['id'] == dept_id), None)
if not department:
return JSONResponse({"success": False, "error": "Department not found"}, status_code=404)
programs = [p for p in data.get('programs', []) if p.get('department_id') == dept_id]
return JSONResponse({"success": True, "department": department, "programs": programs})
except Exception as e:
return JSONResponse({"success": False, "error": str(e)}, status_code=500)
@app.get("/api/budget/amendments/search")
async def budget_amendments_search(q: str = Query("")):
"""Full-text search across departments, programs, and projects"""
try:
data = load_amendments_data()
if not data:
return JSONResponse({"success": False, "error": "Data not available"}, status_code=404)
query = q.lower()
if not query:
return JSONResponse({"success": True, "query": q, "results": []})
results = []
for dept in data['departments']:
if query in dept['name'].lower() or query in dept['code'].lower():
results.append({
"type": "department",
"id": dept['id'],
"name": dept['name'],
"code": dept['code'],
"amount": dept['final_amount']
})
return JSONResponse({"success": True, "query": q, "results": results[:50]})
except Exception as e:
return JSONResponse({"success": False, "error": str(e)}, status_code=500)