From 3ce2bf6efa5d52250e82caa407b7df693bd7dd51 Mon Sep 17 00:00:00 2001 From: "Phyks (Lucas Verney)" Date: Fri, 25 Dec 2015 22:14:10 +0100 Subject: [PATCH] Add routes for deletion --- main.py | 5 ++- routes/__init__.py | 3 +- routes/delete.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++ routes/post.py | 7 +++- 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 routes/delete.py diff --git a/main.py b/main.py index f61a689..b568b23 100755 --- a/main.py +++ b/main.py @@ -34,7 +34,6 @@ app.install(plugin) # Routes -# TODO: Routes for deletion @app.get("/") def index(): return tools.APIResponse(tools.pretty_json({ @@ -47,6 +46,10 @@ app.get("/papers//relationships/", callback=routes.get.fetch_relationship) app.get("/papers//", callback=routes.get.fetch_relationship) +app.route("/papers/", method="DELETE", + callback=routes.delete.delete_paper) +app.route("/papers//relationships/", method="DELETE", + callback=routes.delete.delete_relationship) app.post("/papers", callback=routes.post.create_paper) diff --git a/routes/__init__.py b/routes/__init__.py index 121b1fb..fea823b 100644 --- a/routes/__init__.py +++ b/routes/__init__.py @@ -1,4 +1,5 @@ +from . import delete from . import get from . import post -__all__ = ["get", "post"] +__all__ = ["delete", "get", "post"] diff --git a/routes/delete.py b/routes/delete.py new file mode 100644 index 0000000..cb79a3c --- /dev/null +++ b/routes/delete.py @@ -0,0 +1,85 @@ +""" +This file contains DELETE routes methods. +""" +import bottle + +import database +import json +import tools + + +def delete_paper(id, db): + """ + Delete a given paper. + + .. code-block:: bash + + DELETE /papers/1 + Accept: application/vnd.api+json + + + .. code-block:: bash + + HTTP 204 + + :param id: The id of the requested paper to be deleted. + :param db: A database session, injected by the ``Bottle`` plugin. + :returns: An ``HTTPResponse``. + """ + resource = db.query(database.Paper).filter_by(id=id).first() + if resource: + db.delete(resource) + return tools.APIResponse(status=204, body="") + return bottle.HTTPError(404, "Not found") + + +def delete_relationship(id, name, db): + """ + Delete a given relationship + + .. code-block:: bash + + DELETE /papers/1/relationships/cite + Content-Type: application/vnd.api+json + Accept: application/vnd.api+json + + { + "data": [ + { "type": "cite", "id": "2" }, + … + ] + } + + + .. code-block:: bash + + HTTP 204 + + :param id: The id of the requested paper from which the relationship \ + should be deleted. + :param name: The name of the relationship to delete from. + :param db: A database session, injected by the ``Bottle`` plugin. + :returns: An ``HTTPResponse``. + """ + data = json.loads(bottle.request.body.read().decode("utf-8")) + # Validate the request + if "data" not in data: + return bottle.HTTPError(403, "Forbidden") + # Filter data, invalid entries are ignored + data = [i for i in data["data"] + if "type" in i and i["type"] == name and "id" in i] + # Complete replacement (data == []) is forbidden + if len(data) == 0: + return bottle.HTTPError(403, "Forbidden") + # Delete all the requested relationships + for i in data: + relationship = (db.query(database.Association) + .filter_by(left_id=id, right_id=i["id"]) + .filter(database.Relationship.name == name) + .first()) + if relationship is None: + # An error occurred => 403 + return bottle.HTTPError(403, "Forbidden") + db.delete(relationship) + # Return an empty 204 on success + return tools.APIResponse(status=204, body="") diff --git a/routes/post.py b/routes/post.py index 2aa2c70..8d62d7f 100644 --- a/routes/post.py +++ b/routes/post.py @@ -44,7 +44,12 @@ def create_paper(db): "self": "/papers/1" }, "relationships": { - TODO + "cite": { + "links": { + "related": "/papers/1/relationships/cite" + } + }, + … } } }