From 76ba742d3ce3e07c3cd6d25a4eb9c23716f6f5f6 Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Fri, 18 Jun 2021 21:47:20 +0530 Subject: [PATCH 1/8] changed item resource --- hydrus/app_factory.py | 10 ---------- hydrus/resources.py | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/hydrus/app_factory.py b/hydrus/app_factory.py index 9a47a955..4b2957ed 100644 --- a/hydrus/app_factory.py +++ b/hydrus/app_factory.py @@ -51,16 +51,6 @@ def root_url(): ItemCollection, f"/{api_name}/", endpoint="item_collection" ) api.add_resource(Item, f"/{api_name}//", endpoint="item") - api.add_resource( - ItemMember, - f"/{api_name}///", - endpoint="member" - ) - api.add_resource( - ItemMembers, - f"/{api_name}///delete/", - endpoint="members" - ) api.add_resource( Items, f"/{api_name}//add/", diff --git a/hydrus/resources.py b/hydrus/resources.py index ffa56652..5b0ed15a 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -106,6 +106,13 @@ def get(self, id_: str, path: str) -> Response: # Get path of the collection-class class_path = item_class.path is_collection = True + # To check if it's a request to GET a single instance from Collection + params = request.args.to_dict() + member_id = params.get('instance', None) + if member_id: + return member_get_check_support( + id_, member_id, class_type, class_path, path + ) if checkClassOp(class_path, "GET"): return items_get_check_support( id_, class_type, class_path, path, is_collection @@ -165,6 +172,10 @@ def delete(self, id_: str, path: str) -> Response: :param path - Path for Item type( Specified in APIDoc @id) to be deleted """ id_ = str(id_) + params = request.args.to_dict() + if params.get('instance'): + id_list = params.get('instance',None) + return items_delete_members_response(path, id_, id_list) collections, parsed_classes = get_collections_and_parsed_classes() is_collection = False if path in parsed_classes: From 420e3012760b86fe2f9e554cebf46d1543fb5024 Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Fri, 18 Jun 2021 21:59:16 +0530 Subject: [PATCH 2/8] changed put for itemcollection --- hydrus/data/crud.py | 9 ++++++--- hydrus/resources.py | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/hydrus/data/crud.py b/hydrus/data/crud.py index f991c214..f9d8cccf 100644 --- a/hydrus/data/crud.py +++ b/hydrus/data/crud.py @@ -149,9 +149,10 @@ def insert_multiple( valid/defined RDFClass but is not a dictionary neither an Abstract Property """ - # import pdb;pdb.set_trace() - - id_list = id_.split(",") + if id_: + id_list = id_.split(",") + else: + id_list = None # list to hold all the ids of inserted objects instance_id_list = [] @@ -164,6 +165,8 @@ def insert_multiple( id_of_object_ = id_list[index] except IndexError: pass + except TypeError: + pass inserted_object_id = insert(object_, session, id_of_object_) instance_id_list.append(inserted_object_id) diff --git a/hydrus/resources.py b/hydrus/resources.py index 5b0ed15a..453af008 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -219,6 +219,12 @@ def put(self, path: str) -> Response: if not endpoint_["method"]: # If endpoint and PUT method is not supported in the API abort(endpoint_["status"]) + # If 'instance' is available in request + params = request.args.to_dict() + object_ = json.loads(request.data.decode("utf-8")) + if params.get("instance") or object_.get("data"): + int_list = params.get("instance",None) + return items_put_response(path, int_list) return item_collection_put_response(path) From 0e6e0e0f972e1bb1eadf0631463b77a8edd1eace Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Fri, 18 Jun 2021 22:06:48 +0530 Subject: [PATCH 3/8] delete for itemcollection --- hydrus/app_factory.py | 6 ------ hydrus/resources.py | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/hydrus/app_factory.py b/hydrus/app_factory.py index 4b2957ed..d5196c1c 100644 --- a/hydrus/app_factory.py +++ b/hydrus/app_factory.py @@ -51,11 +51,5 @@ def root_url(): ItemCollection, f"/{api_name}/", endpoint="item_collection" ) api.add_resource(Item, f"/{api_name}//", endpoint="item") - api.add_resource( - Items, - f"/{api_name}//add/", - f"/{api_name}//add", - f"/{api_name}//delete/", - ) return app diff --git a/hydrus/resources.py b/hydrus/resources.py index 453af008..4378360d 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -227,6 +227,20 @@ def put(self, path: str) -> Response: return items_put_response(path, int_list) return item_collection_put_response(path) + @authenticate + def delete(self, path): + """ + To delete multiple objects + :param path: endpoints + :param int_list: Optional String containing ',' separated ID's + :return: + """ + params = request.args.to_dict() + if params.get('instance'): + int_list = params.get('instance',None) + return items_delete_response(path, int_list) + abort(405) + class ItemMember(Resource): """Handles operations(GET,DELETE) related to member of an Item(Collection). From e150a308814ed4b6ae712381d1434fb2b3375415 Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Fri, 18 Jun 2021 22:08:20 +0530 Subject: [PATCH 4/8] removed unused resources --- hydrus/app_factory.py | 3 -- hydrus/resources.py | 97 ------------------------------------------- 2 files changed, 100 deletions(-) diff --git a/hydrus/app_factory.py b/hydrus/app_factory.py index d5196c1c..3184166d 100644 --- a/hydrus/app_factory.py +++ b/hydrus/app_factory.py @@ -19,9 +19,6 @@ def app_factory(api_name: str = "api", vocab_route: str = "vocab") -> Flask: Entrypoint, ItemCollection, Item, - Items, - ItemMember, - ItemMembers, ) app = Flask(__name__) diff --git a/hydrus/resources.py b/hydrus/resources.py index 4378360d..94711d13 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -242,103 +242,6 @@ def delete(self, path): abort(405) -class ItemMember(Resource): - """Handles operations(GET,DELETE) related to member of an Item(Collection). - (Item should be hydra:Collection)""" - - @authenticate - def get(self, id_: str, path: str, collection_id_: str) -> Response: - """ - GET object with collection_id = collection_id_ - and member = id_ (member of a collection) from the database. - :param id_ : Item ID (Member) - :param collection_id_ : Item ID (Collection) - :param path : Path for Item ( Specified in APIDoc @id) - :return : object with member=id_ and collection_id=collection_id_ - """ - collection_id = str(collection_id_) - member_id = str(id_) - collections, parsed_classes = get_collections_and_parsed_classes() - if path in parsed_classes: - abort(405) - if path in collections: - item_class = collections[path]["collection"] - class_type = item_class.name - # Get path of the collection-class - class_path = item_class.path - if checkClassOp(class_path, "GET"): - return member_get_check_support( - collection_id, member_id, class_type, class_path, path - ) - abort(405) - - @authenticate - def delete(self, id_: str, path: str, collection_id_: str) -> Response: - """ - Delete object with id=id_ from database. - :param id_ - ID of Item to be deleted - :param path - Path for Item type( Specified in APIDoc @id) to be deleted - """ - collection_id = str(collection_id_) - member_id = str(id_) - collections, parsed_classes = get_collections_and_parsed_classes() - if path in parsed_classes: - abort(405) - if path in collections: - item_class = collections[path]["collection"] - class_type = item_class.name - # Get path of the collection-class - class_path = item_class.path - if checkClassOp(class_path, "DELETE"): - return member_delete_check_support( - collection_id, member_id, class_type, path - ) - abort(405) - - -class Items(Resource): - """Handles operations(PUT,DELETE) related to multiple objects. - (Item should be hydra:Class)""" - - @authenticate - def put(self, path, int_list="") -> Response: - """ - To insert multiple objects into the database - :param path: endpoint - :param int_list: Optional String containing ',' separated ID's - :return: - """ - endpoint_ = checkEndpoint("PUT", path) - if not endpoint_["method"]: - # If endpoint and PUT method is not supported in the API - abort(endpoint_["status"]) - return items_put_response(path, int_list) - - @authenticate - def delete(self, path, int_list): - """ - To delete multiple objects - :param path: endpoints - :param int_list: Optional String containing ',' separated ID's - :return: - """ - return items_delete_response(path, int_list) - - -class ItemMembers(Resource): - @authenticate - def delete(self, path, collection_id_, int_list): - """ - To delete multiple members from a Collection - :param path: endpoints - :param collection_id_: ID of the collection - :param int_list: Optional String containing ',' separated ID's - :return: - """ - collection_id_ = str(collection_id_) - return items_delete_members_response(path, collection_id_, int_list) - - class Contexts(Resource): """Dynamically generated contexts.""" From 56c7df946637771c39ea900fb03325b4910d2d8d Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Fri, 18 Jun 2021 22:13:16 +0530 Subject: [PATCH 5/8] fix tests --- hydrus/resources.py | 6 +++--- tests/functional/test_app.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hydrus/resources.py b/hydrus/resources.py index 94711d13..589d703b 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -174,7 +174,7 @@ def delete(self, id_: str, path: str) -> Response: id_ = str(id_) params = request.args.to_dict() if params.get('instance'): - id_list = params.get('instance',None) + id_list = params.get('instance', None) return items_delete_members_response(path, id_, id_list) collections, parsed_classes = get_collections_and_parsed_classes() is_collection = False @@ -223,7 +223,7 @@ def put(self, path: str) -> Response: params = request.args.to_dict() object_ = json.loads(request.data.decode("utf-8")) if params.get("instance") or object_.get("data"): - int_list = params.get("instance",None) + int_list = params.get("instance", None) return items_put_response(path, int_list) return item_collection_put_response(path) @@ -237,7 +237,7 @@ def delete(self, path): """ params = request.args.to_dict() if params.get('instance'): - int_list = params.get('instance',None) + int_list = params.get('instance', None) return items_delete_response(path, int_list) abort(405) diff --git a/tests/functional/test_app.py b/tests/functional/test_app.py index b595c67f..e9811d0d 100644 --- a/tests/functional/test_app.py +++ b/tests/functional/test_app.py @@ -319,7 +319,7 @@ def test_object_PUT_at_ids(self, test_app_client, constants, doc): ids = f'{uuid.uuid4()},' data_['data'] = objects if 'PUT' in class_methods: - put_response = test_app_client.put(f'{endpoints[endpoint]}/add/{ids}', + put_response = test_app_client.put(f'{endpoints[endpoint]}?instance={ids}', data=json.dumps(data_)) assert put_response.status_code == 201 assert isinstance(put_response.json['iri'], list) @@ -436,7 +436,7 @@ def test_Collections_member_GET(self, test_app_client, constants, doc): if 'GET' in collection_methods: for member in dummy_object['members']: member_id = member['@id'].split('/')[-1] - get_response = test_app_client.get(f'{collection_endpoint}/{member_id}') + get_response = test_app_client.get(f'{collection_endpoint}?instance={member_id}') assert get_response.status_code == 200 def test_Collections_member_DELETE(self, test_app_client, constants, doc): @@ -458,7 +458,7 @@ def test_Collections_member_DELETE(self, test_app_client, constants, doc): if 'DELETE' in collection_methods: for member in dummy_object['members']: member_id = member['@id'].split('/')[-1] - full_endpoint = f'{collection_endpoint}/{member_id}' + full_endpoint = f'{collection_endpoint}?instance={member_id}' delete_response = test_app_client.delete(full_endpoint) assert delete_response.status_code == 200 @@ -480,7 +480,7 @@ def test_Collections_member_DELETE_multiple(self, capsys, test_app_client, const collection_endpoint = good_response_put.location if 'DELETE' in collection_methods: ids_list = get_ids_list(dummy_object) - full_endpoint = f'{collection_endpoint}/delete/{ids_list}' + full_endpoint = f'{collection_endpoint}?instance={ids_list}' delete_response = test_app_client.delete(full_endpoint) assert delete_response.status_code == 200 From 2872d7b31dc4926f522e83e4f878368547910332 Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Sat, 19 Jun 2021 10:07:04 +0530 Subject: [PATCH 6/8] update docstring --- hydrus/resources.py | 1 - 1 file changed, 1 deletion(-) diff --git a/hydrus/resources.py b/hydrus/resources.py index 589d703b..aac9b130 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -232,7 +232,6 @@ def delete(self, path): """ To delete multiple objects :param path: endpoints - :param int_list: Optional String containing ',' separated ID's :return: """ params = request.args.to_dict() From 3a41c5b1cc07f6bf0919c49995a218a06547aa15 Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Sat, 19 Jun 2021 18:05:07 +0530 Subject: [PATCH 7/8] use ?instances --- hydrus/resources.py | 16 ++++++++-------- tests/functional/test_app.py | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/hydrus/resources.py b/hydrus/resources.py index aac9b130..8bc23ab0 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -108,7 +108,7 @@ def get(self, id_: str, path: str) -> Response: is_collection = True # To check if it's a request to GET a single instance from Collection params = request.args.to_dict() - member_id = params.get('instance', None) + member_id = params.get('instances', None) if member_id: return member_get_check_support( id_, member_id, class_type, class_path, path @@ -173,8 +173,8 @@ def delete(self, id_: str, path: str) -> Response: """ id_ = str(id_) params = request.args.to_dict() - if params.get('instance'): - id_list = params.get('instance', None) + if params.get('instances'): + id_list = params.get('instances', None) return items_delete_members_response(path, id_, id_list) collections, parsed_classes = get_collections_and_parsed_classes() is_collection = False @@ -219,11 +219,11 @@ def put(self, path: str) -> Response: if not endpoint_["method"]: # If endpoint and PUT method is not supported in the API abort(endpoint_["status"]) - # If 'instance' is available in request + # If 'instances' is available in request params = request.args.to_dict() object_ = json.loads(request.data.decode("utf-8")) - if params.get("instance") or object_.get("data"): - int_list = params.get("instance", None) + if params.get("instances") or object_.get("data"): + int_list = params.get("instances", None) return items_put_response(path, int_list) return item_collection_put_response(path) @@ -235,8 +235,8 @@ def delete(self, path): :return: """ params = request.args.to_dict() - if params.get('instance'): - int_list = params.get('instance', None) + if params.get('instances'): + int_list = params.get('instances', None) return items_delete_response(path, int_list) abort(405) diff --git a/tests/functional/test_app.py b/tests/functional/test_app.py index e9811d0d..56342481 100644 --- a/tests/functional/test_app.py +++ b/tests/functional/test_app.py @@ -319,7 +319,7 @@ def test_object_PUT_at_ids(self, test_app_client, constants, doc): ids = f'{uuid.uuid4()},' data_['data'] = objects if 'PUT' in class_methods: - put_response = test_app_client.put(f'{endpoints[endpoint]}?instance={ids}', + put_response = test_app_client.put(f'{endpoints[endpoint]}?instances={ids}', data=json.dumps(data_)) assert put_response.status_code == 201 assert isinstance(put_response.json['iri'], list) @@ -436,7 +436,7 @@ def test_Collections_member_GET(self, test_app_client, constants, doc): if 'GET' in collection_methods: for member in dummy_object['members']: member_id = member['@id'].split('/')[-1] - get_response = test_app_client.get(f'{collection_endpoint}?instance={member_id}') + get_response = test_app_client.get(f'{collection_endpoint}?instances={member_id}') assert get_response.status_code == 200 def test_Collections_member_DELETE(self, test_app_client, constants, doc): @@ -458,7 +458,7 @@ def test_Collections_member_DELETE(self, test_app_client, constants, doc): if 'DELETE' in collection_methods: for member in dummy_object['members']: member_id = member['@id'].split('/')[-1] - full_endpoint = f'{collection_endpoint}?instance={member_id}' + full_endpoint = f'{collection_endpoint}?instances={member_id}' delete_response = test_app_client.delete(full_endpoint) assert delete_response.status_code == 200 @@ -480,7 +480,7 @@ def test_Collections_member_DELETE_multiple(self, capsys, test_app_client, const collection_endpoint = good_response_put.location if 'DELETE' in collection_methods: ids_list = get_ids_list(dummy_object) - full_endpoint = f'{collection_endpoint}?instance={ids_list}' + full_endpoint = f'{collection_endpoint}?instances={ids_list}' delete_response = test_app_client.delete(full_endpoint) assert delete_response.status_code == 200 From 458794d3702a33d530e4ebcf292ebbdf49224368 Mon Sep 17 00:00:00 2001 From: farazkhanfk7 Date: Mon, 21 Jun 2021 22:14:37 +0530 Subject: [PATCH 8/8] minor changes --- hydrus/resources.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hydrus/resources.py b/hydrus/resources.py index 8bc23ab0..b0e0408b 100644 --- a/hydrus/resources.py +++ b/hydrus/resources.py @@ -108,8 +108,8 @@ def get(self, id_: str, path: str) -> Response: is_collection = True # To check if it's a request to GET a single instance from Collection params = request.args.to_dict() - member_id = params.get('instances', None) - if member_id: + member_id = params.get("instances") + if member_id is not None: return member_get_check_support( id_, member_id, class_type, class_path, path ) @@ -173,8 +173,8 @@ def delete(self, id_: str, path: str) -> Response: """ id_ = str(id_) params = request.args.to_dict() - if params.get('instances'): - id_list = params.get('instances', None) + if params.get("instances"): + id_list = params.get("instances") return items_delete_members_response(path, id_, id_list) collections, parsed_classes = get_collections_and_parsed_classes() is_collection = False @@ -223,7 +223,7 @@ def put(self, path: str) -> Response: params = request.args.to_dict() object_ = json.loads(request.data.decode("utf-8")) if params.get("instances") or object_.get("data"): - int_list = params.get("instances", None) + int_list = params.get("instances") return items_put_response(path, int_list) return item_collection_put_response(path) @@ -235,8 +235,8 @@ def delete(self, path): :return: """ params = request.args.to_dict() - if params.get('instances'): - int_list = params.get('instances', None) + if params.get("instances"): + int_list = params.get("instances") return items_delete_response(path, int_list) abort(405)