relax

Finished
1import json
2from typing import Dict, List, Optional, Any
3
14class RestAPI:
25 def __init__(self, database: dict | None = None):
3 pass
4
6 """
7 Initialize the REST API with an optional database.
8
9 Args:
10 database: Initial database with user information
11 """
12 if database is None:
13 self.database = {"users": []}
14 else:
15 self.database = database
16
17 def _find_user(self, name: str) -> Optional[Dict]:
18 """
19 Find a user by name in the database.
20
21 Args:
22 name: Name of the user to find
23
24 Returns:
25 User dictionary if found, None otherwise
26 """
27 for user in self.database["users"]:
28 if user["name"] == name:
29 return user
30 return None
31
32 def _calculate_balance(self, user: Dict) -> float:
33 """
34 Calculate the balance for a user based on what they owe and are owed.
35
36 Args:
37 user: User dictionary
38
39 Returns:
40 Calculated balance
41 """
42 total_owed_by = sum(user["owed_by"].values())
43 total_owes = sum(user["owes"].values())
44 return round(total_owed_by - total_owes, 2)
45
46 def _update_user_balances(self) -> None:
47 """Update balances for all users in the database."""
48 for user in self.database["users"]:
49 user["balance"] = self._calculate_balance(user)
50
551 def get(self, url: str, payload: str | None = None) -> str:
6 pass
7
52 """
53 Handle GET requests to the API.
54
55 Args:
56 url: Request URL
57 payload: Optional JSON payload
58
59 Returns:
60 JSON response string
61 """
62 # Edge Case: Invalid URL
63 if url != "/users":
64 return json.dumps({"error": "Invalid URL"})
65
66 # Edge Case: Malformed payload
67 if payload is not None:
68 try:
69 payload_data = json.loads(payload)
70 except json.JSONDecodeError:
71 return json.dumps({"error": "Invalid JSON payload"})
72 else:
73 payload_data = None
74
75 # Update all user balances before returning data
76 self._update_user_balances()
77
78 # Edge Case: No payload - return all users
79 if payload_data is None:
80 return json.dumps({"users": sorted(self.database["users"], key=lambda x: x["name"])})
81
82 # Edge Case: Missing 'users' key in payload
83 if "users" not in payload_data:
84 return json.dumps({"error": "Missing 'users' key in payload"})
85
86 # Edge Case: Empty users list in payload
87 if not payload_data["users"]:
88 return json.dumps({"users": []})
89
90 # Filter users based on payload
91 requested_users = payload_data["users"]
92 result_users = []
93
94 # Edge Case: Non-existent user requested
95 for user_name in requested_users:
96 user = self._find_user(user_name)
97 if user is not None:
98 result_users.append(user)
99
100 return json.dumps({"users": sorted(result_users, key=lambda x: x["name"])})
101 # Handled Edge Cases: Invalid URL, malformed payload, missing 'users' key, empty users list, non-existent user requested
102
8103 def post(self, url: str, payload: str | None = None) -> str:
9 pass
104 """
105 Handle POST requests to the API.
106
107 Args:
108 url: Request URL
109 payload: JSON payload
110
111 Returns:
112 JSON response string
113 """
114 # Edge Case: Missing payload
115 if payload is None:
116 return json.dumps({"error": "Missing payload"})
117
118 # Edge Case: Malformed payload
119 try:
120 payload_data = json.loads(payload)
121 except json.JSONDecodeError:
122 return json.dumps({"error": "Invalid JSON payload"})
123
124 # Handle /add endpoint
125 if url == "/add":
126 # Edge Case: Missing 'user' key in payload
127 if "user" not in payload_data:
128 return json.dumps({"error": "Missing 'user' key in payload"})
129
130 user_name = payload_data["user"]
131
132 # Edge Case: User already exists
133 if self._find_user(user_name) is not None:
134 return json.dumps({"error": "User already exists"})
135
136 # Create new user
137 new_user = {
138 "name": user_name,
139 "owes": {},
140 "owed_by": {},
141 "balance": 0.0
142 }
143
144 self.database["users"].append(new_user)
145 return json.dumps(new_user)
146
147 # Handle /iou endpoint
148 elif url == "/iou":
149 # Edge Case: Missing required keys in payload
150 required_keys = ["lender", "borrower", "amount"]
151 for key in required_keys:
152 if key not in payload_data:
153 return json.dumps({"error": f"Missing '{key}' key in payload"})
154
155 lender_name = payload_data["lender"]
156 borrower_name = payload_data["borrower"]
157 amount = payload_data["amount"]
158
159 # Edge Case: Lender and borrower are the same person
160 if lender_name == borrower_name:
161 return json.dumps({"error": "Lender and borrower cannot be the same person"})
162
163 # Edge Case: Invalid amount type
164 if not isinstance(amount, (int, float)):
165 return json.dumps({"error": "Amount must be a number"})
166
167 # Edge Case: Negative amount
168 if amount < 0:
169 return json.dumps({"error": "Amount cannot be negative"})
170
171 # Edge Case: Lender does not exist
172 lender = self._find_user(lender_name)
173 if lender is None:
174 return json.dumps({"error": "Lender does not exist"})
175
176 # Edge Case: Borrower does not exist
177 borrower = self._find_user(borrower_name)
178 if borrower is None:
179 return json.dumps({"error": "Borrower does not exist"})
180
181 # Update IOUs
182 # Update lender's owed_by
183 if borrower_name in lender["owed_by"]:
184 lender["owed_by"][borrower_name] += amount
185 else:
186 lender["owed_by"][borrower_name] = amount
187
188 # Update borrower's owes
189 if lender_name in borrower["owes"]:
190 borrower["owes"][lender_name] += amount
191 else:
192 borrower["owes"][lender_name] = amount
193
194 # Update balances
195 lender["balance"] = self._calculate_balance(lender)
196 borrower["balance"] = self._calculate_balance(borrower)
197
198 # Return updated users sorted by name
199 result_users = sorted([lender, borrower], key=lambda x: x["name"])
200 return json.dumps({"users": result_users})
201
202 # Edge Case: Invalid URL
203 else:
204 return json.dumps({"error": "Invalid URL"})
205 # Handled Edge Cases: Missing payload, malformed payload, missing 'user' key, user already exists, missing required keys, lender and borrower are the same, invalid amount type, negative amount, lender does not exist, borrower does not exist, invalid URL
206# Handled Edge Cases: Missing payload, malformed payload, missing 'user' key, user already exists, missing required keys, lender and borrower are the same, invalid amount type, negative amount, lender does not exist, borrower does not exist, invalid URL
Test NameStatus
test_lender_owes_borrower
Fail
test_lender_owes_borrower_less_than_new_loan
Fail
test_lender_owes_borrower_same_as_new_loan
Fail
test_add_user
Pass
test_borrower_has_negative_balance
Pass
test_both_users_have_0_balance
Pass
test_get_single_user
Pass
test_lender_has_negative_balance
Pass
test_no_users
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.