From 4bc52fa7980241fc50124d04ee7829507af4076c Mon Sep 17 00:00:00 2001 From: Zhang Lei Date: Wed, 11 Sep 2024 10:16:21 +0800 Subject: [PATCH] fix(interactive): Fixing tutorial examples for Interactive (#4212) Fixing tutorial examples for Interactive and add them to CI --- .github/workflows/flex-interactive.yml | 20 +- .../graph_db/database/graph_db_operations.cc | 34 ++-- .../sdk/examples/python/basic_example.py | 187 +++++++----------- 3 files changed, 112 insertions(+), 129 deletions(-) diff --git a/.github/workflows/flex-interactive.yml b/.github/workflows/flex-interactive.yml index 5e29a0c106c4..df5147c38ee4 100644 --- a/.github/workflows/flex-interactive.yml +++ b/.github/workflows/flex-interactive.yml @@ -51,7 +51,7 @@ jobs: uses: mxschmitt/action-tmate@v3 if: false - - name: Test + - name: Test gsctl run: | # install gsctl python3 -m pip install ${GITHUB_WORKSPACE}/python/dist/*.whl @@ -69,6 +69,24 @@ jobs: # destroy instance gsctl instance destroy --type interactive -y + - name: Test basic examples + run: | + # build gs_interactive wheel package + cd ${GITHUB_WORKSPACE}/flex/interactive/sdk + bash generate_sdk.sh -g python + cd python && pip3 install -r requirements.txt && python3 setup.py build_proto + python3 setup.py bdist_wheel + pip3 install dist/*.whl + gsctl instance deploy --type interactive --image-registry graphscope --image-tag latest --interactive-config ${GITHUB_WORKSPACE}/flex/tests/hqps/interactive_config_test.yaml + sleep 20 + # test + cd ${GITHUB_WORKSPACE}/flex/interactive/sdk/examples/python + export INTERACTIVE_ADMIN_ENDPOINT=http://localhost:7777 + python3 basic_example.py + + # destroy instance + gsctl instance destroy --type interactive -y + - name: Upload Coverage uses: codecov/codecov-action@v3 continue-on-error: true diff --git a/flex/engines/graph_db/database/graph_db_operations.cc b/flex/engines/graph_db/database/graph_db_operations.cc index ea7317a3cb63..fb7c7760d1cf 100644 --- a/flex/engines/graph_db/database/graph_db_operations.cc +++ b/flex/engines/graph_db/database/graph_db_operations.cc @@ -37,10 +37,10 @@ Result GraphDBOperations::CreateVertex( input_json["vertex_request"].size() == 0 || (input_json.contains("edge_request") == true && input_json["edge_request"].is_array() == false)) { - return Result( + return Result(gs::Status( StatusCode::INVALID_SCHEMA, "Invalid input json, vertex_request and edge_request should be array " - "and not empty"); + "and not empty")); } const Schema& schema = session.schema(); // input vertex data and edge data @@ -53,10 +53,11 @@ Result GraphDBOperations::CreateVertex( for (auto& edge_insert : input_json["edge_request"]) { edge_data.push_back(inputEdge(edge_insert, schema, session)); } + LOG(INFO) << "CreateVertex edge_data: " << edge_data.size(); } catch (std::exception& e) { return Result( - StatusCode::INVALID_SCHEMA, - " Bad input parameter : " + std::string(e.what())); + gs::Status(StatusCode::INVALID_SCHEMA, + " Bad input parameter : " + std::string(e.what()))); } auto insert_result = insertVertex(std::move(vertex_data), std::move(edge_data), session); @@ -73,9 +74,9 @@ Result GraphDBOperations::CreateEdge(GraphDBSession& session, std::vector edge_data; // Check if the input json contains edge_request if (input_json.is_array() == false || input_json.size() == 0) { - return Result( + return Result(gs::Status( StatusCode::INVALID_SCHEMA, - "Invalid input json, edge_request should be array and not empty"); + "Invalid input json, edge_request should be array and not empty")); } const Schema& schema = session.schema(); // input edge data @@ -85,8 +86,8 @@ Result GraphDBOperations::CreateEdge(GraphDBSession& session, } } catch (std::exception& e) { return Result( - StatusCode::INVALID_SCHEMA, - " Bad input parameter : " + std::string(e.what())); + gs::Status(StatusCode::INVALID_SCHEMA, + " Bad input parameter : " + std::string(e.what()))); } auto insert_result = insertEdge(std::move(edge_data), session); if (insert_result.ok()) { @@ -106,8 +107,8 @@ Result GraphDBOperations::UpdateVertex( vertex_data.push_back(inputVertex(input_json, schema, session)); } catch (std::exception& e) { return Result( - StatusCode::INVALID_SCHEMA, - " Bad input parameter : " + std::string(e.what())); + gs::Status(StatusCode::INVALID_SCHEMA, + " Bad input parameter : " + std::string(e.what()))); } auto update_result = updateVertex(std::move(vertex_data), session); if (update_result.ok()) { @@ -127,8 +128,8 @@ Result GraphDBOperations::UpdateEdge(GraphDBSession& session, edge_data.push_back(inputEdge(input_json, schema, session)); } catch (std::exception& e) { return Result( - StatusCode::INVALID_SCHEMA, - " Bad input parameter : " + std::string(e.what())); + gs::Status(StatusCode::INVALID_SCHEMA, + " Bad input parameter : " + std::string(e.what()))); } auto update_result = updateEdge(std::move(edge_data), session); if (update_result.ok()) { @@ -259,7 +260,8 @@ EdgeData GraphDBOperations::inputEdge(const nlohmann::json& edge_json, } std::string property_name = ""; if (edge_json["properties"].size() == 1) { - edge.property_value = Any(jsonToString(edge_json["properties"][0]["value"])); + edge.property_value = + Any(jsonToString(edge_json["properties"][0]["value"])); property_name = edge_json["properties"][0]["name"]; } auto check_result = checkEdgeSchema(schema, edge, src_label, dst_label, @@ -312,14 +314,14 @@ Status GraphDBOperations::checkEdgeSchema(const Schema& schema, EdgeData& edge, edge.src_label_id = schema.get_vertex_label_id(src_label); edge.dst_label_id = schema.get_vertex_label_id(dst_label); edge.edge_label_id = schema.get_edge_label_id(edge_label); - auto &result = schema.get_edge_property_names(edge.src_label_id, edge.dst_label_id, - edge.edge_label_id); + auto& result = schema.get_edge_property_names( + edge.src_label_id, edge.dst_label_id, edge.edge_label_id); if (is_get) { if (result.size() >= 1) { property_name = result[0]; } else { property_name = ""; - } + } } else { // update or add if (property_name != (result.size() >= 1 ? result[0] : "")) { diff --git a/flex/interactive/sdk/examples/python/basic_example.py b/flex/interactive/sdk/examples/python/basic_example.py index 4da901bbd69a..2408700e5ec2 100644 --- a/flex/interactive/sdk/examples/python/basic_example.py +++ b/flex/interactive/sdk/examples/python/basic_example.py @@ -22,6 +22,9 @@ from gs_interactive.client.session import Session from gs_interactive.models import * +MODERN_GRAPH_CSV_DIR=os.path.join(os.path.dirname(__file__), "../../../../interactive/examples/modern_graph") +# get current dir + test_graph_def = { "name": "test_graph", "description": "This is a test graph", @@ -69,10 +72,16 @@ } test_graph_datasource = { + "loading_config": { + "data_source" : { + "scheme": "file" + }, + "import_option" : "init" + }, "vertex_mappings": [ { "type_name": "person", - "inputs": ["@/path/to/person.csv"], + "inputs": [f"@{MODERN_GRAPH_CSV_DIR}/person.csv"], "column_mappings": [ {"column": {"index": 0, "name": "id"}, "property": "id"}, {"column": {"index": 1, "name": "name"}, "property": "name"}, @@ -88,7 +97,7 @@ "destination_vertex": "person", }, "inputs": [ - "@/path/to/person_knows_person.csv" + f"@{MODERN_GRAPH_CSV_DIR}/person_knows_person.csv" ], "source_vertex_mappings": [ {"column": {"index": 0, "name": "person.id"}, "property": "id"} @@ -144,45 +153,23 @@ def addVertex(sess: Session, graph_id: str): ModelProperty(name="age", type="integer", value=1), ], ), - VertexRequest( - label="person", - primary_key_value=7, - properties=[ - ModelProperty(name="name", type="string", value="lisa"), - ModelProperty(name="age", type="integer", value=2), - ], - ), ] edge_request = [ EdgeRequest( src_label="person", - dst_label="software", - edge_label="created", + dst_label="person", + edge_label="knows", src_primary_key_value=8, - dst_primary_key_value=5, + dst_primary_key_value=1, properties=[ModelProperty(name="weight", value=7)], ), - EdgeRequest( - src_label="person", - dst_label="software", - edge_label="created", - src_primary_key_value=8, - dst_primary_key_value=3, - properties=[ModelProperty(name="weight", value=5)], - ), ] params = VertexEdgeRequest(vertex_request=vertex_request, edge_request=edge_request) - try: - api_response = sess.add_vertex(graph_id, vertex_edge_request=params) - print( - "The response of add_vertex:\n", - api_response, - ) - except Exception as e: - print( - "Exception when calling add_vertex: %s\n" - % e - ) + api_response = sess.add_vertex(graph_id, vertex_edge_request=params) + if api_response.is_ok(): + print("The response of add_vertex:\n", api_response) + else: + raise Exception("add_vertex failed with error: %s" % api_response.get_status_message()) def updateVertex(sess: Session, graph_id: str): @@ -191,117 +178,97 @@ def updateVertex(sess: Session, graph_id: str): vertex_request = VertexRequest( label="person", primary_key_value=1, properties=[name_property, age_property] ) - try: - api_response = sess.update_vertex(graph_id, vertex_request=vertex_request) - print("The response of update_vertex:\n", api_response) - except Exception as e: - print("Exception when calling update_vertex: %s\n" % e) + api_response = sess.update_vertex(graph_id, vertex_request=vertex_request) + if api_response.is_ok(): + print("The response of update_vertex", api_response) + else: + raise Exception("update_vertex failed with error: %s" % api_response.get_status_message()) def getVertex(sess: Session, graph_id: str): label = "person" # str | The label name of querying vertex. primary_key_value = 1 # object | The primary key value of querying vertex. - try: - api_response = sess.get_vertex(graph_id, label, primary_key_value) - print("The response of get_vertex:\n", api_response) - except Exception as e: - print("Exception when calling get_vertex: %s" % e) + api_response = sess.get_vertex(graph_id, label, primary_key_value) + if api_response.is_ok(): + print("The response of get_vertex", api_response) + else: + raise Exception("get_vertex failed with error: %s" % api_response.get_status_message()) def updateEdge(sess: Session, graph_id: str): properties = [ModelProperty(name="weight", value=3)] edge_request = EdgeRequest( src_label="person", - dst_label="software", - edge_label="created", + dst_label="person", + edge_label="knows", src_primary_key_value=1, - dst_primary_key_value=3, + dst_primary_key_value=8, properties=properties, ) - try: - api_response = sess.update_edge(graph_id, edge_request=edge_request) - print( - "The response of update_edge:\n", - api_response, - ) - except Exception as e: - print( - "Exception when calling update_edge: %s\n" - % e - ) + + resp = sess.update_edge(graph_id, edge_request) + if resp.is_ok(): + print("The response of update_edge", resp) + else: + raise Exception("update_edge failed with error: %s" % resp.get_status_message()) def getEdge(sess: Session, graph_id: str): src_label = "person" - dst_label = "software" - edge_label = "created" + dst_label = "person" + edge_label = "knows" src_primary_key_value = 1 - dst_primary_key_value = 3 - try: - api_response = sess.get_edge( - graph_id, - edge_label, - src_label, - src_primary_key_value, - dst_label, - dst_primary_key_value, - ) - print( - "The response of get_edge:\n", api_response - ) - except Exception as e: - print( - "Exception when calling get_edge: %s\n" % e - ) + dst_primary_key_value = 8 + api_response = sess.get_edge( + graph_id, + edge_label, + src_label, + src_primary_key_value, + dst_label, + dst_primary_key_value, + ) + if api_response.is_ok(): + print("The response of get_edge", api_response) + else: + raise Exception("get_edge failed with error: %s" % api_response.get_status_message()) + def addEdge(sess: Session, graph_id: str): edge_request = [ EdgeRequest( src_label="person", - dst_label="software", - edge_label="created", + dst_label="person", + edge_label="knows", src_primary_key_value=1, - dst_primary_key_value=5, + dst_primary_key_value=8, properties=[ModelProperty(name="weight", value=9.123)], ), EdgeRequest( src_label="person", - dst_label="software", - edge_label="created", + dst_label="person", + edge_label="knows", src_primary_key_value=2, - dst_primary_key_value=5, + dst_primary_key_value=8, properties=[ModelProperty(name="weight", value=3.233)], ), ] - try: - api_response = sess.add_edge(graph_id, edge_request) - print( - "The response of add_edge:\n", api_response - ) - except Exception as e: - print( - "Exception when calling add_edge: %s\n" % e - ) + api_response = sess.add_edge(graph_id, edge_request) + if api_response.is_ok(): + print("The response of add_edge", api_response) + else: + raise Exception("add_edge failed with error: %s" % api_response.get_status_message()) + if __name__ == "__main__": # expect one argument: interactive_endpoint parser = argparse.ArgumentParser(description="Example Python3 script") - # Add arguments - parser.add_argument( - "--endpoint", - type=str, - help="The interactive endpoint to connect", - required=True, - default="https://virtserver.swaggerhub.com/GRAPHSCOPE/interactive/1.0.0/", - ) - # Parse the arguments args = parser.parse_args() - driver = Driver(endpoint=args.endpoint) + driver = Driver() with driver.session() as sess: graph_id = createGraph(sess) job_id = bulkLoading(sess, graph_id) @@ -323,18 +290,6 @@ def addEdge(sess: Session, graph_id: str): for record in resp: print(record) - # running a simple gremlin query - query = "g.V().count();" - ret = [] - gremlin_client = driver.getGremlinClient() - q = gremlin_client.submit(query) - while True: - try: - ret.extend(q.next()) - except StopIteration: - break - print(ret) - # more advanced usage of procedure create_proc_request = CreateProcedureRequest( name="test_procedure", @@ -356,3 +311,11 @@ def addEdge(sess: Session, graph_id: str): result = session.run("CALL test_procedure();") for record in result: print(record) + + addVertex(sess, graph_id) + getVertex(sess, graph_id) + updateVertex(sess, graph_id) + + addEdge(sess, graph_id) + getEdge(sess, graph_id) + updateEdge(sess, graph_id)