graphs.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. import json
  2. import asyncclick as click
  3. from asyncclick import pass_context
  4. from cli.utils.param_types import JSON
  5. from cli.utils.timer import timer
  6. from r2r import R2RAsyncClient, R2RException
  7. @click.group()
  8. def graphs():
  9. """Graphs commands."""
  10. pass
  11. @graphs.command()
  12. @click.option(
  13. "--collection-ids", multiple=True, help="Collection IDs to fetch"
  14. )
  15. @click.option(
  16. "--offset",
  17. default=0,
  18. help="The offset to start from. Defaults to 0.",
  19. )
  20. @click.option(
  21. "--limit",
  22. default=100,
  23. help="The maximum number of graphs to return. Defaults to 100.",
  24. )
  25. @pass_context
  26. async def list(ctx: click.Context, collection_ids, offset, limit):
  27. """List available graphs."""
  28. collection_ids = list(collection_ids) if collection_ids else None
  29. client: R2RAsyncClient = ctx.obj
  30. try:
  31. with timer():
  32. response = await client.graphs.list(
  33. collection_ids=collection_ids,
  34. offset=offset,
  35. limit=limit,
  36. )
  37. click.echo(json.dumps(response, indent=2))
  38. except R2RException as e:
  39. click.echo(str(e), err=True)
  40. except Exception as e:
  41. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  42. @graphs.command()
  43. @click.argument("collection_id", required=True, type=str)
  44. @pass_context
  45. async def retrieve(ctx: click.Context, collection_id):
  46. """Retrieve a specific graph by collection ID."""
  47. client: R2RAsyncClient = ctx.obj
  48. try:
  49. with timer():
  50. response = await client.graphs.retrieve(
  51. collection_id=collection_id
  52. )
  53. click.echo(json.dumps(response, indent=2))
  54. except R2RException as e:
  55. click.echo(str(e), err=True)
  56. except Exception as e:
  57. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  58. @graphs.command()
  59. @click.argument("collection_id", required=True, type=str)
  60. @pass_context
  61. async def reset(ctx: click.Context, collection_id):
  62. """Reset a graph, removing all its data."""
  63. client: R2RAsyncClient = ctx.obj
  64. try:
  65. with timer():
  66. response = await client.graphs.reset(collection_id=collection_id)
  67. click.echo(json.dumps(response, indent=2))
  68. except R2RException as e:
  69. click.echo(str(e), err=True)
  70. except Exception as e:
  71. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  72. @graphs.command()
  73. @click.argument("collection_id", required=True, type=str)
  74. @click.option("--name", help="New name for the graph")
  75. @click.option("--description", help="New description for the graph")
  76. @pass_context
  77. async def update(ctx: click.Context, collection_id, name, description):
  78. """Update graph information."""
  79. client: R2RAsyncClient = ctx.obj
  80. try:
  81. with timer():
  82. response = await client.graphs.update(
  83. collection_id=collection_id,
  84. name=name,
  85. description=description,
  86. )
  87. click.echo(json.dumps(response, indent=2))
  88. except R2RException as e:
  89. click.echo(str(e), err=True)
  90. except Exception as e:
  91. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  92. @graphs.command()
  93. @click.argument("collection_id", required=True, type=str)
  94. @click.option(
  95. "--offset",
  96. default=0,
  97. help="The offset to start from. Defaults to 0.",
  98. )
  99. @click.option(
  100. "--limit",
  101. default=100,
  102. help="The maximum number of entities to return. Defaults to 100.",
  103. )
  104. @pass_context
  105. async def list_entities(ctx: click.Context, collection_id, offset, limit):
  106. """List entities in a graph."""
  107. client: R2RAsyncClient = ctx.obj
  108. try:
  109. with timer():
  110. response = await client.graphs.list_entities(
  111. collection_id=collection_id,
  112. offset=offset,
  113. limit=limit,
  114. )
  115. click.echo(json.dumps(response, indent=2))
  116. except R2RException as e:
  117. click.echo(str(e), err=True)
  118. except Exception as e:
  119. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  120. @graphs.command()
  121. @click.argument("collection_id", required=True, type=str)
  122. @click.argument("entity_id", required=True, type=str)
  123. @pass_context
  124. async def get_entity(ctx: click.Context, collection_id, entity_id):
  125. """Get entity information from a graph."""
  126. client: R2RAsyncClient = ctx.obj
  127. try:
  128. with timer():
  129. response = await client.graphs.get_entity(
  130. collection_id=collection_id,
  131. entity_id=entity_id,
  132. )
  133. click.echo(json.dumps(response, indent=2))
  134. except R2RException as e:
  135. click.echo(str(e), err=True)
  136. except Exception as e:
  137. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  138. @graphs.command()
  139. @click.argument("collection_id", required=True, type=str)
  140. @click.argument("entity_id", required=True, type=str)
  141. @pass_context
  142. async def remove_entity(ctx: click.Context, collection_id, entity_id):
  143. """Remove an entity from a graph."""
  144. client: R2RAsyncClient = ctx.obj
  145. try:
  146. with timer():
  147. response = await client.graphs.remove_entity(
  148. collection_id=collection_id,
  149. entity_id=entity_id,
  150. )
  151. click.echo(json.dumps(response, indent=2))
  152. except R2RException as e:
  153. click.echo(str(e), err=True)
  154. except Exception as e:
  155. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  156. @graphs.command()
  157. @click.argument("collection_id", required=True, type=str)
  158. @click.option(
  159. "--offset",
  160. default=0,
  161. help="The offset to start from. Defaults to 0.",
  162. )
  163. @click.option(
  164. "--limit",
  165. default=100,
  166. help="The maximum number of relationships to return. Defaults to 100.",
  167. )
  168. @pass_context
  169. async def list_relationships(ctx: click.Context, collection_id, offset, limit):
  170. """List relationships in a graph."""
  171. client: R2RAsyncClient = ctx.obj
  172. try:
  173. with timer():
  174. response = await client.graphs.list_relationships(
  175. collection_id=collection_id,
  176. offset=offset,
  177. limit=limit,
  178. )
  179. click.echo(json.dumps(response, indent=2))
  180. except R2RException as e:
  181. click.echo(str(e), err=True)
  182. except Exception as e:
  183. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  184. @graphs.command()
  185. @click.argument("collection_id", required=True, type=str)
  186. @click.argument("relationship_id", required=True, type=str)
  187. @pass_context
  188. async def get_relationship(ctx: click.Context, collection_id, relationship_id):
  189. """Get relationship information from a graph."""
  190. client: R2RAsyncClient = ctx.obj
  191. try:
  192. with timer():
  193. response = await client.graphs.get_relationship(
  194. collection_id=collection_id,
  195. relationship_id=relationship_id,
  196. )
  197. click.echo(json.dumps(response, indent=2))
  198. except R2RException as e:
  199. click.echo(str(e), err=True)
  200. except Exception as e:
  201. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  202. @graphs.command()
  203. @click.argument("collection_id", required=True, type=str)
  204. @click.argument("relationship_id", required=True, type=str)
  205. @pass_context
  206. async def remove_relationship(
  207. ctx: click.Context, collection_id, relationship_id
  208. ):
  209. """Remove a relationship from a graph."""
  210. client: R2RAsyncClient = ctx.obj
  211. try:
  212. with timer():
  213. response = await client.graphs.remove_relationship(
  214. collection_id=collection_id,
  215. relationship_id=relationship_id,
  216. )
  217. click.echo(json.dumps(response, indent=2))
  218. except R2RException as e:
  219. click.echo(str(e), err=True)
  220. except Exception as e:
  221. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  222. @graphs.command()
  223. @click.argument("collection_id", required=True, type=str)
  224. @click.option(
  225. "--settings", required=True, type=JSON, help="Build settings as JSON"
  226. )
  227. @click.option("--run-type", default="estimate", help="Type of build to run")
  228. @click.option(
  229. "--run-without-orchestration",
  230. is_flag=True,
  231. help="Run without orchestration",
  232. )
  233. @pass_context
  234. async def build(
  235. ctx: click.Context,
  236. collection_id,
  237. settings,
  238. run_type,
  239. run_without_orchestration,
  240. ):
  241. """Build a graph with specified settings."""
  242. run_with_orchestration = not run_without_orchestration
  243. client: R2RAsyncClient = ctx.obj
  244. try:
  245. with timer():
  246. response = await client.graphs.build(
  247. collection_id=collection_id,
  248. settings=settings,
  249. run_type=run_type,
  250. run_with_orchestration=run_with_orchestration,
  251. )
  252. click.echo(json.dumps(response, indent=2))
  253. except R2RException as e:
  254. click.echo(str(e), err=True)
  255. except Exception as e:
  256. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  257. @graphs.command()
  258. @click.argument("collection_id", required=True, type=str)
  259. @click.option(
  260. "--offset",
  261. default=0,
  262. help="The offset to start from. Defaults to 0.",
  263. )
  264. @click.option(
  265. "--limit",
  266. default=100,
  267. help="The maximum number of communities to return. Defaults to 100.",
  268. )
  269. @pass_context
  270. async def list_communities(ctx: click.Context, collection_id, offset, limit):
  271. """List communities in a graph."""
  272. client: R2RAsyncClient = ctx.obj
  273. try:
  274. with timer():
  275. response = await client.graphs.list_communities(
  276. collection_id=collection_id,
  277. offset=offset,
  278. limit=limit,
  279. )
  280. click.echo(json.dumps(response, indent=2))
  281. except R2RException as e:
  282. click.echo(str(e), err=True)
  283. except Exception as e:
  284. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  285. @graphs.command()
  286. @click.argument("collection_id", required=True, type=str)
  287. @click.argument("community_id", required=True, type=str)
  288. @pass_context
  289. async def get_community(ctx: click.Context, collection_id, community_id):
  290. """Get community information from a graph."""
  291. client: R2RAsyncClient = ctx.obj
  292. try:
  293. with timer():
  294. response = await client.graphs.get_community(
  295. collection_id=collection_id,
  296. community_id=community_id,
  297. )
  298. click.echo(json.dumps(response, indent=2))
  299. except R2RException as e:
  300. click.echo(str(e), err=True)
  301. except Exception as e:
  302. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  303. @graphs.command()
  304. @click.argument("collection_id", required=True, type=str)
  305. @click.argument("community_id", required=True, type=str)
  306. @click.option("--name", help="New name for the community")
  307. @click.option("--summary", help="New summary for the community")
  308. @click.option(
  309. "--findings",
  310. type=JSON,
  311. help="New findings for the community as JSON array",
  312. )
  313. @click.option("--rating", type=int, help="New rating for the community")
  314. @click.option(
  315. "--rating-explanation", help="New rating explanation for the community"
  316. )
  317. @click.option("--level", type=int, help="New level for the community")
  318. @click.option(
  319. "--attributes", type=JSON, help="New attributes for the community as JSON"
  320. )
  321. @pass_context
  322. async def update_community(
  323. ctx: click.Context,
  324. collection_id,
  325. community_id,
  326. name,
  327. summary,
  328. findings,
  329. rating,
  330. rating_explanation,
  331. level,
  332. attributes,
  333. ):
  334. """Update community information."""
  335. client: R2RAsyncClient = ctx.obj
  336. try:
  337. with timer():
  338. response = await client.graphs.update_community(
  339. collection_id=collection_id,
  340. community_id=community_id,
  341. name=name,
  342. summary=summary,
  343. findings=findings,
  344. rating=rating,
  345. rating_explanation=rating_explanation,
  346. level=level,
  347. attributes=attributes,
  348. )
  349. click.echo(json.dumps(response, indent=2))
  350. except R2RException as e:
  351. click.echo(str(e), err=True)
  352. except Exception as e:
  353. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  354. @graphs.command()
  355. @click.argument("collection_id", required=True, type=str)
  356. @click.argument("community_id", required=True, type=str)
  357. @pass_context
  358. async def delete_community(ctx: click.Context, collection_id, community_id):
  359. """Delete a community from a graph."""
  360. client: R2RAsyncClient = ctx.obj
  361. try:
  362. with timer():
  363. response = await client.graphs.delete_community(
  364. collection_id=collection_id,
  365. community_id=community_id,
  366. )
  367. click.echo(json.dumps(response, indent=2))
  368. except R2RException as e:
  369. click.echo(str(e), err=True)
  370. except Exception as e:
  371. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  372. @graphs.command()
  373. @click.argument("collection_id", required=True, type=str)
  374. @pass_context
  375. async def pull(ctx: click.Context, collection_id):
  376. """Pull documents into a graph."""
  377. client: R2RAsyncClient = ctx.obj
  378. try:
  379. with timer():
  380. response = await client.graphs.pull(collection_id=collection_id)
  381. click.echo(json.dumps(response, indent=2))
  382. except R2RException as e:
  383. click.echo(str(e), err=True)
  384. except Exception as e:
  385. click.echo(str(f"An unexpected error occurred: {e}"), err=True)
  386. @graphs.command()
  387. @click.argument("collection_id", required=True, type=str)
  388. @click.argument("document_id", required=True, type=str)
  389. @pass_context
  390. async def remove_document(ctx: click.Context, collection_id, document_id):
  391. """Remove a document from a graph."""
  392. client: R2RAsyncClient = ctx.obj
  393. try:
  394. with timer():
  395. response = await client.graphs.remove_document(
  396. collection_id=collection_id,
  397. document_id=document_id,
  398. )
  399. click.echo(json.dumps(response, indent=2))
  400. except R2RException as e:
  401. click.echo(str(e), err=True)
  402. except Exception as e:
  403. click.echo(str(f"An unexpected error occurred: {e}"), err=True)