neuronum 6.0.1__py3-none-any.whl → 7.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
@@ -249,17 +249,14 @@ def delete_cell():
249
249
 
250
250
 
251
251
  @click.command()
252
- @click.option('--sync', multiple=True, default=None, help="Optional stream IDs for sync.")
253
- @click.option('--stream', multiple=True, default=None, help="Optional stream ID for stream.")
254
- @click.option('--app', is_flag=True, help="Generate a Node with app template")
255
- def init_node(sync, stream, app):
252
+ def init_node():
256
253
  descr = click.prompt("Node description: Type up to 25 characters").strip()
257
254
  if descr and len(descr) > 25:
258
255
  click.echo("Description too long. Max 25 characters allowed.")
259
256
  return
260
- asyncio.run(async_init_node(sync, stream, app, descr))
257
+ asyncio.run(async_init_node(descr))
261
258
 
262
- async def async_init_node(sync, stream, app, descr):
259
+ async def async_init_node(descr):
263
260
  credentials_folder_path = Path.home() / ".neuronum"
264
261
  env_path = credentials_folder_path / ".env"
265
262
 
@@ -308,51 +305,37 @@ async def async_init_node(sync, stream, app, descr):
308
305
  click.echo(f"Error sending request: {e}")
309
306
  return
310
307
 
311
- node_filename = "node_" + nodeID.replace("::node", "")
308
+ node_filename = descr + "_" + nodeID.replace("::node", "")
312
309
  project_path = Path(node_filename)
313
310
  project_path.mkdir(exist_ok=True)
314
311
 
315
312
  env_path = project_path / ".env"
316
313
  await asyncio.to_thread(env_path.write_text, f"NODE={nodeID}\nHOST={host}\nPASSWORD={password}\nNETWORK={network}\nSYNAPSE={synapse}\n")
317
-
318
-
319
- config_path = project_path / "config.json"
320
- await asyncio.to_thread(config_path.write_text, """{
321
- "data_gateways": [
322
- {
323
- "type": "stream",
324
- "id": "id::stx",
325
- "info": "provide a detailed description about the stream"
326
- },
327
- {
328
- "type": "transmitter",
329
- "id": "id::tx",
330
- "info": "provide a detailed description about the transmitter"
331
- },
332
- {
333
- "type": "circuit",
334
- "id": "id::ctx",
335
- "info": "provide a detailed description about the circuit"
336
- }
337
- ]
338
- }
339
- """
340
- )
341
314
 
342
- nodemd_path = project_path / "NODE.md"
343
- await asyncio.to_thread(nodemd_path.write_text, """### NODE.md: Create a detailed Markdown File on how to interact with this Node""")
315
+ stx_descr = f"{nodeID} App"
316
+ partners = ["private"]
317
+ stxID = await cell.create_stx(stx_descr, partners)
344
318
 
345
- stx = sync[0] if sync else (stream[0] if stream else host.replace("::cell", "::stx"))
319
+ tx_descr = f"Greet {nodeID}"
320
+ key_values = {
321
+ "ping": "pong",
322
+ }
323
+ STX = stxID
324
+ label = "ping:pong"
325
+ partners = ["private"]
326
+ txID = await cell.create_tx(tx_descr, key_values, STX, label, partners)
346
327
 
347
- if sync:
348
- for stx in sync:
349
- sync_path = project_path / f"sync_{stx.replace('::stx', '')}.py"
350
- sync_path.write_text(f"""\
328
+ app_path = project_path / "app.py"
329
+ app_path.write_text(f"""\
351
330
  import asyncio
352
331
  import neuronum
353
332
  import os
354
333
  from dotenv import load_dotenv
334
+ from jinja2 import Environment, FileSystemLoader
355
335
 
336
+ env = Environment(loader=FileSystemLoader('.'))
337
+ template = env.get_template('ping.html')
338
+
356
339
  load_dotenv()
357
340
  host = os.getenv("HOST")
358
341
  password = os.getenv("PASSWORD")
@@ -366,188 +349,293 @@ cell = neuronum.Cell(
366
349
  synapse=synapse
367
350
  )
368
351
 
369
- async def main():
370
- STX = "{stx}"
371
- async for operation in cell.sync(STX):
372
- label = operation.get("label")
373
- data = operation.get("data")
374
- ts = operation.get("time")
375
- stxID = operation.get("stxID")
376
- operator = operation.get("operator")
377
- print(label, data, ts, stxID, operator)
378
-
379
- asyncio.run(main())
380
- """)
352
+ async def main():
353
+ STX = "{stxID}"
354
+ async for operation in cell.sync(STX):
355
+ txID = operation.get("txID")
356
+ client = operation.get("operator")
357
+ ts = operation.get("time")
358
+ data = operation.get("data")
359
+ operation_id = operation.get("operationID")
360
+
361
+ if txID == "{txID}":
362
+
363
+ def render_html_template(client, ts, data, operation_id):
364
+ return template.render(client=client, ts=ts, data=data, operation_id=operation_id)
381
365
 
366
+ html_content = render_html_template(client, ts, data, operation_id)
382
367
 
383
- if stream:
384
- for stx in stream:
385
- stream_path = project_path / f"stream_{stx.replace('::stx', '')}.py"
386
- stream_path.write_text(f"""\
387
- import asyncio
388
- import neuronum
389
- import os
390
- from dotenv import load_dotenv
391
- import time
368
+ data = {{
369
+ "json": f"{{operation_id}} - Reply from {nodeID}: Pinged by {{client}} at {{ts}} with data: {{data}}",
370
+ "html": html_content
371
+ }}
392
372
 
393
- load_dotenv()
394
- host = os.getenv("HOST")
395
- password = os.getenv("PASSWORD")
396
- network = os.getenv("NETWORK")
397
- synapse = os.getenv("SYNAPSE")
373
+ await cell.notify(f"{{client}}", "{nodeID} Ping","Pinged successfully")
398
374
 
399
- cell = neuronum.Cell(
400
- host=host,
401
- password=password,
402
- network=network,
403
- synapse=synapse
404
- )
405
-
406
- async def main():
407
- STX = "{stx}"
408
- label = "your_label"
409
-
410
- while True:
411
- data = {{
412
- "key1": "value1",
413
- "key2": "value2",
414
- "key3": "value3",
415
- }}
416
- await cell.stream(label, data, STX)
417
- time.sleep(5)
375
+ await cell.tx_response(txID, client, data)
418
376
 
419
377
  asyncio.run(main())
420
378
  """)
421
379
 
422
- if not sync and not stream and not app:
423
- sync_path = project_path / f"sync_{stx.replace('::stx', '')}.py"
424
- sync_path.write_text(f"""\
425
- import asyncio
426
- import neuronum
427
- import os
428
- from dotenv import load_dotenv
380
+ html_path = project_path / "ping.html"
381
+ html_content = f"""\
382
+ <!DOCTYPE html>
383
+ <html>
384
+ <head>
385
+ <style>
386
+ body {{
387
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
388
+ background-color: #121212;
389
+ color: #e0e0e0;
390
+ margin: 0;
391
+ padding: 0;
392
+ display: flex;
393
+ justify-content: center;
394
+ align-items: center;
395
+ min-height: 100vh;
396
+ }}
397
+
398
+ .container {{
399
+ background-color: #1e1e1e;
400
+ border-radius: 12px;
401
+ padding: 40px;
402
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
403
+ width: 100%;
404
+ max-width: 500px;
405
+ text-align: center;
406
+ box-sizing: border-box;
407
+ }}
408
+
409
+ .logo {{
410
+ width: 80px;
411
+ margin-bottom: 25px;
412
+ filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.1));
413
+ }}
414
+
415
+ h1 {{
416
+ font-size: 1.5em;
417
+ font-weight: 600;
418
+ margin-bottom: 5px;
419
+ color: #f5f5f5;
420
+ }}
421
+
422
+ .subtitle {{
423
+ font-size: 0.9em;
424
+ color: #a0a0a0;
425
+ margin-bottom: 30px;
426
+ }}
427
+
428
+ .data-row {{
429
+ background-color: #2a2a2a;
430
+ padding: 12px 15px;
431
+ border-radius: 8px;
432
+ margin-bottom: 10px;
433
+ display: flex;
434
+ justify-content: space-between;
435
+ align-items: center;
436
+ }}
437
+
438
+ .data-label {{
439
+ font-weight: 400;
440
+ color: #a0a0a0;
441
+ margin: 0;
442
+ }}
443
+
444
+ .data-value {{
445
+ font-weight: 500;
446
+ color: #e0e0e0;
447
+ margin: 0;
448
+ }}
449
+
450
+ .data-value.truncated {{
451
+ white-space: nowrap;
452
+ overflow: hidden;
453
+ text-overflow: ellipsis;
454
+ max-width: 60%;
455
+ }}
456
+
457
+ .data-value.client {{
458
+ color: #8cafff;
459
+ }}
460
+ .data-value.timestamp {{
461
+ color: #a1e8a1;
462
+ }}
463
+ .data-value.operation-id {{
464
+ color: #f7a2a2;
465
+ }}
466
+ .api-button {{
467
+ background: #01c07d 100%;
468
+ color: white;
469
+ border: none;
470
+ border-radius: 8px;
471
+ padding: 12px 24px;
472
+ font-size: 16px;
473
+ font-weight: bold;
474
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
475
+ cursor: pointer;
476
+ margin-top: 10px;
477
+ }}
478
+ </style>
479
+ </head>
480
+ <body>
481
+ <div class="container">
482
+ <img class="logo" src="https://neuronum.net/static/logo.png" alt="Neuronum Logo">
483
+
484
+ <h1>Reply from {nodeID}</h1>
485
+ <p class="subtitle">Pinged successfully.</p>
486
+
487
+ <div class="data-row">
488
+ <p class="data-label">Client</p>
489
+ <p class="data-value client">{{{{client}}}}</p>
490
+ </div>
491
+
492
+ <div class="data-row">
493
+ <p class="data-label">Timestamp</p>
494
+ <p class="data-value timestamp">{{{{ts}}}}</p>
495
+ </div>
496
+
497
+ <div class="data-row">
498
+ <p class="data-label">Data</p>
499
+ <p class="data-value">{{{{data}}}}</p>
500
+ </div>
501
+
502
+ <div class="data-row">
503
+ <p class="data-label">Operation ID</p>
504
+ <p class="data-value operation-id truncated">{{{{operation_id}}}}</p>
505
+ </div>
506
+
507
+ <button id="send-request-btn" class="api-button">Ping again</button>
508
+ </div>
429
509
 
430
- load_dotenv()
431
- host = os.getenv("HOST")
432
- password = os.getenv("PASSWORD")
433
- network = os.getenv("NETWORK")
434
- synapse = os.getenv("SYNAPSE")
510
+ <script>
511
+ document.getElementById('send-request-btn').addEventListener('click', () => {{
512
+ const apiEndpoint = 'https://neuronum.net/api/activate/{txID}';
435
513
 
436
- cell = neuronum.Cell(
437
- host=host,
438
- password=password,
439
- network=network,
440
- synapse=synapse
514
+ const dataToSend = {{
515
+ "data": {{"ping": "node"}},
516
+ "cell": {{
517
+ "host": CLIENT_CELL,
518
+ "session": CLIENT_SESSION,
519
+ }}
520
+ }};
521
+
522
+ fetch(apiEndpoint, {{
523
+ method: 'POST',
524
+ headers: {{
525
+ 'Content-Type': 'application/json',
526
+ 'Accept': 'application/json'
527
+ }},
528
+ body: JSON.stringify(dataToSend)
529
+ }})
530
+ .then(response => {{
531
+ if (!response.ok) {{
532
+ throw new Error(`HTTP error! status: ${{response.status}}`);
533
+ }}
534
+ return response.json();
535
+ }})
536
+ .then(data => {{
537
+ if (data.success && data.response && data.response.html) {{
538
+ document.open();
539
+ document.write(data.response.html);
540
+ document.close();
541
+ console.log('API Response: Page replaced with new HTML.');
542
+ }} else {{
543
+ console.error('API Response does not contain HTML to replace the page:', data);
544
+ alert('API response error: Expected HTML content to replace the page.');
545
+ }}
546
+ }})
547
+ .catch(error => {{
548
+ console.error('API request failed:', error);
549
+ alert('API request failed. See the console for details.');
550
+ }});
551
+ }});
552
+ </script>
553
+ </body>
554
+ </html>
555
+ """
556
+ html_path.write_text(html_content)
557
+
558
+ config_path = project_path / "config.json"
559
+ await asyncio.to_thread(
560
+ config_path.write_text,
561
+ f"""{{
562
+ "app_metadata": {{
563
+ "name": "{descr}",
564
+ "version": "1.0.0",
565
+ "author": "{host}"
566
+ }},
567
+ "data_gateways": [
568
+ {{
569
+ "type": "transmitter",
570
+ "id": "{txID}",
571
+ "info": "Ping Your Node"
572
+ }}
573
+ ],
574
+ "legals": {{
575
+ "terms_and_conditions": "https://neuronum.net/legals",
576
+ "data_privacy": "https://neuronum.net/legals"
577
+ }}
578
+ }}"""
441
579
  )
442
580
 
443
- async def main():
444
- async for operation in cell.sync():
445
- message = operation.get("data").get("message")
446
- print(message)
581
+ nodemd_path = project_path / "NODE.md"
582
+ await asyncio.to_thread(nodemd_path.write_text, f"""### NODE.md of {nodeID}
447
583
 
448
- asyncio.run(main())
449
- """)
450
-
451
- stream_path = project_path / f"stream_{stx.replace('::stx', '')}.py"
452
- stream_path.write_text(f"""\
453
- import asyncio
454
- import neuronum
455
- import os
456
- from dotenv import load_dotenv
457
- import time
584
+ Welcome to your Node's documentation! This guide provides several ways for users to interact with your application.
458
585
 
459
- load_dotenv()
460
- host = os.getenv("HOST")
461
- password = os.getenv("PASSWORD")
462
- network = os.getenv("NETWORK")
463
- synapse = os.getenv("SYNAPSE")
586
+ ***
464
587
 
465
- cell = neuronum.Cell(
466
- host=host,
467
- password=password,
468
- network=network,
469
- synapse=synapse
470
- )
588
+ ### 💻 Using the CLI
471
589
 
472
- async def main():
473
- label = "Welcome to Neuronum"
474
-
475
- while True:
476
- data = {{
477
- "message": "Hello, Neuronum!"
478
- }}
479
- await cell.stream(label, data)
480
- time.sleep(5)
590
+ To ping this Node via the command-line interface, use the following command:
481
591
 
482
- asyncio.run(main())
483
- """)
484
-
485
- if app and nodeID:
592
+ `neuronum activate --tx {txID} 'ping:node'`
486
593
 
487
- descr = f"{nodeID} App"
488
- partners = ["private"]
489
- stxID = await cell.create_stx(descr, partners)
594
+ ***
490
595
 
596
+ ### 🌐 Via the Web
491
597
 
492
- descr = f"Greet {nodeID}"
493
- key_values = {
494
- "say": "hello",
495
- }
496
- STX = stxID
497
- label = "say:hello"
498
- partners = ["private"]
499
- txID = await cell.create_tx(descr, key_values, STX, label, partners)
598
+ You can also interact with this Node by simply visiting this URL in your web browser:
500
599
 
600
+ [https://neuronum.net/tx/{txID}](https://neuronum.net/tx/{txID})
501
601
 
502
- app_path = project_path / "app.py"
503
- app_path.write_text(f"""\
602
+ ***
603
+
604
+ ### 🐍 With Python
605
+
606
+ For programmatic access, use the following Python code snippet. This script utilizes the `neuronum` library to activate the transaction and receive a response.
607
+
608
+ ```python
504
609
  import asyncio
505
610
  import neuronum
506
- import os
507
- from dotenv import load_dotenv
508
-
509
- load_dotenv()
510
- host = os.getenv("HOST")
511
- password = os.getenv("PASSWORD")
512
- network = os.getenv("NETWORK")
513
- synapse = os.getenv("SYNAPSE")
514
611
 
612
+ # Set up Cell connection parameters
515
613
  cell = neuronum.Cell(
516
- host=host,
517
- password=password,
518
- network=network,
519
- synapse=synapse
614
+ host="host", # Cell host
615
+ password="password", # Cell password
616
+ network="neuronum.net", # Cell network
617
+ synapse="synapse" # Cell synapse
520
618
  )
521
619
 
522
- async def main():
523
- STX = "{stxID}"
524
- async for operation in cell.sync(STX):
525
- txID = operation.get("txID")
526
- client = operation.get("operator")
527
-
528
- if txID == "{txID}":
529
- data = {{
530
- "json": f"Hello {{client}} from {nodeID}",
531
- "html": f\"\"\"
532
- <!DOCTYPE html>
533
- <html>
534
- <head>
535
- <meta charset="UTF-8">
536
- <title>Greeting Node</title>
537
- </head>
538
- <body>
539
- <div class="card">
540
- <h1>Hello, {{client}}</h1>
541
- <p>Greetings from <span class="node">{nodeID}</span></p>
542
- </div>
543
- </body>
544
- </html>
545
- \"\"\"
546
-
547
- }}
548
- await cell.tx_response(txID, client, data)
620
+ async def main():
621
+ # Define the transaction ID and data payload
622
+ TX = "{txID}"
623
+ data = {{"ping": "node"}}
624
+
625
+ # Activate the transaction and get the response
626
+ tx_response = await cell.activate_tx(TX, data)
627
+
628
+ # Print the response from the Node
629
+ print(tx_response)
630
+
631
+ # Run the main asynchronous function
632
+ if __name__ == "__main__":
633
+ asyncio.run(main())
634
+ ```
549
635
 
550
- asyncio.run(main())
636
+ 🤖 Via Cellai (Android App - Currently in Testing)
637
+ Download the app from the Google Play Store.
638
+ Send the command "Ping Node" to Cellai
551
639
  """)
552
640
 
553
641
  click.echo(f"Neuronum Node '{nodeID}' initialized!")
@@ -556,6 +644,7 @@ asyncio.run(main())
556
644
  @click.command()
557
645
  @click.option('--d', is_flag=True, help="Start node in detached mode")
558
646
  def start_node(d):
647
+ update_node()
559
648
  pid_file = Path.cwd() / "status.txt"
560
649
  system_name = platform.system()
561
650
  active_pids = []
@@ -586,27 +675,24 @@ def start_node(d):
586
675
  click.echo("Starting Node...")
587
676
 
588
677
  project_path = Path.cwd()
589
- script_files = glob.glob("sync_*.py") + glob.glob("stream_*.py") + glob.glob("app.py")
678
+ script_files = glob.glob("stream.py") + glob.glob("app.py")
590
679
  processes = []
591
680
 
592
681
  for script in script_files:
593
682
  script_path = project_path / script
594
683
  if script_path.exists():
595
- python_cmd = "pythonw" if system_name == "Windows" else "python"
596
684
 
597
685
  if d:
598
686
  process = subprocess.Popen(
599
- ["nohup", python_cmd, str(script_path), "&"] if system_name != "Windows"
600
- else [python_cmd, str(script_path)],
687
+ ["nohup", sys.executable, str(script_path), "&"] if system_name != "Windows"
688
+ else ["pythonw", str(script_path)],
601
689
  stdout=subprocess.DEVNULL,
602
690
  stderr=subprocess.DEVNULL,
603
691
  start_new_session=True
604
692
  )
605
693
  else:
606
694
  process = subprocess.Popen(
607
- [sys.executable, str(script_path)],
608
- stdout=None,
609
- stderr=None
695
+ [sys.executable, str(script_path)]
610
696
  )
611
697
 
612
698
  processes.append(process.pid)
@@ -678,11 +764,6 @@ def check_node():
678
764
  continue
679
765
 
680
766
  if running_pids:
681
- for pid in running_pids:
682
- proc = psutil.Process(pid)
683
- mem = proc.memory_info().rss / (1024 * 1024) # in MB
684
- cpu = proc.cpu_percent(interval=0.1)
685
- click.echo(f"PID {pid} → Memory: {mem:.2f} MB | CPU: {cpu:.1f}%")
686
767
  click.echo(f"Node {nodeID} is running. Active PIDs: {', '.join(map(str, running_pids))}")
687
768
  else:
688
769
  click.echo(f"Node {nodeID} is not running.")
@@ -691,6 +772,7 @@ def check_node():
691
772
  @click.command()
692
773
  @click.option('--d', is_flag=True, help="Restart node in detached mode")
693
774
  def restart_node(d):
775
+ update_node()
694
776
  pid_file = Path.cwd() / "status.txt"
695
777
  system_name = platform.system()
696
778
 
@@ -740,27 +822,23 @@ def restart_node(d):
740
822
 
741
823
  click.echo(f"Starting Node {nodeID}...")
742
824
  project_path = Path.cwd()
743
- script_files = glob.glob("sync_*.py") + glob.glob("stream_*.py") + glob.glob("app.py")
825
+ script_files = glob.glob("stream.py") + glob.glob("app.py")
744
826
  processes = []
745
827
 
746
- python_cmd = "pythonw" if system_name == "Windows" else "python"
747
-
748
828
  for script in script_files:
749
829
  script_path = project_path / script
750
830
  if script_path.exists():
751
831
  if d:
752
832
  process = subprocess.Popen(
753
- ["nohup", python_cmd, str(script_path), "&"] if system_name != "Windows"
754
- else [python_cmd, str(script_path)],
833
+ ["nohup", sys.executable, str(script_path), "&"] if system_name != "Windows"
834
+ else ["pythonw", str(script_path)],
755
835
  stdout=subprocess.DEVNULL,
756
836
  stderr=subprocess.DEVNULL,
757
837
  start_new_session=True
758
838
  )
759
839
  else:
760
840
  process = subprocess.Popen(
761
- [sys.executable, str(script_path)],
762
- stdout=None,
763
- stderr=None
841
+ [sys.executable, str(script_path)]
764
842
  )
765
843
 
766
844
  processes.append(process.pid)
@@ -825,7 +903,6 @@ async def async_stop_node():
825
903
  click.echo("Error: Unable to stop some node processes.")
826
904
 
827
905
 
828
- @click.command()
829
906
  def update_node():
830
907
  click.echo("Update your Node")
831
908
  env_data = {}
@@ -1126,7 +1203,6 @@ cli.add_command(start_node)
1126
1203
  cli.add_command(restart_node)
1127
1204
  cli.add_command(stop_node)
1128
1205
  cli.add_command(check_node)
1129
- cli.add_command(update_node)
1130
1206
  cli.add_command(delete_node)
1131
1207
  cli.add_command(activate)
1132
1208
  cli.add_command(load)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuronum
3
- Version: 6.0.1
3
+ Version: 7.0.1
4
4
  Summary: Official client library to interact with the Neuronum Network
5
5
  Home-page: https://neuronum.net
6
6
  Author: Neuronum Cybernetics
@@ -19,6 +19,7 @@ Requires-Dist: questionary
19
19
  Requires-Dist: python-dotenv
20
20
  Requires-Dist: requests
21
21
  Requires-Dist: psutil
22
+ Requires-Dist: jinja2
22
23
  Dynamic: author
23
24
  Dynamic: author-email
24
25
  Dynamic: classifier
@@ -78,7 +79,6 @@ Neuronum is the real-time data engine designed for developers to build event-dri
78
79
 
79
80
  ### Requirements
80
81
  - Python >= 3.8
81
- - neuronum >= 5.5.0
82
82
 
83
83
  ------------------
84
84
 
@@ -104,102 +104,27 @@ neuronum connect-cell # connect Cell
104
104
 
105
105
 
106
106
  ### **Build On Neuronum**
107
- To dive deeper into Neuronum App development, visit & build with [Node Examples](https://github.com/neuronumcybernetics/neuronum/tree/main/features/nodes/examples)
107
+ Visit & build with [Node Examples](https://github.com/neuronumcybernetics/neuronum/tree/main/features/nodes/examples) to gain deeper knowledge on how to build on Neuronum.
108
108
 
109
- Initialize a Node (app template):
109
+ To get started, initialize a new Node with the command below.
110
110
  ```sh
111
- neuronum init-node --app # initialize a Node with app template
111
+ neuronum init-node
112
112
  ```
113
113
 
114
- This command prompts you to enter a Node description (e.g Test App) and creates a new directory named node_<node_id> containing the following files:
114
+ This command will prompt you for a description (e.g., Test App) and will create
115
115
 
116
- .env
117
- ```env
118
- NODE=your_node_id
119
- HOST=your_cell_id
120
- PASSWORD=your_password
121
- NETWORK=neuronum.net
122
- SYNAPSE=your_synapse # auth token
123
- ```
116
+ 1. A Stream (STX) so your App can receive requests, and a Transmitter (TX) to match those requests
117
+ 2. A new directory named "Test App_<your_node_id>" with the following files
124
118
 
125
- app.py
126
- ```python
127
- import asyncio
128
- import neuronum
129
- import os
130
- from dotenv import load_dotenv
131
-
132
- load_dotenv()
133
- host = os.getenv("HOST")
134
- password = os.getenv("PASSWORD")
135
- network = os.getenv("NETWORK")
136
- synapse = os.getenv("SYNAPSE")
137
-
138
- cell = neuronum.Cell(
139
- host=host,
140
- password=password,
141
- network=network,
142
- synapse=synapse
143
- )
119
+ .env: Stores your Node's credentials for connecting to the network.
144
120
 
145
- async def main():
146
- STX = "id::stx"
147
- async for operation in cell.sync(STX):
148
- txID = operation.get("txID")
149
- client = operation.get("operator")
150
-
151
- if txID == "id::tx":
152
- data = {
153
- "json": f"Hello {client}",
154
- "html": f"""
155
- <!DOCTYPE html>
156
- <html>
157
- <head>
158
- <meta charset="UTF-8">
159
- <title>Greeting Node</title>
160
- </head>
161
- <body>
162
- <div class="card">
163
- <h1>Hello, {client}</h1>
164
- </div>
165
- </body>
166
- </html>
167
- """
168
-
169
- }
170
- await cell.tx_response(txID, client, data)
121
+ app.py: The main Python script that contains your Node's core logic.
171
122
 
172
- asyncio.run(main())
173
- ```
174
-
175
- config.json (required if you want to make your app accessible to Cellai (currently in testing))
176
- ```json
177
- {
178
- "data_gateways": [
179
- {
180
- "type": "stream",
181
- "id": "id::stx",
182
- "info": "provide a detailed description about the stream"
183
- },
184
- {
185
- "type": "transmitter",
186
- "id": "id::tx",
187
- "info": "provide a detailed description about the transmitter"
188
- },
189
- {
190
- "type": "circuit",
191
- "id": "id::ctx",
192
- "info": "provide a detailed description about the circuit"
193
- }
194
- ]
195
- }
196
- ```
123
+ NODE.md: Public documentation that provides instructions for interacting with your Node.
197
124
 
198
- NODE.md (required if you want to publish your App)
199
- ```
200
- ### NODE.md: Create a detailed Markdown File on how to interact with this Node
201
- ```
125
+ config.json: A configuration file that stores metadata about your app and enables Cellai to interact with your Node's data gateways.
202
126
 
127
+ ping.html: A static HTML file used to render web-based responses.
203
128
 
204
129
  Change into Node folder
205
130
  ```sh
@@ -247,6 +172,6 @@ asyncio.run(main())
247
172
  neuronum activate --tx id::tx 'say:hello'
248
173
  ```
249
174
 
250
- #### **Cellai**
251
- Cellai is a mobile interface that lets you interact with Neuronum apps using natural language. It is currently in testing.
175
+ #### **Cellai (in Testing)**
176
+ Cellai is an AI tool for developers to test their apps built on Neuronum and will soon be published to the Google Play Store.
252
177
 
@@ -0,0 +1,10 @@
1
+ cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ cli/main.py,sha256=nOoWfn7zdukLZQuGYx-47nINMZVSdPbcdMuu0bDCKzM,36520
3
+ neuronum/__init__.py,sha256=tAdqNC9rByY_CwG63yAyEe34phBdQ_Vv3FyFpTXQ2wo,45
4
+ neuronum/neuronum.py,sha256=5OjJIAmY7haT6eJ3P767RFk-LTvNFRrlkjB9mOozgN8,17971
5
+ neuronum-7.0.1.dist-info/licenses/LICENSE.md,sha256=m7pw_FktMNCs4tcy2UXP3QQP2S_je28P1SepdYoo0Xo,1961
6
+ neuronum-7.0.1.dist-info/METADATA,sha256=ymaVKlx87rwW30nBkXE-wxgPRo8KaI9cfjkV4etqZGM,6098
7
+ neuronum-7.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ neuronum-7.0.1.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
9
+ neuronum-7.0.1.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
10
+ neuronum-7.0.1.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- cli/main.py,sha256=gQ5AE9JwsQQf60jJEwXnHsNWZg0wlSv3PCTuGK4WS4I,33971
3
- neuronum/__init__.py,sha256=tAdqNC9rByY_CwG63yAyEe34phBdQ_Vv3FyFpTXQ2wo,45
4
- neuronum/neuronum.py,sha256=5OjJIAmY7haT6eJ3P767RFk-LTvNFRrlkjB9mOozgN8,17971
5
- neuronum-6.0.1.dist-info/licenses/LICENSE.md,sha256=m7pw_FktMNCs4tcy2UXP3QQP2S_je28P1SepdYoo0Xo,1961
6
- neuronum-6.0.1.dist-info/METADATA,sha256=N91j-LoSDy3ovC8V09yNwxEFCAFrEDLQjYfAfkZeVB0,7467
7
- neuronum-6.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- neuronum-6.0.1.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
9
- neuronum-6.0.1.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
10
- neuronum-6.0.1.dist-info/RECORD,,