From 9b15e9b5218937c9e468fb196faf5b06683b92d6 Mon Sep 17 00:00:00 2001 From: laura-ding <48548375+laura-ding@users.noreply.github.com> Date: Tue, 3 Aug 2021 16:47:51 +0800 Subject: [PATCH] add annotation --- nebula2/data/DataObject.py | 382 +++++++++++++++++++++----- nebula2/data/ResultSet.py | 90 ++++-- nebula2/gclient/net/__init__.py | 111 +++++--- nebula2/mclient/__init__.py | 81 +++++- nebula2/sclient/BaseResult.py | 53 +++- nebula2/sclient/GraphStorageClient.py | 35 ++- nebula2/sclient/ScanResult.py | 18 +- 7 files changed, 602 insertions(+), 168 deletions(-) diff --git a/nebula2/data/DataObject.py b/nebula2/data/DataObject.py index b526b429..548bc390 100644 --- a/nebula2/data/DataObject.py +++ b/nebula2/data/DataObject.py @@ -18,6 +18,12 @@ def date_time_convert_with_timezone(date_time: DateTime, timezone_offset: int): + """the function to convert utc date_time to local date_time + + :param date_time: the utc date_time + :param timezone_offset: the timezone offset + :return: the date_time with timezone + """ native_date_time = datetime(date_time.year, date_time.month, date_time.day, @@ -39,6 +45,12 @@ def date_time_convert_with_timezone(date_time: DateTime, timezone_offset: int): def time_convert_with_timezone(n_time: Time, timezone_offset: int): + """the function to convert utc date_time to local date_time + + :param n_time: the utc time + :param timezone_offset: the timezone offset + :return: the time with the timezone + """ native_date_time = datetime(1, 1, 1, @@ -93,20 +105,25 @@ def __iter__(self): return iter(self._record) def size(self): + """the size of record + + :return: record size + """ return len(self._names) def get_value(self, index): - """ - get value by index - :return: Value + """get value by specified index + + :param index: the index of column + :return: ValueWrapper """ if index >= len(self._names): raise OutOfRangeException() return self._record[index] def get_value_by_key(self, key): - """ - get value by key + """get value by key + :return: Value """ try: @@ -115,13 +132,17 @@ def get_value_by_key(self, key): raise InvalidKeyException(key) def keys(self): - """ - keys() - :return: the col name of the recod + """get column names of record + + :return: the column names """ return self._names def values(self): + """get all values + + :return: values + """ return self._record def __repr__(self): @@ -161,8 +182,8 @@ def get_rows(self): return self._data_set.rows def get_row_types(self): - """ - Get row types + """Get row types + :param empty :return: list ttypes.Value.__EMPTY__ = 0 @@ -187,9 +208,9 @@ def get_row_types(self): return [(value.getType()) for value in self._data_set.rows[0].values] def row_values(self, row_index): - """ - Get row values - :param index: the Record index + """get row values + + :param row_index: the Record index :return: list """ if row_index >= len(self._data_set.rows): @@ -200,8 +221,8 @@ def row_values(self, row_index): for value in self._data_set.rows[row_index].values] def column_values(self, key): - """ - get column values + """get column values + :param key: the col name :return: list """ @@ -218,8 +239,8 @@ def __iter__(self): return self def __next__(self): - """ - The record iterator + """The record iterator + :return: record """ if len(self._data_set.rows) == 0 or self._pos >= len(self._data_set.rows) - 1: @@ -265,119 +286,192 @@ def __init__(self, value, decode_type='utf-8', timezone_offset: int = 0): self._timezone_offset = timezone_offset def get_value(self): + """get raw data + + :return: Value + """ return self._value def is_null(self): + """judge the value if is Null type + + :return: true or false + """ return self._value.getType() == Value.NVAL def is_empty(self): + """judge the value if is Empty type + + :return: true or false + """ return self._value.getType() == Value.__EMPTY__ def is_bool(self): + """judge the value if is Bool type + + :return: true or false + """ return self._value.getType() == Value.BVAL def is_int(self): + """judge the value if is Int type + + :return: true or false + """ return self._value.getType() == Value.IVAL def is_double(self): + """judge the value if is Double type + + :return: true or false + """ return self._value.getType() == Value.FVAL def is_string(self): + """judge the value if is String type + + :return: true or false + """ return self._value.getType() == Value.SVAL def is_list(self): + """judge the value if is List type + + :return: true or false + """ return self._value.getType() == Value.LVAL def is_set(self): + """judge the value if is Set type + + :return: true or false + """ return self._value.getType() == Value.UVAL def is_map(self): + """judge the value if is Map type + + :return: true or false + """ return self._value.getType() == Value.MVAL def is_time(self): + """judge the value if is Time type + + :return: true or false + """ return self._value.getType() == Value.TVAL def is_date(self): + """judge the value if is Date type + + :return: true or false + """ return self._value.getType() == Value.DVAL def is_datetime(self): + """judge the value if is Datetime type + + :return: true or false + """ return self._value.getType() == Value.DTVAL def is_vertex(self): + """judge the value if is Vertex type + + :return: true or false + """ return self._value.getType() == Value.VVAL def is_edge(self): + """judge the value if is Edge type + + :return: true or false + """ return self._value.getType() == Value.EVAL def is_path(self): + """judge the value if is Path type + + :return: true or false + """ return self._value.getType() == Value.PVAL def as_null(self): - """ - :return: Null + """converts the original data type to Null type + + :return: Null value """ if self._value.getType() == Value.NVAL: return Null(self._value.get_nVal()) raise InvalidValueTypeException("expect NULL type, but is " + self._get_type_name()) def as_bool(self): - """ - :return Boolean: + """converts the original data type to Bool type + + :return: Bool value """ if self._value.getType() == Value.BVAL: return self._value.get_bVal() raise InvalidValueTypeException("expect bool type, but is " + self._get_type_name()) def as_int(self): - """ - :return int: + """converts the original data type to Int type + + :return: Int value """ if self._value.getType() == Value.IVAL: return self._value.get_iVal() raise InvalidValueTypeException("expect bool type, but is " + self._get_type_name()) def as_double(self): - """ - :return double: + """converts the original data type to Double type + + :return: Double value """ if self._value.getType() == Value.FVAL: return self._value.get_fVal() raise InvalidValueTypeException("expect int type, but is " + self._get_type_name()) def as_string(self): - """ - :return string: + """converts the original data type to String type + + :return: String value """ if self._value.getType() == Value.SVAL: return self._value.get_sVal().decode(self._decode_type) raise InvalidValueTypeException("expect string type, but is " + self._get_type_name()) def as_time(self): - """ - :return: TimeWrapper + """converts the original data type to Time type + + :return: Time value """ if self._value.getType() == Value.TVAL: return TimeWrapper(self._value.get_tVal()).set_timezone_offset(self._timezone_offset) raise InvalidValueTypeException("expect time type, but is " + self._get_type_name()) def as_date(self): - """ - :return: DateWrapper + """converts the original data type to Date type + + :return: Date value """ if self._value.getType() == Value.DVAL: return DateWrapper(self._value.get_dVal()) raise InvalidValueTypeException("expect date type, but is " + self._get_type_name()) def as_datetime(self): - """ - :return: DateTimeWrapper + """converts the original data type to Datetime type + + :return: Datetime value """ if self._value.getType() == Value.DTVAL: return DateTimeWrapper(self._value.get_dtVal()).set_timezone_offset(self._timezone_offset) raise InvalidValueTypeException("expect datetime type, but is " + self._get_type_name()) def as_list(self): - """ + """converts the original data type to list of ValueWrapper + :return: list """ if self._value.getType() == Value.LVAL: @@ -390,7 +484,8 @@ def as_list(self): raise InvalidValueTypeException("expect list type, but is " + self._get_type_name()) def as_set(self): - """ + """converts the original data type to set of ValueWrapper + :return: set """ if self._value.getType() == Value.UVAL: @@ -403,8 +498,9 @@ def as_set(self): raise InvalidValueTypeException("expect set type, but is " + self._get_type_name()) def as_map(self): - """ - :return: map + """converts the original data type to map type + + :return: map """ if self._value.getType() == Value.MVAL: result = {} @@ -417,8 +513,9 @@ def as_map(self): raise InvalidValueTypeException("expect map type, but is " + self._get_type_name()) def as_node(self): - """ - :return: Node + """converts the original data type to Node type + + :return: Node type """ if self._value.getType() == Value.VVAL: return Node(self._value.get_vVal())\ @@ -427,8 +524,9 @@ def as_node(self): raise InvalidValueTypeException("expect vertex type, but is " + self._get_type_name()) def as_relationship(self): - """ - :return: Relationship + """converts the original data type to Relationship type + + :return: Relationship type """ if self._value.getType() == Value.EVAL: return Relationship(self._value.get_eVal())\ @@ -437,8 +535,9 @@ def as_relationship(self): raise InvalidValueTypeException("expect edge type, but is " + self._get_type_name()) def as_path(self): - """ - :return: PathWrapper + """converts the original data type to PathWrapper type + + :return: PathWrapper type """ if self._value.getType() == Value.PVAL: return PathWrapper(self._value.get_pVal())\ @@ -563,38 +662,58 @@ def __init__(self, time): self._time = time def get_hour(self): + """get utc hour + + :return: hour + """ return self._time.hour def get_minute(self): + """get utc minute + + :return: minute + """ return self._time.minute def get_sec(self): + """get utc second + + :return: second + """ return self._time.sec def get_microsec(self): + """get utc microseconds + + :return: microseconds + """ return self._time.microsec def get_time(self): - """ - get utc time + """get utc time + + :return: Time value """ return self._time def get_local_time(self): - """ - get time with the timezone from graph service + """get time with the timezone from graph service + + :return: Time value with timezone offset """ return time_convert_with_timezone(self._time, self.get_timezone_offset()) def get_local_time_by_timezone_offset(self, timezone_offset): - """ - get local time with the specified timezone by user + """get local time with the specified timezone by user + + :return: Time value with timezone offset """ return time_convert_with_timezone(self._time, timezone_offset) def get_local_time_str(self): - """ - get local time str + """convert local time string format + + :return: return local time string format """ local_time = time_convert_with_timezone(self._time, self.get_timezone_offset()) return "%02d:%02d:%02d.%06d" % (local_time.hour, @@ -624,15 +743,31 @@ def __init__(self, date): self._date = date def get_year(self): + """get year + + :return: year + """ return self._date.year def get_month(self): + """get month + + :return: month + """ return self._date.month def get_day(self): + """get day + + :return: day + """ return self._date.day def get_date(self): + """get original date + + :return: Date + """ return self._date def __eq__(self, other): @@ -652,47 +787,79 @@ def __init__(self, date_time): self._date_time = date_time def get_year(self): + """get utc year + + :return: year + """ return self._date_time.year def get_month(self): + """get utc month + + :return: month + """ return self._date_time.month def get_day(self): + """get utc day + + :return: day + """ return self._date_time.day def get_hour(self): + """get utc hour + + :return: hour + """ return self._date_time.hour def get_minute(self): + """get utc minute + + :return: minute + """ return self._date_time.minute def get_sec(self): + """get utc seconds + + :return: seconds + """ return self._date_time.sec def get_microsec(self): + """get utc microseconds + + :return: microseconds + """ return self._date_time.microsec def get_datetime(self): - """ - get utc datetime + """get utc datetime + + :return: datetime """ return self._date_time def get_local_datetime(self): - """ - get datetime with the timezone from the graph service + """get datetime with the timezone from graph service + + :return: Datetime value with timezone offset """ return date_time_convert_with_timezone(self._date_time, self.get_timezone_offset()) def get_local_datetime_by_timezone_offset(self, timezone_offset): - """ - get local datetime with the specified timezone by user + """get local datetime with the specified timezone by user + + :return: Time value with timezone offset """ return date_time_convert_with_timezone(self._date_time, timezone_offset) def get_local_datetime_str(self): - """ - get date time str with the timezone from the graph service + """convert local datetime string format + + :return: return local datetime string format """ local_date_time = date_time_convert_with_timezone(self._date_time, self.get_timezone_offset()) return "%d-%02d-%02dT%02d:%02d:%02d.%06d" % (local_date_time.year, @@ -763,21 +930,35 @@ def __init__(self, vertex): self._tag_indexes[tag.name.decode(self.get_decode_type())] = index def get_id(self): - """ - get vertex id - :return: ValueWrapper + """get the vid of Node + + :return: ValueWrapper type vid """ return ValueWrapper(value=self._value.vid, decode_type=self.get_decode_type(), timezone_offset=self.get_timezone_offset()) def tags(self): + """get tag names + + :return: the list of tag name + """ return list(self._tag_indexes.keys()) def has_tag(self, tag): + """whether the specified tag is included + + :param tag: the tag name + :return: true or false + """ return True if tag in self._tag_indexes.keys() else False def properties(self, tag): + """get all properties of the specified tag + + :param tag: the tag name + :return: the properties + """ if tag not in self._tag_indexes.keys(): raise InvalidKeyException(tag) @@ -792,6 +973,11 @@ def properties(self, tag): return result_props def prop_names(self, tag): + """get the property names of the specified tag + + :param tag: the tag name + :return: property name list + """ if tag not in self._tag_indexes.keys(): raise InvalidKeyException(tag) index = self._tag_indexes[tag] @@ -801,6 +987,11 @@ def prop_names(self, tag): return [(key.decode(self.get_decode_type())) for key in self._value.tags[index].props.keys()] def prop_values(self, tag): + """get all property values of the specified tag + + :param tag: the tag name + :return: property name list + """ if tag not in self._tag_indexes.keys(): raise InvalidKeyException(tag) index = self._tag_indexes[tag] @@ -835,9 +1026,10 @@ def __init__(self, edge: Edge): self._value = edge def start_vertex_id(self): - """ - get start vid - :return: ValueWrapper + """get start vertex vid, if your space vid_type is int, you can use start_vertex_id().as_int(), + if your space vid_type is fixed_string, you can use start_vertex_id().as_string() + + :return: ValueWrapper type vid """ if self._value.type > 0: return ValueWrapper(self._value.src, self.get_decode_type()) @@ -845,9 +1037,10 @@ def start_vertex_id(self): return ValueWrapper(self._value.dst, self.get_decode_type()) def end_vertex_id(self): - """ - get end vid - :return: ValueWrapper + """get end vertex vid, if your space vid_type is int, you can use end_vertex_id().as_int(), + if your space vid_type is fixed_string, you can use end_vertex_id().as_string() + + :return: ValueWrapper type vid """ if self._value.type > 0: return ValueWrapper(self._value.dst, self.get_decode_type()) @@ -855,12 +1048,24 @@ def end_vertex_id(self): return ValueWrapper(self._value.src, self.get_decode_type()) def edge_name(self): + """get the edge name + + :return: edge name + """ return self._value.name.decode(self.get_decode_type()) def ranking(self): + """get the edge ranking + + :return: ranking + """ return self._value.ranking def properties(self): + """get all properties + + :return: the properties + """ props = {} if self._value.props is None: return props @@ -871,11 +1076,19 @@ def properties(self): return props def keys(self): + """get all property names + + :return: the property names + """ if self._value.props is None: return [] return [(key.decode(self._decode_type)) for key in self._value.props.keys()] def values(self): + """get all property values + + :return: the property values + """ if self._value.props is None: return [] return [(ValueWrapper(value, @@ -924,6 +1137,9 @@ def __eq__(self, other): class PathWrapper(BaseObject): + """ + PathWrapper is wrapper handling for the Path from the service + """ def __init__(self, path): super(PathWrapper, self).__init__() self._nodes = list() @@ -980,26 +1196,56 @@ def __iter__(self): return iter(self._segments) def start_node(self): + """get start node of the Path + + :return: start node + """ if len(self._nodes) == 0: return None return self._nodes[0] def length(self): + """get the length of the path + + :return: path length + """ return len(self._segments) def contain_node(self, node): + """whether the node is in the path + + :param node: the specified node + :return: true or false + """ return True if node in self._nodes else False def contain_relationship(self, relationship): + """whether the relationship is in the path + + :param relationship: the specified relationship + :return: true or false + """ return True if relationship in self._relationships else False def nodes(self): + """get all nodes of the path + + :return: nodes + """ return self._nodes def relationships(self): + """get all relationships of the path + + :return: relationships + """ return self._relationships def segments(self): + """get all segments of the path + + :return: segments + """ return self._segments def __repr__(self): diff --git a/nebula2/data/ResultSet.py b/nebula2/data/ResultSet.py index 7a704514..e7d667dc 100644 --- a/nebula2/data/ResultSet.py +++ b/nebula2/data/ResultSet.py @@ -13,8 +13,15 @@ class ResultSet(object): def __init__(self, resp, all_latency, decode_type='utf-8', timezone_offset: int = 0): - """ - get data from ResultSet + """Constructor method + + :param resp: the response from the service + :param all_latency: the execution time from the time the client + sends the request to the time the response is received and the data is decoded + :param decode_type: the decode_type for decode binary value, it comes from the service, + but now the service not return, use utf-8 default + :param timezone_offset: the timezone offset for calculate local time, + it comes from the service """ self._decode_type = decode_type self._resp = resp @@ -27,72 +34,105 @@ def __init__(self, resp, all_latency, decode_type='utf-8', timezone_offset: int timezone_offset=self._timezone_offset) def is_succeeded(self): + """check the response from the sesrvice is succeeded + + :return: bool + """ return self._resp.error_code == ErrorCode.SUCCEEDED def error_code(self): + """if the response is failed, the service return the error code + + :return: nebula2.common.ttypes.ErrorCode + """ return self._resp.error_code def space_name(self): + """get the space for the current operation + + :return: space name or '' + """ if self._resp.space_name is None: return '' return self._resp.space_name.decode(self._decode_type) def error_msg(self): + """if the response is failed, the service return the error message + + :return: error message + """ if self._resp.error_msg is None: return '' return self._resp.error_msg.decode(self._decode_type) def comment(self): + """the comment return by service, it maybe some warning message + + :return: comment message + """ if self._resp.error_msg is None: return '' return self._resp.comment.decode(self._decode_type) def latency(self): - """ - the server's latency, unit us + """the time the server processes the request + + :return: latency """ return self._resp.latency_in_us def whole_latency(self): - """ - the whole latency of the query + """the execution time from the time the client + sends the request to the time the response is received and the data is decoded + + :return: all_latency """ return self._all_latency def plan_desc(self): + """get plan desc, whe user want to get the execute plan use `PROFILE` and `EXPLAIN` + + :return:plan desc + """ return self._resp.plan_desc def is_empty(self): + """the data of response is empty + + :return: true of false + """ return self._data_set_wrapper is None or self._data_set_wrapper.get_row_size() == 0 def keys(self): - """ - get colNames + """get the column names + + :return: column names """ if self._data_set_wrapper is None: return [] return self._data_set_wrapper.get_col_names() def row_size(self): - """ - get one row size + """get the row size + + :return: row size """ if self._data_set_wrapper is None: return 0 return len(self._data_set_wrapper.get_rows()) def col_size(self): - """ - get one col size + """get column size + + :return: column size """ if self._data_set_wrapper is None: return 0 return len(self._data_set_wrapper.get_col_names()) def get_row_types(self): - """ - Get row types - :param empty + """get the value type of the row + :return: list ttypes.Value.__EMPTY__ = 0 ttypes.Value.NVAL = 1 @@ -116,9 +156,9 @@ def get_row_types(self): return self._data_set_wrapper.get_row_types() def row_values(self, row_index): - """ - Get row values - :param index: the Record index + """get row values + + :param row_index: :return: list """ if self._data_set_wrapper is None: @@ -126,9 +166,9 @@ def row_values(self, row_index): return self._data_set_wrapper.row_values(row_index) def column_values(self, key): - """ - get column values - :param key: the col name + """get column values + + :param key: the specified column name :return: list """ if self._data_set_wrapper is None: @@ -136,8 +176,8 @@ def column_values(self, key): return self._data_set_wrapper.column_values(key) def rows(self): - """ - get all rows + """get all rows + :return: list """ if self._data_set_wrapper is None: @@ -145,6 +185,10 @@ def rows(self): return self._data_set_wrapper.get_rows() def __iter__(self): + """the iterator for per row + + :return: iter + """ return iter(self._data_set_wrapper) def __repr__(self): diff --git a/nebula2/gclient/net/__init__.py b/nebula2/gclient/net/__init__.py index 3dfd0a6c..66b7c401 100644 --- a/nebula2/gclient/net/__init__.py +++ b/nebula2/gclient/net/__init__.py @@ -62,8 +62,8 @@ def __init__(self, connection, auth_result: AuthResult, pool, retry_connect=True self._retry_connect = retry_connect def execute(self, stmt): - """ - execute statement + """execute statement + :param stmt: the ngql :return: ResultSet """ @@ -96,8 +96,9 @@ def execute(self, stmt): raise def release(self): - """ - release the connection to pool + """release the connection to pool, and the session couldn't been use again + + :return: """ if self._connection is None: return @@ -106,9 +107,9 @@ def release(self): self._connection = None def ping(self): - """ - check the connection is ok - :return Boolean + """check the connection is ok + + :return: True or False """ if self._connection is None: return False @@ -150,10 +151,10 @@ def __del__(self): self.close() def init(self, addresses, configs): - """ - init the connection pool + """init the connection pool + :param addresses: the graphd servers' addresses - :param configs: the config + :param configs: the config of the pool :return: if all addresses are ok, return True else return False. """ if self._close: @@ -190,12 +191,12 @@ def init(self, addresses, configs): return True def get_session(self, user_name, password, retry_connect=True): - """ - get session - :param user_name: - :param password: - :param retry_connect: if auto retry connect - :return: void + """get session + + :param user_name: the user name to authenticate graphd + :param password: the password to authenticate graphd + :param retry_connect: + :return: Session """ connection = self.get_connection() if connection is None: @@ -215,8 +216,8 @@ def session_context(self, *args, **kwargs): When session_context is exited, the connection will be released. - :param user_name: - :param password: + :param user_name: the user name to authenticate graphd + :param password: the password to authenticate graphd :param retry_connect: if auto retry connect :return: contextlib._GeneratorContextManager """ @@ -231,9 +232,9 @@ def session_context(self, *args, **kwargs): session.release() def get_connection(self): - """ - get available connection - :return: Connection Object + """get available connection + + :return: Connection """ with self._lock: if self._close: @@ -277,8 +278,8 @@ def get_connection(self): return None def ping(self, address): - """ - check the server is ok + """check the server is ok + :param address: the server address want to connect :return: True or False """ @@ -292,8 +293,8 @@ def ping(self, address): return False def close(self): - """ - close all connections in pool + """close all connections in pool + :return: void """ with self._lock: @@ -305,9 +306,9 @@ def close(self): self._close = True def connnects(self): - """ - get the number of existing connections - :return: int + """get the number of existing connections + + :return: the number of connections """ with self._lock: count = 0 @@ -316,8 +317,8 @@ def connnects(self): return count def in_used_connects(self): - """ - get the number of the used connections + """get the number of the used connections + :return: int """ with self._lock: @@ -329,8 +330,8 @@ def in_used_connects(self): return count def get_ok_servers_num(self): - """ - get the number of the ok servers + """get the number of the ok servers + :return: int """ count = 0 @@ -349,8 +350,7 @@ def _get_services_status(self): return ', '.join(msg_list) def update_servers_status(self): - """ - update the servers' status + """update the servers' status """ for address in self._addresses: if self.ping(address): @@ -394,6 +394,13 @@ def __init__(self): self._port = None def open(self, ip, port, timeout): + """open the connection + + :param ip: the server ip + :param port: the server port + :param timeout: the timeout for connect and execute + :return: void + """ self._ip = ip self._port = port try: @@ -408,6 +415,12 @@ def open(self, ip, port, timeout): raise def authenticate(self, user_name, password): + """authenticate to graphd + + :param user_name: the user name + :param password: the password + :return: + """ try: resp = self._connection.authenticate(user_name, password) if resp.error_code != ErrorCode.SUCCEEDED: @@ -419,6 +432,12 @@ def authenticate(self, user_name, password): raise IOErrorException(IOErrorException.E_CONNECT_BROKEN, te.message) def execute(self, session_id, stmt): + """execute interface with session_id and ngql + + :param session_id: the session id get from result of authenticate interface + :param stmt: the ngql + :return: ExecutionResponse + """ try: resp = self._connection.execute(session_id, stmt) return resp @@ -428,6 +447,11 @@ def execute(self, session_id, stmt): raise IOErrorException(IOErrorException.E_CONNECT_BROKEN, te.message) def signout(self, session_id): + """tells the graphd can release the session info + + :param session_id:the session id + :return: void + """ try: self._connection.signout(session_id) except TTransportException as te: @@ -435,7 +459,7 @@ def signout(self, session_id): self.close() def close(self): - """ + """close the connection :return: void """ @@ -445,9 +469,8 @@ def close(self): logging.error('Close connection to {}:{} failed:{}'.format(self._ip, self._port, e)) def ping(self): - """ - check the connection if ok - :return: Boolean + """check the connection if ok + :return: True or False """ try: self._connection.execute(0, 'YIELD 1;') @@ -458,12 +481,24 @@ def ping(self): return True def reset(self): + """reset the idletime + + :return: void + """ self.start_use_time = time.time() def idle_time(self): + """get idletime of connection + + :return: idletime + """ if self.is_used: return 0 return (time.time() - self.start_use_time) * 1000 def get_address(self): + """get the address of the connected service + + :return: (ip, port) + """ return (self._ip, self._port) diff --git a/nebula2/mclient/__init__.py b/nebula2/mclient/__init__.py index 7816cba2..a0e0eff6 100644 --- a/nebula2/mclient/__init__.py +++ b/nebula2/mclient/__init__.py @@ -53,6 +53,10 @@ def __init__(self, addresses, timeout): self._lock = RLock() def open(self): + """open the connection to connect meta service + + :eturn: void + """ try: self.close() s = TSocket.TSocket(self._leader[0], self._leader[1]) @@ -66,6 +70,11 @@ def open(self): raise def list_tags(self, space_id): + """get all version tags + + :param space_id: the specified space id + :eturn: list + """ with self._lock: if self._connection is None: raise RuntimeError('The connection is no open') @@ -86,6 +95,11 @@ def list_tags(self, space_id): .format(space_id, ErrorCode._VALUES_TO_NAMES.get(resp.code))) def list_edges(self, space_id): + """get all version edge + + :param space_id: the specified space id + :eturn: list + """ with self._lock: if self._connection is None: raise RuntimeError('The connection is no open') @@ -106,6 +120,10 @@ def list_edges(self, space_id): .format(space_id, ErrorCode._VALUES_TO_NAMES.get(resp.code))) def list_spaces(self): + """get all spaces info + + :eturn: list + """ with self._lock: if self._connection is None: raise RuntimeError('The connection is no open') @@ -125,6 +143,10 @@ def list_spaces(self): .format(ErrorCode._VALUES_TO_NAMES.get(resp.code))) def list_hosts(self): + """get all online hosts info + + :eturn: list + """ with self._lock: if self._connection is None: raise RuntimeError('The connection is no open') @@ -149,6 +171,11 @@ def list_hosts(self): .format(ErrorCode._VALUES_TO_NAMES.get(resp.code))) def get_parts_alloc(self, space_id): + """get all parts info of the specified space id + + :param space_id: + :eturn: map> + """ with self._lock: if self._connection is None: raise RuntimeError('The connection is no open') @@ -169,6 +196,10 @@ def get_parts_alloc(self, space_id): .format(space_id, ErrorCode._VALUES_TO_NAMES.get(resp.code))) def close(self): + """close the connection + + :eturn: void + """ try: if self._connection is not None: self._connection._iprot.trans.close() @@ -176,6 +207,11 @@ def close(self): raise def update_leader(self, leader): + """update the leader meta info when hanppen leader change + + :param leader: the address of meta leader + :eturn: + """ try: self._leader = (leader.host, leader.port) self.open() @@ -219,6 +255,10 @@ def __init__(self, meta_addrs, timeout=2000, load_period=10, decode_type='utf-8' self._load_all() def close(self): + """close the metaClient + + :eturn: void + """ if self._close: return self._close = True @@ -229,6 +269,10 @@ def __del__(self): self.close() def _load_all(self): + """load all space info and schema info from meta services + + :eturn: void + """ try: spaces = self._meta_client.list_spaces() space_caches = {} @@ -282,14 +326,15 @@ def _load_all(self): logging.error(traceback.format_exc()) def get_all_storage_addrs(self): - """ + """get all storage address + :return: list[HostAddr] """ return self._storage_addrs def get_tag_id(self, space_name, tag_name): - """ - get_tag_id + """get tag id + :param space_name: :param tag_name: :return: tag_id @@ -299,8 +344,8 @@ def get_tag_id(self, space_name, tag_name): return tag_item.tag_id def get_edge_type(self, space_name, edge_name): - """ - get_edge_type + """get edge type + :param space_name: :param edge_name: :return: edge_type @@ -310,8 +355,8 @@ def get_edge_type(self, space_name, edge_name): return edge_item.edge_type def get_space_id(self, space_name): - """ - get_space_id + """get space id + :param space_name: :return: space_id """ @@ -323,8 +368,8 @@ def get_space_id(self, space_name): return self._space_caches[space_name].space_id def get_tag_schema(self, space_name, tag_name): - """ - get_tag_schema + """get tag schema + :param space_name: :param tag_name: :return: schema @@ -333,8 +378,8 @@ def get_tag_schema(self, space_name, tag_name): return tag_item.schema def get_edge_schema(self, space_name, edge_name): - """ - get_edge_schema + """get edge schema + :param space_name: :param edge_name: :return: schema @@ -355,6 +400,11 @@ def get_part_leader(self, space_name, part_id): return part_leaders[part_id] def get_part_leaders(self, space_name): + """get all part leader info of the space + + :param space_name: space name + :eturn: map + """ with self._lock: if space_name not in self._storage_leader.keys(): self._load_all() @@ -363,6 +413,11 @@ def get_part_leaders(self, space_name): return self._storage_leader[space_name] def get_part_alloc(self, space_name): + """get all part info of the space + + :param space_name: space name + :eturn: map> + """ with self._lock: if space_name not in self._space_caches.keys(): self._load_all() @@ -397,8 +452,8 @@ def _get_edge_item(self, space_name, edge_name): return space_info.edge_items[edge_name] def update_storage_leader(self, space_id, part_id, address: HostAddr): - """ - if the storage leader change, storage client need to call this function + """if the storage leader change, storage client need to call this function + :param space_id: :param part_id: :param address: HostAddr, if the address is None, it means the leader can't connect, diff --git a/nebula2/sclient/BaseResult.py b/nebula2/sclient/BaseResult.py index d9feee91..95a2b4fb 100644 --- a/nebula2/sclient/BaseResult.py +++ b/nebula2/sclient/BaseResult.py @@ -45,6 +45,11 @@ def __init__(self, self._tag_name = names[0] def get_id(self): + """get vertex id, if the space vid_type is int, you can use get_id().as_int(), + if the space vid_type is fixed_string, you can use get_id().as_string() + + :return: ValueWrapper + """ if len(self._row.values) < 1: raise RuntimeError('The row value is bad format, ' 'get vertex id failed: len is {}' @@ -52,8 +57,8 @@ def get_id(self): return ValueWrapper(self._row.values[0], self._decode_type) def as_node(self): - """ - convert the vertex data to structure Node + """convert the vertex data to structure Node + :return: Node """ if len(self._row.values) < self.PROP_START_INDEX: @@ -76,8 +81,8 @@ def as_node(self): return Node(vertex).set_decode_type(self._decode_type) def get_prop_values(self): - """ - get all prop values from the vertex data + """get all prop values from the vertex data + :return: list """ index = self.PROP_START_INDEX @@ -121,6 +126,11 @@ def __init__(self, self._edge_name = names[0] def get_src_id(self): + """get src id, if the space vid_type is int, you can use get_src_id().as_int(), + if the space vid_type is fixed_string, you can use get_src_id().as_string() + + :return: ValueWrapper + """ if len(self._row.values) < 1: raise RuntimeError('The row value is bad format, ' 'get edge src id failed: len is {}' @@ -128,9 +138,17 @@ def get_src_id(self): return ValueWrapper(self._row.values[0], self._decode_type) def get_edge_name(self): + """get edge name + + :return: edge name + """ return self._edge_name.decode(self._decode_type) def get_ranking(self): + """get edge ranking + + :return: ranking + """ if len(self._row.values) < 3: raise RuntimeError('The row value is bad format, ' 'get edge ranking failed: len is {}' @@ -139,6 +157,11 @@ def get_ranking(self): return self._row.values[2].get_iVal() def get_dst_id(self): + """get dst id, if the space vid_type is int, you can use get_dst_id().as_int(), + if the space vid_type is fixed_string, you can use get_dst_id().as_string() + + :return: ValueWrapper + """ if len(self._row.values) < 4: raise RuntimeError('The row value is bad format, ' 'get edge dst id failed: len is {}' @@ -147,9 +170,9 @@ def get_dst_id(self): return ValueWrapper(self._row.values[3], self._decode_type) def as_relationship(self): - """ - convert the edge data to structure Relationship - :return: Node + """convert the edge data to structure Relationship + + :return: Relationship """ if len(self._row.values) < self.PROP_START_INDEX: raise RuntimeError('The row value is bad format, ' @@ -170,8 +193,8 @@ def as_relationship(self): return Relationship(edge).set_decode_type(self._decode_type) def get_prop_values(self): - """ - get all prop values from the edge data + """get all prop values from the edge data + :return: list """ index = self.PROP_START_INDEX @@ -202,8 +225,8 @@ def __init__(self, self._size += len(data_set.rows) def get_data_set(self): - """ - get_data_set: return the origin values, the string type is binary + """get DataSet, it's the origin values, the string type is binary + :return: DataSet """ result = None @@ -218,8 +241,8 @@ def get_data_set(self): return result def get_data_set_wrapper(self): - """ - get_data_set_wrapper: + """get DataSetWrapper, it's the wrapper for DataSet value, the string type is str + :return: DataSetWrapper """ result = None @@ -243,8 +266,8 @@ def __iter__(self): return self def __next__(self): - """ - The VertexData or EdgeData iterator + """The VertexData or EdgeData iterator + :return: VertexData or EdgeData Iterator """ if len(self._data_sets) == 0 or self._pos >= self._size - 1: diff --git a/nebula2/sclient/GraphStorageClient.py b/nebula2/sclient/GraphStorageClient.py index cfcdd996..7bea7306 100644 --- a/nebula2/sclient/GraphStorageClient.py +++ b/nebula2/sclient/GraphStorageClient.py @@ -41,12 +41,20 @@ def __init__(self, meta_cache, time_out=60000): self._create_connection() def get_conns(self): + """get all connections which connect to storaged, the ScanResult use it + + :return: list + """ return self._connections def __del__(self): self.close() def close(self): + """close the GraphStorageClient + + :return: + """ try: for conn in self._connections: conn.close() @@ -55,6 +63,10 @@ def close(self): raise def _create_connection(self): + """create GraphStorageConnection + + :return: GraphStorageConnection + """ storage_addrs = self._meta_cache.get_all_storage_addrs() if len(storage_addrs) == 0: raise RuntimeError('Get storage address from meta cache is empty') @@ -68,6 +80,11 @@ def _create_connection(self): raise def get_space_addrs(self, space_name): + """get all storage addresses that manage space + + :param space_name: the specified space name + :return: list<(ip, port)> + """ return self.meta_cache.get_space_addrs(space_name) def scan_vertex(self, @@ -81,8 +98,9 @@ def scan_vertex(self, only_latest_version=False, enable_read_from_follower=True, partial_success=False): - """ - scan_vertex + """scan vertex with the specified space_name, tag_name, + if the prop_names is empty, will return all properties of the tag + :param prop_names: if given empty, return all property :param tag_name: the tag name :param space_name: the space name @@ -122,8 +140,9 @@ def scan_vertex_with_part(self, only_latest_version=False, enable_read_from_follower=True, partial_success=False): - """ - scan_vertex_with_part + """scan vertex with the specified space_name, partId, tag_name, + if the prop_names is empty, will return all properties of the tag + :param prop_names: if given empty, return all property :param tag_name: the tag name :type part: part id @@ -205,9 +224,9 @@ def scan_edge(self, only_latest_version=False, enable_read_from_follower=True, partial_success=False): - """ + """scan edge with the specified space_name, edge_name, + if the prop_names is empty, will return all properties of the edge - scan_edge :param prop_names: if given empty, return all property :param edge_name: the edge name :param space_name: the space name @@ -247,7 +266,9 @@ def scan_edge_with_part(self, only_latest_version=False, enable_read_from_follower=True, partial_success=False): - """ + """scan edge with the specified space_name, partId, edge_name, + if the prop_names is empty, will return all properties of the edge + :param space_name: the space name :param part: the partition num of the given space :type prop_names: if given empty, return all property diff --git a/nebula2/sclient/ScanResult.py b/nebula2/sclient/ScanResult.py index 52880098..de109d98 100644 --- a/nebula2/sclient/ScanResult.py +++ b/nebula2/sclient/ScanResult.py @@ -29,8 +29,8 @@ def __init__(self, data_sets, decode_type='utf-8'): is_vertex=True) def as_nodes(self): - """ - as_nodes + """convert the vertexes to relationships + :return: list """ nodes = [] @@ -50,8 +50,8 @@ def __init__(self, data_sets: list, decode_type='utf-8'): is_vertex=False) def as_relationships(self): - """ - as_relationships + """convert the edges to relationships + :return: list """ relationships = [] @@ -65,6 +65,8 @@ def as_relationships(self): class ScanResult(object): + """the scan result + """ def __init__(self, graph_storage_client, req, @@ -84,9 +86,17 @@ def __init__(self, self._parts_manager = PartManager(part_infos) def has_next(self): + """whether if has data, the first call is always return True + + :return: True of False + """ return self._parts_manager.has_next() def next(self): + """get scan data result + + :return: VertexResult or EdgeResult + """ conns = self._graph_storage_client.get_conns() num = len(conns) if num == 0: