[WIP] Python: rest_api working prototype

This commit is contained in:
Dmitry Kokorin 2021-06-30 17:56:39 +03:00
parent 69f1ffe661
commit 592f9cc8f5

View file

@ -1,9 +1,12 @@
import json import json
from collections import defaultdict from collections import defaultdict
from functools import wraps from functools import wraps
from operator import attrgetter
VALID_HTTP_METHODS = ['GET', 'POST'] VALID_HTTP_METHODS = ['GET', 'POST']
def dump(obj):
return obj.__dict__
class User: class User:
def __init__(self, name): def __init__(self, name):
@ -12,18 +15,32 @@ class User:
self.owed_by = defaultdict(float) self.owed_by = defaultdict(float)
self.balance = 0.0 self.balance = 0.0
def lend(self, lender_name, amount): def lend(self, borrower, amount):
self.owed_by[lender_name] += amount
if not self.owed_by[lender_name]:
del self.owed_by[lender_name]
def borrow(self, borrower_name, amount): total_owed = self.owed_by[borrower] - self.owes[borrower] + amount
self.owes[borrower_name] += amount if total_owed > 0:
if not self.owed_by[borrower_name]: self.owed_by[borrower] = total_owed
del self.owed_by[borrower_name] self.owes.pop(borrower, None)
elif total_owed < 0:
self.owes[borrower] = -total_owed
self.owed_by.pop(borrower, None)
else:
self.owed_by.pop(borrower, None)
self.owes.pop(borrower, None)
self.balance += amount
def borrow(self, lender, amount):
self.lend(lender, -amount)
@classmethod
def from_dict(cls, d):
user = cls(d['name'])
user.owed_by.update(d['owed_by'])
user.owes.update(d['owes'])
user.balance = d['balance']
return user
def to_json(self):
return json.dumps(self.__dict__)
class Registry: class Registry:
def __init__(self): def __init__(self):
@ -45,39 +62,45 @@ class RestAPI:
registry = Registry() registry = Registry()
def __init__(self, database=None): def __init__(self, database=None):
self._database = database if database else {} self._users = {user['name'] : User.from_dict(user) for user in database['users']} if database else {}
self._users = {}
@registry.register_url('/users', 'GET') @registry.register_url('/users', 'GET')
def users(self, payload=None): def users(self, payload=None):
pass if payload:
requested_users = json.loads(payload)['users']
response = [user for user in self._users.values() if user.name in requested_users]
else:
response = [user for user in self._users.values()]
return json.dumps({'users': response}, default=dump, sort_keys=True)
@registry.register_url('/add', 'POST') @registry.register_url('/add', 'POST')
def add(self, payload=None): def add(self, payload=None):
try: payload = json.loads(payload)
payload = json.loads(payload) user = User(payload['user'])
user = User(payload['user']) self._users[user.name] = user
self._users[user.name] = user return json.dumps(user, default=dump)
return user.to_json()
except:
pass
@registry.register_url('/iou', 'POST') @registry.register_url('/iou', 'POST')
def iou(self, payload=None): def iou(self, payload=None):
pass payload = json.loads(payload)
lender = payload['lender']
borrower = payload['borrower']
amount = payload['amount']
self._users[lender].lend(borrower, amount)
self._users[borrower].borrow(lender, amount)
return json.dumps({'users': sorted([self._users[lender], self._users[borrower]], key=attrgetter('name'))}, default=dump, sort_keys=True)
def get(self, url, payload=None): def get(self, url, payload=None):
methods = self.registry.methods['GET'] methods = self.registry.methods['GET']
if url in methods.keys(): if url in methods.keys():
return methods[url](self, payload) return methods[url](self, payload)
return '' else:
# else: raise Exception('Error 404')
# raise Exception('Error 404')
def post(self, url, payload=None): def post(self, url, payload=None):
methods = self.registry.methods['POST'] methods = self.registry.methods['POST']
if url in methods.keys(): if url in methods.keys():
return methods[url](self, payload) return methods[url](self, payload)
return '' else:
# else: raise Exception('Error 404')
# raise Exception('Error 404')