def __init__(self, api_doc, url, test): self.endpoint_query = EndpointQuery() self.api_doc = api_doc self.url = url self.properties = PropertiesQuery() self.compare = CompareProperties() self.test = test self.redis_connection = RedisProxy() self.connection = self.redis_connection.get_connection()
def __init__(self, api_doc, url, graph): self.redis_connection = RedisProxy() self.handle_data = HandleData() self.connection = self.redis_connection.get_connection() self._data = self.handle_data self.clas = ClassEndpoints(graph.redis_graph, graph.class_endpoints) self.api_doc = api_doc self.url = url
def check_url_exist(check_url,facades): redis_connection = RedisProxy() connection = redis_connection.get_connection() url = check_url.decode("utf8") if (str.encode("fs:url") in connection.keys() and check_url in connection.smembers("fs:url")): print("url already exist in Redis") facades.initialize(False) else: facades.initialize(True) connection.sadd("fs:url", url)
def main(self, new_url, api_doc, check_commit): redis_connection = RedisProxy() redis_con = redis_connection.get_connection() self.url = new_url self.redis_graph = Graph("apidoc", redis_con) print("loading... of graph") self.get_endpoints(api_doc, redis_con) if check_commit: print("commiting") self.redis_graph.commit() # creating whole the graph in redis print("done!!!!")
class EndpointQuery: """ EndpointQuery is used for get the endpoints from the Redis. """ def __init__(self): self.redis_connection = RedisProxy() self.handle_data = HandleData() self.connection = self.redis_connection.get_connection() self._data = self.handle_data def get_allEndpoints(self, query): """ It will return both type(class and collection) of endpoints. :param query: query gets from the user, Ex: endpoints :returns: data get from the Redis memory. """ get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', "MATCH (p:classes) RETURN p") + self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', "MATCH (p:collection) RETURN p") print("classEndpoints + CollectionEndpoints") return self._data.show_data(get_data) def get_classEndpoints(self, query): """ It will return all class Endpoints. :param query: query get from user, Ex: classEndpoint :return: get data from the Redis memory. """ get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', "MATCH (p:classes) RETURN p") print("classEndpoints") return self._data.show_data(get_data) def get_collectionEndpoints(self, query): """ It will returns all collection Endpoints. :param query: query get from the user, Ex: collectionEndpoint :return: get data from the Redis memory. """ get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', "MATCH (p:collection) RETURN p") print("collectoinEndpoints") return self._data.show_data(get_data)
def query(apidoc, url): """ It uses only for query purpose. Querying still user wants or still user enters the exit. :param apidoc: Apidocumentation for the given url. :param url: url given by user. """ redis_connection = RedisProxy() connection = redis_connection.get_connection() api_doc = doc_maker.create_doc(apidoc) facades = QueryFacades(api_doc, url, False) check_url = str.encode(url) check_url_exist(check_url,facades) while True: print("press exit to quit") query = input(">>>") if query == "exit": break elif query == "help": help() else: print(facades.user_query(query))
def __init__(self): self.redis_connection = RedisProxy() self.handle_data = HandleData() self.connection = self.redis_connection.get_connection() self._data = self.handle_data
class QueryFacades: """ It is used for call the above defined functions based on given query. Using test as a bool which identify that function is using for tests. """ def __init__(self, api_doc, url, test): self.endpoint_query = EndpointQuery() self.api_doc = api_doc self.url = url self.properties = PropertiesQuery() self.compare = CompareProperties() self.test = test self.redis_connection = RedisProxy() self.connection = self.redis_connection.get_connection() def initialize(self, check_commit): """ Initialize is used to initialize the graph for given url. """ print("just initialize") self.graph = InitialGraph() self.graph.main(self.url, self.api_doc, check_commit) def check_fine_query(self, query): if query.count(" ") != 1: return RequestError("error") def user_query(self, query): """ It calls function based on queries type. """ query = query.replace("show ", "") if query == "endpoints": data = self.endpoint_query.get_allEndpoints(query) return data elif query == "classEndpoints": data = self.endpoint_query.get_classEndpoints(query) return data elif query == "collectionEndpoints": data = self.endpoint_query.get_collectionEndpoints(query) return data elif "members" in query: check_query = self.check_fine_query(query) if isinstance (check_query, RequestError): logger.info("Error: Incorrect query") return None else: self.members = CollectionmembersQuery(self.api_doc, self.url, self.graph) if self.test: data = self.members.data_from_server( query.replace(" members", "")) return data else: data = self.members.get_members(query) return data elif "objects" in query: if query[-1] == " ": logger.info("Error: incorrect query") return None check_query = self.check_fine_query(query) if isinstance (check_query, RequestError): logger.info("Error: Incorrect query") return None else: data = self.properties.get_members_properties(query) return data elif "object" in query: if query[-1] == " ": logger.info("Error: incorrect query") return None check_query = self.check_fine_query(query) if isinstance (check_query, RequestError): logger.info("Error: Incorrect query") return None else: data = self.properties.get_object_property(query) return data elif "Collection" in query: if query[-1] == " ": logger.info("Error: incorrect query") return None check_query = self.check_fine_query(query) if isinstance (check_query, RequestError): logger.info("Error: Incorrect query") return None else: data = self.properties.get_collection_properties(query) return data elif "class" in query and "property_value" in query: check_query = self.check_fine_query(query) if isinstance (check_query, RequestError): logger.info("Error: Incorrect query") return None else: self.class_property = ClassPropertiesValue(self.api_doc, self.url, self.graph) data = self.class_property.get_property_value(query) return data elif "class" in query: if query[-1] == " ": logger.info("Error: incorrect query") return None check_query = self.check_fine_query(query) if isinstance (check_query, RequestError): logger.info("Error: Incorrect query") return None else: data = self.properties.get_classes_properties(query) return data else: if " and " in query or " or " in query: if query[-1] == " " or query[-3] == "and" or query[-2] == "or": logger.info("Error: incorrect query") return None query_len = len(query.split()) and_or_count = query.count("and") + query.count("or") if query_len != (and_or_count + 2 * (and_or_count + 1)): logger.info("Error: Incorrect query") return None data = self.compare.object_property_comparison_list(query) return data elif query.count(" ") == 1: key, value = query.split(" ") print("query: ", query) search_index = "fs:" + key + ":" + value for key in self.connection.keys(): if search_index == key.decode("utf8"): data = self.connection.smembers(key) return data logger.info("Incorrect query: Use 'help' to know about querying format") return None
class CompareProperties: """ CompareProperties is used for extracting endpoints with help of properties Like input: name Drone1 and model xyz Then output: /api/DroneCollection/2 With follows objects_property_comparison_list() """ def __init__(self): self.redis_connection = RedisProxy() self.handle_data = HandleData() self.connection = self.redis_connection.get_connection() self._data = self.handle_data def faceted_key(self, key, value): """ It is simply concatenate the arguments and make faceted key. """ return ("{}".format("fs:" + key + ":" + value)) def convert_byte_string(self, value_set): """ It converts byte strings to strings. """ new_value_set = set() for obj in value_set: string = obj.decode('utf-8') new_value_set.add(string) return new_value_set def and_or_query(self, query_list): """ It is a recursive function. It takes the arguement as list(query_list) which contains the faceted indexes and operation and brackets also. List Ex:['fs:model:xyz', 'and', '(', 'fs:name:Drone1', 'or', 'fs:name:Drone2', ')'] for query "model xyz and (name Drone1 or name Drone2)" :param query_list: get a list of faceted indexes and operations :param return: get data from the Redis memory for specific query. """ # check if there is both "and" and "or" with help of bracket. if ")" not in query_list: # if only one operation "and" or "or". if "or" in query_list: while query_list.count("or") > 0: query_list.remove("or") get_data = self.connection.sunion(*query_list) return (get_data) else: while query_list.count("and") > 0: query_list.remove("and") get_data = self.connection.sinter(*query_list) return (get_data) else: # if both the operators are present in query for query_element in query_list: if query_element == ")": # find index for closed bracket close_index = query_list.index(query_element) break for i in range(close_index, -1, -1): if query_list[i] == "(": # find index for open bracket open_index = i break get_value = self.and_or_query( query_list[open_index + 1:close_index]) get_value = self.convert_byte_string(get_value) # design random faceted key for store result of partial query. faceted_key = "fs:" + \ ''.join(random.choice(string.ascii_letters + string.digits) for letter in range(8)) # add data in random faceted key. for obj in get_value: self.connection.sadd(faceted_key, obj) # add new executed partial query value with key in query list. query_list.insert(open_index, faceted_key) # generate new query after remove executed partial query query_list = query_list[0:open_index + 1] + \ query_list[close_index + 2:len(query_list)] return self.and_or_query(query_list) def object_property_comparison_list(self, query): """ It takes the argument as a string that can contain many keys and value And make a list of all keys and values and identify operator(if there) And execute sinter or sunion commands of Redis over faceted keys. :param query: get query from the user, Ex: name Drone1 :return: get data from the Redis memory. """ faceted_list = [] query_list = [] while True: if query.count(" ") > 1: key, value, query = query.split(" ", 2) while "(" in key: query_list.append("(") key = key.replace("(", "", 1) faceted_list.append(self.faceted_key(key, value)) query_list.append( self.faceted_key( key.replace( "(", ""), value.replace( ")", ""))) while ")" in value: query_list.append(")") value = value.replace(")", "", 1) else: key, value = query.split(" ") query = "" while "(" in key: query_list.append("(") key = key.replace("(", "", 1) faceted_list.append(self.faceted_key(key, value)) query_list.append( self.faceted_key( key.replace( "(", ""), value.replace( ")", ""))) while ")" in value: query_list.append(")") value = value.replace(")", "", 1) if len(query) > 0: operation, query = query.split(" ", 1) query_list.append(operation) else: break get_data = self.and_or_query(query_list) return self.show_data(get_data) def show_data(self, get_data): """It returns the data in readable format.""" property_list = [] for string1 in get_data: string1 = string1.decode('utf-8') property_list.append(string1) # print("list ",property_list) return property_list
class ClassPropertiesValue: """ ClassPropertiesValue is used for geting the values for properties of class And once values get from server and then it stored in Redis. """ def __init__(self, api_doc, url, graph): self.redis_connection = RedisProxy() self.handle_data = HandleData() self.connection = self.redis_connection.get_connection() self._data = self.handle_data self.clas = ClassEndpoints(graph.redis_graph, graph.class_endpoints) self.api_doc = api_doc self.url = url def data_from_server(self, endpoint): """ Load data from the server for once. :param endpoint: endpoint for getting data from the server. :return: get data from the Redis memory. """ self.clas.load_from_server(endpoint, self.api_doc, self.url, self.connection) get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', """MATCH(p:classes) WHERE(p.type='{}') RETURN p.property_value""".format( endpoint)) return get_data def get_property_value(self, query): """ Load data in Redis if data is not in it with help of checklist. Checklist have the track on endpoints. And access the properties values and show them. :param query: get query from the user, Ex:classLocation property_value :return: get data from the Redis memory. """ query = query.replace("class", "") endpoint = query.replace(" property_value", "") if (str.encode("fs:endpoints") in self.connection.keys() and str.encode(endpoint) in self.connection.smembers( "fs:endpoints")): get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', """MATCH (p:classes) WHERE (p.type = '{}') RETURN p.property_value""".format( endpoint)) else: self.connection.sadd("fs:endpoints", endpoint) print(self.connection.smembers("fs:endpoints")) get_data = self.data_from_server(endpoint) print(endpoint, "property_value") return self._data.show_data(get_data)
class PropertiesQuery: """ PropertiesQuery is used for all properties for alltypes of nodes like: classes or collection endpoints, members,object. """ def __init__(self): self.redis_connection = RedisProxy() self.handle_data = HandleData() self.connection = self.redis_connection.get_connection() self._data = self.handle_data def get_classes_properties(self, query): """ Show the given type of property of given Class endpoint. :param query: get query from the user, Ex: classLocation properties :return: get data from the Redis memory. """ query = query.replace("class", "") endpoint, query = query.split(" ") get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', 'MATCH ( p:classes ) WHERE (p.type="{}") RETURN p.{}'.format( endpoint, query)) print("class", endpoint, query) return self._data.show_data(get_data) def get_collection_properties(self, query): """ Show the given type of property of given collection endpoint. :param query: get query from the user, Ex: DroneCollection properties. :return: get data from the Redis memory. """ endpoint, query = query.split(" ") get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', 'MATCH ( p:collection ) WHERE (p.type="{}") RETURN p.{}'.format( endpoint, query)) print("collection", endpoint, query) return self._data.show_data(get_data) def get_members_properties(self, query): """ Show the given type of property of given member. :param query: gete query from the user, Ex: objectsDrone properties :return: get data from the Redis memory. """ endpoint, query = query.split(" ") get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', 'MATCH ( p:{} ) RETURN p.id,p.{}'.format( endpoint, query)) print("member", endpoint, query) return self._data.show_data(get_data) def get_object_property(self, query): """ Show the given type of property of given object. :param query: get query from the user,Ex:object</api/DroneCollection/2 :return: get data from the Redis memory. """ endpoint, query = query.split(" ") endpoint = endpoint.replace("object", "") index = endpoint.find("Collection") id_ = "object" + endpoint[5:index] get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', 'MATCH ( p:{}) WHERE (p.parent_id = "{}") RETURN p.{}'.format( id_, endpoint, query)) print("object", endpoint, query) return self._data.show_data(get_data)
class CollectionmembersQuery: """ CollectionmembersQuery is used for get members of any collectionendpoint. Once it get the data from the server and store it in Redis. And after that it can query from Redis memory. "fs:endpoints" is using as a faceted index, for track which collection endpoint's data is stored in Redis. """ def __init__(self, api_doc, url, graph): self.redis_connection = RedisProxy() self.handle_data = HandleData() self.connection = self.redis_connection.get_connection() self._data = self.handle_data self.collection = CollectionEndpoints(graph.redis_graph, graph.class_endpoints) self.api_doc = api_doc self.url = url def data_from_server(self, endpoint): """ Load data from the server for first time. :param endpoint: endpoint for getting data from the server. :return: get data from the Redis memory. """ self.collection.load_from_server(endpoint, self.api_doc, self.url, self.connection) get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', 'MATCH(p:collection) WHERE(p.type="{}") RETURN p.members'.format( endpoint)) print(endpoint, " members") return self._data.show_data(get_data) def get_members(self, query): """ Gets Data from the Redis. :param query: query get from the user, Ex: DroneCollection members :return: get data from the Redis memory. """ endpoint = query.replace(" members", "") if (str.encode("fs:endpoints") in self.connection.keys() and str.encode(endpoint) in self.connection.smembers( "fs:endpoints")): get_data = self.connection.execute_command( 'GRAPH.QUERY', 'apidoc', """MATCH(p:collection) WHERE(p.type='{}') RETURN p.members""".format( endpoint)) print(endpoint, " members") return self._data.show_data(get_data) else: self.connection.sadd("fs:endpoints", endpoint) print(self.connection.smembers("fs:endpoints")) return self.data_from_server(endpoint)