neuronum 1.5.0__py3-none-any.whl → 1.6.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/__init__.py +0 -0
- cli/main.py +341 -0
- neuronum/neuronum.py +150 -75
- {neuronum-1.5.0.dist-info → neuronum-1.6.0.dist-info}/METADATA +165 -99
- neuronum-1.6.0.dist-info/RECORD +10 -0
- neuronum-1.6.0.dist-info/entry_points.txt +2 -0
- {neuronum-1.5.0.dist-info → neuronum-1.6.0.dist-info}/top_level.txt +1 -0
- neuronum-1.5.0.dist-info/RECORD +0 -7
- {neuronum-1.5.0.dist-info → neuronum-1.6.0.dist-info}/LICENSE +0 -0
- {neuronum-1.5.0.dist-info → neuronum-1.6.0.dist-info}/WHEEL +0 -0
cli/__init__.py
ADDED
|
File without changes
|
cli/main.py
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import questionary
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import requests
|
|
5
|
+
import subprocess
|
|
6
|
+
import os
|
|
7
|
+
import neuronum
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
@click.group()
|
|
11
|
+
def cli():
|
|
12
|
+
"""Neuronum CLI Tool"""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@click.command()
|
|
16
|
+
def init_node():
|
|
17
|
+
click.echo("Initialize Node")
|
|
18
|
+
|
|
19
|
+
node_type = questionary.select(
|
|
20
|
+
"Choose Node type:",
|
|
21
|
+
choices=["public", "private"]
|
|
22
|
+
).ask()
|
|
23
|
+
|
|
24
|
+
descr = click.prompt("Node description (max. 25 characters)")
|
|
25
|
+
host = click.prompt("Enter your cell host")
|
|
26
|
+
password = click.prompt("Enter your password", hide_input=True)
|
|
27
|
+
network = click.prompt("Enter your network")
|
|
28
|
+
synapse = click.prompt("Enter your synapse", hide_input=True)
|
|
29
|
+
|
|
30
|
+
cell = neuronum.Cell(
|
|
31
|
+
host=host,
|
|
32
|
+
password=password,
|
|
33
|
+
network=network,
|
|
34
|
+
synapse=synapse
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
tx = cell.list_tx()
|
|
38
|
+
ctx = cell.list_ctx()
|
|
39
|
+
stx = cell.list_stx()
|
|
40
|
+
contracts = cell.list_contracts()
|
|
41
|
+
|
|
42
|
+
url = f"https://{network}/api/init_node/{node_type}"
|
|
43
|
+
|
|
44
|
+
node = {"descr": descr, "host": host, "password": password, "synapse": synapse}
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
response = requests.post(url, json=node)
|
|
48
|
+
response.raise_for_status()
|
|
49
|
+
nodeID = response.json()["nodeID"]
|
|
50
|
+
except requests.exceptions.RequestException as e:
|
|
51
|
+
click.echo(f"Error sending request: {e}")
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
node_filename = "node"
|
|
55
|
+
project_path = Path(node_filename)
|
|
56
|
+
project_path.mkdir(exist_ok=True)
|
|
57
|
+
|
|
58
|
+
env_path = project_path / ".env"
|
|
59
|
+
env_path.write_text(f"NODE={nodeID}\nHOST={host}\nPASSWORD={password}\nNETWORK={network}\nSYNAPSE={synapse}\n")
|
|
60
|
+
|
|
61
|
+
tx_path = project_path / "transmitters.json"
|
|
62
|
+
tx_path.write_text(json.dumps(tx, indent=4))
|
|
63
|
+
|
|
64
|
+
ctx_path = project_path / "circuits.json"
|
|
65
|
+
ctx_path.write_text(json.dumps(ctx, indent=4))
|
|
66
|
+
|
|
67
|
+
stx_path = project_path / "streams.json"
|
|
68
|
+
stx_path.write_text(json.dumps(stx, indent=4))
|
|
69
|
+
|
|
70
|
+
contracts_path = project_path / "contracts.json"
|
|
71
|
+
contracts_path.write_text(json.dumps(contracts, indent=4))
|
|
72
|
+
|
|
73
|
+
nodemd_path = project_path / "NODE.md"
|
|
74
|
+
nodemd_path.write_text("""\
|
|
75
|
+
#some markdown
|
|
76
|
+
""")
|
|
77
|
+
|
|
78
|
+
main_path = project_path / "main.py"
|
|
79
|
+
main_path.write_text("""\
|
|
80
|
+
import neuronum
|
|
81
|
+
import os
|
|
82
|
+
from dotenv import load_dotenv
|
|
83
|
+
|
|
84
|
+
load_dotenv()
|
|
85
|
+
host = os.getenv("HOST")
|
|
86
|
+
password = os.getenv("PASSWORD")
|
|
87
|
+
network = os.getenv("NETWORK")
|
|
88
|
+
synapse = os.getenv("SYNAPSE")
|
|
89
|
+
|
|
90
|
+
#set cell connection
|
|
91
|
+
cell = neuronum.Cell(
|
|
92
|
+
host=host,
|
|
93
|
+
password=password,
|
|
94
|
+
network=network,
|
|
95
|
+
synapse=synapse
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
STX = "n9gW3LxQcecI::stx"
|
|
99
|
+
stream = cell.sync(STX)
|
|
100
|
+
for operation in stream:
|
|
101
|
+
label = operation.get("label")
|
|
102
|
+
value = operation.get("data").get("message")
|
|
103
|
+
ts = operation.get("time")
|
|
104
|
+
stxID = operation.get("stxID")
|
|
105
|
+
operator = operation.get("operator")
|
|
106
|
+
print(label, value, ts, stxID, operator)
|
|
107
|
+
""")
|
|
108
|
+
|
|
109
|
+
click.echo(f"Neuronum Node '{nodeID}' initialized!")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@click.command()
|
|
113
|
+
def start_node():
|
|
114
|
+
click.echo("Starting Node...")
|
|
115
|
+
|
|
116
|
+
project_path = Path.cwd()
|
|
117
|
+
main_file = project_path / "main.py"
|
|
118
|
+
|
|
119
|
+
if not main_file.exists():
|
|
120
|
+
click.echo("Error: main.py not found. Make sure the node is set up.")
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
process = subprocess.Popen(["python", str(main_file)], start_new_session=True)
|
|
124
|
+
|
|
125
|
+
with open("node_pid.txt", "w") as f:
|
|
126
|
+
f.write(str(process.pid))
|
|
127
|
+
|
|
128
|
+
click.echo("Neuronum Node started successfully!")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@click.command()
|
|
132
|
+
def stop_node():
|
|
133
|
+
"""Stops the Neuronum node"""
|
|
134
|
+
click.echo("Stopping Neuronum Node...")
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
with open("node_pid.txt", "r") as f:
|
|
138
|
+
pid = int(f.read().strip())
|
|
139
|
+
os.kill(pid, 9)
|
|
140
|
+
os.remove("node_pid.txt")
|
|
141
|
+
click.echo("Neuronum Node stopped successfully!")
|
|
142
|
+
except FileNotFoundError:
|
|
143
|
+
click.echo("Error: No active node process found.")
|
|
144
|
+
except Exception as e:
|
|
145
|
+
click.echo(f"Error stopping node: {e}")
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@click.command()
|
|
149
|
+
def register_node():
|
|
150
|
+
click.echo("Register Node")
|
|
151
|
+
|
|
152
|
+
env_data = {}
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
with open(".env", "r") as f:
|
|
156
|
+
for line in f:
|
|
157
|
+
key, value = line.strip().split("=")
|
|
158
|
+
env_data[key] = value
|
|
159
|
+
|
|
160
|
+
nodeID = env_data.get("NODE", "")
|
|
161
|
+
host = env_data.get("HOST", "")
|
|
162
|
+
password = env_data.get("PASSWORD", "")
|
|
163
|
+
network = env_data.get("NETWORK", "")
|
|
164
|
+
synapse = env_data.get("SYNAPSE", "")
|
|
165
|
+
|
|
166
|
+
except FileNotFoundError:
|
|
167
|
+
print("Error: .env with credentials not found")
|
|
168
|
+
return
|
|
169
|
+
except Exception as e:
|
|
170
|
+
print(f"Error reading .env file: {e}")
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
with open("NODE.md", "r") as f:
|
|
175
|
+
nodemd_file = f.read()
|
|
176
|
+
|
|
177
|
+
except FileNotFoundError:
|
|
178
|
+
print("Error: NODE.md file not found")
|
|
179
|
+
return
|
|
180
|
+
except Exception as e:
|
|
181
|
+
print(f"Error reading NODE.md file: {e}")
|
|
182
|
+
return
|
|
183
|
+
|
|
184
|
+
url = f"https://{network}/api/register_node"
|
|
185
|
+
|
|
186
|
+
node = {
|
|
187
|
+
"nodeID": nodeID,
|
|
188
|
+
"host": host,
|
|
189
|
+
"password": password,
|
|
190
|
+
"synapse": synapse,
|
|
191
|
+
"nodemd_file": nodemd_file
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
response = requests.post(url, json=node)
|
|
196
|
+
response.raise_for_status()
|
|
197
|
+
nodeID = response.json()["nodeID"]
|
|
198
|
+
node_url = response.json()["node_url"]
|
|
199
|
+
except requests.exceptions.RequestException as e:
|
|
200
|
+
click.echo(f"Error sending request: {e}")
|
|
201
|
+
return
|
|
202
|
+
|
|
203
|
+
click.echo(f"Neuronum Node '{nodeID}' registered! Visit: {node_url}")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@click.command()
|
|
207
|
+
def update_node():
|
|
208
|
+
click.echo("Update Node")
|
|
209
|
+
|
|
210
|
+
env_data = {}
|
|
211
|
+
|
|
212
|
+
try:
|
|
213
|
+
with open(".env", "r") as f:
|
|
214
|
+
for line in f:
|
|
215
|
+
key, value = line.strip().split("=")
|
|
216
|
+
env_data[key] = value
|
|
217
|
+
|
|
218
|
+
nodeID = env_data.get("NODE", "")
|
|
219
|
+
host = env_data.get("HOST", "")
|
|
220
|
+
password = env_data.get("PASSWORD", "")
|
|
221
|
+
network = env_data.get("NETWORK", "")
|
|
222
|
+
synapse = env_data.get("SYNAPSE", "")
|
|
223
|
+
|
|
224
|
+
except FileNotFoundError:
|
|
225
|
+
print("Error: .env with credentials not found")
|
|
226
|
+
return
|
|
227
|
+
except Exception as e:
|
|
228
|
+
print(f"Error reading .env file: {e}")
|
|
229
|
+
return
|
|
230
|
+
|
|
231
|
+
try:
|
|
232
|
+
with open("NODE.md", "r") as f:
|
|
233
|
+
nodemd_file = f.read()
|
|
234
|
+
|
|
235
|
+
except FileNotFoundError:
|
|
236
|
+
print("Error: NODE.md file not found")
|
|
237
|
+
return
|
|
238
|
+
except Exception as e:
|
|
239
|
+
print(f"Error reading NODE.md file: {e}")
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
url = f"https://{network}/api/update_node"
|
|
243
|
+
|
|
244
|
+
node = {
|
|
245
|
+
"nodeID": nodeID,
|
|
246
|
+
"host": host,
|
|
247
|
+
"password": password,
|
|
248
|
+
"synapse": synapse,
|
|
249
|
+
"nodemd_file": nodemd_file
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
try:
|
|
253
|
+
response = requests.post(url, json=node)
|
|
254
|
+
response.raise_for_status()
|
|
255
|
+
nodeID = response.json()["nodeID"]
|
|
256
|
+
node_url = response.json()["node_url"]
|
|
257
|
+
except requests.exceptions.RequestException as e:
|
|
258
|
+
click.echo(f"Error sending request: {e}")
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
cell = neuronum.Cell(
|
|
263
|
+
host=host,
|
|
264
|
+
password=password,
|
|
265
|
+
network=network,
|
|
266
|
+
synapse=synapse
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
tx = cell.list_tx()
|
|
270
|
+
ctx = cell.list_ctx()
|
|
271
|
+
stx = cell.list_stx()
|
|
272
|
+
contracts = cell.list_contracts()
|
|
273
|
+
|
|
274
|
+
tx_path = Path("transmitters.json")
|
|
275
|
+
ctx_path = Path("circuits.json")
|
|
276
|
+
stx_path = Path("streams.json")
|
|
277
|
+
contracts_path = Path("contracts.json")
|
|
278
|
+
|
|
279
|
+
tx_path.write_text(json.dumps(tx, indent=4))
|
|
280
|
+
ctx_path.write_text(json.dumps(ctx, indent=4))
|
|
281
|
+
stx_path.write_text(json.dumps(stx, indent=4))
|
|
282
|
+
contracts_path.write_text(json.dumps(contracts, indent=4))
|
|
283
|
+
|
|
284
|
+
click.echo(f"Neuronum Node '{nodeID}' updated! Visit: {node_url}")
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
@click.command()
|
|
288
|
+
def delete_node():
|
|
289
|
+
click.echo("Delete Node")
|
|
290
|
+
|
|
291
|
+
env_data = {}
|
|
292
|
+
|
|
293
|
+
try:
|
|
294
|
+
with open(".env", "r") as f:
|
|
295
|
+
for line in f:
|
|
296
|
+
key, value = line.strip().split("=")
|
|
297
|
+
env_data[key] = value
|
|
298
|
+
|
|
299
|
+
nodeID = env_data.get("NODE", "")
|
|
300
|
+
host = env_data.get("HOST", "")
|
|
301
|
+
password = env_data.get("PASSWORD", "")
|
|
302
|
+
network = env_data.get("NETWORK", "")
|
|
303
|
+
synapse = env_data.get("SYNAPSE", "")
|
|
304
|
+
|
|
305
|
+
except FileNotFoundError:
|
|
306
|
+
print("Error: .env with credentials not found")
|
|
307
|
+
return
|
|
308
|
+
except Exception as e:
|
|
309
|
+
print(f"Error reading .env file: {e}")
|
|
310
|
+
return
|
|
311
|
+
|
|
312
|
+
url = f"https://{network}/api/delete_node"
|
|
313
|
+
|
|
314
|
+
node = {
|
|
315
|
+
"nodeID": nodeID,
|
|
316
|
+
"host": host,
|
|
317
|
+
"password": password,
|
|
318
|
+
"synapse": synapse
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
try:
|
|
322
|
+
response = requests.post(url, json=node)
|
|
323
|
+
response.raise_for_status()
|
|
324
|
+
nodeID = response.json()["nodeID"]
|
|
325
|
+
except requests.exceptions.RequestException as e:
|
|
326
|
+
click.echo(f"Error sending request: {e}")
|
|
327
|
+
return
|
|
328
|
+
|
|
329
|
+
click.echo(f"Neuronum Node '{nodeID}' deleted!")
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
cli.add_command(init_node)
|
|
333
|
+
cli.add_command(start_node)
|
|
334
|
+
cli.add_command(stop_node)
|
|
335
|
+
cli.add_command(register_node)
|
|
336
|
+
cli.add_command(update_node)
|
|
337
|
+
cli.add_command(delete_node)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
if __name__ == "__main__":
|
|
341
|
+
cli()
|
neuronum/neuronum.py
CHANGED
|
@@ -32,13 +32,13 @@ class Cell:
|
|
|
32
32
|
return "Authentication successful" in response
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def create_tx(self, descr: str, key_values: dict,
|
|
35
|
+
def create_tx(self, descr: str, key_values: dict, stx: str, label: str, partners: list):
|
|
36
36
|
url = f"https://{self.network}/api/create_tx"
|
|
37
37
|
|
|
38
38
|
TX = {
|
|
39
39
|
"descr": descr,
|
|
40
40
|
"key_values": key_values,
|
|
41
|
-
"
|
|
41
|
+
"stx": stx,
|
|
42
42
|
"label": label,
|
|
43
43
|
"partners": partners,
|
|
44
44
|
"cell": self.to_dict()
|
|
@@ -206,108 +206,51 @@ class Cell:
|
|
|
206
206
|
print(f"Unexpected error: {e}")
|
|
207
207
|
|
|
208
208
|
|
|
209
|
-
def
|
|
210
|
-
if mode == "public":
|
|
211
|
-
url = f"https://{self.network}/api/register_node/public"
|
|
212
|
-
elif mode == "private":
|
|
213
|
-
url = f"https://{self.network}/api/register_node/private"
|
|
214
|
-
else:
|
|
215
|
-
return {"error": "Invalid mode", "message": "Mode has to be 'public' or 'private'"}
|
|
216
|
-
|
|
217
|
-
node_data = {
|
|
218
|
-
"descr": descr,
|
|
219
|
-
"mode": mode,
|
|
220
|
-
"stream": stx,
|
|
221
|
-
"cell": self.to_dict()
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
try:
|
|
225
|
-
response = requests.post(
|
|
226
|
-
url,
|
|
227
|
-
json=node_data,
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
response.raise_for_status()
|
|
231
|
-
|
|
232
|
-
return response.json()["nodeID"]
|
|
233
|
-
|
|
234
|
-
except requests.exceptions.RequestException as e:
|
|
235
|
-
print(f"Error sending request: {e}")
|
|
236
|
-
except Exception as e:
|
|
237
|
-
print(f"Unexpected error: {e}")
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
def delete_node(self, nodeID: str):
|
|
241
|
-
url = f"https://{self.network}/api/delete_node"
|
|
242
|
-
|
|
243
|
-
delete_node = {
|
|
244
|
-
"nodeID": nodeID,
|
|
245
|
-
"cell": self.to_dict()
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
try:
|
|
249
|
-
response = requests.post(
|
|
250
|
-
url,
|
|
251
|
-
json=delete_node,
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
response.raise_for_status()
|
|
255
|
-
print(response.json())
|
|
256
|
-
|
|
257
|
-
except requests.exceptions.RequestException as e:
|
|
258
|
-
print(f"Error sending request: {e}")
|
|
259
|
-
except Exception as e:
|
|
260
|
-
print(f"Unexpected error: {e}")
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
def list_tx(self, cellID: str):
|
|
209
|
+
def list_tx(self):
|
|
264
210
|
full_url = f"https://{self.network}/api/list_tx"
|
|
265
211
|
|
|
266
212
|
list_tx = {
|
|
267
|
-
"cell": self.to_dict()
|
|
268
|
-
"cellID": cellID
|
|
213
|
+
"cell": self.to_dict()
|
|
269
214
|
}
|
|
270
215
|
|
|
271
216
|
try:
|
|
272
217
|
response = requests.post(full_url, json=list_tx)
|
|
273
218
|
response.raise_for_status()
|
|
274
|
-
return response.json()
|
|
219
|
+
return response.json()["Transmitters"]
|
|
275
220
|
except requests.exceptions.RequestException as e:
|
|
276
221
|
print(f"Error sending request: {e}")
|
|
277
222
|
except Exception as e:
|
|
278
223
|
print(f"Unexpected error: {e}")
|
|
279
224
|
|
|
280
225
|
|
|
281
|
-
def list_ctx(self
|
|
226
|
+
def list_ctx(self):
|
|
282
227
|
full_url = f"https://{self.network}/api/list_ctx"
|
|
283
228
|
|
|
284
229
|
list_ctx = {
|
|
285
|
-
"cell": self.to_dict()
|
|
286
|
-
"cellID": cellID
|
|
230
|
+
"cell": self.to_dict()
|
|
287
231
|
}
|
|
288
232
|
|
|
289
233
|
try:
|
|
290
234
|
response = requests.post(full_url, json=list_ctx)
|
|
291
235
|
response.raise_for_status()
|
|
292
|
-
return response.json()
|
|
236
|
+
return response.json()["Circuits"]
|
|
293
237
|
except requests.exceptions.RequestException as e:
|
|
294
238
|
print(f"Error sending request: {e}")
|
|
295
239
|
except Exception as e:
|
|
296
240
|
print(f"Unexpected error: {e}")
|
|
297
241
|
|
|
298
242
|
|
|
299
|
-
def list_stx(self
|
|
243
|
+
def list_stx(self):
|
|
300
244
|
full_url = f"https://{self.network}/api/list_stx"
|
|
301
245
|
|
|
302
246
|
list_stx = {
|
|
303
|
-
"cell": self.to_dict()
|
|
304
|
-
"cellID": cellID
|
|
247
|
+
"cell": self.to_dict()
|
|
305
248
|
}
|
|
306
249
|
|
|
307
250
|
try:
|
|
308
251
|
response = requests.post(full_url, json=list_stx)
|
|
309
252
|
response.raise_for_status()
|
|
310
|
-
return response.json()
|
|
253
|
+
return response.json()["Streams"]
|
|
311
254
|
except requests.exceptions.RequestException as e:
|
|
312
255
|
print(f"Error sending request: {e}")
|
|
313
256
|
except Exception as e:
|
|
@@ -459,14 +402,13 @@ class Cell:
|
|
|
459
402
|
try:
|
|
460
403
|
ws = create_connection(f"wss://{self.network}/sync/{stx}")
|
|
461
404
|
ws.send(json.dumps(auth))
|
|
462
|
-
print("
|
|
405
|
+
print("Listening to Stream...")
|
|
463
406
|
|
|
464
407
|
try:
|
|
465
408
|
while True:
|
|
466
409
|
try:
|
|
467
410
|
raw_operation = ws.recv()
|
|
468
411
|
operation = json.loads(raw_operation)
|
|
469
|
-
print("Listening to Stream...")
|
|
470
412
|
yield operation
|
|
471
413
|
|
|
472
414
|
except socket.timeout:
|
|
@@ -474,17 +416,150 @@ class Cell:
|
|
|
474
416
|
continue
|
|
475
417
|
|
|
476
418
|
except KeyboardInterrupt:
|
|
477
|
-
print("Stream-Synchronization ended!")
|
|
478
|
-
except Exception as e:
|
|
479
|
-
print(f"Error: {e}")
|
|
480
|
-
finally:
|
|
481
419
|
ws.close()
|
|
482
420
|
print("Connection closed.")
|
|
483
|
-
|
|
421
|
+
except Exception as e:
|
|
422
|
+
print(f"Error: {e}")
|
|
423
|
+
|
|
424
|
+
|
|
484
425
|
except KeyboardInterrupt:
|
|
485
426
|
print("Stream-Synchronization ended!")
|
|
486
427
|
ws.close()
|
|
487
428
|
print("Connection closed. Goodbye!")
|
|
488
429
|
|
|
489
430
|
|
|
431
|
+
def sign_contract(self, contractID: str):
|
|
432
|
+
full_url = f"https://{self.network}/api/sign_contract"
|
|
433
|
+
|
|
434
|
+
sign_contract = {
|
|
435
|
+
"contractID": contractID,
|
|
436
|
+
"cell": self.to_dict()
|
|
437
|
+
}
|
|
438
|
+
|
|
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
|
+
|
|
448
|
+
|
|
449
|
+
def validate_token(self, token: str, cp: str, contractID: str):
|
|
450
|
+
full_url = f"https://{self.network}/api/validate_token"
|
|
451
|
+
|
|
452
|
+
validate = {
|
|
453
|
+
"token": token,
|
|
454
|
+
"cp": cp,
|
|
455
|
+
"contractID": contractID,
|
|
456
|
+
"cell": self.to_dict()
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
try:
|
|
460
|
+
response = requests.post(full_url, json=validate)
|
|
461
|
+
response.raise_for_status()
|
|
462
|
+
return response.json()["validity"]
|
|
463
|
+
except requests.exceptions.RequestException as e:
|
|
464
|
+
print(f"Error sending request: {e}")
|
|
465
|
+
except Exception as e:
|
|
466
|
+
print(f"Unexpected error: {e}")
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def request_token(self, cp: str, contractID: str):
|
|
470
|
+
full_url = f"https://{self.network}/api/request_token"
|
|
471
|
+
|
|
472
|
+
request_token = {
|
|
473
|
+
"cp": cp,
|
|
474
|
+
"contractID": contractID,
|
|
475
|
+
"cell": self.to_dict()
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
try:
|
|
479
|
+
response = requests.post(full_url, json=request_token)
|
|
480
|
+
response.raise_for_status()
|
|
481
|
+
print(response.json())
|
|
482
|
+
except requests.exceptions.RequestException as e:
|
|
483
|
+
print(f"Error sending request: {e}")
|
|
484
|
+
except Exception as e:
|
|
485
|
+
print(f"Unexpected error: {e}")
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
def present_token(self, token: str, cp: str, contractID: str):
|
|
489
|
+
full_url = f"https://{self.network}/api/present_token"
|
|
490
|
+
|
|
491
|
+
present_token = {
|
|
492
|
+
"token": token,
|
|
493
|
+
"cp": cp,
|
|
494
|
+
"contractID": contractID,
|
|
495
|
+
"cell": self.to_dict()
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
try:
|
|
499
|
+
response = requests.post(full_url, json=present_token)
|
|
500
|
+
response.raise_for_status()
|
|
501
|
+
print(response.json())
|
|
502
|
+
except requests.exceptions.RequestException as e:
|
|
503
|
+
print(f"Error sending request: {e}")
|
|
504
|
+
except Exception as e:
|
|
505
|
+
print(f"Unexpected error: {e}")
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def create_contract(self, descr: str, details: dict, partners: list):
|
|
509
|
+
full_url = f"https://{self.network}/api/create_contract"
|
|
510
|
+
|
|
511
|
+
create_contract = {
|
|
512
|
+
"cell": self.to_dict(),
|
|
513
|
+
"descr": descr,
|
|
514
|
+
"details": details,
|
|
515
|
+
"partners": partners
|
|
516
|
+
}
|
|
517
|
+
try:
|
|
518
|
+
response = requests.post(full_url, json=create_contract)
|
|
519
|
+
response.raise_for_status()
|
|
520
|
+
return response.json()["contractID"]
|
|
521
|
+
except requests.exceptions.RequestException as e:
|
|
522
|
+
print(f"Error sending request: {e}")
|
|
523
|
+
except Exception as e:
|
|
524
|
+
print(f"Unexpected error: {e}")
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
def delete_contract(self, contractID: str):
|
|
528
|
+
full_url = f"https://{self.network}/api/delete_contract"
|
|
529
|
+
|
|
530
|
+
request = {
|
|
531
|
+
"cell": self.to_dict(),
|
|
532
|
+
"contractID": contractID
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
try:
|
|
536
|
+
response = requests.post(full_url, json=request)
|
|
537
|
+
response.raise_for_status()
|
|
538
|
+
print(f"Response from Neuronum: {response.json()}")
|
|
539
|
+
except requests.exceptions.RequestException as e:
|
|
540
|
+
print(f"Error sending request: {e}")
|
|
541
|
+
except Exception as e:
|
|
542
|
+
print(f"Unexpected error: {e}")
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
def list_contracts(self):
|
|
546
|
+
full_url = f"https://{self.network}/api/list_contracts"
|
|
547
|
+
|
|
548
|
+
list_contracts = {
|
|
549
|
+
"cell": self.to_dict()
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
try:
|
|
553
|
+
response = requests.post(full_url, json=list_contracts)
|
|
554
|
+
response.raise_for_status()
|
|
555
|
+
return response.json()["Contracts"]
|
|
556
|
+
except requests.exceptions.RequestException as e:
|
|
557
|
+
print(f"Error sending request: {e}")
|
|
558
|
+
except Exception as e:
|
|
559
|
+
print(f"Unexpected error: {e}")
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
|
|
490
565
|
__all__ = ['Cell']
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: neuronum
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.0
|
|
4
4
|
Summary: Interact with the Neuronum Network to build & automate interconnected networks of soft- and hardware components
|
|
5
5
|
Home-page: https://neuronum.net
|
|
6
6
|
Author: Neuronum Cybernetics
|
|
@@ -14,172 +14,207 @@ Description-Content-Type: text/markdown
|
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: requests
|
|
16
16
|
Requires-Dist: websocket-client
|
|
17
|
-
Requires-Dist:
|
|
17
|
+
Requires-Dist: click
|
|
18
|
+
Requires-Dist: questionary
|
|
19
|
+
Requires-Dist: python-dotenv
|
|
18
20
|
|
|
19
21
|

|
|
20
22
|
|
|
21
|
-
[](https://neuronum.net)
|
|
22
|
-
[](https://github.com/neuronumcybernetics/neuronum)
|
|
23
|
-
[](https://www.youtube.com/@neuronumnet)
|
|
23
|
+
[](https://neuronum.net) [](https://github.com/neuronumcybernetics/neuronum)
|
|
24
24
|
|
|
25
25
|
`Neuronum` is a cybernetic framework enabling businesses to build & automate interconnected networks of soft- and hardware components
|
|
26
26
|
|
|
27
27
|
## Features
|
|
28
28
|
- **Cell**: Identity to connect and interact with the Neuronum Network
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
29
|
+
- **Nodes/Node-CLI**: Setup and manage Neuronum Nodes from the command line.
|
|
30
|
+
- **Transmitters (TX)**: Automate economic data transfer
|
|
31
|
+
- **Circuits (CTX)**: Store data in Key-Value-Label databases
|
|
31
32
|
- **Streams (STX)**: Stream, synchronize and control data in real time
|
|
32
|
-
- **
|
|
33
|
+
- **Contracts/Tokens**: Automate contract-based authorization between Nodes and Cells
|
|
33
34
|
|
|
34
|
-
To interact with the Network you will need to create a Neuronum Cell.
|
|
35
|
-
Create your Cell: [Create Cell](https://neuronum.net/createcell)
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
### Installation
|
|
37
|
+
Install the Neuronum library using pip:
|
|
38
38
|
```python
|
|
39
39
|
pip install neuronum
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
### Cell
|
|
43
|
+
To interact with the Network you will need to create a Neuronum Cell.
|
|
44
|
+
Create your Cell: [Create Cell](https://neuronum.net/createcell)
|
|
45
|
+
|
|
46
|
+
Set and test Cell connection:
|
|
43
47
|
```python
|
|
44
48
|
import neuronum
|
|
45
49
|
|
|
46
50
|
cell = neuronum.Cell(
|
|
47
|
-
host="host::cell",
|
|
48
|
-
password="your_password",
|
|
49
|
-
network="neuronum.net",
|
|
50
|
-
synapse="your_synapse"
|
|
51
|
+
host="host::cell", # cell host
|
|
52
|
+
password="your_password", # cell password
|
|
53
|
+
network="neuronum.net", # cell network
|
|
54
|
+
synapse="your_synapse" # cell synapse
|
|
51
55
|
)
|
|
52
|
-
cell.connect()
|
|
56
|
+
cell.connect() # connect to network
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Nodes/Node-CLI
|
|
60
|
+
Neuronum Nodes are computing hardware powered by the Neuronum library, enabling seamless communication between Nodes and Cells.
|
|
61
|
+
|
|
62
|
+
Initialize your Node:
|
|
63
|
+
```bash
|
|
64
|
+
>>> neuronum init-node
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Start your Node:
|
|
68
|
+
```bash
|
|
69
|
+
>>> neuronum start-node
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Stop your Node:
|
|
73
|
+
```bash
|
|
74
|
+
>>> neuronum stop-node
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Register your Node on the Neuronum Network:
|
|
78
|
+
```bash
|
|
79
|
+
>>> neuronum register-node
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Update your Node:
|
|
83
|
+
```bash
|
|
84
|
+
>>> neuronum update-node
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Delete your Node:
|
|
88
|
+
```bash
|
|
89
|
+
>>> neuronum delete-node
|
|
53
90
|
```
|
|
54
91
|
|
|
55
92
|
### Transmitters (TX)
|
|
56
|
-
Transmitters (TX) are used to create predefined templates to receive and send data in a standardized format.
|
|
93
|
+
Transmitters (TX) are used to create predefined templates to receive and send data in a standardized format.
|
|
57
94
|
|
|
58
95
|
Create Transmitter (TX):
|
|
59
96
|
```python
|
|
60
|
-
descr = "Test Transmitter"
|
|
61
|
-
key_values = {
|
|
97
|
+
descr = "Test Transmitter" # description (max 25 characters)
|
|
98
|
+
key_values = { # defined keys and example values
|
|
62
99
|
"key1": "value1",
|
|
63
100
|
"key2": "value2",
|
|
64
101
|
"key3": "value3",
|
|
65
102
|
}
|
|
66
|
-
|
|
67
|
-
label = "key1:key2"
|
|
68
|
-
partners = ["id::cell", "id::cell"]
|
|
69
|
-
txID = cell.create_tx(descr, key_values,
|
|
103
|
+
stx = "id::stx" # select Stream (STX)
|
|
104
|
+
label = "key1:key2" # label TX data
|
|
105
|
+
partners = ["id::cell", "id::cell"] # authorized Cells
|
|
106
|
+
txID = cell.create_tx(descr, key_values, stx, label, partners) # create TX
|
|
70
107
|
```
|
|
71
108
|
|
|
72
109
|
Activate Transmitter (TX):
|
|
73
110
|
```python
|
|
74
|
-
TX = "id::tx"
|
|
75
|
-
data = {
|
|
111
|
+
TX = "id::tx" # select Transmitter (TX)
|
|
112
|
+
data = { # enter key-values
|
|
76
113
|
"key1": "value1",
|
|
77
114
|
"key2": "value2",
|
|
78
115
|
"key3": "value3",
|
|
79
116
|
}
|
|
80
|
-
cell.activate_tx(TX, data)
|
|
117
|
+
cell.activate_tx(TX, data) # activate TX
|
|
81
118
|
```
|
|
82
119
|
|
|
83
120
|
Delete Transmitter (TX):
|
|
84
121
|
```python
|
|
85
|
-
TX = "id::tx"
|
|
86
|
-
cell.delete_tx(TX)
|
|
122
|
+
TX = "id::tx" # select Transmitter (TX)
|
|
123
|
+
cell.delete_tx(TX) # delete TX
|
|
87
124
|
```
|
|
88
125
|
|
|
89
|
-
List Transmitter (TX)
|
|
90
|
-
```python
|
|
91
|
-
|
|
92
|
-
txList = cell.list_tx(cellID) # list Transmitters (TX)
|
|
126
|
+
List Transmitter (TX) your Cell can activate:
|
|
127
|
+
```python
|
|
128
|
+
txList = cell.list_tx() # list Transmitters (TX)
|
|
93
129
|
```
|
|
94
130
|
|
|
95
131
|
### Circuits (CTX)
|
|
96
|
-
Circuits (CTX) store and organize data
|
|
132
|
+
Circuits (CTX) store and organize data using a Key-Value-Label system
|
|
97
133
|
|
|
98
134
|
Create Circuit (CTX):
|
|
99
135
|
```python
|
|
100
|
-
descr = "Test Circuit"
|
|
101
|
-
partners = ["id::cell", "id::cell"]
|
|
102
|
-
ctxID = cell.create_ctx(descr, partners)
|
|
136
|
+
descr = "Test Circuit" # description (max 25 characters)
|
|
137
|
+
partners = ["id::cell", "id::cell"] # authorized Cells
|
|
138
|
+
ctxID = cell.create_ctx(descr, partners) # create Circuit (CTX)
|
|
103
139
|
```
|
|
104
140
|
|
|
105
141
|
Store data on your private Circuit (CTX):
|
|
106
142
|
```python
|
|
107
|
-
label = "your_label"
|
|
108
|
-
data = {
|
|
143
|
+
label = "your_label" # data label (should be unique)
|
|
144
|
+
data = { # data as key-value pairs
|
|
109
145
|
"key1": "value1",
|
|
110
146
|
"key2": "value2",
|
|
111
147
|
"key3": "value3",
|
|
112
148
|
}
|
|
113
|
-
cell.store(label, data)
|
|
149
|
+
cell.store(label, data) # store data
|
|
114
150
|
```
|
|
115
151
|
|
|
116
152
|
Store data on a public Circuit (CTX):
|
|
117
153
|
```python
|
|
118
|
-
CTX = "id::ctx"
|
|
119
|
-
label = "your_label"
|
|
120
|
-
data = {
|
|
154
|
+
CTX = "id::ctx" # select Circuit (CTX
|
|
155
|
+
label = "your_label" # data label (should be unique)
|
|
156
|
+
data = { # data as key-value pairs
|
|
121
157
|
"key1": "value1",
|
|
122
158
|
"key2": "value2",
|
|
123
159
|
"key3": "value3",
|
|
124
160
|
}
|
|
125
|
-
cell.store(label, data, CTX)
|
|
161
|
+
cell.store(label, data, CTX) # store data
|
|
126
162
|
```
|
|
127
163
|
|
|
128
164
|
Load data from your private Circuit (CTX):
|
|
129
165
|
```python
|
|
130
|
-
label = "your_label"
|
|
131
|
-
data = cell.load(label)
|
|
132
|
-
key1 = data["key1"]
|
|
166
|
+
label = "your_label" # select label
|
|
167
|
+
data = cell.load(label) # load data by label
|
|
168
|
+
key1 = data["key1"] # get data from key
|
|
133
169
|
key2 = data["key2"]
|
|
134
170
|
key3 = data["key3"]
|
|
135
|
-
print(key1, key2, key3)
|
|
171
|
+
print(key1, key2, key3) # print data
|
|
136
172
|
```
|
|
137
173
|
|
|
138
174
|
Load data from a public Circuit (CTX):
|
|
139
175
|
```python
|
|
140
|
-
CTX = "id::ctx"
|
|
141
|
-
label = "your_label"
|
|
142
|
-
data = cell.load(label, CTX)
|
|
143
|
-
key1 = data["key1"]
|
|
176
|
+
CTX = "id::ctx" # select Circuit (CTX)
|
|
177
|
+
label = "your_label" # select label
|
|
178
|
+
data = cell.load(label, CTX) # load data by label
|
|
179
|
+
key1 = data["key1"] # get data from key
|
|
144
180
|
key2 = data["key2"]
|
|
145
181
|
key3 = data["key3"]
|
|
146
|
-
print(key1, key2, key3)
|
|
182
|
+
print(key1, key2, key3) # print data
|
|
147
183
|
```
|
|
148
184
|
|
|
149
185
|
Delete data from your private Circuit (CTX):
|
|
150
186
|
```python
|
|
151
|
-
label = "your_label"
|
|
152
|
-
cell.delete(label)
|
|
187
|
+
label = "your_label" # select label
|
|
188
|
+
cell.delete(label) # delete data by label
|
|
153
189
|
```
|
|
154
190
|
|
|
155
191
|
Delete data from a public Circuit (CTX):
|
|
156
192
|
```python
|
|
157
|
-
CTX = "id::ctx"
|
|
158
|
-
label = "your_label"
|
|
159
|
-
cell.delete(label, CTX)
|
|
193
|
+
CTX = "id::ctx" # select Circuits (CTX)
|
|
194
|
+
label = "your_label" # select label
|
|
195
|
+
cell.delete(label, CTX) # delete data by label
|
|
160
196
|
```
|
|
161
197
|
|
|
162
198
|
Clear your private Circuit (CTX):
|
|
163
199
|
```python
|
|
164
|
-
cell.clear()
|
|
200
|
+
cell.clear() # clear Circuit (CTX)
|
|
165
201
|
```
|
|
166
202
|
|
|
167
203
|
Clear Circuit (CTX):
|
|
168
204
|
```python
|
|
169
|
-
CTX = "id::ctx"
|
|
170
|
-
cell.clear(CTX)
|
|
205
|
+
CTX = "id::ctx" # select Circuit (CTX)
|
|
206
|
+
cell.clear(CTX) # clear CTX
|
|
171
207
|
```
|
|
172
208
|
|
|
173
209
|
Delete Circuit (CTX):
|
|
174
210
|
```python
|
|
175
|
-
CTX = "id::ctx"
|
|
176
|
-
cell.delete_ctx(CTX)
|
|
211
|
+
CTX = "id::ctx" # select Circuit (CTX)
|
|
212
|
+
cell.delete_ctx(CTX) # delete CTX
|
|
177
213
|
```
|
|
178
214
|
|
|
179
|
-
List Circuits (CTX)
|
|
180
|
-
```python
|
|
181
|
-
|
|
182
|
-
ctxList = cell.list_ctx(cellID) # list Circuits (CTX)
|
|
215
|
+
List Circuits (CTX) your Cell can interact with:
|
|
216
|
+
```python
|
|
217
|
+
ctxList = cell.list_ctx() # list Circuits (CTX)
|
|
183
218
|
```
|
|
184
219
|
|
|
185
220
|
### Streams (STX)
|
|
@@ -187,39 +222,39 @@ Streams (STX) facilitate real-time data synchronization and interaction, ensurin
|
|
|
187
222
|
|
|
188
223
|
Create Stream (STX):
|
|
189
224
|
```python
|
|
190
|
-
descr = "Test Stream"
|
|
191
|
-
partners = ["id::cell", "id::cell"]
|
|
192
|
-
stxID = cell.create_stx(descr, partners)
|
|
225
|
+
descr = "Test Stream" # description (max 25 characters)
|
|
226
|
+
partners = ["id::cell", "id::cell"] # authorized Cells
|
|
227
|
+
stxID = cell.create_stx(descr, partners) # create Stream (STX)
|
|
193
228
|
```
|
|
194
229
|
|
|
195
230
|
Stream data to your private Stream (STX):
|
|
196
231
|
```python
|
|
197
|
-
label = "your_label"
|
|
198
|
-
data = {
|
|
232
|
+
label = "your_label" # data label
|
|
233
|
+
data = { # data as key-value pairs
|
|
199
234
|
"key1": "value1",
|
|
200
235
|
"key2": "value2",
|
|
201
236
|
"key3": "value3",
|
|
202
237
|
}
|
|
203
|
-
cell.stream(label, data)
|
|
238
|
+
cell.stream(label, data) # stream data
|
|
204
239
|
```
|
|
205
240
|
|
|
206
241
|
Stream data to a public Stream (STX):
|
|
207
242
|
```python
|
|
208
|
-
STX = "id::stx"
|
|
209
|
-
label = "your_label"
|
|
210
|
-
data = {
|
|
243
|
+
STX = "id::stx" # select Stream (STX)
|
|
244
|
+
label = "your_label" # data label
|
|
245
|
+
data = { # data as key-value pairs
|
|
211
246
|
"key1": "value1",
|
|
212
247
|
"key2": "value2",
|
|
213
248
|
"key3": "value3",
|
|
214
249
|
}
|
|
215
|
-
cell.stream(label, data, STX)
|
|
250
|
+
cell.stream(label, data, STX) # stream data
|
|
216
251
|
```
|
|
217
252
|
|
|
218
253
|
Sync data from your private Stream (STX):
|
|
219
254
|
```python
|
|
220
|
-
stream = cell.sync()
|
|
221
|
-
for operation in stream:
|
|
222
|
-
label = operation.get("label")
|
|
255
|
+
stream = cell.sync() # synchronize Stream (STX)
|
|
256
|
+
for operation in stream: # load stream operations
|
|
257
|
+
label = operation.get("label") # get the operation details by key
|
|
223
258
|
key1 = operation.get("data").get("key1")
|
|
224
259
|
key2 = operation.get("data").get("key2")
|
|
225
260
|
key3 = operation.get("data").get("key3")
|
|
@@ -230,10 +265,10 @@ for operation in stream: # load s
|
|
|
230
265
|
|
|
231
266
|
Sync data from a public Stream (STX):
|
|
232
267
|
```python
|
|
233
|
-
STX = "id::stx"
|
|
234
|
-
stream = cell.sync(STX)
|
|
235
|
-
for operation in stream:
|
|
236
|
-
label = operation.get("label")
|
|
268
|
+
STX = "id::stx" # select Stream (STX)
|
|
269
|
+
stream = cell.sync(STX) # synchronize Stream (STX)
|
|
270
|
+
for operation in stream: # load stream operations
|
|
271
|
+
label = operation.get("label") # get the operation details by key
|
|
237
272
|
key1 = operation.get("data").get("key1")
|
|
238
273
|
key2 = operation.get("data").get("key2")
|
|
239
274
|
key3 = operation.get("data").get("key3")
|
|
@@ -242,25 +277,56 @@ for operation in stream: # load s
|
|
|
242
277
|
operator = operation.get("operator")
|
|
243
278
|
```
|
|
244
279
|
|
|
245
|
-
List Streams (STX)
|
|
246
|
-
```python
|
|
247
|
-
|
|
248
|
-
stxList = cell.list_stx(cellID) # list Streams (STX)
|
|
280
|
+
List Streams (STX) your Cell can interact with:
|
|
281
|
+
```python
|
|
282
|
+
stxList = cell.list_stx() # list Streams (STX)
|
|
249
283
|
```
|
|
250
284
|
|
|
251
|
-
###
|
|
252
|
-
|
|
285
|
+
### Contracts/Tokens
|
|
286
|
+
Contracts define rules for authorization, allowing users to sign and generate unique tokens for secure access
|
|
253
287
|
|
|
254
|
-
|
|
288
|
+
Create a Contract:
|
|
255
289
|
```python
|
|
256
|
-
descr = "
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
290
|
+
descr = "Test Contract" # short description (max 25 characters)
|
|
291
|
+
details = { # define token details
|
|
292
|
+
"price_in_eur": 10, # token price in EUR
|
|
293
|
+
"max_usage": 10, # max number of uses
|
|
294
|
+
"validity_in_min": 10 # token expiration time (minutes)
|
|
295
|
+
}
|
|
296
|
+
partners = ["id::cell", "id::cell"]
|
|
297
|
+
contractID = cell.create_contract(descr, details, partners)
|
|
260
298
|
```
|
|
261
299
|
|
|
262
|
-
|
|
263
|
-
```python
|
|
264
|
-
|
|
265
|
-
cell.
|
|
300
|
+
Sign a Contract:
|
|
301
|
+
```python
|
|
302
|
+
contractID = "id::contract" # select contract
|
|
303
|
+
token = cell.sign_contract(contractID)
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Request a Token from another Cell to authorize a service:
|
|
307
|
+
```python
|
|
308
|
+
cp = "id::cell" # select counterparty cell
|
|
309
|
+
contractID = "id::contract" # select contract
|
|
310
|
+
cell.request_token(cp, contractID)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Present a Token to another Cell to authorize a service:
|
|
314
|
+
```python
|
|
315
|
+
token = "token" # select token
|
|
316
|
+
cp = "id::cell" # select counterparty cell
|
|
317
|
+
contractID = "id::contract" # select the contract
|
|
318
|
+
cell.present_token(token, cp, contractID)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Validate a Token to authorize a service:
|
|
322
|
+
```python
|
|
323
|
+
token = "token" # select token
|
|
324
|
+
cp = "id::cell" # select counterparty cell
|
|
325
|
+
contractID = "id::contract" # select contract
|
|
326
|
+
cell.validate_token(token, cp, contractID)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
List Contracts your Cell can interact with:
|
|
330
|
+
```python
|
|
331
|
+
contractList = cell.list_contracts()
|
|
266
332
|
```
|
|
@@ -0,0 +1,10 @@
|
|
|
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,,
|
neuronum-1.5.0.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
neuronum/__init__.py,sha256=Drsm263_w3_VWgl1YsKLUr8WwVodqV3TSjqpxLjyq_M,46
|
|
2
|
-
neuronum/neuronum.py,sha256=BymDHznUPI3mD09mquEbVODFMWiBaxNHYOst4-qDxZ8,14363
|
|
3
|
-
neuronum-1.5.0.dist-info/LICENSE,sha256=UiZjNHiCyRP6WoZfbYQh9cv4JW96wIofKXmzBJrYSUk,1125
|
|
4
|
-
neuronum-1.5.0.dist-info/METADATA,sha256=9s6uAwEgWSVAM0FwIwayvuskht2myPMUeGXEMgxV8ew,11764
|
|
5
|
-
neuronum-1.5.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
6
|
-
neuronum-1.5.0.dist-info/top_level.txt,sha256=73zXVVO9UTTiwEcSaXytsJ8n0q47OCwAqPlIh-hzWJU,9
|
|
7
|
-
neuronum-1.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|