neuronum 2.0.8__py3-none-any.whl → 3.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of neuronum might be problematic. Click here for more details.

cli/main.py CHANGED
@@ -1,13 +1,16 @@
1
- import click
2
- import questionary
3
- from pathlib import Path
4
- import requests
5
1
  import subprocess
6
2
  import os
7
3
  import neuronum
8
4
  import json
9
5
  import platform
10
6
  import glob
7
+ import asyncio
8
+ import aiohttp
9
+ import click
10
+ import questionary
11
+ from pathlib import Path
12
+ import requests
13
+
11
14
 
12
15
  @click.group()
13
16
  def cli():
@@ -83,7 +86,6 @@ def create_cell():
83
86
  click.echo(f"Error:'{email}' already assigned!")
84
87
 
85
88
 
86
-
87
89
  @click.command()
88
90
  def connect_cell():
89
91
  email = click.prompt("Enter your Email")
@@ -242,13 +244,15 @@ def delete_cell():
242
244
  click.echo(f"Neuronum Cell '{host}' has been deleted!")
243
245
  else:
244
246
  click.echo(f"Neuronum Cell '{host}' deletion failed!")
245
-
247
+
246
248
 
247
249
  @click.command()
248
250
  @click.option('--sync', multiple=True, default=None, help="Optional stream IDs for sync.")
249
251
  @click.option('--stream', multiple=True, default=None, help="Optional stream ID for stream.")
250
252
  def init_node(sync, stream):
253
+ asyncio.run(async_init_node(sync, stream))
251
254
 
255
+ async def async_init_node(sync, stream):
252
256
  credentials_folder_path = Path.home() / ".neuronum"
253
257
  env_path = credentials_folder_path / ".env"
254
258
 
@@ -273,15 +277,17 @@ def init_node(sync, stream):
273
277
  return
274
278
 
275
279
  url = f"https://{network}/api/init_node"
276
- node = {"host": host, "password": password, "synapse": synapse}
280
+ node_payload = {"host": host, "password": password, "synapse": synapse}
277
281
 
278
- try:
279
- response = requests.post(url, json=node)
280
- response.raise_for_status()
281
- nodeID = response.json()["nodeID"]
282
- except requests.exceptions.RequestException as e:
283
- click.echo(f"Error sending request: {e}")
284
- return
282
+ async with aiohttp.ClientSession() as session:
283
+ try:
284
+ async with session.post(url, json=node_payload) as response:
285
+ response.raise_for_status()
286
+ data = await response.json()
287
+ nodeID = data["nodeID"]
288
+ except aiohttp.ClientError as e:
289
+ click.echo(f"Error sending request: {e}")
290
+ return
285
291
 
286
292
  node_filename = "node_" + nodeID.replace("::node", "")
287
293
  project_path = Path(node_filename)
@@ -294,35 +300,50 @@ def init_node(sync, stream):
294
300
  synapse=synapse
295
301
  )
296
302
 
297
- cells = cell.list_cells()
298
- tx = cell.list_tx()
299
- ctx = cell.list_ctx()
300
- stx = cell.list_stx()
301
- contracts = cell.list_contracts()
302
- nodes = cell.list_nodes()
303
-
304
- cells_path = project_path / "cells.json"
305
- tx_path = project_path / "transmitters.json"
306
- ctx_path = project_path / "circuits.json"
307
- stx_path = project_path / "streams.json"
308
- contracts_path = project_path / "contracts.json"
309
- nodes_path = project_path / "nodes.json"
310
-
311
- cells_path.write_text(json.dumps(cells, indent=4))
312
- tx_path.write_text(json.dumps(tx, indent=4))
313
- ctx_path.write_text(json.dumps(ctx, indent=4))
314
- stx_path.write_text(json.dumps(stx, indent=4))
315
- contracts_path.write_text(json.dumps(contracts, indent=4))
316
- nodes_path.write_text(json.dumps(nodes, indent=4))
303
+ cells = await cell.list_cells()
304
+ tx = await cell.list_tx()
305
+ ctx = await cell.list_ctx()
306
+ stx = await cell.list_stx()
307
+ contracts = await cell.list_contracts()
308
+ nodes = await cell.list_nodes()
309
+
310
+ await asyncio.to_thread((project_path / "cells.json").write_text, json.dumps(cells, indent=4))
311
+ await asyncio.to_thread((project_path / "transmitters.json").write_text, json.dumps(tx, indent=4))
312
+ await asyncio.to_thread((project_path / "circuits.json").write_text, json.dumps(ctx, indent=4))
313
+ await asyncio.to_thread((project_path / "streams.json").write_text, json.dumps(stx, indent=4))
314
+ await asyncio.to_thread((project_path / "contracts.json").write_text, json.dumps(contracts, indent=4))
315
+ await asyncio.to_thread((project_path / "nodes.json").write_text, json.dumps(nodes, indent=4))
317
316
 
318
317
  env_path = project_path / ".env"
319
- env_path.write_text(f"NODE={nodeID}\nHOST={host}\nPASSWORD={password}\nNETWORK={network}\nSYNAPSE={synapse}\n")
318
+ await asyncio.to_thread(env_path.write_text, f"NODE={nodeID}\nHOST={host}\nPASSWORD={password}\nNETWORK={network}\nSYNAPSE={synapse}\n")
320
319
 
321
320
  gitignore_path = project_path / ".gitignore"
322
- gitignore_path.write_text(".env\n")
321
+ await asyncio.to_thread(gitignore_path.write_text, ".env\n")
323
322
 
324
323
  nodemd_path = project_path / "NODE.md"
325
- nodemd_path.write_text("## Use this NODE.md file to add instructions on how to interact with your node\n")
324
+ await asyncio.to_thread(nodemd_path.write_text, """### Getting started template: Neuronum NODE.md
325
+ ### Use this .md file to add instructions on how to interact with your Node
326
+
327
+ ```json
328
+ {
329
+ "Use Case": "Getting started Node streaming: Hello, Neuronum!",
330
+ "Requirements": [
331
+ {
332
+ "name": "Python",
333
+ "version": ">= 3.8",
334
+ "link": "https://www.python.org/downloads/"
335
+ },
336
+ {
337
+ "name": "Neuronum Lib",
338
+ "version": ">= 3.0.1",
339
+ "link": "https://pypi.org/project/neuronum/"
340
+ }
341
+ ],
342
+ "Installation": "pip install neuronum",
343
+ "Initialization": "neuronum init-node"
344
+ }
345
+ ```"""
346
+ )
326
347
 
327
348
  stx = sync[0] if sync else (stream[0] if stream else host.replace("::cell", "::stx"))
328
349
 
@@ -330,6 +351,7 @@ def init_node(sync, stream):
330
351
  for stx in sync:
331
352
  sync_path = project_path / f"sync_{stx.replace('::stx', '')}.py"
332
353
  sync_path.write_text(f"""\
354
+ import asyncio
333
355
  import neuronum
334
356
  import os
335
357
  from dotenv import load_dotenv
@@ -347,15 +369,17 @@ cell = neuronum.Cell(
347
369
  synapse=synapse
348
370
  )
349
371
 
350
- STX = "{stx}"
351
- stream = cell.sync(STX)
352
- for operation in stream:
353
- label = operation.get("label")
354
- data = operation.get("data")
355
- ts = operation.get("time")
356
- stxID = operation.get("stxID")
357
- operator = operation.get("operator")
358
- print(label, data, ts, stxID, operator)
372
+ async def main():
373
+ STX = "{stx}"
374
+ async for operation in cell.sync(STX):
375
+ label = operation.get("label")
376
+ data = operation.get("data")
377
+ ts = operation.get("time")
378
+ stxID = operation.get("stxID")
379
+ operator = operation.get("operator")
380
+ print(label, data, ts, stxID, operator)
381
+
382
+ asyncio.run(main())
359
383
  """)
360
384
 
361
385
 
@@ -363,6 +387,7 @@ for operation in stream:
363
387
  for stx in stream:
364
388
  stream_path = project_path / f"stream_{stx.replace('::stx', '')}.py"
365
389
  stream_path.write_text(f"""\
390
+ import asyncio
366
391
  import neuronum
367
392
  import os
368
393
  from dotenv import load_dotenv
@@ -380,20 +405,25 @@ cell = neuronum.Cell(
380
405
  synapse=synapse
381
406
  )
382
407
 
383
- STX = "{stx}"
384
- label = "your_label"
385
- while True:
386
- data = {{
387
- "key1": "value1",
388
- "key2": "value2",
389
- "key3": "value3",
390
- }}
391
- cell.stream(label, data, STX)
408
+ async def main():
409
+ STX = "{stx}"
410
+ label = "your_label"
411
+
412
+ while True:
413
+ data = {{
414
+ "key1": "value1",
415
+ "key2": "value2",
416
+ "key3": "value3",
417
+ }}
418
+ await cell.stream(label, data, STX)
419
+
420
+ asyncio.run(main())
392
421
  """)
393
422
 
394
423
  if not sync and not stream:
395
424
  sync_path = project_path / f"sync_{stx.replace('::stx', '')}.py"
396
425
  sync_path.write_text(f"""\
426
+ import asyncio
397
427
  import neuronum
398
428
  import os
399
429
  from dotenv import load_dotenv
@@ -410,16 +440,19 @@ cell = neuronum.Cell(
410
440
  network=network,
411
441
  synapse=synapse
412
442
  )
413
-
414
- STX = "{stx}"
415
- stream = cell.sync(STX)
416
- for operation in stream:
417
- message = operation.get("data").get("message")
418
- print(message)
443
+
444
+ async def main():
445
+ STX = "{stx}"
446
+ async for operation in cell.sync(STX):
447
+ message = operation.get("data").get("message")
448
+ print(message)
449
+
450
+ asyncio.run(main())
419
451
  """)
420
452
 
421
453
  stream_path = project_path / f"stream_{stx.replace('::stx', '')}.py"
422
454
  stream_path.write_text(f"""\
455
+ import asyncio
423
456
  import neuronum
424
457
  import os
425
458
  from dotenv import load_dotenv
@@ -436,28 +469,65 @@ cell = neuronum.Cell(
436
469
  network=network,
437
470
  synapse=synapse
438
471
  )
439
-
440
- STX = "{stx}"
441
- label = "Welcome to Neuronum"
442
- while True:
443
- data = {{
444
- "message": "Hello, Neuronum!"
445
- }}
446
- cell.stream(label, data, STX)
472
+
473
+ async def main():
474
+ STX = "{stx}"
475
+ label = "Welcome to Neuronum"
476
+
477
+ while True:
478
+ data = {{
479
+ "message": "Hello, Neuronum!"
480
+ }}
481
+ await cell.stream(label, data, STX)
482
+
483
+ asyncio.run(main())
447
484
  """)
485
+
486
+ scan_path = project_path / f"scan.py"
487
+ scan_path.write_text(f"""\
488
+ import asyncio
489
+ import neuronum
490
+ import os
491
+ from dotenv import load_dotenv
448
492
 
449
- click.echo(f"Neuronum Node '{nodeID}' initialized!")
493
+ load_dotenv()
494
+ host = os.getenv("HOST")
495
+ password = os.getenv("PASSWORD")
496
+ network = os.getenv("NETWORK")
497
+ synapse = os.getenv("SYNAPSE")
498
+
499
+ cell = neuronum.Cell(
500
+ host=host,
501
+ password=password,
502
+ network=network,
503
+ synapse=synapse
504
+ )
505
+
506
+ async def main():
507
+ async for cp in cell.scan():
508
+ print(cp)
450
509
 
510
+ asyncio.run(main())
511
+ """)
512
+
513
+ click.echo(f"Neuronum Node '{nodeID}' initialized!")
451
514
 
452
515
 
453
516
  @click.command()
454
517
  def start_node():
518
+ scan_type = questionary.select(
519
+ "Scan for Neuronum Cells and Nodes (Ensure Bluetooth is enabled)",
520
+ choices=["On", "Off"]
521
+ ).ask()
522
+
455
523
  click.echo("Starting Node...")
456
524
 
457
525
  project_path = Path.cwd()
458
-
459
526
  script_files = glob.glob("sync_*.py") + glob.glob("stream_*.py")
460
527
 
528
+ if scan_type == "On":
529
+ script_files += glob.glob("scan.py")
530
+
461
531
  processes = []
462
532
 
463
533
  for script in script_files:
@@ -473,13 +543,19 @@ def start_node():
473
543
  with open("node_pid.txt", "w") as f:
474
544
  f.write("\n".join(map(str, processes)))
475
545
 
476
- click.echo(f"Node started successfully!")
546
+ click.echo("Node started successfully!")
547
+
477
548
 
478
549
 
479
550
  @click.command()
480
551
  def stop_node():
552
+ asyncio.run(async_stop_node())
553
+
554
+ async def async_stop_node():
481
555
  click.echo("Stopping Node...")
482
556
 
557
+ node_pid_path = Path("node_pid.txt")
558
+
483
559
  try:
484
560
  with open("node_pid.txt", "r") as f:
485
561
  pids = [int(pid.strip()) for pid in f.readlines()]
@@ -489,18 +565,14 @@ def stop_node():
489
565
  for pid in pids:
490
566
  try:
491
567
  if system_name == "Windows":
492
- subprocess.run(
493
- ["taskkill", "/F", "/PID", str(pid)],
494
- stdout=subprocess.DEVNULL,
495
- stderr=subprocess.DEVNULL
496
- )
568
+ await asyncio.to_thread(subprocess.run, ["taskkill", "/F", "/PID", str(pid)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
497
569
  else:
498
- os.kill(pid, 9)
570
+ await asyncio.to_thread(os.kill, pid, 9)
499
571
  except ProcessLookupError:
500
572
  click.echo(f"Warning: Process {pid} already stopped or does not exist.")
501
573
 
502
- os.remove("node_pid.txt")
503
- click.echo(f"Node stopped successfully!")
574
+ await asyncio.to_thread(os.remove, node_pid_path)
575
+ click.echo("Node stopped successfully!")
504
576
 
505
577
  except FileNotFoundError:
506
578
  click.echo("Error: No active node process found.")
@@ -509,7 +581,11 @@ def stop_node():
509
581
 
510
582
 
511
583
  @click.command()
512
- def register_node():
584
+ def connect_node():
585
+ descr = click.prompt("Node description (max. 25 characters)")
586
+ asyncio.run(async_connect_node(descr))
587
+
588
+ async def async_connect_node(descr):
513
589
  env_data = {}
514
590
  try:
515
591
  with open(".env", "r") as f:
@@ -529,13 +605,6 @@ def register_node():
529
605
  except Exception as e:
530
606
  print(f"Error reading .env file: {e}")
531
607
  return
532
-
533
- node_type = questionary.select(
534
- "Choose Node type:",
535
- choices=["public", "private"]
536
- ).ask()
537
-
538
- descr = click.prompt("Node description (max. 25 characters)")
539
608
 
540
609
  try:
541
610
  with open("NODE.md", "r") as f:
@@ -548,7 +617,7 @@ def register_node():
548
617
  print(f"Error reading NODE.md file: {e}")
549
618
  return
550
619
 
551
- url = f"https://{network}/api/register_node/{node_type}"
620
+ url = f"https://{network}/api/connect_node"
552
621
 
553
622
  node = {
554
623
  "nodeID": nodeID,
@@ -559,21 +628,30 @@ def register_node():
559
628
  "nodemd_file": nodemd_file
560
629
  }
561
630
 
562
- try:
563
- response = requests.post(url, json=node)
564
- response.raise_for_status()
565
- nodeID = response.json()["nodeID"]
566
- node_url = response.json()["node_url"]
567
- except requests.exceptions.RequestException as e:
568
- click.echo(f"Error sending request: {e}")
569
- return
570
-
571
- click.echo(f"Neuronum Node '{nodeID}' registered! Visit: {node_url}")
631
+ async with aiohttp.ClientSession() as session:
632
+ try:
633
+ async with session.post(url, json=node) as response:
634
+ response.raise_for_status()
635
+ data = await response.json()
636
+ nodeID = data["nodeID"]
637
+ node_url = data["node_url"]
638
+ except aiohttp.ClientError as e:
639
+ click.echo(f"Error sending request: {e}")
640
+ return
641
+
642
+ if nodeID == "Node does not exist":
643
+ click.echo(f"Neuronum Node not found! Make sure you initialized your Node correctly")
644
+ else:
645
+ click.echo(f"Neuronum Node '{nodeID}' connected! Visit: {node_url}")
572
646
 
573
647
 
574
648
  @click.command()
575
649
  def update_node():
650
+ asyncio.run(async_update_node())
651
+
652
+ async def async_update_node():
576
653
  env_data = {}
654
+
577
655
  try:
578
656
  with open(".env", "r") as f:
579
657
  for line in f:
@@ -587,26 +665,25 @@ def update_node():
587
665
  synapse = env_data.get("SYNAPSE", "")
588
666
 
589
667
  except FileNotFoundError:
590
- print("Error: .env with credentials not found")
668
+ click.echo("Error: .env with credentials not found")
591
669
  return
592
670
  except Exception as e:
593
- print(f"Error reading .env file: {e}")
671
+ click.echo(f"Error reading .env file: {e}")
594
672
  return
595
673
 
596
674
  try:
597
- with open("NODE.md", "r") as f:
598
- nodemd_file = f.read()
675
+ with open("NODE.md", "r") as f:
676
+ nodemd_file = f.read()
599
677
 
600
678
  except FileNotFoundError:
601
- print("Error: NODE.md file not found")
679
+ click.echo("Error: NODE.md file not found")
602
680
  return
603
681
  except Exception as e:
604
- print(f"Error reading NODE.md file: {e}")
682
+ click.echo(f"Error reading NODE.md file: {e}")
605
683
  return
606
684
 
607
685
  url = f"https://{network}/api/update_node"
608
-
609
- node = {
686
+ node_payload = {
610
687
  "nodeID": nodeID,
611
688
  "host": host,
612
689
  "password": password,
@@ -614,50 +691,48 @@ def update_node():
614
691
  "nodemd_file": nodemd_file
615
692
  }
616
693
 
617
- try:
618
- response = requests.post(url, json=node)
619
- response.raise_for_status()
620
- nodeID = response.json()["nodeID"]
621
- node_url = response.json()["node_url"]
622
- except requests.exceptions.RequestException as e:
623
- click.echo(f"Error sending request: {e}")
624
- return
625
-
694
+ async with aiohttp.ClientSession() as session:
695
+ try:
696
+ async with session.post(url, json=node_payload) as response:
697
+ response.raise_for_status()
698
+ data = await response.json()
699
+ nodeID = data["nodeID"]
700
+ node_url = data["node_url"]
701
+ except aiohttp.ClientError as e:
702
+ click.echo(f"Error sending request: {e}")
703
+ return
626
704
 
627
705
  cell = neuronum.Cell(
628
- host=host,
629
- password=password,
630
- network=network,
631
- synapse=synapse
706
+ host=host,
707
+ password=password,
708
+ network=network,
709
+ synapse=synapse
632
710
  )
633
711
 
634
- cells = cell.list_cells()
635
- tx = cell.list_tx()
636
- ctx = cell.list_ctx()
637
- stx = cell.list_stx()
638
- contracts = cell.list_contracts()
639
- nodes = cell.list_nodes()
640
-
641
- cells_path = Path("cells.json")
642
- tx_path = Path("transmitters.json")
643
- ctx_path = Path("circuits.json")
644
- stx_path = Path("streams.json")
645
- contracts_path = Path("contracts.json")
646
- nodes_path = Path("nodes.json")
647
-
648
- cells_path.write_text(json.dumps(cells, indent=4))
649
- tx_path.write_text(json.dumps(tx, indent=4))
650
- ctx_path.write_text(json.dumps(ctx, indent=4))
651
- stx_path.write_text(json.dumps(stx, indent=4))
652
- contracts_path.write_text(json.dumps(contracts, indent=4))
653
- nodes_path.write_text(json.dumps(nodes, indent=4))
712
+ cells = await cell.list_cells()
713
+ tx = await cell.list_tx()
714
+ ctx = await cell.list_ctx()
715
+ stx = await cell.list_stx()
716
+ contracts = await cell.list_contracts()
717
+ nodes = await cell.list_nodes()
718
+
719
+ await asyncio.to_thread(Path("cells.json").write_text, json.dumps(cells, indent=4))
720
+ await asyncio.to_thread(Path("transmitters.json").write_text, json.dumps(tx, indent=4))
721
+ await asyncio.to_thread(Path("circuits.json").write_text, json.dumps(ctx, indent=4))
722
+ await asyncio.to_thread(Path("streams.json").write_text, json.dumps(stx, indent=4))
723
+ await asyncio.to_thread(Path("contracts.json").write_text, json.dumps(contracts, indent=4))
724
+ await asyncio.to_thread(Path("nodes.json").write_text, json.dumps(nodes, indent=4))
654
725
 
655
726
  click.echo(f"Neuronum Node '{nodeID}' updated! Visit: {node_url}")
656
727
 
657
728
 
658
729
  @click.command()
659
- def delete_node():
730
+ def disconnect_node():
731
+ asyncio.run(async_disconnect_node())
732
+
733
+ async def async_disconnect_node():
660
734
  env_data = {}
735
+
661
736
  try:
662
737
  with open(".env", "r") as f:
663
738
  for line in f:
@@ -671,40 +746,90 @@ def delete_node():
671
746
  synapse = env_data.get("SYNAPSE", "")
672
747
 
673
748
  except FileNotFoundError:
674
- print("Error: .env with credentials not found")
749
+ click.echo("Error: .env with credentials not found")
675
750
  return
676
751
  except Exception as e:
677
- print(f"Error reading .env file: {e}")
752
+ click.echo(f"Error reading .env file: {e}")
678
753
  return
679
754
 
680
- url = f"https://{network}/api/delete_node"
681
-
682
- node = {
755
+ url = f"https://{network}/api/disconnect_node"
756
+ node_payload = {
683
757
  "nodeID": nodeID,
684
758
  "host": host,
685
759
  "password": password,
686
760
  "synapse": synapse
687
761
  }
688
762
 
763
+ async with aiohttp.ClientSession() as session:
764
+ try:
765
+ async with session.post(url, json=node_payload) as response:
766
+ response.raise_for_status()
767
+ data = await response.json()
768
+ nodeID = data["nodeID"]
769
+ except aiohttp.ClientError as e:
770
+ click.echo(f"Error sending request: {e}")
771
+ return
772
+
773
+ click.echo(f"Neuronum Node '{nodeID}' disconnected!")
774
+
775
+
776
+ @click.command()
777
+ def delete_node():
778
+ asyncio.run(async_delete_node())
779
+
780
+ async def async_delete_node():
781
+ env_data = {}
782
+
689
783
  try:
690
- response = requests.post(url, json=node)
691
- response.raise_for_status()
692
- nodeID = response.json()["nodeID"]
693
- except requests.exceptions.RequestException as e:
694
- click.echo(f"Error sending request: {e}")
784
+ with open(".env", "r") as f:
785
+ for line in f:
786
+ key, value = line.strip().split("=")
787
+ env_data[key] = value
788
+
789
+ nodeID = env_data.get("NODE", "")
790
+ host = env_data.get("HOST", "")
791
+ password = env_data.get("PASSWORD", "")
792
+ network = env_data.get("NETWORK", "")
793
+ synapse = env_data.get("SYNAPSE", "")
794
+
795
+ except FileNotFoundError:
796
+ click.echo("Error: .env with credentials not found")
695
797
  return
798
+ except Exception as e:
799
+ click.echo(f"Error reading .env file: {e}")
800
+ return
801
+
802
+ url = f"https://{network}/api/delete_node"
803
+ node_payload = {
804
+ "nodeID": nodeID,
805
+ "host": host,
806
+ "password": password,
807
+ "synapse": synapse
808
+ }
809
+
810
+ async with aiohttp.ClientSession() as session:
811
+ try:
812
+ async with session.post(url, json=node_payload) as response:
813
+ response.raise_for_status()
814
+ data = await response.json()
815
+ nodeID = data["nodeID"]
816
+ except aiohttp.ClientError as e:
817
+ click.echo(f"Error sending request: {e}")
818
+ return
696
819
 
697
820
  click.echo(f"Neuronum Node '{nodeID}' deleted!")
698
821
 
699
822
 
700
- @click.command()
701
- def call_cellai():
702
- try:
703
- from cellai import cellai
704
- cellai.main()
705
- except ImportError:
823
+
824
+ @click.command()
825
+ def call_cellai():
826
+ try:
827
+ from cellai import cellai
828
+ cellai.main()
829
+ except ImportError:
706
830
  click.echo("Cellai not found. Please check the necessary dependencies.")
707
831
 
832
+
708
833
  cli.add_command(create_cell)
709
834
  cli.add_command(connect_cell)
710
835
  cli.add_command(view_cell)
@@ -713,8 +838,9 @@ cli.add_command(delete_cell)
713
838
  cli.add_command(init_node)
714
839
  cli.add_command(start_node)
715
840
  cli.add_command(stop_node)
716
- cli.add_command(register_node)
841
+ cli.add_command(connect_node)
717
842
  cli.add_command(update_node)
843
+ cli.add_command(disconnect_node)
718
844
  cli.add_command(delete_node)
719
845
  cli.add_command(call_cellai)
720
846