def items_put_check_support(id_, class_path, path, is_collection): """Check if class_type supports PUT operation""" object_ = json.loads(request.data.decode('utf-8')) collections, parsed_classes = get_collections_and_parsed_classes() if path in parsed_classes: class_path = path obj_type = getType(path, "PUT") elif path in collections: collection = collections[path]["collection"] class_path = collection.path obj_type = collection.name link_props, link_type_check = get_link_props(class_path, object_) # Load new object and type if (validate_object(object_, obj_type, class_path) and link_type_check): if is_collection: object_ = parse_collection_members(object_) try: # Add the object with given ID object_id = crud.insert(object_=object_, id_=id_, session=get_session(), collection=is_collection) headers_ = [{"Location": f"{get_hydrus_server_url()}" f"{get_api_name()}/{path}/{object_id}"}] status_description = f"Object with ID {object_id} successfully added" status = HydraStatus(code=201, title="Object successfully added.", desc=status_description) return set_response_headers( jsonify(status.generate()), headers=headers_, status_code=status.code) except (ClassNotFound, InstanceExists, PropertyNotFound) as e: error = e.get_HTTP() return error_response(error) else: error = HydraError(code=400, title="Data is not valid") return error_response(error)
def items_put_response(path: str, int_list="") -> Response: """ Handles PUT operation to insert multiple items. :param path: Path for Item Collection :type path: str :param int_list: Optional String containing ',' separated ID's :type int_list: List :return: Appropriate response for the PUT operation on multiple items. :rtype: Response """ object_ = json.loads(request.data.decode('utf-8')) object_ = object_["data"] _, parsed_classes = get_collections_and_parsed_classes() if path in parsed_classes: class_path = path obj_type = getType(path, "PUT") incomplete_objects = [] for obj in object_: if not check_required_props(class_path, obj): incomplete_objects.append(obj) object_.remove(obj) link_props_list, link_type_check = get_link_props_for_multiple_objects(class_path, object_) if validObjectList(object_) and link_type_check: type_result = type_match(object_, obj_type) # If Item in request's JSON is a valid object # ie. @type is one of the keys in object_ if type_result: # If the right Item type is being added to the # collection try: # Insert object and return location in Header object_id = crud.insert_multiple( objects_=object_, session=get_session(), id_=int_list) headers_ = [{"Location": f"{get_hydrus_server_url()}" f"{get_api_name()}/{path}/{object_id}"}] if len(incomplete_objects) > 0: status = HydraStatus(code=202, title="Object(s) missing required property") response = status.generate() response["objects"] = incomplete_objects return set_response_headers( jsonify(response), headers=headers_, status_code=status.code) else: status_description = f"Objects with ID {object_id} successfully added" status = HydraStatus(code=201, title="Objects successfully added", desc=status_description) return set_response_headers( jsonify(status.generate()), headers=headers_, status_code=status.code) except (ClassNotFound, InstanceExists, PropertyNotFound) as e: error = e.get_HTTP() return error_response(error) error = HydraError(code=400, title="Data is not valid") return error_response(error)
def items_post_check_support(id_, object_, class_path, path, is_collection): """Check if class_type supports POST operation""" collections, parsed_classes = get_collections_and_parsed_classes() if path in parsed_classes: class_path = path obj_type = getType(path, "PUT") elif path in collections: collection = collections[path]["collection"] class_path = collection.path obj_type = collection.name link_props, link_type_check = get_link_props(class_path, object_) # Load new object and type if (validate_object(object_, obj_type, class_path) and link_type_check): if is_collection: object_ = parse_collection_members(object_) try: # Update the right ID if the object is valid and matches # type of Item object_id = crud.update(object_=object_, id_=id_, type_=object_["@type"], session=get_session(), api_name=get_api_name(), collection=is_collection) method = "POST" resource_url = f"{get_hydrus_server_url()}{get_api_name()}/{path}/{object_id}" last_job_id = crud.get_last_modification_job_id( session=get_session()) new_job_id = crud.insert_modification_record(method, resource_url, session=get_session()) send_sync_update(socketio=socketio, new_job_id=new_job_id, last_job_id=last_job_id, method=method, resource_url=resource_url) headers_ = [{"Location": resource_url}] status_description = (f"Object with ID {object_id} successfully " "updated") status = HydraStatus(code=200, title="Object updated", desc=status_description) return set_response_headers(jsonify(status.generate()), headers=headers_) except (ClassNotFound, InstanceNotFound, InstanceExists, PropertyNotFound) as e: error = e.get_HTTP() return error_response(error) else: error = HydraError(code=400, title="Data is not valid") return error_response(error)
def item_collection_put_response(path: str) -> Response: """ Handles PUT operation on item collection classes. :param path: Path for Item Collection :type path: str :return: Appropriate response for the PUT operation. :rtype: Response """ object_ = json.loads(request.data.decode('utf-8')) collections, parsed_classes = get_collections_and_parsed_classes() is_collection = False if path in parsed_classes: class_path = path is_collection = False obj_type = getType(path, "PUT") elif path in collections: collection = collections[path]["collection"] class_path = collection.path obj_type = collection.name is_collection = True if validate_object(object_, obj_type, class_path): # If Item in request's JSON is a valid object ie. @type is a key in object_ # and the right Item type is being added to the collection if is_collection: object_ = parse_collection_members(object_) try: # Insert object and return location in Header object_id = crud.insert(object_=object_, session=get_session(), collection=is_collection) headers_ = [{ "Location": f"{get_hydrus_server_url()}{get_api_name()}/{path}/{object_id}" }] status_description = f"Object with ID {object_id} successfully added" status = HydraStatus(code=201, title="Object successfully added", desc=status_description) return set_response_headers(jsonify(status.generate()), headers=headers_, status_code=status.code) except (ClassNotFound, InstanceExists, PropertyNotFound, PropertyNotGiven) as e: error = e.get_HTTP() return error_response(error) else: error = HydraError(code=400, title="Data is not valid") return error_response(error)
def items_delete_check_support(id_, class_type, path, is_collection): """Check if class_type supports PUT operation""" try: # Delete the Item with ID == id_ # for colletions, id_ is corresponding to their collection_id and not the id_ # primary key crud.delete(id_, class_type, session=get_session(), collection=is_collection) method = "DELETE" resource_url = f"{get_hydrus_server_url()}{get_api_name()}/{path}/{id_}" last_job_id = crud.get_last_modification_job_id(session=get_session()) new_job_id = crud.insert_modification_record(method, resource_url, session=get_session()) send_sync_update(socketio=socketio, new_job_id=new_job_id, last_job_id=last_job_id, method=method, resource_url=resource_url) status_description = f"Object with ID {id_} successfully deleted" status = HydraStatus(code=200, title="Object successfully deleted.", desc=status_description) return set_response_headers(jsonify(status.generate())) except (ClassNotFound, InstanceNotFound) as e: error = e.get_HTTP() return error_response(error)
def item_collection_get_response(path: str) -> Response: """ Handles GET operation on item collection classes. :param path: Path for Item Collection :type path: str :return: Appropriate response for the GET operation. :rtype: Response """ search_params = request.args.to_dict() collections, parsed_classes = get_collections_and_parsed_classes() api_name = get_api_name() expanded_base_url = DocUrl.doc_url # If endpoint and GET method is supported in the API and class is supported if path in parsed_classes: abort(405) if path in collections: collection = collections[path]["collection"] class_name = collection.manages["object"].split(expanded_base_url)[1] collection_manages_class = parsed_classes[class_name]["class"] class_type = collection_manages_class.title class_path = collection_manages_class.path try: # Get collection details from the database # create partial function for crud operation crud_response = partial(crud.get_collection, api_name, class_type, session=get_session(), path=path, search_params=search_params, collection=False) if get_pagination(): # Get paginated response response = crud_response(paginate=True, page_size=get_page_size()) else: # Get whole collection response = crud_response(paginate=False) response["search"] = add_iri_template(path=class_path, API_NAME=api_name, collection_path=path) return set_response_headers(jsonify(hydrafy(response, path=path))) except (ClassNotFound, PageNotFound, InvalidSearchParameter, OffsetOutOfRange) as e: error = e.get_HTTP() return error_response(error)
def verify_user() -> Union[Response, None]: """ Verify the credentials of the user and assign token. """ try: auth = check_authorization(request, get_session()) if auth is False: return failed_authentication(True) elif get_token(): token = add_token(request, get_session()) return token_response(token) except Exception as e: error = e.get_HTTP() # type: HydraError return error_response(error) return None
def items_delete_response(path: str, int_list="") -> Response: """ Handles DELETE operation to insert multiple items. :param path: Path for Item Collection :type path: str :param int_list: Optional String containing ',' separated ID's :type int_list: List :return: Appropriate response for the DELETE operation on multiple items. :rtype: Response """ _, parsed_classes = get_collections_and_parsed_classes() if path in parsed_classes: class_type = getType(path, "DELETE") if checkClassOp(class_type, "DELETE"): # Check if class_type supports PUT operation try: # Delete the Item with ID == id_ crud.delete_multiple(int_list, class_type, session=get_session()) method = "DELETE" path_url = f"{get_hydrus_server_url()}{get_api_name()}/{path}" last_job_id = crud.get_last_modification_job_id(session=get_session()) id_list = int_list.split(',') for item in id_list: resource_url = path_url + item new_job_id = crud.insert_modification_record(method, resource_url, session=get_session()) send_sync_update(socketio=socketio, new_job_id=new_job_id, last_job_id=last_job_id, method=method, resource_url=resource_url) last_job_id = new_job_id status_description = f"Objects with ID {id_list} successfully deleted" status = HydraStatus(code=200, title="Objects successfully deleted", desc=status_description) return set_response_headers(jsonify(status.generate())) except (ClassNotFound, InstanceNotFound) as e: error = e.get_HTTP() return error_response(error) abort(405)
def items_get_check_support(id_, class_type, class_path, path, is_collection=False): """Check if class_type supports GET operation""" try: # Try getting the Item based on ID and Class type response = crud.get( id_, class_type, api_name=get_api_name(), session=get_session(), path=path, collection=is_collection) response = finalize_response(class_path, response) return set_response_headers( jsonify(hydrafy(response, path=path))) except (ClassNotFound, InstanceNotFound) as e: error = e.get_HTTP() return error_response(error)