neuronum 7.0.3__py3-none-any.whl → 8.0.0__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 +144 -370
- neuronum/neuronum.py +385 -437
- neuronum-8.0.0.dist-info/METADATA +126 -0
- neuronum-8.0.0.dist-info/RECORD +10 -0
- neuronum-7.0.3.dist-info/METADATA +0 -171
- neuronum-7.0.3.dist-info/RECORD +0 -10
- {neuronum-7.0.3.dist-info → neuronum-8.0.0.dist-info}/WHEEL +0 -0
- {neuronum-7.0.3.dist-info → neuronum-8.0.0.dist-info}/entry_points.txt +0 -0
- {neuronum-7.0.3.dist-info → neuronum-8.0.0.dist-info}/licenses/LICENSE.md +0 -0
- {neuronum-7.0.3.dist-info → neuronum-8.0.0.dist-info}/top_level.txt +0 -0
cli/main.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import subprocess
|
|
2
2
|
import os
|
|
3
|
-
import neuronum
|
|
4
3
|
import platform
|
|
5
4
|
import glob
|
|
6
5
|
import asyncio
|
|
@@ -12,7 +11,9 @@ import requests
|
|
|
12
11
|
import psutil
|
|
13
12
|
from datetime import datetime
|
|
14
13
|
import sys
|
|
15
|
-
|
|
14
|
+
import json
|
|
15
|
+
from cryptography.hazmat.primitives.asymmetric import ec
|
|
16
|
+
from cryptography.hazmat.primitives import serialization
|
|
16
17
|
|
|
17
18
|
@click.group()
|
|
18
19
|
def cli():
|
|
@@ -223,6 +224,7 @@ def delete_cell():
|
|
|
223
224
|
return
|
|
224
225
|
|
|
225
226
|
confirm = click.confirm(f" Are you sure you want to delete '{host}'?", default=True)
|
|
227
|
+
os.remove(env_path)
|
|
226
228
|
if not confirm:
|
|
227
229
|
click.echo("Deletion canceled.")
|
|
228
230
|
return
|
|
@@ -268,18 +270,12 @@ async def async_init_node(descr):
|
|
|
268
270
|
key, value = line.strip().split("=")
|
|
269
271
|
env_data[key] = value
|
|
270
272
|
|
|
273
|
+
|
|
271
274
|
host = env_data.get("HOST", "")
|
|
272
275
|
password = env_data.get("PASSWORD", "")
|
|
273
276
|
network = env_data.get("NETWORK", "")
|
|
274
277
|
synapse = env_data.get("SYNAPSE", "")
|
|
275
278
|
|
|
276
|
-
cell = neuronum.Cell(
|
|
277
|
-
host=host,
|
|
278
|
-
password=password,
|
|
279
|
-
network=network,
|
|
280
|
-
synapse=synapse
|
|
281
|
-
)
|
|
282
|
-
|
|
283
279
|
except FileNotFoundError:
|
|
284
280
|
click.echo("No cell connected. Connect your cell with command neuronum connect-cell")
|
|
285
281
|
return
|
|
@@ -300,87 +296,84 @@ async def async_init_node(descr):
|
|
|
300
296
|
async with session.post(url, json=node) as response:
|
|
301
297
|
response.raise_for_status()
|
|
302
298
|
data = await response.json()
|
|
303
|
-
|
|
299
|
+
node_id = data["nodeID"]
|
|
304
300
|
except aiohttp.ClientError as e:
|
|
305
301
|
click.echo(f"Error sending request: {e}")
|
|
306
302
|
return
|
|
307
303
|
|
|
308
|
-
node_filename = descr + "_" +
|
|
304
|
+
node_filename = descr + "_" + node_id.replace("::node", "")
|
|
309
305
|
project_path = Path(node_filename)
|
|
310
306
|
project_path.mkdir(exist_ok=True)
|
|
311
307
|
|
|
312
|
-
|
|
313
|
-
|
|
308
|
+
try:
|
|
309
|
+
private_key = ec.generate_private_key(ec.SECP256R1())
|
|
310
|
+
public_key = private_key.public_key()
|
|
314
311
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
312
|
+
pem_private = private_key.private_bytes(
|
|
313
|
+
encoding=serialization.Encoding.PEM,
|
|
314
|
+
format=serialization.PrivateFormat.PKCS8,
|
|
315
|
+
encryption_algorithm=serialization.NoEncryption()
|
|
316
|
+
)
|
|
318
317
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
318
|
+
pem_public = public_key.public_bytes(
|
|
319
|
+
encoding=serialization.Encoding.PEM,
|
|
320
|
+
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
public_key_pem_file = project_path / "public_key.pem"
|
|
324
|
+
with open(public_key_pem_file, "wb") as key_file:
|
|
325
|
+
key_file.write(pem_public)
|
|
327
326
|
|
|
327
|
+
private_key_pem_file = project_path / "private_key.pem"
|
|
328
|
+
with open(private_key_pem_file, "wb") as key_file:
|
|
329
|
+
key_file.write(pem_private)
|
|
330
|
+
|
|
331
|
+
pem_public_str = pem_public.decode('utf-8')
|
|
332
|
+
pem_public_oneline = "".join(pem_public_str.split())
|
|
333
|
+
|
|
334
|
+
current_directory = os.getcwd()
|
|
335
|
+
private_key_file = os.path.join(current_directory / project_path, "private_key.pem")
|
|
336
|
+
public_key_file = os.path.join(current_directory / project_path, "public_key.pem")
|
|
337
|
+
except:
|
|
338
|
+
print("Error creating Private/Public Key Pair")
|
|
339
|
+
|
|
328
340
|
app_path = project_path / "app.py"
|
|
329
341
|
app_path.write_text(f"""\
|
|
330
342
|
import asyncio
|
|
331
|
-
import neuronum
|
|
332
|
-
import
|
|
333
|
-
|
|
334
|
-
from dotenv import load_dotenv
|
|
335
|
-
from jinja2 import Environment, FileSystemLoader
|
|
336
|
-
|
|
343
|
+
import neuronum
|
|
344
|
+
from jinja2 import Environment, FileSystemLoader
|
|
345
|
+
|
|
337
346
|
env = Environment(loader=FileSystemLoader('.'))
|
|
338
347
|
template = env.get_template('ping.html')
|
|
339
|
-
|
|
340
|
-
with open('config.json', 'r') as f:
|
|
341
|
-
data = json.load(f)
|
|
342
|
-
terms_url = data['legals']['terms']
|
|
343
|
-
privacy_url = data['legals']['privacy_policy']
|
|
344
|
-
last_update = data['legals']['last_update']
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
load_dotenv()
|
|
348
|
-
host = os.getenv("HOST")
|
|
349
|
-
password = os.getenv("PASSWORD")
|
|
350
|
-
network = os.getenv("NETWORK")
|
|
351
|
-
synapse = os.getenv("SYNAPSE")
|
|
352
|
-
|
|
348
|
+
|
|
353
349
|
cell = neuronum.Cell(
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
network=network,
|
|
357
|
-
synapse=synapse
|
|
350
|
+
private_key_path="{private_key_file}",
|
|
351
|
+
public_key_path="{public_key_file}"
|
|
358
352
|
)
|
|
359
|
-
|
|
360
|
-
async def main():
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
353
|
+
|
|
354
|
+
async def main():
|
|
355
|
+
|
|
356
|
+
node_id = "{node_id}"
|
|
357
|
+
async for transmitter in cell.sync(node_id):
|
|
358
|
+
ts = transmitter.get("time")
|
|
359
|
+
data = transmitter.get("data")
|
|
360
|
+
transmitter_id = transmitter.get("transmitter_id")
|
|
361
|
+
client = transmitter.get("operator")
|
|
362
|
+
client_public_key = data.get("publicKey")
|
|
363
|
+
action = data.get("action")
|
|
364
|
+
|
|
365
|
+
response_data = {{}}
|
|
366
|
+
|
|
367
|
+
if action == "ping_node":
|
|
370
368
|
|
|
371
|
-
|
|
372
|
-
return template.render(client=client, ts=ts, data=data, operation_id=operation_id, terms_url=terms_url, privacy_url=privacy_url, last_update=last_update)
|
|
373
|
-
|
|
374
|
-
html_content = render_html_template(client, ts, data, operation_id, terms_url, privacy_url, last_update)
|
|
369
|
+
html_content = template.render(client=client, ts=ts, data=action, transmitter_id=transmitter_id)
|
|
375
370
|
|
|
376
|
-
|
|
377
|
-
"json": f"{{
|
|
371
|
+
response_data = {{
|
|
372
|
+
"json": f"{{transmitter_id}} - Reply from {node_id}: Pinged by {{client}} at {{ts}} with action: {{action}}",
|
|
378
373
|
"html": html_content
|
|
379
374
|
}}
|
|
380
|
-
|
|
381
|
-
await cell.
|
|
382
|
-
|
|
383
|
-
await cell.tx_response(txID, client, data)
|
|
375
|
+
|
|
376
|
+
await cell.tx_response(transmitter_id, response_data, client_public_key)
|
|
384
377
|
|
|
385
378
|
asyncio.run(main())
|
|
386
379
|
""")
|
|
@@ -468,7 +461,7 @@ asyncio.run(main())
|
|
|
468
461
|
.data-value.timestamp {{
|
|
469
462
|
color: #a1e8a1;
|
|
470
463
|
}}
|
|
471
|
-
.data-value.
|
|
464
|
+
.data-value.transmitter-id {{
|
|
472
465
|
color: #f7a2a2;
|
|
473
466
|
}}
|
|
474
467
|
.api-button {{
|
|
@@ -489,7 +482,7 @@ asyncio.run(main())
|
|
|
489
482
|
<div class="container">
|
|
490
483
|
<img class="logo" src="https://neuronum.net/static/logo.png" alt="Neuronum Logo">
|
|
491
484
|
|
|
492
|
-
<h1>Reply from {
|
|
485
|
+
<h1>Reply from {node_id}</h1>
|
|
493
486
|
<p class="subtitle">Pinged successfully.</p>
|
|
494
487
|
|
|
495
488
|
<div class="data-row">
|
|
@@ -508,157 +501,61 @@ asyncio.run(main())
|
|
|
508
501
|
</div>
|
|
509
502
|
|
|
510
503
|
<div class="data-row">
|
|
511
|
-
<p class="data-label">
|
|
512
|
-
<p class="data-value
|
|
504
|
+
<p class="data-label">Transmitter ID</p>
|
|
505
|
+
<p class="data-value transmitter-id truncated">{{{{transmitter_id}}}}</p>
|
|
513
506
|
</div>
|
|
514
507
|
|
|
515
508
|
<button id="send-request-btn" class="api-button">Ping again</button>
|
|
516
509
|
</div>
|
|
517
510
|
|
|
518
511
|
<script>
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
fetch(apiEndpoint, {{
|
|
531
|
-
method: 'POST',
|
|
532
|
-
headers: {{
|
|
533
|
-
'Content-Type': 'application/json',
|
|
534
|
-
'Accept': 'application/json'
|
|
535
|
-
}},
|
|
536
|
-
body: JSON.stringify(dataToSend)
|
|
537
|
-
}})
|
|
538
|
-
.then(response => {{
|
|
539
|
-
if (!response.ok) {{
|
|
540
|
-
throw new Error(`HTTP error! status: ${{response.status}}`);
|
|
512
|
+
document.getElementById('send-request-btn').addEventListener('click', () => {{
|
|
513
|
+
const messagePayload = {{
|
|
514
|
+
type: 'iframe_request',
|
|
515
|
+
endpoint: 'https://neuronum.net/browser/api/activate_tx/{node_id}',
|
|
516
|
+
data: {{ "action": "ping_node" }},
|
|
517
|
+
nodePublicKey: '{pem_public_oneline}',
|
|
518
|
+
}};
|
|
519
|
+
|
|
520
|
+
if (window.parent) {{
|
|
521
|
+
window.parent.postMessage(messagePayload, '*');
|
|
541
522
|
}}
|
|
542
|
-
return response.json();
|
|
543
|
-
}})
|
|
544
|
-
.then(data => {{
|
|
545
|
-
if (data.success && data.response && data.response.html) {{
|
|
546
|
-
document.open();
|
|
547
|
-
document.write(data.response.html);
|
|
548
|
-
document.close();
|
|
549
|
-
console.log('API Response: Page replaced with new HTML.');
|
|
550
|
-
}} else {{
|
|
551
|
-
console.error('API Response does not contain HTML to replace the page:', data);
|
|
552
|
-
alert('API response error: Expected HTML content to replace the page.');
|
|
553
|
-
}}
|
|
554
|
-
}})
|
|
555
|
-
.catch(error => {{
|
|
556
|
-
console.error('API request failed:', error);
|
|
557
|
-
alert('API request failed. See the console for details.');
|
|
558
523
|
}});
|
|
559
|
-
}});
|
|
560
|
-
</script>
|
|
561
|
-
|
|
562
|
-
<div id="legal-banner" style="border-radius: 10px; margin: 15px; position: fixed; bottom: 0; left: 0; right: 0; background-color: #2a2a2a; color: #e0e0e0; padding: 16px; text-align: center; font-size: 14px; z-index: 9999; box-shadow: 0 -2px 10px rgba(0,0,0,0.5);">
|
|
563
|
-
By continuing, you agree to our
|
|
564
|
-
Terms (<span style="color: #8cafff;">{{{{terms_url}}}}</span>) &
|
|
565
|
-
Privacy Policy (<span style="color: #8cafff;">{{{{privacy_url}}}}</span>)
|
|
566
|
-
<br>
|
|
567
|
-
<button id="accept-legal" style="margin-top: 15px; margin-bottom: 15px; background: #01c07d; color: white; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer;">Accept</button>
|
|
568
|
-
<br>
|
|
569
|
-
Last Update: {{{{last_update}}}}
|
|
570
|
-
</div>
|
|
571
|
-
|
|
572
|
-
<script>
|
|
573
|
-
const banner = document.getElementById('legal-banner');
|
|
574
|
-
const acceptBtn = document.getElementById('accept-legal');
|
|
575
|
-
acceptBtn.addEventListener('click', () => {{
|
|
576
|
-
banner.remove();
|
|
577
|
-
}});
|
|
578
524
|
</script>
|
|
579
525
|
|
|
580
526
|
</body>
|
|
581
527
|
</html>
|
|
582
528
|
"""
|
|
583
529
|
html_path.write_text(html_content)
|
|
584
|
-
|
|
585
530
|
config_path = project_path / "config.json"
|
|
586
531
|
await asyncio.to_thread(
|
|
587
532
|
config_path.write_text,
|
|
588
533
|
f"""{{
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
534
|
+
"app_metadata": {{
|
|
535
|
+
"name": "{descr}",
|
|
536
|
+
"version": "1.0.0",
|
|
537
|
+
"author": "{host}"
|
|
538
|
+
}},
|
|
539
|
+
"data_gateways": [
|
|
540
|
+
{{
|
|
541
|
+
"node_id": "{node_id}",
|
|
542
|
+
"actions": [
|
|
595
543
|
{{
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
"info": "Ping Your Node"
|
|
544
|
+
"action": "ping_node",
|
|
545
|
+
"info": "Ping Node"
|
|
599
546
|
}}
|
|
600
|
-
|
|
601
|
-
"legals": {{
|
|
602
|
-
"terms": "https://url_to_your/terms",
|
|
603
|
-
"privacy_policy": "https://url_to_your/privacy_policy",
|
|
604
|
-
"last_update" : "DD/MM/YYYY"
|
|
547
|
+
]
|
|
605
548
|
}}
|
|
549
|
+
],
|
|
550
|
+
"legals": {{
|
|
551
|
+
"terms": "https://url_to_your/terms",
|
|
552
|
+
"privacy_policy": "https://url_to_your/privacy_policy"
|
|
553
|
+
}},
|
|
554
|
+
"public_key": "{pem_public_oneline}"
|
|
606
555
|
}}"""
|
|
607
|
-
)
|
|
608
|
-
|
|
609
|
-
nodemd_path = project_path / "NODE.md"
|
|
610
|
-
await asyncio.to_thread(nodemd_path.write_text, f"""### NODE.md of {nodeID}
|
|
611
|
-
|
|
612
|
-
Welcome to your Node's documentation! This guide provides several ways for users to interact with your application.
|
|
613
|
-
|
|
614
|
-
***
|
|
615
|
-
|
|
616
|
-
### 💻 Using the CLI
|
|
617
|
-
|
|
618
|
-
To ping this Node via the command-line interface, use the following command:
|
|
619
|
-
|
|
620
|
-
`neuronum activate --tx {txID} 'ping:node'`
|
|
621
|
-
|
|
622
|
-
***
|
|
623
|
-
|
|
624
|
-
### 🐍 With Python
|
|
625
556
|
|
|
626
|
-
For programmatic access, use the following Python code snippet. This script utilizes the `neuronum` library to activate the transaction and receive a response.
|
|
627
|
-
|
|
628
|
-
```python
|
|
629
|
-
import asyncio
|
|
630
|
-
import neuronum
|
|
631
|
-
|
|
632
|
-
# Set up Cell connection parameters
|
|
633
|
-
cell = neuronum.Cell(
|
|
634
|
-
host="host", # Cell host
|
|
635
|
-
password="password", # Cell password
|
|
636
|
-
network="neuronum.net", # Cell network
|
|
637
|
-
synapse="synapse" # Cell synapse
|
|
638
557
|
)
|
|
639
|
-
|
|
640
|
-
async def main():
|
|
641
|
-
# Define the transaction ID and data payload
|
|
642
|
-
TX = "{txID}"
|
|
643
|
-
data = {{"ping": "node"}}
|
|
644
|
-
|
|
645
|
-
# Activate the transaction and get the response
|
|
646
|
-
tx_response = await cell.activate_tx(TX, data)
|
|
647
|
-
|
|
648
|
-
# Print the response from the Node
|
|
649
|
-
print(tx_response)
|
|
650
|
-
|
|
651
|
-
# Run the main asynchronous function
|
|
652
|
-
if __name__ == "__main__":
|
|
653
|
-
asyncio.run(main())
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
🤖 Via Cellai (Android App - Currently in Testing)
|
|
657
|
-
Download the app from the Google Play Store.
|
|
658
|
-
Send the command "Ping Node" to Cellai
|
|
659
|
-
""")
|
|
660
|
-
|
|
661
|
-
click.echo(f"Neuronum Node '{nodeID}' initialized!")
|
|
558
|
+
click.echo(f"Neuronum Node '{node_id}' initialized!")
|
|
662
559
|
|
|
663
560
|
|
|
664
561
|
@click.command()
|
|
@@ -695,7 +592,7 @@ def start_node(d):
|
|
|
695
592
|
click.echo("Starting Node...")
|
|
696
593
|
|
|
697
594
|
project_path = Path.cwd()
|
|
698
|
-
script_files = glob.glob("
|
|
595
|
+
script_files = glob.glob("app.py")
|
|
699
596
|
processes = []
|
|
700
597
|
|
|
701
598
|
for script in script_files:
|
|
@@ -732,14 +629,12 @@ def start_node(d):
|
|
|
732
629
|
def check_node():
|
|
733
630
|
click.echo("Checking Node status...")
|
|
734
631
|
|
|
735
|
-
env_data = {}
|
|
736
632
|
try:
|
|
737
|
-
with open(
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
nodeID = env_data.get("NODE", "")
|
|
633
|
+
with open('config.json', 'r') as f:
|
|
634
|
+
data = json.load(f)
|
|
635
|
+
|
|
636
|
+
nodeID = data['data_gateways'][0]['node_id']
|
|
637
|
+
|
|
743
638
|
except FileNotFoundError:
|
|
744
639
|
click.echo("Error: .env with credentials not found")
|
|
745
640
|
return
|
|
@@ -798,14 +693,11 @@ def restart_node(d):
|
|
|
798
693
|
|
|
799
694
|
start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
800
695
|
|
|
801
|
-
env_data = {}
|
|
802
696
|
try:
|
|
803
|
-
with open(
|
|
804
|
-
|
|
805
|
-
key, value = line.strip().split("=")
|
|
806
|
-
env_data[key] = value
|
|
697
|
+
with open('config.json', 'r') as f:
|
|
698
|
+
data = json.load(f)
|
|
807
699
|
|
|
808
|
-
nodeID =
|
|
700
|
+
nodeID = data['data_gateways'][0]['node_id']
|
|
809
701
|
|
|
810
702
|
except FileNotFoundError:
|
|
811
703
|
print("Error: .env with credentials not found")
|
|
@@ -842,7 +734,7 @@ def restart_node(d):
|
|
|
842
734
|
|
|
843
735
|
click.echo(f"Starting Node {nodeID}...")
|
|
844
736
|
project_path = Path.cwd()
|
|
845
|
-
script_files = glob.glob("
|
|
737
|
+
script_files = glob.glob("app.py")
|
|
846
738
|
processes = []
|
|
847
739
|
|
|
848
740
|
for script in script_files:
|
|
@@ -883,14 +775,11 @@ async def async_stop_node():
|
|
|
883
775
|
|
|
884
776
|
node_pid_path = Path("status.txt")
|
|
885
777
|
|
|
886
|
-
env_data = {}
|
|
887
778
|
try:
|
|
888
|
-
with open(
|
|
889
|
-
|
|
890
|
-
key, value = line.strip().split("=")
|
|
891
|
-
env_data[key] = value
|
|
779
|
+
with open('config.json', 'r') as f:
|
|
780
|
+
data = json.load(f)
|
|
892
781
|
|
|
893
|
-
nodeID =
|
|
782
|
+
nodeID = data['data_gateways'][0]['node_id']
|
|
894
783
|
|
|
895
784
|
except FileNotFoundError:
|
|
896
785
|
print("Error: .env with credentials not found")
|
|
@@ -926,10 +815,12 @@ async def async_stop_node():
|
|
|
926
815
|
@click.command()
|
|
927
816
|
def update_node():
|
|
928
817
|
click.echo("Update your Node")
|
|
818
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
819
|
+
env_path = credentials_folder_path / ".env"
|
|
929
820
|
env_data = {}
|
|
930
821
|
|
|
931
822
|
try:
|
|
932
|
-
with open(
|
|
823
|
+
with open(env_path, "r") as f:
|
|
933
824
|
for line in f:
|
|
934
825
|
key, value = line.strip().split("=")
|
|
935
826
|
env_data[key] = value
|
|
@@ -976,20 +867,26 @@ def update_node():
|
|
|
976
867
|
asyncio.run(async_update_node(node_type, descr, partners))
|
|
977
868
|
|
|
978
869
|
async def async_update_node(node_type: str, descr: str, partners:str) -> None:
|
|
870
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
871
|
+
env_path = credentials_folder_path / ".env"
|
|
979
872
|
env_data = {}
|
|
980
873
|
|
|
981
874
|
try:
|
|
982
|
-
with open(
|
|
875
|
+
with open(env_path, "r") as f:
|
|
983
876
|
for line in f:
|
|
984
877
|
key, value = line.strip().split("=")
|
|
985
878
|
env_data[key] = value
|
|
986
879
|
|
|
987
|
-
nodeID = env_data.get("NODE", "")
|
|
988
880
|
host = env_data.get("HOST", "")
|
|
989
881
|
password = env_data.get("PASSWORD", "")
|
|
990
882
|
network = env_data.get("NETWORK", "")
|
|
991
883
|
synapse = env_data.get("SYNAPSE", "")
|
|
992
884
|
|
|
885
|
+
with open('config.json', 'r') as f:
|
|
886
|
+
data = json.load(f)
|
|
887
|
+
|
|
888
|
+
nodeID = data['data_gateways'][0]['node_id']
|
|
889
|
+
|
|
993
890
|
except FileNotFoundError:
|
|
994
891
|
click.echo("Error: .env with credentials not found")
|
|
995
892
|
return
|
|
@@ -998,17 +895,14 @@ async def async_update_node(node_type: str, descr: str, partners:str) -> None:
|
|
|
998
895
|
return
|
|
999
896
|
|
|
1000
897
|
try:
|
|
1001
|
-
with open("NODE.md", "r") as f:
|
|
1002
|
-
nodemd_file = f.read()
|
|
1003
|
-
|
|
1004
898
|
with open("config.json", "r") as f:
|
|
1005
899
|
config_file = f.read()
|
|
1006
900
|
|
|
1007
901
|
except FileNotFoundError:
|
|
1008
|
-
click.echo("Error:
|
|
902
|
+
click.echo("Error: Config File not found")
|
|
1009
903
|
return
|
|
1010
904
|
except Exception as e:
|
|
1011
|
-
click.echo(f"Error reading
|
|
905
|
+
click.echo(f"Error reading Config file: {e}")
|
|
1012
906
|
return
|
|
1013
907
|
|
|
1014
908
|
if node_type == "partners":
|
|
@@ -1021,7 +915,6 @@ async def async_update_node(node_type: str, descr: str, partners:str) -> None:
|
|
|
1021
915
|
"password": password,
|
|
1022
916
|
"synapse": synapse,
|
|
1023
917
|
"node_type": node_type,
|
|
1024
|
-
"nodemd_file": nodemd_file,
|
|
1025
918
|
"config_file": config_file,
|
|
1026
919
|
"descr": descr,
|
|
1027
920
|
}
|
|
@@ -1032,23 +925,24 @@ async def async_update_node(node_type: str, descr: str, partners:str) -> None:
|
|
|
1032
925
|
response.raise_for_status()
|
|
1033
926
|
data = await response.json()
|
|
1034
927
|
nodeID = data["nodeID"]
|
|
1035
|
-
node_url = data["node_url"]
|
|
1036
928
|
except aiohttp.ClientError as e:
|
|
1037
929
|
click.echo(f"Error sending request: {e}")
|
|
1038
930
|
return
|
|
1039
931
|
|
|
1040
932
|
if node_type == "public":
|
|
1041
|
-
click.echo(f"Neuronum Node '{nodeID}' updated!
|
|
933
|
+
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
1042
934
|
else:
|
|
1043
935
|
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
1044
936
|
|
|
1045
937
|
|
|
1046
938
|
def update_node_at_start():
|
|
1047
939
|
click.echo("Update your Node")
|
|
940
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
941
|
+
env_path = credentials_folder_path / ".env"
|
|
1048
942
|
env_data = {}
|
|
1049
943
|
|
|
1050
944
|
try:
|
|
1051
|
-
with open(
|
|
945
|
+
with open(env_path, "r") as f:
|
|
1052
946
|
for line in f:
|
|
1053
947
|
key, value = line.strip().split("=")
|
|
1054
948
|
env_data[key] = value
|
|
@@ -1095,20 +989,26 @@ def update_node_at_start():
|
|
|
1095
989
|
asyncio.run(async_update_node_at_start(node_type, descr, partners))
|
|
1096
990
|
|
|
1097
991
|
async def async_update_node_at_start(node_type: str, descr: str, partners:str) -> None:
|
|
992
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
993
|
+
env_path = credentials_folder_path / ".env"
|
|
1098
994
|
env_data = {}
|
|
1099
995
|
|
|
1100
996
|
try:
|
|
1101
|
-
with open(
|
|
997
|
+
with open(env_path, "r") as f:
|
|
1102
998
|
for line in f:
|
|
1103
999
|
key, value = line.strip().split("=")
|
|
1104
1000
|
env_data[key] = value
|
|
1105
1001
|
|
|
1106
|
-
nodeID = env_data.get("NODE", "")
|
|
1107
1002
|
host = env_data.get("HOST", "")
|
|
1108
1003
|
password = env_data.get("PASSWORD", "")
|
|
1109
1004
|
network = env_data.get("NETWORK", "")
|
|
1110
1005
|
synapse = env_data.get("SYNAPSE", "")
|
|
1111
1006
|
|
|
1007
|
+
with open('config.json', 'r') as f:
|
|
1008
|
+
data = json.load(f)
|
|
1009
|
+
|
|
1010
|
+
nodeID = data['data_gateways'][0]['node_id']
|
|
1011
|
+
|
|
1112
1012
|
except FileNotFoundError:
|
|
1113
1013
|
click.echo("Error: .env with credentials not found")
|
|
1114
1014
|
return
|
|
@@ -1117,17 +1017,14 @@ async def async_update_node_at_start(node_type: str, descr: str, partners:str) -
|
|
|
1117
1017
|
return
|
|
1118
1018
|
|
|
1119
1019
|
try:
|
|
1120
|
-
with open("NODE.md", "r") as f:
|
|
1121
|
-
nodemd_file = f.read()
|
|
1122
|
-
|
|
1123
1020
|
with open("config.json", "r") as f:
|
|
1124
1021
|
config_file = f.read()
|
|
1125
1022
|
|
|
1126
1023
|
except FileNotFoundError:
|
|
1127
|
-
click.echo("Error:
|
|
1024
|
+
click.echo("Error: File not found")
|
|
1128
1025
|
return
|
|
1129
1026
|
except Exception as e:
|
|
1130
|
-
click.echo(f"Error reading
|
|
1027
|
+
click.echo(f"Error reading file: {e}")
|
|
1131
1028
|
return
|
|
1132
1029
|
|
|
1133
1030
|
if node_type == "partners":
|
|
@@ -1140,7 +1037,6 @@ async def async_update_node_at_start(node_type: str, descr: str, partners:str) -
|
|
|
1140
1037
|
"password": password,
|
|
1141
1038
|
"synapse": synapse,
|
|
1142
1039
|
"node_type": node_type,
|
|
1143
|
-
"nodemd_file": nodemd_file,
|
|
1144
1040
|
"config_file": config_file,
|
|
1145
1041
|
"descr": descr,
|
|
1146
1042
|
}
|
|
@@ -1151,13 +1047,12 @@ async def async_update_node_at_start(node_type: str, descr: str, partners:str) -
|
|
|
1151
1047
|
response.raise_for_status()
|
|
1152
1048
|
data = await response.json()
|
|
1153
1049
|
nodeID = data["nodeID"]
|
|
1154
|
-
node_url = data["node_url"]
|
|
1155
1050
|
except aiohttp.ClientError as e:
|
|
1156
1051
|
click.echo(f"Error sending request: {e}")
|
|
1157
1052
|
return
|
|
1158
1053
|
|
|
1159
1054
|
if node_type == "public":
|
|
1160
|
-
click.echo(f"Neuronum Node '{nodeID}' updated!
|
|
1055
|
+
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
1161
1056
|
else:
|
|
1162
1057
|
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
1163
1058
|
|
|
@@ -1167,20 +1062,26 @@ def delete_node():
|
|
|
1167
1062
|
asyncio.run(async_delete_node())
|
|
1168
1063
|
|
|
1169
1064
|
async def async_delete_node():
|
|
1065
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
1066
|
+
env_path = credentials_folder_path / ".env"
|
|
1170
1067
|
env_data = {}
|
|
1171
1068
|
|
|
1172
1069
|
try:
|
|
1173
|
-
with open(
|
|
1070
|
+
with open(env_path, "r") as f:
|
|
1174
1071
|
for line in f:
|
|
1175
1072
|
key, value = line.strip().split("=")
|
|
1176
1073
|
env_data[key] = value
|
|
1177
1074
|
|
|
1178
|
-
nodeID = env_data.get("NODE", "")
|
|
1179
1075
|
host = env_data.get("HOST", "")
|
|
1180
1076
|
password = env_data.get("PASSWORD", "")
|
|
1181
1077
|
network = env_data.get("NETWORK", "")
|
|
1182
1078
|
synapse = env_data.get("SYNAPSE", "")
|
|
1183
1079
|
|
|
1080
|
+
with open('config.json', 'r') as f:
|
|
1081
|
+
data = json.load(f)
|
|
1082
|
+
|
|
1083
|
+
nodeID = data['data_gateways'][0]['node_id']
|
|
1084
|
+
|
|
1184
1085
|
except FileNotFoundError:
|
|
1185
1086
|
click.echo("Error: .env with credentials not found")
|
|
1186
1087
|
return
|
|
@@ -1209,130 +1110,6 @@ async def async_delete_node():
|
|
|
1209
1110
|
click.echo(f"Neuronum Node '{nodeID}' deleted!")
|
|
1210
1111
|
|
|
1211
1112
|
|
|
1212
|
-
@click.command()
|
|
1213
|
-
@click.option('--tx', required=True, help="Transmitter ID")
|
|
1214
|
-
@click.argument('kvpairs', nargs=-1)
|
|
1215
|
-
def activate(tx, kvpairs):
|
|
1216
|
-
try:
|
|
1217
|
-
data = dict(pair.split(':', 1) for pair in kvpairs)
|
|
1218
|
-
except ValueError:
|
|
1219
|
-
click.echo("Invalid input. Use key:value pairs.")
|
|
1220
|
-
return
|
|
1221
|
-
|
|
1222
|
-
asyncio.run(async_activate(tx, data))
|
|
1223
|
-
|
|
1224
|
-
async def async_activate(tx, data):
|
|
1225
|
-
credentials_folder_path = Path.home() / ".neuronum"
|
|
1226
|
-
env_path = credentials_folder_path / ".env"
|
|
1227
|
-
env_data = {}
|
|
1228
|
-
|
|
1229
|
-
try:
|
|
1230
|
-
with open(env_path, "r") as f:
|
|
1231
|
-
for line in f:
|
|
1232
|
-
key, value = line.strip().split("=")
|
|
1233
|
-
env_data[key] = value
|
|
1234
|
-
except FileNotFoundError:
|
|
1235
|
-
click.echo("No cell connected. Try: neuronum connect-cell")
|
|
1236
|
-
return
|
|
1237
|
-
except Exception as e:
|
|
1238
|
-
click.echo(f"Error reading .env: {e}")
|
|
1239
|
-
return
|
|
1240
|
-
|
|
1241
|
-
cell = neuronum.Cell(
|
|
1242
|
-
host=env_data.get("HOST", ""),
|
|
1243
|
-
password=env_data.get("PASSWORD", ""),
|
|
1244
|
-
network=env_data.get("NETWORK", ""),
|
|
1245
|
-
synapse=env_data.get("SYNAPSE", "")
|
|
1246
|
-
)
|
|
1247
|
-
|
|
1248
|
-
tx_response = await cell.activate_tx(tx, data)
|
|
1249
|
-
click.echo(tx_response)
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
@click.command()
|
|
1253
|
-
@click.option('--ctx', required=True, help="Circuit ID")
|
|
1254
|
-
@click.argument('label', nargs=-1)
|
|
1255
|
-
def load(ctx, label):
|
|
1256
|
-
if len(label) > 1 and all(Path(x).exists() for x in label):
|
|
1257
|
-
label = "*"
|
|
1258
|
-
else:
|
|
1259
|
-
label = " ".join(label)
|
|
1260
|
-
|
|
1261
|
-
asyncio.run(async_load(ctx, label))
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
async def async_load(ctx, label):
|
|
1265
|
-
credentials_folder_path = Path.home() / ".neuronum"
|
|
1266
|
-
env_path = credentials_folder_path / ".env"
|
|
1267
|
-
env_data = {}
|
|
1268
|
-
|
|
1269
|
-
try:
|
|
1270
|
-
with open(env_path, "r") as f:
|
|
1271
|
-
for line in f:
|
|
1272
|
-
key, value = line.strip().split("=")
|
|
1273
|
-
env_data[key] = value
|
|
1274
|
-
except FileNotFoundError:
|
|
1275
|
-
click.echo("No cell connected. Try: neuronum connect-cell")
|
|
1276
|
-
return
|
|
1277
|
-
except Exception as e:
|
|
1278
|
-
click.echo(f"Error reading .env: {e}")
|
|
1279
|
-
return
|
|
1280
|
-
|
|
1281
|
-
cell = neuronum.Cell(
|
|
1282
|
-
host=env_data.get("HOST", ""),
|
|
1283
|
-
password=env_data.get("PASSWORD", ""),
|
|
1284
|
-
network=env_data.get("NETWORK", ""),
|
|
1285
|
-
synapse=env_data.get("SYNAPSE", "")
|
|
1286
|
-
)
|
|
1287
|
-
|
|
1288
|
-
data = await cell.load(label, ctx)
|
|
1289
|
-
click.echo(data)
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
@click.command()
|
|
1293
|
-
@click.option('--stx', default=None, help="Stream ID (optional)")
|
|
1294
|
-
def sync(stx):
|
|
1295
|
-
asyncio.run(async_sync(stx))
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
async def async_sync(stx):
|
|
1299
|
-
credentials_folder_path = Path.home() / ".neuronum"
|
|
1300
|
-
env_path = credentials_folder_path / ".env"
|
|
1301
|
-
env_data = {}
|
|
1302
|
-
|
|
1303
|
-
try:
|
|
1304
|
-
with open(env_path, "r") as f:
|
|
1305
|
-
for line in f:
|
|
1306
|
-
key, value = line.strip().split("=")
|
|
1307
|
-
env_data[key] = value
|
|
1308
|
-
except FileNotFoundError:
|
|
1309
|
-
click.echo("No cell connected. Try: neuronum connect-cell")
|
|
1310
|
-
return
|
|
1311
|
-
except Exception as e:
|
|
1312
|
-
click.echo(f"Error reading .env: {e}")
|
|
1313
|
-
return
|
|
1314
|
-
|
|
1315
|
-
cell = neuronum.Cell(
|
|
1316
|
-
host=env_data.get("HOST", ""),
|
|
1317
|
-
password=env_data.get("PASSWORD", ""),
|
|
1318
|
-
network=env_data.get("NETWORK", ""),
|
|
1319
|
-
synapse=env_data.get("SYNAPSE", "")
|
|
1320
|
-
)
|
|
1321
|
-
|
|
1322
|
-
if stx:
|
|
1323
|
-
print(f"Listening to Stream '{stx}'! Close connection with CTRL+C")
|
|
1324
|
-
else:
|
|
1325
|
-
print(f"Listening to '{cell.host}' private Stream! Close connection with CTRL+C")
|
|
1326
|
-
async for operation in cell.sync() if stx is None else cell.sync(stx):
|
|
1327
|
-
label = operation.get("label")
|
|
1328
|
-
data = operation.get("data")
|
|
1329
|
-
ts = operation.get("time")
|
|
1330
|
-
stxID = operation.get("stxID")
|
|
1331
|
-
operator = operation.get("operator")
|
|
1332
|
-
txID = operation.get("txID")
|
|
1333
|
-
print(label, data, ts, operator, txID, stxID)
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
1113
|
cli.add_command(create_cell)
|
|
1337
1114
|
cli.add_command(connect_cell)
|
|
1338
1115
|
cli.add_command(view_cell)
|
|
@@ -1345,9 +1122,6 @@ cli.add_command(restart_node)
|
|
|
1345
1122
|
cli.add_command(stop_node)
|
|
1346
1123
|
cli.add_command(check_node)
|
|
1347
1124
|
cli.add_command(delete_node)
|
|
1348
|
-
cli.add_command(activate)
|
|
1349
|
-
cli.add_command(load)
|
|
1350
|
-
cli.add_command(sync)
|
|
1351
1125
|
|
|
1352
1126
|
|
|
1353
1127
|
if __name__ == "__main__":
|