From 0d1e321b7e331ff52ae9e6cb33c0e88e0321dd7f Mon Sep 17 00:00:00 2001 From: Ivan Date: Sun, 18 Apr 2021 16:07:59 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20api=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D1=8B=20=D1=81=D0=BE=20=D1=81=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=D0=B0=D0=BC=D0=B8=20=D0=B8=20=D0=B7=D0=B0=D0=B4=D0=B0?= =?UTF-8?q?=D1=87=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/api.py | 192 +++++++++++++++++++++++++++---------------- frontend/api_demo.py | 59 +++++++++---- frontend/user.py | 95 +++++++++++++++++++++ 3 files changed, 262 insertions(+), 84 deletions(-) create mode 100644 frontend/user.py diff --git a/frontend/api.py b/frontend/api.py index 8292761..e180c72 100644 --- a/frontend/api.py +++ b/frontend/api.py @@ -1,17 +1,27 @@ +from types import SimpleNamespace import urllib import requests DEFAULT_URL = "http://127.0.0.1:8000" + +API_TODO_ITEMS_LIST = "api/todo_items/" +API_TODO_ITEMS_CREATE = "api/todo_items/" +API_TODO_ITEMS_READ = "api/todo_items/{0}/" +API_TODO_ITEMS_UPDATE = "api/todo_items/{0}/" +API_TODO_ITEMS_PARTIAL_UPDATE = "api/todo_items/{0}/" +API_TODO_ITEMS_DELETE = "api/todo_items/{0}/" + API_LISTS_LIST = "api/lists/" API_LISTS_CREATE = "api/lists/" API_LISTS_READ = "lists/{0}/" API_LISTS_UPDATE = "lists/{0}/" API_LISTS_PARTIAL_UPDATE = "lists/{0}/" API_LISTS_DELETE = "lists/{0}/" + API_TOKEN = "api/token/" -class User(object): +class UserApi(object): def __init__(self, url=DEFAULT_URL, token=None): """ Constructor @@ -50,14 +60,13 @@ class User(object): Generated auth token. """ - url = self.get_api(API_TOKEN) - data = {"username": user, "password": passwd} - response = requests.post(url=url, json=data) - response.raise_for_status() - self.token = response.json() + token = UserApi._raise_or_return_( + requests.post(url=self.get_api(API_TOKEN), json={"username": user, "password": passwd}) + ) + self.token = SimpleNamespace(**token) return self.token - def list(self): + def lists_list(self, **argv): """ List all the exsiting to-do lists. Auth required @@ -68,13 +77,16 @@ class User(object): to-do lists. """ - response = requests.get(url=self.get_api(API_LISTS_LIST), headers=self._access_token_()) - response.raise_for_status() - return response.json() + return UserApi._raise_or_return_( + requests.get( + url=self.get_api(API_LISTS_LIST), headers=self._access_token_(), params=argv + ) + ) - def create(self, title="Untitled"): + def lists_create(self, title="Untitled"): """ Create a new to-do list + Auth required Parameters ---------- @@ -82,83 +94,125 @@ class User(object): New list name. The default is "Untitled". """ - response = requests.post( - url=self.get_api(API_LISTS_CREATE), json={"title": title}, headers=self._access_token_() + return UserApi._raise_or_return_( + requests.post( + url=self.get_api(API_LISTS_CREATE), + json={"title": title}, + headers=self._access_token_(), + ) ) - response.raise_for_status() - return response.json() - def read(self, id): + def todo_items_list(self, **argv): """ - Read a to-do list contents - - Parameters - ---------- - id : int - List id. + List all the exsiting to-do items. + Auth required Returns ------- list - Requested contents + to-do items. """ - response = requests.post( - url=self.get_api(API_LISTS_READ).format(id), headers=self._access_token_() + return UserApi._raise_or_return_( + requests.get( + url=self.get_api(API_TODO_ITEMS_LIST), headers=self._access_token_(), params=argv + ) ) - response.raise_for_status() - return response.json() - def update(self, id, title="Untitled"): - """ - Add a to-do item to the list + # def create(self, title="Untitled"): + # """ + # Create a new to-do list + # Auth required - Parameters - ---------- - id : int - List id. - title : str, optional - To-do item title. The default is "Untitled". + # Parameters + # ---------- + # title : str, optional + # New list name. The default is "Untitled". - """ - response = requests.put( - json={"title": title}, - url=self.get_api(API_LISTS_UPDATE).format(id), - headers=self._access_token_(), - ) - response.raise_for_status() - return response.json() + # """ + # response = requests.post( + # url=self.get_api(API_LISTS_CREATE), json={"title": title}, headers=self._access_token_() + # url=self.get_api(API_TODO_ITEMS_CREATE), json={"title": title}, headers=self._access_token_() + # ) + # response.raise_for_status() + # return response.json() - def partial_update(self, id, title="Untitled"): - """ - Update list item - untrusted + # def read(self, id): + # """ + # Read a to-do list contents - """ - response = requests.patch( - json={"title": title}, - url=self.get_api(API_LISTS_PARTIAL_UPDATE).format(id), - headers=self._access_token_(), - ) - response.raise_for_status() - return response.json() + # Parameters + # ---------- + # id : int + # List id. - def delete(self, id): - """ - Delete list + # Returns + # ------- + # list + # Requested contents - Parameters - ---------- - id : int - List id to delete. + # """ + # response = requests.post( + # url=self.get_api(API_LISTS_READ).format(id), headers=self._access_token_() + # ) + # response.raise_for_status() + # return response.json() - """ - response = requests.delete( - url=self.get_api(API_LISTS_DELETE).format(id), headers=self._access_token_() - ) - response.raise_for_status() - return response.json() + # def update(self, id, title="Untitled"): + # """ + # Add a to-do item to the list + + # Parameters + # ---------- + # id : int + # List id. + # title : str, optional + # To-do item title. The default is "Untitled". + + # """ + # response = requests.put( + # json={"title": title}, + # url=self.get_api(API_LISTS_UPDATE).format(id), + # headers=self._access_token_(), + # ) + # response.raise_for_status() + # return response.json() + + # def partial_update(self, id, title="Untitled"): + # """ + # Update list item - untrusted + + # """ + # response = requests.patch( + # json={"title": title}, + # url=self.get_api(API_LISTS_PARTIAL_UPDATE).format(id), + # headers=self._access_token_(), + # ) + # response.raise_for_status() + # return response.json() + + # def delete(self, id): + # """ + # Delete list + + # Parameters + # ---------- + # id : int + # List id to delete. + + # """ + # response = requests.delete( + # url=self.get_api(API_LISTS_DELETE).format(id), headers=self._access_token_() + # ) + # response.raise_for_status() + # return response.json() def _access_token_(self): if self.token is None: raise RuntimeError("Authosization required for requested operation!") - return {"Authorization": f'Bearer {self.token["access"]}'} + return {"Authorization": f"Bearer {self.token.access}"} + + @staticmethod + def _raise_or_return_(response): + response.raise_for_status() + return response.json() diff --git a/frontend/api_demo.py b/frontend/api_demo.py index 92ad4c1..f79bbc3 100644 --- a/frontend/api_demo.py +++ b/frontend/api_demo.py @@ -1,19 +1,48 @@ -from api import User +from user import User -def ignore_exceptions(*args, **argv): - try: - args[0](*(args[1:]), **argv) - except Exception as e: - print(e) +def print_lists(lists): + for item in lists: + print(f"List: '{item}'", f"Id: {item.id}", "|", "|".join([str(x) for x in item.items])) -user = User() -print("testing api methods...") -print("auth..."), ignore_exceptions(user.auth, "root", "root") -print("list..."), ignore_exceptions(user.list) -print("create..."), ignore_exceptions(user.create) -print("read..."), ignore_exceptions(user.read, id=0) -print("update..."), ignore_exceptions(user.update, id=0, title="Title") -print("partial_update..."), ignore_exceptions(user.partial_update, id=0, title="Title") -print("delete..."), ignore_exceptions(user.update, id=0) +DEFAULT_URL = "http://127.0.0.1:8000" + +user = User(url=DEFAULT_URL) +user.auth("root", "root") + +# Fetch existing lists: +lists = user.fetchUserLists() +print("Fecthing...") +print_lists(lists) + +# Remove user list by id: +user.removeUserList(5) +lists = user.fetchUserLists() +print(f"Removing {5}...") +print_lists(lists) + +# Append a new list to user: +print("Appending list...") +scroll = user.appendUserList(title="a new list!") +print_lists(lists) + +# Modify list 0: +print("Modifyng list...") +lists[0].modify(title="A new title") +print_lists(lists) + +# Append item to list: +print("Appending item to last list...") +item = lists[-1].append(text="this is an item") +print_lists(lists) + +# Modifying item +print("Modifyng appended item...") +item.modify(finished=True, text="this is an updated item") +print_lists(lists) + +# Removing item at 0 +print("Removing item 0 from list 0...") +lists[0].remove(0) +print_lists(lists) diff --git a/frontend/user.py b/frontend/user.py new file mode 100644 index 0000000..aa91e63 --- /dev/null +++ b/frontend/user.py @@ -0,0 +1,95 @@ +from datetime import datetime +from api import UserApi + + +class ToDoList(object): + def __init__(self, id, title, created_at=None, items=[], parent=None): + self.id = id + self.title = title + self.items = items + self.created_at = created_at + + def __getitem__(self, index): + return self.items[index] + + def __len__(self): + return len(self.items) + + def __str__(self): + return f"[{self.id}] {self.title}" + + # ToDo + def remove(self, index): + self.items.remove(self.items[0]) + self.sync() + + # ToDo + def append(self, text): + item = ToDoItem(id=None, text=text, created_at=datetime.now()) + self.items.append(item) + item.sync() + self.sync() + return item + + def modify(self, **argv): + for key, value in argv.items(): + setattr(self, key, value) + self.sync() + + # ToDo + def sync(self): + # ToDo send request or store in form + print(f"Item '{self}' is being synchronized...") + + +class ToDoItem(object): + def __init__(self, id, text, finished=False, created_at=None, parent=None): + self.id = id + self.text = text + self.finished = finished + self.created_at = created_at + + def __str__(self): + return f"[{self.id}] {self.text}" + + def modify(self, **argv): + for key, value in argv.items(): + setattr(self, key, value) + self.sync() + + # ToDo + def sync(self): + # ToDo send request or store in form + print(f"Item '{self}' is being synchronized...") + + +class User(UserApi): + + # ToDo + items = [ + ToDoList( + id=i, + title=f"List {i}", + created_at=datetime.now(), + items=[ + ToDoItem(id=i * 10 + j, text=f"Item {i*10+j}", created_at=datetime.now()) + for j in range(10) + ], + ) + for i in range(10) + ] + + # ToDo + def fetchUserLists(self): + return self.items + + # ToDo + def removeUserList(self, id): + self.items = [item for item in self.items if item.id != id] + + # ToDo + def appendUserList(self, title): + item = ToDoList(id=None, title=title, created_at=datetime.now()) + self.items.append(item) + item.sync() + return item