neuronum 1.6.0__py3-none-any.whl → 1.7.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 +287 -32
- neuronum/neuronum.py +32 -35
- {neuronum-1.6.0.dist-info → neuronum-1.7.1.dist-info}/METADATA +62 -47
- neuronum-1.7.1.dist-info/RECORD +10 -0
- neuronum-1.6.0.dist-info/RECORD +0 -10
- {neuronum-1.6.0.dist-info → neuronum-1.7.1.dist-info}/LICENSE +0 -0
- {neuronum-1.6.0.dist-info → neuronum-1.7.1.dist-info}/WHEEL +0 -0
- {neuronum-1.6.0.dist-info → neuronum-1.7.1.dist-info}/entry_points.txt +0 -0
- {neuronum-1.6.0.dist-info → neuronum-1.7.1.dist-info}/top_level.txt +0 -0
cli/main.py
CHANGED
|
@@ -13,8 +13,238 @@ def cli():
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
@click.command()
|
|
16
|
-
def
|
|
17
|
-
|
|
16
|
+
def create_cell():
|
|
17
|
+
cell_type = questionary.select(
|
|
18
|
+
"Choose Cell type:",
|
|
19
|
+
choices=["business", "community"]
|
|
20
|
+
).ask()
|
|
21
|
+
|
|
22
|
+
network = questionary.select(
|
|
23
|
+
"Choose Network:",
|
|
24
|
+
choices=["neuronum.net"]
|
|
25
|
+
).ask()
|
|
26
|
+
|
|
27
|
+
if cell_type == "business":
|
|
28
|
+
click.echo("Visit https://neuronum.net/createcell to create your Neuronum Business Cell")
|
|
29
|
+
|
|
30
|
+
if cell_type == "community":
|
|
31
|
+
|
|
32
|
+
email = click.prompt("Enter email")
|
|
33
|
+
password = click.prompt("Enter password", hide_input=True)
|
|
34
|
+
repeat_password = click.prompt("Repeat password", hide_input=True)
|
|
35
|
+
|
|
36
|
+
if password != repeat_password:
|
|
37
|
+
click.echo("Passwords do not match!")
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
url = f"https://{network}/api/create_cell/{cell_type}"
|
|
41
|
+
|
|
42
|
+
create_cell = {"email": email, "password": password}
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
response = requests.post(url, json=create_cell)
|
|
46
|
+
response.raise_for_status()
|
|
47
|
+
status = response.json()["status"]
|
|
48
|
+
|
|
49
|
+
except requests.exceptions.RequestException as e:
|
|
50
|
+
click.echo(f"Error sending request: {e}")
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
if status == True:
|
|
54
|
+
host = response.json()["host"]
|
|
55
|
+
cellkey = click.prompt(f"Please verify your email address with the Cell Key send to {email}")
|
|
56
|
+
|
|
57
|
+
url = f"https://{network}/api/verify_email"
|
|
58
|
+
|
|
59
|
+
verify_email = {"host": host, "email": email, "cellkey": cellkey}
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
response = requests.post(url, json=verify_email)
|
|
63
|
+
response.raise_for_status()
|
|
64
|
+
status = response.json()["status"]
|
|
65
|
+
|
|
66
|
+
except requests.exceptions.RequestException as e:
|
|
67
|
+
click.echo(f"Error sending request: {e}")
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
if status == True:
|
|
71
|
+
synapse = response.json()["synapse"]
|
|
72
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
73
|
+
credentials_folder_path.mkdir(parents=True, exist_ok=True)
|
|
74
|
+
|
|
75
|
+
env_path = credentials_folder_path / ".env"
|
|
76
|
+
env_path.write_text(f"HOST={host}\nPASSWORD={password}\nNETWORK={network}\nSYNAPSE={synapse}\n")
|
|
77
|
+
|
|
78
|
+
click.echo(f"Welcome to Neuronum! Community Cell '{host}' created and connected!")
|
|
79
|
+
|
|
80
|
+
if status == False:
|
|
81
|
+
click.echo(f"Error:'{email}' already assigned!")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@click.command()
|
|
86
|
+
def connect_cell():
|
|
87
|
+
email = click.prompt("Enter your Email")
|
|
88
|
+
password = click.prompt("Enter password", hide_input=True)
|
|
89
|
+
|
|
90
|
+
network = questionary.select(
|
|
91
|
+
"Choose Network:",
|
|
92
|
+
choices=["neuronum.net"]
|
|
93
|
+
).ask()
|
|
94
|
+
|
|
95
|
+
url = f"https://{network}/api/connect_cell"
|
|
96
|
+
payload = {"email": email, "password": password}
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
response = requests.post(url, json=payload)
|
|
100
|
+
response.raise_for_status()
|
|
101
|
+
status = response.json()["status"]
|
|
102
|
+
host = response.json()["host"]
|
|
103
|
+
except requests.exceptions.RequestException as e:
|
|
104
|
+
click.echo(f"Error connecting: {e}")
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
if status == True:
|
|
108
|
+
cellkey = click.prompt(f"Please verify your email address with the Cell Key send to {email}")
|
|
109
|
+
url = f"https://{network}/api/verify_email"
|
|
110
|
+
verify_email = {"host": host, "email": email, "cellkey": cellkey}
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
response = requests.post(url, json=verify_email)
|
|
114
|
+
response.raise_for_status()
|
|
115
|
+
status = response.json()["status"]
|
|
116
|
+
synapse = response.json()["synapse"]
|
|
117
|
+
|
|
118
|
+
except requests.exceptions.RequestException as e:
|
|
119
|
+
click.echo(f"Error sending request: {e}")
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
if status == True:
|
|
123
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
124
|
+
credentials_folder_path.mkdir(parents=True, exist_ok=True)
|
|
125
|
+
|
|
126
|
+
env_path = credentials_folder_path / f".env"
|
|
127
|
+
env_path.write_text(f"HOST={host}\nPASSWORD={password}\nNETWORK={network}\nSYNAPSE={synapse}\n")
|
|
128
|
+
|
|
129
|
+
click.echo(f"Cell '{host}' connected!")
|
|
130
|
+
else:
|
|
131
|
+
click.echo(f"Connection failed!")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@click.command()
|
|
135
|
+
def view_cell():
|
|
136
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
137
|
+
env_path = credentials_folder_path / ".env"
|
|
138
|
+
|
|
139
|
+
env_data = {}
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
with open(env_path, "r") as f:
|
|
143
|
+
for line in f:
|
|
144
|
+
key, value = line.strip().split("=")
|
|
145
|
+
env_data[key] = value
|
|
146
|
+
|
|
147
|
+
host = env_data.get("HOST", "")
|
|
148
|
+
|
|
149
|
+
except FileNotFoundError:
|
|
150
|
+
click.echo("Error: No credentials found. Please connect to a cell first.")
|
|
151
|
+
return
|
|
152
|
+
except Exception as e:
|
|
153
|
+
click.echo(f"Error reading .env file: {e}")
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
if host:
|
|
157
|
+
click.echo(f"Connected Cell: '{host}'")
|
|
158
|
+
else:
|
|
159
|
+
click.echo("No active cell connection found.")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@click.command()
|
|
163
|
+
def disconnect_cell():
|
|
164
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
165
|
+
env_path = credentials_folder_path / ".env"
|
|
166
|
+
|
|
167
|
+
env_data = {}
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
with open(env_path, "r") as f:
|
|
171
|
+
for line in f:
|
|
172
|
+
key, value = line.strip().split("=")
|
|
173
|
+
env_data[key] = value
|
|
174
|
+
|
|
175
|
+
host = env_data.get("HOST", "")
|
|
176
|
+
|
|
177
|
+
except FileNotFoundError:
|
|
178
|
+
click.echo("Error: .env with credentials not found")
|
|
179
|
+
return
|
|
180
|
+
except Exception as e:
|
|
181
|
+
click.echo(f"Error reading .env file: {e}")
|
|
182
|
+
return
|
|
183
|
+
|
|
184
|
+
if env_path.exists():
|
|
185
|
+
if click.confirm(f"Are you sure you want to disconnect Cell '{host}'?", default=True):
|
|
186
|
+
os.remove(env_path)
|
|
187
|
+
click.echo(f"'{host}' disconnected!")
|
|
188
|
+
else:
|
|
189
|
+
click.echo("Disconnect canceled.")
|
|
190
|
+
else:
|
|
191
|
+
click.echo(f"No Neuronum Cell connected!")
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@click.command()
|
|
195
|
+
def delete_cell():
|
|
196
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
197
|
+
env_path = credentials_folder_path / ".env"
|
|
198
|
+
|
|
199
|
+
env_data = {}
|
|
200
|
+
|
|
201
|
+
try:
|
|
202
|
+
with open(env_path, "r") as f:
|
|
203
|
+
for line in f:
|
|
204
|
+
key, value = line.strip().split("=")
|
|
205
|
+
env_data[key] = value
|
|
206
|
+
|
|
207
|
+
host = env_data.get("HOST", "")
|
|
208
|
+
password = env_data.get("PASSWORD", "")
|
|
209
|
+
network = env_data.get("NETWORK", "")
|
|
210
|
+
synapse = env_data.get("SYNAPSE", "")
|
|
211
|
+
|
|
212
|
+
except FileNotFoundError:
|
|
213
|
+
click.echo("Error: No cell connected. Connect Cell first to delete")
|
|
214
|
+
return
|
|
215
|
+
except Exception as e:
|
|
216
|
+
click.echo(f"Error reading .env file: {e}")
|
|
217
|
+
return
|
|
218
|
+
|
|
219
|
+
confirm = click.confirm(f" Are you sure you want to delete '{host}'?", default=True)
|
|
220
|
+
if not confirm:
|
|
221
|
+
click.echo("Deletion canceled.")
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
url = f"https://{network}/api/delete_cell"
|
|
225
|
+
payload = {"host": host, "password": password, "synapse": synapse}
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
response = requests.delete(url, json=payload)
|
|
229
|
+
response.raise_for_status()
|
|
230
|
+
status = response.json()["status"]
|
|
231
|
+
except requests.exceptions.RequestException as e:
|
|
232
|
+
click.echo(f"Error deleting cell: {e}")
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
if status == True:
|
|
236
|
+
env_path = credentials_folder_path / f"{host}.env"
|
|
237
|
+
if env_path.exists():
|
|
238
|
+
os.remove(env_path)
|
|
239
|
+
click.echo("Credentials deleted successfully!")
|
|
240
|
+
click.echo(f"Neuronum Cell '{host}' has been deleted!")
|
|
241
|
+
else:
|
|
242
|
+
click.echo(f"Neuronum Cell '{host}' deletion failed!")
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@click.command()
|
|
246
|
+
@click.option('--sync', default=None, help="Optional stream ID to generate the sync template.")
|
|
247
|
+
def init_node(sync):
|
|
18
248
|
|
|
19
249
|
node_type = questionary.select(
|
|
20
250
|
"Choose Node type:",
|
|
@@ -22,10 +252,31 @@ def init_node():
|
|
|
22
252
|
).ask()
|
|
23
253
|
|
|
24
254
|
descr = click.prompt("Node description (max. 25 characters)")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
255
|
+
|
|
256
|
+
stream = sync if sync else "n9gW3LxQcecI::stx"
|
|
257
|
+
|
|
258
|
+
credentials_folder_path = Path.home() / ".neuronum"
|
|
259
|
+
env_path = credentials_folder_path / ".env"
|
|
260
|
+
|
|
261
|
+
env_data = {}
|
|
262
|
+
|
|
263
|
+
try:
|
|
264
|
+
with open(env_path, "r") as f:
|
|
265
|
+
for line in f:
|
|
266
|
+
key, value = line.strip().split("=")
|
|
267
|
+
env_data[key] = value
|
|
268
|
+
|
|
269
|
+
host = env_data.get("HOST", "")
|
|
270
|
+
password = env_data.get("PASSWORD", "")
|
|
271
|
+
network = env_data.get("NETWORK", "")
|
|
272
|
+
synapse = env_data.get("SYNAPSE", "")
|
|
273
|
+
|
|
274
|
+
except FileNotFoundError:
|
|
275
|
+
click.echo("No cell connected. Connect your cell with command neuronum connect-cell")
|
|
276
|
+
return
|
|
277
|
+
except Exception as e:
|
|
278
|
+
click.echo(f"Error reading .env file: {e}")
|
|
279
|
+
return
|
|
29
280
|
|
|
30
281
|
cell = neuronum.Cell(
|
|
31
282
|
host=host,
|
|
@@ -38,6 +289,7 @@ def init_node():
|
|
|
38
289
|
ctx = cell.list_ctx()
|
|
39
290
|
stx = cell.list_stx()
|
|
40
291
|
contracts = cell.list_contracts()
|
|
292
|
+
nodes = cell.list_nodes()
|
|
41
293
|
|
|
42
294
|
url = f"https://{network}/api/init_node/{node_type}"
|
|
43
295
|
|
|
@@ -51,13 +303,16 @@ def init_node():
|
|
|
51
303
|
click.echo(f"Error sending request: {e}")
|
|
52
304
|
return
|
|
53
305
|
|
|
54
|
-
node_filename = "node"
|
|
306
|
+
node_filename = "node_" + nodeID.replace("::node", "")
|
|
55
307
|
project_path = Path(node_filename)
|
|
56
308
|
project_path.mkdir(exist_ok=True)
|
|
57
309
|
|
|
58
310
|
env_path = project_path / ".env"
|
|
59
311
|
env_path.write_text(f"NODE={nodeID}\nHOST={host}\nPASSWORD={password}\nNETWORK={network}\nSYNAPSE={synapse}\n")
|
|
60
312
|
|
|
313
|
+
gitignore_path = project_path / ".gitignore"
|
|
314
|
+
gitignore_path.write_text(f".env\n")
|
|
315
|
+
|
|
61
316
|
tx_path = project_path / "transmitters.json"
|
|
62
317
|
tx_path.write_text(json.dumps(tx, indent=4))
|
|
63
318
|
|
|
@@ -70,32 +325,34 @@ def init_node():
|
|
|
70
325
|
contracts_path = project_path / "contracts.json"
|
|
71
326
|
contracts_path.write_text(json.dumps(contracts, indent=4))
|
|
72
327
|
|
|
328
|
+
nodes_path = project_path / "nodes.json"
|
|
329
|
+
nodes_path.write_text(json.dumps(nodes, indent=4))
|
|
330
|
+
|
|
73
331
|
nodemd_path = project_path / "NODE.md"
|
|
74
332
|
nodemd_path.write_text("""\
|
|
75
|
-
|
|
333
|
+
## Use this NODE.md file to add instructions on how to interact with your node
|
|
76
334
|
""")
|
|
77
335
|
|
|
78
336
|
main_path = project_path / "main.py"
|
|
79
|
-
main_path.write_text("""\
|
|
337
|
+
main_path.write_text(f"""\
|
|
80
338
|
import neuronum
|
|
81
339
|
import os
|
|
82
340
|
from dotenv import load_dotenv
|
|
83
341
|
|
|
84
342
|
load_dotenv()
|
|
85
|
-
host = os.getenv("HOST")
|
|
343
|
+
host = os.getenv("HOST")
|
|
86
344
|
password = os.getenv("PASSWORD")
|
|
87
|
-
network = os.getenv("NETWORK")
|
|
88
|
-
synapse = os.getenv("SYNAPSE")
|
|
345
|
+
network = os.getenv("NETWORK")
|
|
346
|
+
synapse = os.getenv("SYNAPSE")
|
|
89
347
|
|
|
90
|
-
#set cell connection
|
|
91
348
|
cell = neuronum.Cell(
|
|
92
|
-
host=host,
|
|
93
|
-
password=password,
|
|
94
|
-
network=network,
|
|
95
|
-
synapse=synapse
|
|
349
|
+
host=host,
|
|
350
|
+
password=password,
|
|
351
|
+
network=network,
|
|
352
|
+
synapse=synapse
|
|
96
353
|
)
|
|
97
354
|
|
|
98
|
-
STX = "
|
|
355
|
+
STX = "{stream}"
|
|
99
356
|
stream = cell.sync(STX)
|
|
100
357
|
for operation in stream:
|
|
101
358
|
label = operation.get("label")
|
|
@@ -104,7 +361,7 @@ for operation in stream:
|
|
|
104
361
|
stxID = operation.get("stxID")
|
|
105
362
|
operator = operation.get("operator")
|
|
106
363
|
print(label, value, ts, stxID, operator)
|
|
107
|
-
|
|
364
|
+
""")
|
|
108
365
|
|
|
109
366
|
click.echo(f"Neuronum Node '{nodeID}' initialized!")
|
|
110
367
|
|
|
@@ -125,20 +382,19 @@ def start_node():
|
|
|
125
382
|
with open("node_pid.txt", "w") as f:
|
|
126
383
|
f.write(str(process.pid))
|
|
127
384
|
|
|
128
|
-
click.echo("
|
|
385
|
+
click.echo("Node started successfully!")
|
|
129
386
|
|
|
130
387
|
|
|
131
388
|
@click.command()
|
|
132
389
|
def stop_node():
|
|
133
|
-
"
|
|
134
|
-
click.echo("Stopping Neuronum Node...")
|
|
390
|
+
click.echo("Stopping Node...")
|
|
135
391
|
|
|
136
392
|
try:
|
|
137
393
|
with open("node_pid.txt", "r") as f:
|
|
138
394
|
pid = int(f.read().strip())
|
|
139
395
|
os.kill(pid, 9)
|
|
140
396
|
os.remove("node_pid.txt")
|
|
141
|
-
click.echo("
|
|
397
|
+
click.echo("Node stopped successfully!")
|
|
142
398
|
except FileNotFoundError:
|
|
143
399
|
click.echo("Error: No active node process found.")
|
|
144
400
|
except Exception as e:
|
|
@@ -147,10 +403,7 @@ def stop_node():
|
|
|
147
403
|
|
|
148
404
|
@click.command()
|
|
149
405
|
def register_node():
|
|
150
|
-
click.echo("Register Node")
|
|
151
|
-
|
|
152
406
|
env_data = {}
|
|
153
|
-
|
|
154
407
|
try:
|
|
155
408
|
with open(".env", "r") as f:
|
|
156
409
|
for line in f:
|
|
@@ -205,10 +458,7 @@ def register_node():
|
|
|
205
458
|
|
|
206
459
|
@click.command()
|
|
207
460
|
def update_node():
|
|
208
|
-
click.echo("Update Node")
|
|
209
|
-
|
|
210
461
|
env_data = {}
|
|
211
|
-
|
|
212
462
|
try:
|
|
213
463
|
with open(".env", "r") as f:
|
|
214
464
|
for line in f:
|
|
@@ -270,26 +520,26 @@ def update_node():
|
|
|
270
520
|
ctx = cell.list_ctx()
|
|
271
521
|
stx = cell.list_stx()
|
|
272
522
|
contracts = cell.list_contracts()
|
|
523
|
+
nodes = cell.list_nodes()
|
|
273
524
|
|
|
274
525
|
tx_path = Path("transmitters.json")
|
|
275
526
|
ctx_path = Path("circuits.json")
|
|
276
527
|
stx_path = Path("streams.json")
|
|
277
528
|
contracts_path = Path("contracts.json")
|
|
529
|
+
nodes_path = Path("nodes.json")
|
|
278
530
|
|
|
279
531
|
tx_path.write_text(json.dumps(tx, indent=4))
|
|
280
532
|
ctx_path.write_text(json.dumps(ctx, indent=4))
|
|
281
533
|
stx_path.write_text(json.dumps(stx, indent=4))
|
|
282
534
|
contracts_path.write_text(json.dumps(contracts, indent=4))
|
|
535
|
+
nodes_path.write_text(json.dumps(nodes, indent=4))
|
|
283
536
|
|
|
284
537
|
click.echo(f"Neuronum Node '{nodeID}' updated! Visit: {node_url}")
|
|
285
538
|
|
|
286
539
|
|
|
287
540
|
@click.command()
|
|
288
541
|
def delete_node():
|
|
289
|
-
click.echo("Delete Node")
|
|
290
|
-
|
|
291
542
|
env_data = {}
|
|
292
|
-
|
|
293
543
|
try:
|
|
294
544
|
with open(".env", "r") as f:
|
|
295
545
|
for line in f:
|
|
@@ -329,6 +579,11 @@ def delete_node():
|
|
|
329
579
|
click.echo(f"Neuronum Node '{nodeID}' deleted!")
|
|
330
580
|
|
|
331
581
|
|
|
582
|
+
cli.add_command(create_cell)
|
|
583
|
+
cli.add_command(connect_cell)
|
|
584
|
+
cli.add_command(view_cell)
|
|
585
|
+
cli.add_command(disconnect_cell)
|
|
586
|
+
cli.add_command(delete_cell)
|
|
332
587
|
cli.add_command(init_node)
|
|
333
588
|
cli.add_command(start_node)
|
|
334
589
|
cli.add_command(stop_node)
|
neuronum/neuronum.py
CHANGED
|
@@ -214,7 +214,7 @@ class Cell:
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
try:
|
|
217
|
-
response = requests.
|
|
217
|
+
response = requests.get(full_url, json=list_tx)
|
|
218
218
|
response.raise_for_status()
|
|
219
219
|
return response.json()["Transmitters"]
|
|
220
220
|
except requests.exceptions.RequestException as e:
|
|
@@ -231,7 +231,7 @@ class Cell:
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
try:
|
|
234
|
-
response = requests.
|
|
234
|
+
response = requests.get(full_url, json=list_ctx)
|
|
235
235
|
response.raise_for_status()
|
|
236
236
|
return response.json()["Circuits"]
|
|
237
237
|
except requests.exceptions.RequestException as e:
|
|
@@ -248,7 +248,7 @@ class Cell:
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
try:
|
|
251
|
-
response = requests.
|
|
251
|
+
response = requests.get(full_url, json=list_stx)
|
|
252
252
|
response.raise_for_status()
|
|
253
253
|
return response.json()["Streams"]
|
|
254
254
|
except requests.exceptions.RequestException as e:
|
|
@@ -257,21 +257,21 @@ class Cell:
|
|
|
257
257
|
print(f"Unexpected error: {e}")
|
|
258
258
|
|
|
259
259
|
|
|
260
|
-
def
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
260
|
+
def list_nodes(self):
|
|
261
|
+
full_url = f"https://{self.network}/api/list_nodes"
|
|
262
|
+
|
|
263
|
+
list_nodes = {
|
|
264
|
+
"cell": self.to_dict()
|
|
265
|
+
}
|
|
266
266
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
267
|
+
try:
|
|
268
|
+
response = requests.get(full_url, json=list_nodes)
|
|
269
|
+
response.raise_for_status()
|
|
270
|
+
return response.json()["Nodes"]
|
|
271
|
+
except requests.exceptions.RequestException as e:
|
|
272
|
+
print(f"Error sending request: {e}")
|
|
273
|
+
except Exception as e:
|
|
274
|
+
print(f"Unexpected error: {e}")
|
|
275
275
|
|
|
276
276
|
|
|
277
277
|
def store(self, label: str, data: dict, ctx: Optional[str] = None):
|
|
@@ -429,21 +429,21 @@ class Cell:
|
|
|
429
429
|
|
|
430
430
|
|
|
431
431
|
def sign_contract(self, contractID: str):
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
432
|
+
full_url = f"https://{self.network}/api/sign_contract"
|
|
433
|
+
|
|
434
|
+
sign_contract = {
|
|
435
|
+
"contractID": contractID,
|
|
436
|
+
"cell": self.to_dict()
|
|
437
|
+
}
|
|
438
438
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
439
|
+
try:
|
|
440
|
+
response = requests.post(full_url, json=sign_contract)
|
|
441
|
+
response.raise_for_status()
|
|
442
|
+
return response.json()["token"]
|
|
443
|
+
except requests.exceptions.RequestException as e:
|
|
444
|
+
print(f"Error sending request: {e}")
|
|
445
|
+
except Exception as e:
|
|
446
|
+
print(f"Unexpected error: {e}")
|
|
447
447
|
|
|
448
448
|
|
|
449
449
|
def validate_token(self, token: str, cp: str, contractID: str):
|
|
@@ -550,7 +550,7 @@ class Cell:
|
|
|
550
550
|
}
|
|
551
551
|
|
|
552
552
|
try:
|
|
553
|
-
response = requests.
|
|
553
|
+
response = requests.get(full_url, json=list_contracts)
|
|
554
554
|
response.raise_for_status()
|
|
555
555
|
return response.json()["Contracts"]
|
|
556
556
|
except requests.exceptions.RequestException as e:
|
|
@@ -559,7 +559,4 @@ class Cell:
|
|
|
559
559
|
print(f"Unexpected error: {e}")
|
|
560
560
|
|
|
561
561
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
562
|
__all__ = ['Cell']
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: neuronum
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.7.1
|
|
4
|
+
Summary: Official client library to interact with the Neuronum Network
|
|
5
5
|
Home-page: https://neuronum.net
|
|
6
6
|
Author: Neuronum Cybernetics
|
|
7
7
|
Author-email: welcome@neuronum.net
|
|
@@ -9,7 +9,7 @@ Project-URL: GitHub, https://github.com/neuronumcybernetics/neuronum
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: requests
|
|
@@ -22,75 +22,90 @@ Requires-Dist: python-dotenv
|
|
|
22
22
|
|
|
23
23
|
[](https://neuronum.net) [](https://github.com/neuronumcybernetics/neuronum)
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Build, deploy and automate serverless IoT connectivity with `Neuronum`
|
|
26
26
|
|
|
27
27
|
## Features
|
|
28
|
-
- **Cell**:
|
|
29
|
-
- **Nodes/Node-CLI**: Setup and manage Neuronum Nodes from the command line
|
|
28
|
+
- **Cells/Cell-CLI**: Create and manage Neuronum Cells from the command line
|
|
29
|
+
- **Nodes/Node-CLI**: Setup and manage Neuronum Nodes from the command line
|
|
30
30
|
- **Transmitters (TX)**: Automate economic data transfer
|
|
31
31
|
- **Circuits (CTX)**: Store data in Key-Value-Label databases
|
|
32
32
|
- **Streams (STX)**: Stream, synchronize and control data in real time
|
|
33
|
-
- **Contracts/Tokens**: Automate
|
|
34
|
-
|
|
33
|
+
- **Contracts/Tokens**: Automate services exchange and authorization between Cells and Nodes
|
|
35
34
|
|
|
36
35
|
### Installation
|
|
37
36
|
Install the Neuronum library using pip:
|
|
38
|
-
```
|
|
39
|
-
pip install neuronum
|
|
37
|
+
```sh
|
|
38
|
+
$ pip install neuronum
|
|
40
39
|
```
|
|
41
40
|
|
|
42
|
-
### Cell
|
|
43
|
-
To interact with the Network you
|
|
44
|
-
Create your Cell: [Create Cell](https://neuronum.net/createcell)
|
|
41
|
+
### Cells/Cell-CLI
|
|
42
|
+
To interact with the Neuronum Network, you must first create a Neuronum Cell
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
|
|
44
|
+
Create Cell:
|
|
45
|
+
```sh
|
|
46
|
+
$ neuronum create-cell
|
|
47
|
+
```
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
Connect Cell:
|
|
50
|
+
```sh
|
|
51
|
+
$ neuronum connect-cell
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
View connected Cell:
|
|
55
|
+
```sh
|
|
56
|
+
$ neuronum view-cell
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Disconnect Cell:
|
|
60
|
+
```sh
|
|
61
|
+
$ neuronum disconnect-cell
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Delete Cell:
|
|
65
|
+
```sh
|
|
66
|
+
$ neuronum delete-cell
|
|
57
67
|
```
|
|
58
68
|
|
|
59
69
|
### Nodes/Node-CLI
|
|
60
|
-
Neuronum Nodes are
|
|
70
|
+
Neuronum Nodes are soft- and hardware components that power the Neuronum Network, enabling seamless communication between Nodes and Cells
|
|
61
71
|
|
|
62
|
-
Initialize
|
|
63
|
-
```
|
|
64
|
-
|
|
72
|
+
Initialize a Node:
|
|
73
|
+
```sh
|
|
74
|
+
$ neuronum init-node # neuronum init-node --sync id::stx (optional)
|
|
65
75
|
```
|
|
66
76
|
|
|
67
|
-
Start
|
|
68
|
-
```
|
|
69
|
-
|
|
77
|
+
Start a Node:
|
|
78
|
+
```sh
|
|
79
|
+
$ neuronum start-node
|
|
70
80
|
```
|
|
71
81
|
|
|
72
|
-
Stop
|
|
73
|
-
```
|
|
74
|
-
|
|
82
|
+
Stop a Node:
|
|
83
|
+
```sh
|
|
84
|
+
$ neuronum stop-node
|
|
75
85
|
```
|
|
76
86
|
|
|
77
|
-
Register
|
|
78
|
-
```
|
|
79
|
-
|
|
87
|
+
Register a Node on the Neuronum Network:
|
|
88
|
+
```sh
|
|
89
|
+
$ neuronum register-node
|
|
80
90
|
```
|
|
81
91
|
|
|
82
|
-
Update
|
|
83
|
-
```
|
|
84
|
-
|
|
92
|
+
Update a Node:
|
|
93
|
+
```sh
|
|
94
|
+
$ neuronum update-node
|
|
85
95
|
```
|
|
86
96
|
|
|
87
|
-
Delete
|
|
88
|
-
```
|
|
89
|
-
|
|
97
|
+
Delete a Node:
|
|
98
|
+
```sh
|
|
99
|
+
$ neuronum delete-node
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
List Nodes your Cell can interact with:
|
|
103
|
+
```python
|
|
104
|
+
nodesList = cell.list_nodes() # list Nodes
|
|
90
105
|
```
|
|
91
106
|
|
|
92
107
|
### Transmitters (TX)
|
|
93
|
-
Transmitters (TX) are used to create predefined templates to receive and send data in a standardized format
|
|
108
|
+
Transmitters (TX) are used to create predefined templates to receive and send data in a standardized format
|
|
94
109
|
|
|
95
110
|
Create Transmitter (TX):
|
|
96
111
|
```python
|
|
@@ -283,15 +298,15 @@ stxList = cell.list_stx() # list Streams
|
|
|
283
298
|
```
|
|
284
299
|
|
|
285
300
|
### Contracts/Tokens
|
|
286
|
-
Contracts
|
|
301
|
+
Contracts are predefined token-based rules to automate service exchange and authorization between Cells and Nodes
|
|
287
302
|
|
|
288
303
|
Create a Contract:
|
|
289
304
|
```python
|
|
290
305
|
descr = "Test Contract" # short description (max 25 characters)
|
|
291
306
|
details = { # define token details
|
|
292
|
-
"price_in_eur":
|
|
293
|
-
"max_usage":
|
|
294
|
-
"validity_in_min":
|
|
307
|
+
"price_in_eur": False, # token price in EUR (int, float or False)
|
|
308
|
+
"max_usage": False, # max number of uses (int or False)
|
|
309
|
+
"validity_in_min": False # token expiration time in min (int, float or False)
|
|
295
310
|
}
|
|
296
311
|
partners = ["id::cell", "id::cell"]
|
|
297
312
|
contractID = cell.create_contract(descr, details, partners)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
cli/main.py,sha256=hjo8-q9M_DUm7_Xe2ynb6L6wIMq2jfWnlp1oH5tBQD4,17896
|
|
3
|
+
neuronum/__init__.py,sha256=Drsm263_w3_VWgl1YsKLUr8WwVodqV3TSjqpxLjyq_M,46
|
|
4
|
+
neuronum/neuronum.py,sha256=91lOreL7TeD8VWdDCtS2xu7MO34taI4HEYr-Lpv6L9Y,17019
|
|
5
|
+
neuronum-1.7.1.dist-info/LICENSE,sha256=UiZjNHiCyRP6WoZfbYQh9cv4JW96wIofKXmzBJrYSUk,1125
|
|
6
|
+
neuronum-1.7.1.dist-info/METADATA,sha256=nDYzJ4gJGP9ZGX_3S0EEVyE0j7e64td3HH9wUkOrsTw,13000
|
|
7
|
+
neuronum-1.7.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
8
|
+
neuronum-1.7.1.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
|
|
9
|
+
neuronum-1.7.1.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
|
|
10
|
+
neuronum-1.7.1.dist-info/RECORD,,
|
neuronum-1.6.0.dist-info/RECORD
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
cli/main.py,sha256=wD5wj2qy-VKwrx9CWoHbxmERSO1Z11B59oMJc49GM9E,9449
|
|
3
|
-
neuronum/__init__.py,sha256=Drsm263_w3_VWgl1YsKLUr8WwVodqV3TSjqpxLjyq_M,46
|
|
4
|
-
neuronum/neuronum.py,sha256=qJqYpVoKdUw0YOa7aMp85QSOflkn8R7sqF5dIlTkBe0,16993
|
|
5
|
-
neuronum-1.6.0.dist-info/LICENSE,sha256=UiZjNHiCyRP6WoZfbYQh9cv4JW96wIofKXmzBJrYSUk,1125
|
|
6
|
-
neuronum-1.6.0.dist-info/METADATA,sha256=BblXzU3CeyyrTzdEyj0K--RnillyBYhNi-61mao50HA,13089
|
|
7
|
-
neuronum-1.6.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
8
|
-
neuronum-1.6.0.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
|
|
9
|
-
neuronum-1.6.0.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
|
|
10
|
-
neuronum-1.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|