gsctl 0.29.0a20250114__py2.py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. graphscope/flex/rest/__init__.py +106 -0
  2. graphscope/flex/rest/api/__init__.py +12 -0
  3. graphscope/flex/rest/api/alert_api.py +2790 -0
  4. graphscope/flex/rest/api/data_source_api.py +1177 -0
  5. graphscope/flex/rest/api/deployment_api.py +1323 -0
  6. graphscope/flex/rest/api/graph_api.py +2813 -0
  7. graphscope/flex/rest/api/job_api.py +1408 -0
  8. graphscope/flex/rest/api/service_api.py +1316 -0
  9. graphscope/flex/rest/api/stored_procedure_api.py +1454 -0
  10. graphscope/flex/rest/api/utils_api.py +310 -0
  11. graphscope/flex/rest/api_client.py +789 -0
  12. graphscope/flex/rest/api_response.py +21 -0
  13. graphscope/flex/rest/configuration.py +451 -0
  14. graphscope/flex/rest/exceptions.py +200 -0
  15. graphscope/flex/rest/models/__init__.py +82 -0
  16. graphscope/flex/rest/models/base_edge_type.py +102 -0
  17. graphscope/flex/rest/models/base_edge_type_vertex_type_pair_relations_inner.py +108 -0
  18. graphscope/flex/rest/models/base_edge_type_vertex_type_pair_relations_inner_x_csr_params.py +98 -0
  19. graphscope/flex/rest/models/base_property_meta.py +105 -0
  20. graphscope/flex/rest/models/base_vertex_type.py +96 -0
  21. graphscope/flex/rest/models/base_vertex_type_x_csr_params.py +88 -0
  22. graphscope/flex/rest/models/column_mapping.py +94 -0
  23. graphscope/flex/rest/models/column_mapping_column.py +90 -0
  24. graphscope/flex/rest/models/create_alert_receiver_request.py +103 -0
  25. graphscope/flex/rest/models/create_alert_rule_request.py +112 -0
  26. graphscope/flex/rest/models/create_dataloading_job_response.py +88 -0
  27. graphscope/flex/rest/models/create_edge_type.py +114 -0
  28. graphscope/flex/rest/models/create_graph_request.py +106 -0
  29. graphscope/flex/rest/models/create_graph_response.py +88 -0
  30. graphscope/flex/rest/models/create_graph_schema_request.py +106 -0
  31. graphscope/flex/rest/models/create_property_meta.py +105 -0
  32. graphscope/flex/rest/models/create_stored_proc_request.py +101 -0
  33. graphscope/flex/rest/models/create_stored_proc_response.py +88 -0
  34. graphscope/flex/rest/models/create_vertex_type.py +108 -0
  35. graphscope/flex/rest/models/dataloading_job_config.py +136 -0
  36. graphscope/flex/rest/models/dataloading_job_config_edges_inner.py +92 -0
  37. graphscope/flex/rest/models/dataloading_job_config_loading_config.py +104 -0
  38. graphscope/flex/rest/models/dataloading_job_config_loading_config_format.py +90 -0
  39. graphscope/flex/rest/models/dataloading_job_config_vertices_inner.py +88 -0
  40. graphscope/flex/rest/models/dataloading_mr_job_config.py +88 -0
  41. graphscope/flex/rest/models/date_type.py +88 -0
  42. graphscope/flex/rest/models/edge_mapping.py +122 -0
  43. graphscope/flex/rest/models/edge_mapping_type_triplet.py +92 -0
  44. graphscope/flex/rest/models/error.py +90 -0
  45. graphscope/flex/rest/models/get_alert_message_response.py +123 -0
  46. graphscope/flex/rest/models/get_alert_receiver_response.py +107 -0
  47. graphscope/flex/rest/models/get_alert_rule_response.py +114 -0
  48. graphscope/flex/rest/models/get_edge_type.py +116 -0
  49. graphscope/flex/rest/models/get_graph_response.py +139 -0
  50. graphscope/flex/rest/models/get_graph_schema_response.py +106 -0
  51. graphscope/flex/rest/models/get_pod_log_response.py +88 -0
  52. graphscope/flex/rest/models/get_property_meta.py +107 -0
  53. graphscope/flex/rest/models/get_resource_usage_response.py +105 -0
  54. graphscope/flex/rest/models/get_storage_usage_response.py +88 -0
  55. graphscope/flex/rest/models/get_stored_proc_response.py +130 -0
  56. graphscope/flex/rest/models/get_vertex_type.py +110 -0
  57. graphscope/flex/rest/models/gs_data_type.py +152 -0
  58. graphscope/flex/rest/models/job_status.py +107 -0
  59. graphscope/flex/rest/models/long_text.py +93 -0
  60. graphscope/flex/rest/models/node_status.py +94 -0
  61. graphscope/flex/rest/models/parameter.py +96 -0
  62. graphscope/flex/rest/models/pod_status.py +108 -0
  63. graphscope/flex/rest/models/primitive_type.py +95 -0
  64. graphscope/flex/rest/models/resource_usage.py +92 -0
  65. graphscope/flex/rest/models/running_deployment_info.py +128 -0
  66. graphscope/flex/rest/models/running_deployment_status.py +124 -0
  67. graphscope/flex/rest/models/schema_mapping.py +106 -0
  68. graphscope/flex/rest/models/service_status.py +112 -0
  69. graphscope/flex/rest/models/service_status_sdk_endpoints.py +94 -0
  70. graphscope/flex/rest/models/start_service_request.py +88 -0
  71. graphscope/flex/rest/models/stored_procedure_meta.py +126 -0
  72. graphscope/flex/rest/models/string_type.py +92 -0
  73. graphscope/flex/rest/models/string_type_string.py +124 -0
  74. graphscope/flex/rest/models/temporal_type.py +92 -0
  75. graphscope/flex/rest/models/temporal_type_temporal.py +138 -0
  76. graphscope/flex/rest/models/time_stamp_type.py +88 -0
  77. graphscope/flex/rest/models/update_alert_message_status_request.py +97 -0
  78. graphscope/flex/rest/models/update_stored_proc_request.py +88 -0
  79. graphscope/flex/rest/models/upload_file_response.py +90 -0
  80. graphscope/flex/rest/models/vertex_mapping.py +100 -0
  81. graphscope/flex/rest/py.typed +0 -0
  82. graphscope/flex/rest/rest.py +258 -0
  83. graphscope/gsctl/V6D_VERSION +1 -0
  84. graphscope/gsctl/VERSION +1 -0
  85. graphscope/gsctl/__init__.py +22 -0
  86. graphscope/gsctl/commands/__init__.py +148 -0
  87. graphscope/gsctl/commands/common.py +200 -0
  88. graphscope/gsctl/commands/dev.py +448 -0
  89. graphscope/gsctl/commands/insight/__init__.py +17 -0
  90. graphscope/gsctl/commands/insight/glob.py +234 -0
  91. graphscope/gsctl/commands/insight/graph.py +205 -0
  92. graphscope/gsctl/commands/interactive/__init__.py +17 -0
  93. graphscope/gsctl/commands/interactive/glob.py +280 -0
  94. graphscope/gsctl/commands/interactive/graph.py +259 -0
  95. graphscope/gsctl/config.py +221 -0
  96. graphscope/gsctl/gsctl.py +51 -0
  97. graphscope/gsctl/impl/__init__.py +64 -0
  98. graphscope/gsctl/impl/alert.py +135 -0
  99. graphscope/gsctl/impl/common.py +53 -0
  100. graphscope/gsctl/impl/datasource.py +80 -0
  101. graphscope/gsctl/impl/deployment.py +62 -0
  102. graphscope/gsctl/impl/graph.py +150 -0
  103. graphscope/gsctl/impl/job.py +63 -0
  104. graphscope/gsctl/impl/service.py +62 -0
  105. graphscope/gsctl/impl/stored_procedure.py +92 -0
  106. graphscope/gsctl/impl/utils.py +38 -0
  107. graphscope/gsctl/scripts/install_deps.sh +969 -0
  108. graphscope/gsctl/tests/__init__.py +17 -0
  109. graphscope/gsctl/tests/test_graphscope_insight.py +401 -0
  110. graphscope/gsctl/tests/test_interactive.py +516 -0
  111. graphscope/gsctl/utils.py +337 -0
  112. graphscope/gsctl/version.py +31 -0
  113. gsctl-0.29.0a20250114.dist-info/METADATA +20 -0
  114. gsctl-0.29.0a20250114.dist-info/RECORD +117 -0
  115. gsctl-0.29.0a20250114.dist-info/WHEEL +6 -0
  116. gsctl-0.29.0a20250114.dist-info/entry_points.txt +3 -0
  117. gsctl-0.29.0a20250114.dist-info/top_level.txt +1 -0
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 2024 Alibaba Group Holding Limited. All Rights Reserved.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ import click
20
+ import yaml
21
+
22
+ from graphscope.gsctl.config import get_current_context
23
+ from graphscope.gsctl.impl import create_edge_type
24
+ from graphscope.gsctl.impl import create_vertex_type
25
+ from graphscope.gsctl.impl import delete_edge_type_by_name
26
+ from graphscope.gsctl.impl import delete_vertex_type_by_name
27
+ from graphscope.gsctl.impl import get_datasource_by_id
28
+ from graphscope.gsctl.impl import import_schema
29
+ from graphscope.gsctl.impl import list_graphs
30
+ from graphscope.gsctl.impl import switch_context
31
+ from graphscope.gsctl.utils import TreeDisplay
32
+ from graphscope.gsctl.utils import err
33
+ from graphscope.gsctl.utils import info
34
+ from graphscope.gsctl.utils import is_valid_file_path
35
+ from graphscope.gsctl.utils import read_yaml_file
36
+ from graphscope.gsctl.utils import succ
37
+ from graphscope.gsctl.utils import terminal_display
38
+
39
+
40
+ @click.group()
41
+ def cli():
42
+ pass
43
+
44
+
45
+ @cli.group()
46
+ def use():
47
+ """Switch back to the global scope"""
48
+ pass
49
+
50
+
51
+ @cli.group()
52
+ def delete():
53
+ """Delete vertex or edge type by name"""
54
+ pass
55
+
56
+
57
+ @cli.group()
58
+ def create():
59
+ """Create vertex or edge type from file"""
60
+ pass
61
+
62
+
63
+ @cli.command()
64
+ def ls(): # noqa: F811
65
+ """Display schema and data source mapping information"""
66
+ tree = TreeDisplay()
67
+ # context
68
+ current_context = get_current_context()
69
+ try:
70
+ graphs = list_graphs()
71
+ using_graph = None
72
+ for g in graphs:
73
+ if g.id == current_context.context:
74
+ using_graph = g
75
+ break
76
+ # schema
77
+ tree.create_graph_node(using_graph)
78
+ # data source mapping
79
+ datasource_mapping = get_datasource_by_id(using_graph.id)
80
+ tree.create_datasource_mapping_node(using_graph, datasource_mapping)
81
+ except Exception as e:
82
+ err(f"Failed to display graph information: {str(e)}")
83
+ else:
84
+ tree.show(graph_identifier=current_context.context)
85
+
86
+
87
+ @create.command()
88
+ @click.option(
89
+ "-f",
90
+ "--filename",
91
+ required=True,
92
+ help="Path of yaml file",
93
+ )
94
+ def schema(filename): # noqa: F811
95
+ """Import schema from file"""
96
+ if not is_valid_file_path(filename):
97
+ err(f"Invalid file: {filename}")
98
+ return
99
+ current_context = get_current_context()
100
+ graph_identifier = current_context.context
101
+ try:
102
+ schema = read_yaml_file(filename)
103
+ import_schema(graph_identifier, schema)
104
+ except Exception as e:
105
+ err(f"Failed to import schema: {str(e)}")
106
+ else:
107
+ succ("Import schema successfully.")
108
+
109
+
110
+ @create.command()
111
+ @click.option(
112
+ "-f",
113
+ "--filename",
114
+ required=True,
115
+ help="Path of yaml file",
116
+ )
117
+ def vertex_type(filename): # noqa: F811
118
+ """Create a vertex type from file"""
119
+ if not is_valid_file_path(filename):
120
+ err(f"Invalid file: {filename}")
121
+ return
122
+ current_context = get_current_context()
123
+ graph_identifier = current_context.context
124
+ try:
125
+ vtype = read_yaml_file(filename)
126
+ create_vertex_type(graph_identifier, vtype)
127
+ except Exception as e:
128
+ err(f"Failed to create vertex type: {str(e)}")
129
+ else:
130
+ succ(f"Create vertex type {vtype['type_name']} successfully.")
131
+
132
+
133
+ @delete.command()
134
+ @click.argument("vertex_type", required=True)
135
+ def vertex_type(vertex_type): # noqa: F811
136
+ """Delete a vertex type by name"""
137
+ current_context = get_current_context()
138
+ graph_identifier = current_context.context
139
+ try:
140
+ delete_vertex_type_by_name(graph_identifier, vertex_type)
141
+ except Exception as e:
142
+ err(f"Failed to delete vertex type {vertex_type}: {str(e)}")
143
+ else:
144
+ succ(f"Delete vertex type {vertex_type} successfully.")
145
+
146
+
147
+ @create.command()
148
+ @click.option(
149
+ "-f",
150
+ "--filename",
151
+ required=True,
152
+ help="Path of yaml file",
153
+ )
154
+ def edge_type(filename): # noqa: F811
155
+ """Create an edge type from file"""
156
+ if not is_valid_file_path(filename):
157
+ err(f"Invalid file: {filename}")
158
+ return
159
+ current_context = get_current_context()
160
+ graph_identifier = current_context.context
161
+ try:
162
+ etype = read_yaml_file(filename)
163
+ create_edge_type(graph_identifier, etype)
164
+ except Exception as e:
165
+ err(f"Failed to create edge type: {str(e)}")
166
+ else:
167
+ succ(f"Create edge type {etype['type_name']} successfully.")
168
+
169
+
170
+ @delete.command()
171
+ @click.argument("edge_type", required=True)
172
+ @click.option(
173
+ "-s",
174
+ "--source_vertex_type",
175
+ required=True,
176
+ help="Source vertex type of the edge",
177
+ )
178
+ @click.option(
179
+ "-d",
180
+ "--destination_vertex_type",
181
+ required=True,
182
+ help="Destination vertex type of the edge",
183
+ )
184
+ def edge_type(edge_type, source_vertex_type, destination_vertex_type): # noqa: F811
185
+ """Delete an edge type by name"""
186
+ current_context = get_current_context()
187
+ graph_identifier = current_context.context
188
+ try:
189
+ etype_full_name = (
190
+ f"({source_vertex_type})-[{edge_type}]->({destination_vertex_type})"
191
+ )
192
+ delete_edge_type_by_name(
193
+ graph_identifier, edge_type, source_vertex_type, destination_vertex_type
194
+ )
195
+ except Exception as e:
196
+ err(f"Failed to delete edge type {etype_full_name}: {str(e)}")
197
+ else:
198
+ succ(f"Delete edge type {etype_full_name} successfully.")
199
+
200
+
201
+ @use.command(name="GLOBAL")
202
+ def _global():
203
+ """Switch back to the global scope"""
204
+ switch_context("global")
205
+ click.secho("Using GLOBAL", fg="green")
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 2024 Alibaba Group Holding Limited. All Rights Reserved.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
@@ -0,0 +1,280 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Copyright 2024 Alibaba Group Holding Limited. All Rights Reserved.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ import click
20
+ import yaml
21
+
22
+ from graphscope.gsctl.impl import bind_datasource_in_batch
23
+ from graphscope.gsctl.impl import create_graph
24
+ from graphscope.gsctl.impl import delete_graph_by_id
25
+ from graphscope.gsctl.impl import delete_job_by_id
26
+ from graphscope.gsctl.impl import get_datasource_by_id
27
+ from graphscope.gsctl.impl import get_graph_id_by_name
28
+ from graphscope.gsctl.impl import get_graph_name_by_id
29
+ from graphscope.gsctl.impl import get_job_by_id
30
+ from graphscope.gsctl.impl import list_graphs
31
+ from graphscope.gsctl.impl import list_jobs
32
+ from graphscope.gsctl.impl import list_service_status
33
+ from graphscope.gsctl.impl import list_stored_procedures
34
+ from graphscope.gsctl.impl import start_service
35
+ from graphscope.gsctl.impl import submit_dataloading_job
36
+ from graphscope.gsctl.impl import switch_context
37
+ from graphscope.gsctl.impl import unbind_edge_datasource
38
+ from graphscope.gsctl.impl import unbind_vertex_datasource
39
+ from graphscope.gsctl.utils import TreeDisplay
40
+ from graphscope.gsctl.utils import err
41
+ from graphscope.gsctl.utils import info
42
+ from graphscope.gsctl.utils import is_valid_file_path
43
+ from graphscope.gsctl.utils import read_yaml_file
44
+ from graphscope.gsctl.utils import succ
45
+ from graphscope.gsctl.utils import terminal_display
46
+
47
+
48
+ @click.group()
49
+ def cli():
50
+ pass
51
+
52
+
53
+ @cli.group()
54
+ def create():
55
+ """Create graph, data source, loader job from file"""
56
+ pass
57
+
58
+
59
+ @cli.group()
60
+ def delete():
61
+ """Delete graph, data source, loader job by id"""
62
+ pass
63
+
64
+
65
+ @cli.group()
66
+ def desc():
67
+ """Show job's details by id"""
68
+ pass
69
+
70
+
71
+ @cli.command()
72
+ @click.argument(
73
+ "context", type=click.Choice(["GRAPH"], case_sensitive=False), required=True
74
+ )
75
+ @click.argument("GRAPH_IDENTIFIER", required=True)
76
+ def use(context, graph_identifier):
77
+ """Switch to GRAPH context, see identifier with `ls` command"""
78
+ try:
79
+ graph_identifier = get_graph_id_by_name(graph_identifier)
80
+ graph_name = get_graph_name_by_id(graph_identifier)
81
+ status = list_service_status()
82
+ for s in status:
83
+ if s.graph_id == graph_identifier and s.status != "Running":
84
+ info(
85
+ f"Starting service on graph {graph_name}(id={graph_identifier})..."
86
+ )
87
+ start_service(graph_identifier)
88
+ switch_context(graph_identifier, graph_name)
89
+ except Exception as e:
90
+ err(f"Failed to switch context: {str(e)}")
91
+ else:
92
+ click.secho(f"Using GRAPH {graph_name}(id={graph_identifier})", fg="green")
93
+
94
+
95
+ @cli.command()
96
+ @click.option("-l", is_flag=True, help="List sub resources recursively")
97
+ def ls(l): # noqa: F811, E741
98
+ """Display graph resources in database"""
99
+ tree = TreeDisplay()
100
+ try:
101
+ graphs = list_graphs()
102
+ for g in graphs:
103
+ # schema
104
+ tree.create_graph_node(g, recursive=l)
105
+ if l:
106
+ # data source mapping
107
+ datasource_mapping = get_datasource_by_id(g.id)
108
+ tree.create_datasource_mapping_node(g, datasource_mapping)
109
+ # stored procedure
110
+ stored_procedures = list_stored_procedures(g.id)
111
+ tree.create_stored_procedure_node(g, stored_procedures)
112
+ # job
113
+ jobs = list_jobs()
114
+ tree.create_job_node(g, jobs)
115
+ except Exception as e:
116
+ err(f"Failed to list resources: {str(e)}")
117
+ else:
118
+ tree.show()
119
+ if not l:
120
+ info("Run `gsctl ls -l` to list all resources recursively.")
121
+
122
+
123
+ @create.command()
124
+ @click.option(
125
+ "-f",
126
+ "--filename",
127
+ required=True,
128
+ help="Path of yaml file",
129
+ )
130
+ def graph(filename): # noqa: F811
131
+ """Create a new graph in database"""
132
+ if not is_valid_file_path(filename):
133
+ err(f"Invalid file: {filename}")
134
+ return
135
+ try:
136
+ graph = read_yaml_file(filename)
137
+ graph_id = create_graph(graph)
138
+ except Exception as e:
139
+ err(f"Failed to create graph: {str(e)}")
140
+ else:
141
+ succ(f"Create graph {graph['name']}(id={graph_id}) successfully.")
142
+
143
+
144
+ @delete.command()
145
+ @click.argument("graph_identifier", required=True)
146
+ def graph(graph_identifier): # noqa: F811
147
+ """Delete a graph, see graph identifier with `ls` command"""
148
+ try:
149
+ if click.confirm("Do you want to continue?"):
150
+ delete_graph_by_id(get_graph_id_by_name(graph_identifier))
151
+ succ(f"Delete graph {graph_identifier} successfully.")
152
+ except Exception as e:
153
+ err(f"Failed to delete graph {graph_identifier}: {str(e)}")
154
+
155
+
156
+ @create.command
157
+ @click.option(
158
+ "-g",
159
+ "--graph_identifier",
160
+ required=True,
161
+ help="See graph identifier with `ls` command",
162
+ )
163
+ @click.option(
164
+ "-f",
165
+ "--filename",
166
+ required=True,
167
+ help="Path of yaml file",
168
+ )
169
+ def datasource(graph_identifier, filename): # noqa: F811
170
+ """Bind data source mapping from file"""
171
+ if not is_valid_file_path(filename):
172
+ err(f"Invalid file: {filename}")
173
+ return
174
+ graph_identifier = get_graph_id_by_name(graph_identifier)
175
+ try:
176
+ datasource = read_yaml_file(filename)
177
+ bind_datasource_in_batch(graph_identifier, datasource)
178
+ except Exception as e:
179
+ err(f"Failed to bind data source: {str(e)}")
180
+ else:
181
+ succ("Bind data source successfully.")
182
+
183
+
184
+ @delete.command
185
+ @click.option(
186
+ "-g",
187
+ "--graph_identifier",
188
+ required=True,
189
+ help="See graph identifier with `ls` command",
190
+ )
191
+ @click.option(
192
+ "-t",
193
+ "--type",
194
+ required=True,
195
+ help="Vertex or edge type",
196
+ )
197
+ @click.option(
198
+ "-s",
199
+ "--source_vertex_type",
200
+ required=False,
201
+ help="Source vertex type of the edge [edge only]",
202
+ )
203
+ @click.option(
204
+ "-d",
205
+ "--destination_vertex_type",
206
+ required=False,
207
+ help="Destination vertex type of the edge [edge only]",
208
+ )
209
+ def datasource( # noqa: F811
210
+ graph_identifier, type, source_vertex_type, destination_vertex_type
211
+ ):
212
+ """Unbind data source mapping on vertex or edge type"""
213
+ try:
214
+ graph_identifier = get_graph_id_by_name(graph_identifier)
215
+ if source_vertex_type is not None and destination_vertex_type is not None:
216
+ unbind_edge_datasource(
217
+ graph_identifier, type, source_vertex_type, destination_vertex_type
218
+ )
219
+ else:
220
+ unbind_vertex_datasource(graph_identifier, type)
221
+ except Exception as e:
222
+ err(f"Failed to unbind data source: {str(e)}")
223
+ else:
224
+ succ("Unbind data source successfully.")
225
+
226
+
227
+ @create.command()
228
+ @click.option(
229
+ "-g",
230
+ "--graph_identifier",
231
+ required=True,
232
+ help="See graph identifier with `ls` command",
233
+ )
234
+ @click.option(
235
+ "-f",
236
+ "--filename",
237
+ required=True,
238
+ help="Path of yaml file",
239
+ )
240
+ def loaderjob(graph_identifier, filename): # noqa: F811
241
+ """Create a data loading job from file"""
242
+ if not is_valid_file_path(filename):
243
+ err(f"Invalid file: {filename}")
244
+ return
245
+ graph_identifier = get_graph_id_by_name(graph_identifier)
246
+ try:
247
+ config = read_yaml_file(filename)
248
+ jobid = submit_dataloading_job(graph_identifier, config)
249
+ except Exception as e:
250
+ err(f"Failed to create a job: {str(e)}")
251
+ else:
252
+ succ(f"Create job {jobid} successfully.")
253
+
254
+
255
+ @delete.command()
256
+ @click.argument("identifier", required=True)
257
+ def job(identifier): # noqa: F811
258
+ """Cancel a job, see identifier with `ls` command"""
259
+ try:
260
+ if click.confirm("Do you want to continue?"):
261
+ delete_job_by_id(identifier)
262
+ succ(f"Delete job {identifier} successfully.")
263
+ except Exception as e:
264
+ err(f"Failed to delete job {identifier}: {str(e)}")
265
+
266
+
267
+ @desc.command()
268
+ @click.argument("identifier", required=True)
269
+ def job(identifier): # noqa: F811
270
+ """Show details of job, see identifier with `ls` command"""
271
+ try:
272
+ job = get_job_by_id(identifier)
273
+ except Exception as e:
274
+ err(f"Failed to get job: {str(e)}")
275
+ else:
276
+ info(yaml.dump(job.to_dict()))
277
+
278
+
279
+ if __name__ == "__main__":
280
+ cli()