neuronum 5.2.0__tar.gz → 5.4.0__tar.gz

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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuronum
3
- Version: 5.2.0
3
+ Version: 5.4.0
4
4
  Summary: Official client library to interact with the Neuronum Network
5
5
  Home-page: https://neuronum.net
6
6
  Author: Neuronum Cybernetics
@@ -18,6 +18,7 @@ Requires-Dist: click
18
18
  Requires-Dist: questionary
19
19
  Requires-Dist: python-dotenv
20
20
  Requires-Dist: requests
21
+ Requires-Dist: rapidfuzz
21
22
  Dynamic: author
22
23
  Dynamic: author-email
23
24
  Dynamic: classifier
@@ -39,6 +40,7 @@ Dynamic: summary
39
40
  - Learn about Neuronum
40
41
  - Connect to Neuronum
41
42
  - Build on Neuronum
43
+ - Interact with Neuronum
42
44
 
43
45
 
44
46
  ### **About Neuronum**
@@ -55,10 +57,13 @@ Neuronum is a framework to build serverless connected app & data gateways automa
55
57
  - Circuits (CTX): Store data in cloud-based key-value-label databases
56
58
  - Streams (STX): Stream, synchronize, and control data in real time
57
59
 
60
+ **Cellai**
61
+ Cellai is a CLI-based assistant that helps you interact with Neuronum
62
+
58
63
 
59
64
  #### Requirements
60
65
  - Python >= 3.8 -> https://www.python.org/downloads/
61
- - neuronum >= 4.0.0 -> https://pypi.org/project/neuronum/
66
+ - neuronum >= 5.4.0 -> https://pypi.org/project/neuronum/
62
67
 
63
68
 
64
69
  ------------------
@@ -82,22 +87,18 @@ Connect Cell:
82
87
  neuronum connect-cell # connect Cell
83
88
  ```
84
89
 
85
- View connected Cell:
86
- ```sh
87
- neuronum view-cell # view Cell / output = Connected Cell: 'cell_id'"
88
- ```
89
-
90
-
91
90
  ------------------
92
91
 
93
92
 
94
93
  ### **Build on Neuronum**
95
- **Node Examples:**
96
- Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
94
+ Initialize Node (app template):
95
+ ```sh
96
+ neuronum init-node --app # initialize a Node with app template
97
+ ```
97
98
 
98
- Initialize Node (default template):
99
+ Change into Node folder
99
100
  ```sh
100
- neuronum init-node # initialize a Node with default template
101
+ cd node_node_id # change directory
101
102
  ```
102
103
 
103
104
  Start Node:
@@ -105,12 +106,15 @@ Start Node:
105
106
  neuronum start-node # start Node
106
107
  ```
107
108
 
108
- Stop Node:
109
- ```sh
110
- neuronum stop-node # stop Node
111
- ```
109
+ **Node Examples**
110
+ Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
112
111
 
113
- Connect Node to Neuronum:
114
- ```sh
115
- neuronum connect-node # connect Node
116
- ```
112
+
113
+ ------------------
114
+
115
+
116
+ ### **Interact with Neuronum**
117
+ 1. Visit: https://neuronum.net
118
+ 2. Connect your Cell
119
+ 3. Explore Transmitters
120
+ 4. Activate Transmitters
@@ -7,6 +7,7 @@
7
7
  - Learn about Neuronum
8
8
  - Connect to Neuronum
9
9
  - Build on Neuronum
10
+ - Interact with Neuronum
10
11
 
11
12
 
12
13
  ### **About Neuronum**
@@ -23,10 +24,13 @@ Neuronum is a framework to build serverless connected app & data gateways automa
23
24
  - Circuits (CTX): Store data in cloud-based key-value-label databases
24
25
  - Streams (STX): Stream, synchronize, and control data in real time
25
26
 
27
+ **Cellai**
28
+ Cellai is a CLI-based assistant that helps you interact with Neuronum
29
+
26
30
 
27
31
  #### Requirements
28
32
  - Python >= 3.8 -> https://www.python.org/downloads/
29
- - neuronum >= 4.0.0 -> https://pypi.org/project/neuronum/
33
+ - neuronum >= 5.4.0 -> https://pypi.org/project/neuronum/
30
34
 
31
35
 
32
36
  ------------------
@@ -50,22 +54,18 @@ Connect Cell:
50
54
  neuronum connect-cell # connect Cell
51
55
  ```
52
56
 
53
- View connected Cell:
54
- ```sh
55
- neuronum view-cell # view Cell / output = Connected Cell: 'cell_id'"
56
- ```
57
-
58
-
59
57
  ------------------
60
58
 
61
59
 
62
60
  ### **Build on Neuronum**
63
- **Node Examples:**
64
- Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
61
+ Initialize Node (app template):
62
+ ```sh
63
+ neuronum init-node --app # initialize a Node with app template
64
+ ```
65
65
 
66
- Initialize Node (default template):
66
+ Change into Node folder
67
67
  ```sh
68
- neuronum init-node # initialize a Node with default template
68
+ cd node_node_id # change directory
69
69
  ```
70
70
 
71
71
  Start Node:
@@ -73,12 +73,15 @@ Start Node:
73
73
  neuronum start-node # start Node
74
74
  ```
75
75
 
76
- Stop Node:
77
- ```sh
78
- neuronum stop-node # stop Node
79
- ```
76
+ **Node Examples**
77
+ Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
80
78
 
81
- Connect Node to Neuronum:
82
- ```sh
83
- neuronum connect-node # connect Node
84
- ```
79
+
80
+ ------------------
81
+
82
+
83
+ ### **Interact with Neuronum**
84
+ 1. Visit: https://neuronum.net
85
+ 2. Connect your Cell
86
+ 3. Explore Transmitters
87
+ 4. Activate Transmitters
@@ -0,0 +1,118 @@
1
+ import asyncio
2
+ from rapidfuzz import process
3
+ import neuronum
4
+ import datetime
5
+ from pathlib import Path
6
+
7
+
8
+ def log_interaction(user_input, output, log_path=Path("cellai.log")):
9
+ log_path = Path(log_path)
10
+
11
+ timestamp = datetime.datetime.now().isoformat()
12
+ with open(log_path, "a", encoding="utf-8") as log_file:
13
+ log_file.write(f"[{timestamp}]\n")
14
+ log_file.write(f"USER: {user_input}")
15
+ log_file.write(f"{output}\n\n")
16
+
17
+
18
+ async def main(host, password, network, synapse):
19
+ cell = neuronum.Cell(
20
+ host=host,
21
+ password=password,
22
+ network=network,
23
+ synapse=synapse
24
+ )
25
+
26
+ tx = await cell.list_tx()
27
+ nodes = await cell.list_nodes()
28
+
29
+ transmitters = tx
30
+ transmitters_by_id = {t["txID"]: t for t in transmitters}
31
+
32
+ info_to_gateway = []
33
+ for node in nodes:
34
+ for g in node["Node.md"]["gateways"]:
35
+ info_to_gateway.append({
36
+ "nodeID": node["nodeID"],
37
+ "gateway": g,
38
+ "info": g["info"],
39
+ "descr": node["descr"]
40
+ })
41
+
42
+ print("Cellai: Ready for your instruction!")
43
+ loop = asyncio.get_event_loop()
44
+
45
+ while True:
46
+ try:
47
+ user_input = await loop.run_in_executor(None, input, ">> ")
48
+ user_input = user_input.strip()
49
+ if user_input.lower() in {"exit", "quit"}:
50
+ log_interaction(user_input, "Session ended by user.")
51
+ break
52
+
53
+ match, score, idx = process.extractOne(user_input, [x["info"] for x in info_to_gateway])
54
+ best = info_to_gateway[idx]
55
+
56
+ output_log = (
57
+ f"\nMatched: {match} ({score:.1f}%)\n"
58
+ f"Node: {best['descr']} [{best['nodeID']}]\n"
59
+ f"Gateway: {best['gateway']['id']} ({best['gateway']['type']})"
60
+ )
61
+ print(output_log)
62
+
63
+ if best['gateway']['type'] == "transmitter":
64
+ tx_id = best['gateway']['id']
65
+ tx_data = transmitters_by_id.get(tx_id)
66
+ if tx_data:
67
+ print(f"Executing transmitter: {tx_data['descr']}")
68
+
69
+ dynamic_payload = {}
70
+ for key in tx_data["data"].keys():
71
+ prompt = f"Enter value for '{key}': "
72
+ value = await loop.run_in_executor(None, input, prompt)
73
+ dynamic_payload[key] = value
74
+
75
+ print(f"Payload: {dynamic_payload}")
76
+ TX = tx_id
77
+ tx_response = await cell.activate_tx(TX, dynamic_payload)
78
+ print(tx_response["json"])
79
+ output_log += f"\nTransmitter executed: {tx_data['descr']}\nPayload: {dynamic_payload}\nResponse: {tx_response['json']}"
80
+ else:
81
+ warning = "Transmitter not found."
82
+ print(warning)
83
+ output_log += f"{warning}"
84
+
85
+ elif best['gateway']['type'] == "stream":
86
+ STX = best['gateway']['id']
87
+ print(f"Starting stream sync for STX: {STX}")
88
+ async for operation in cell.sync(STX):
89
+ label = operation.get("label")
90
+ data = operation.get("data")
91
+ ts = operation.get("time")
92
+ stxID = operation.get("stxID")
93
+ operator = operation.get("operator")
94
+ line = f"[{ts}] {label} | Operator: {operator} | STX: {stxID}\nData: {data}"
95
+ print(line)
96
+ output_log += f"\n{line}"
97
+ elif best['gateway']['type'] == "circuit":
98
+ CTX = best['gateway']['id']
99
+ label = await loop.run_in_executor(None, input, "Enter label to load from circuit: ")
100
+ label = label.strip()
101
+ data = await cell.load(label, CTX)
102
+ print(data)
103
+ output_log += f"\nCircuit loaded from CTX: {CTX} with label '{label}'\nData: {data}"
104
+ else:
105
+ msg = "Unknown gateway type."
106
+ print(msg)
107
+ output_log += f"{msg}"
108
+
109
+ log_interaction(user_input, output_log)
110
+
111
+ except KeyboardInterrupt:
112
+ print("\nExiting.")
113
+ log_interaction("KeyboardInterrupt", "Session exited with Ctrl+C")
114
+ break
115
+
116
+
117
+ if __name__ == "__main__":
118
+ asyncio.run(main(host, password, network, synapse))
File without changes
@@ -324,40 +324,24 @@ async def async_init_node(sync, stream, app):
324
324
 
325
325
  ```json
326
326
  {
327
- "info": {
328
- "use_case": "This Node...",
329
- "github": "https://github.com/user"
330
- },
331
327
  "gateways": [
332
328
  {
333
329
  "type": "stream",
334
330
  "id": "id::stx",
335
- "link": "https://neuronum.net/stream/id::stx"
331
+ "link": "https://neuronum.net/stream/id::stx",
332
+ "info": "stream info"
336
333
  },
337
334
  {
338
335
  "type": "transmitter",
339
336
  "id": "id::tx",
340
- "link": "https://neuronum.net/tx/id::tx",
341
- }
337
+ "link": "https://neuronum.net/tx/id::tx",
338
+ "info": "transmitter info"
339
+ },
342
340
  {
343
341
  "type": "circuit",
344
342
  "id": "id::ctx",
345
- "link": "https://neuronum.net/circuit/id::ctx",
346
- }
347
- ],
348
- "initialization": {
349
- "command": "neuronum init-node --sync id::stx"
350
- },
351
- "requirements": [
352
- {
353
- "name": "Python",
354
- "version": ">= 3.8",
355
- "link": "https://www.python.org/downloads/"
356
- },
357
- {
358
- "name": "neuronum",
359
- "version": ">= 5.1.0",
360
- "link": "https://pypi.org/project/neuronum/"
343
+ "link": "https://neuronum.net/circuit/id::ctx",
344
+ "info": "circuit info"
361
345
  }
362
346
  ]
363
347
  }
@@ -500,7 +484,23 @@ async def main():
500
484
  asyncio.run(main())
501
485
  """)
502
486
 
503
- if app:
487
+ if app and nodeID:
488
+
489
+ descr = f"{nodeID} App"
490
+ partners = ["public"]
491
+ stxID = await cell.create_stx(descr, partners)
492
+
493
+
494
+ descr = f"Greet {nodeID}"
495
+ key_values = {
496
+ "say": "hello",
497
+ }
498
+ STX = stxID
499
+ label = "say:hello"
500
+ partners = ["public"]
501
+ txID = await cell.create_tx(descr, key_values, STX, label, partners)
502
+
503
+
504
504
  app_path = project_path / "app.py"
505
505
  app_path.write_text(f"""\
506
506
  import asyncio
@@ -521,27 +521,31 @@ cell = neuronum.Cell(
521
521
  synapse=synapse
522
522
  )
523
523
 
524
- async def main():
525
- STX = "id::stx"
524
+ async def main():
525
+ STX = "{stxID}"
526
526
  async for operation in cell.sync(STX):
527
527
  txID = operation.get("txID")
528
528
  client = operation.get("operator")
529
529
 
530
- if txID == "id::tx":
531
- data = {{
532
- "response": "TX activated!"
533
- }}
534
- await cell.tx_response(txID, client, data)
535
-
536
- if txID == "id::tx":
530
+ if txID == "{txID}":
537
531
  data = {{
538
- "response": "TX activated!"
539
- }}
540
- await cell.tx_response(txID, client, data)
532
+ "json": f"Hello {{client}} from {nodeID}",
533
+ "html": f\"\"\"
534
+ <!DOCTYPE html>
535
+ <html>
536
+ <head>
537
+ <meta charset="UTF-8">
538
+ <title>Greeting Node</title>
539
+ </head>
540
+ <body>
541
+ <div class="card">
542
+ <h1>Hello, {{client}}</h1>
543
+ <p>Greetings from <span class="node">{nodeID}</span></p>
544
+ </div>
545
+ </body>
546
+ </html>
547
+ \"\"\"
541
548
 
542
- if txID == "id::tx":
543
- data = {{
544
- "response": "TX activated!"
545
549
  }}
546
550
  await cell.tx_response(txID, client, data)
547
551
 
@@ -868,6 +872,42 @@ async def async_delete_node():
868
872
  click.echo(f"Neuronum Node '{nodeID}' deleted!")
869
873
 
870
874
 
875
+ @click.command()
876
+ def call_cellai():
877
+ try:
878
+ credentials_folder_path = Path.home() / ".neuronum"
879
+ env_path = credentials_folder_path / ".env"
880
+
881
+ env_data = {}
882
+
883
+ try:
884
+ with open(env_path, "r") as f:
885
+ for line in f:
886
+ key, value = line.strip().split("=")
887
+ env_data[key] = value
888
+
889
+ host = env_data.get("HOST", "")
890
+ password = env_data.get("PASSWORD", "")
891
+ network = env_data.get("NETWORK", "")
892
+ synapse = env_data.get("SYNAPSE", "")
893
+ except FileNotFoundError:
894
+ click.echo("No cell connected. Connect your cell with command neuronum connect-cell")
895
+ return
896
+ except Exception as e:
897
+ click.echo(f"Error reading .env file: {e}")
898
+ return
899
+
900
+ from cellai import cellai
901
+ asyncio.run(cellai.main(host, password, network, synapse))
902
+
903
+ except FileNotFoundError:
904
+ click.echo("Error: .env with credentials not found")
905
+ except ImportError:
906
+ click.echo("Cellai not found. Please check the necessary dependencies.")
907
+ except Exception as e:
908
+ click.echo(f"Unexpected error: {e}")
909
+
910
+
871
911
  cli.add_command(create_cell)
872
912
  cli.add_command(connect_cell)
873
913
  cli.add_command(view_cell)
@@ -880,6 +920,7 @@ cli.add_command(connect_node)
880
920
  cli.add_command(update_node)
881
921
  cli.add_command(disconnect_node)
882
922
  cli.add_command(delete_node)
923
+ cli.add_command(call_cellai)
883
924
 
884
925
 
885
926
  if __name__ == "__main__":
@@ -92,8 +92,6 @@ class Cell:
92
92
  try:
93
93
  async with websockets.connect(full_url) as ws:
94
94
  await ws.send(json.dumps(auth_payload))
95
- print("Listening to Stream...")
96
-
97
95
  try:
98
96
  while True:
99
97
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuronum
3
- Version: 5.2.0
3
+ Version: 5.4.0
4
4
  Summary: Official client library to interact with the Neuronum Network
5
5
  Home-page: https://neuronum.net
6
6
  Author: Neuronum Cybernetics
@@ -18,6 +18,7 @@ Requires-Dist: click
18
18
  Requires-Dist: questionary
19
19
  Requires-Dist: python-dotenv
20
20
  Requires-Dist: requests
21
+ Requires-Dist: rapidfuzz
21
22
  Dynamic: author
22
23
  Dynamic: author-email
23
24
  Dynamic: classifier
@@ -39,6 +40,7 @@ Dynamic: summary
39
40
  - Learn about Neuronum
40
41
  - Connect to Neuronum
41
42
  - Build on Neuronum
43
+ - Interact with Neuronum
42
44
 
43
45
 
44
46
  ### **About Neuronum**
@@ -55,10 +57,13 @@ Neuronum is a framework to build serverless connected app & data gateways automa
55
57
  - Circuits (CTX): Store data in cloud-based key-value-label databases
56
58
  - Streams (STX): Stream, synchronize, and control data in real time
57
59
 
60
+ **Cellai**
61
+ Cellai is a CLI-based assistant that helps you interact with Neuronum
62
+
58
63
 
59
64
  #### Requirements
60
65
  - Python >= 3.8 -> https://www.python.org/downloads/
61
- - neuronum >= 4.0.0 -> https://pypi.org/project/neuronum/
66
+ - neuronum >= 5.4.0 -> https://pypi.org/project/neuronum/
62
67
 
63
68
 
64
69
  ------------------
@@ -82,22 +87,18 @@ Connect Cell:
82
87
  neuronum connect-cell # connect Cell
83
88
  ```
84
89
 
85
- View connected Cell:
86
- ```sh
87
- neuronum view-cell # view Cell / output = Connected Cell: 'cell_id'"
88
- ```
89
-
90
-
91
90
  ------------------
92
91
 
93
92
 
94
93
  ### **Build on Neuronum**
95
- **Node Examples:**
96
- Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
94
+ Initialize Node (app template):
95
+ ```sh
96
+ neuronum init-node --app # initialize a Node with app template
97
+ ```
97
98
 
98
- Initialize Node (default template):
99
+ Change into Node folder
99
100
  ```sh
100
- neuronum init-node # initialize a Node with default template
101
+ cd node_node_id # change directory
101
102
  ```
102
103
 
103
104
  Start Node:
@@ -105,12 +106,15 @@ Start Node:
105
106
  neuronum start-node # start Node
106
107
  ```
107
108
 
108
- Stop Node:
109
- ```sh
110
- neuronum stop-node # stop Node
111
- ```
109
+ **Node Examples**
110
+ Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
112
111
 
113
- Connect Node to Neuronum:
114
- ```sh
115
- neuronum connect-node # connect Node
116
- ```
112
+
113
+ ------------------
114
+
115
+
116
+ ### **Interact with Neuronum**
117
+ 1. Visit: https://neuronum.net
118
+ 2. Connect your Cell
119
+ 3. Explore Transmitters
120
+ 4. Activate Transmitters
@@ -1,6 +1,8 @@
1
1
  LICENSE
2
2
  README.md
3
3
  setup.py
4
+ cellai/__init__.py
5
+ cellai/cellai.py
4
6
  cli/__init__.py
5
7
  cli/main.py
6
8
  neuronum/__init__.py
@@ -4,3 +4,4 @@ click
4
4
  questionary
5
5
  python-dotenv
6
6
  requests
7
+ rapidfuzz
@@ -1,2 +1,3 @@
1
+ cellai
1
2
  cli
2
3
  neuronum
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='neuronum',
5
- version='5.2.0',
5
+ version='5.4.0',
6
6
  author='Neuronum Cybernetics',
7
7
  author_email='welcome@neuronum.net',
8
8
  description='Official client library to interact with the Neuronum Network',
@@ -12,7 +12,7 @@ setup(
12
12
  project_urls={
13
13
  "GitHub": "https://github.com/neuronumcybernetics/neuronum",
14
14
  },
15
- packages=find_packages(include=["neuronum", "cli"]),
15
+ packages=find_packages(include=["neuronum", "cellai", "cli"]),
16
16
  classifiers=[
17
17
  "Programming Language :: Python :: 3",
18
18
  "License :: OSI Approved :: MIT License",
@@ -26,6 +26,7 @@ setup(
26
26
  'questionary',
27
27
  'python-dotenv',
28
28
  'requests',
29
+ 'rapidfuzz',
29
30
  ],
30
31
  entry_points={
31
32
  "console_scripts": [
File without changes
File without changes
File without changes