neuronum 4.0.0__py3-none-any.whl → 5.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 +2 -4
- neuronum/neuronum.py +127 -77
- {neuronum-4.0.0.dist-info → neuronum-5.0.0.dist-info}/METADATA +9 -62
- neuronum-5.0.0.dist-info/RECORD +10 -0
- neuronum-4.0.0.dist-info/RECORD +0 -10
- {neuronum-4.0.0.dist-info → neuronum-5.0.0.dist-info}/WHEEL +0 -0
- {neuronum-4.0.0.dist-info → neuronum-5.0.0.dist-info}/entry_points.txt +0 -0
- {neuronum-4.0.0.dist-info → neuronum-5.0.0.dist-info}/licenses/LICENSE +0 -0
- {neuronum-4.0.0.dist-info → neuronum-5.0.0.dist-info}/top_level.txt +0 -0
cli/main.py
CHANGED
|
@@ -440,8 +440,7 @@ cell = neuronum.Cell(
|
|
|
440
440
|
)
|
|
441
441
|
|
|
442
442
|
async def main():
|
|
443
|
-
|
|
444
|
-
async for operation in cell.sync(STX):
|
|
443
|
+
async for operation in cell.sync():
|
|
445
444
|
message = operation.get("data").get("message")
|
|
446
445
|
print(message)
|
|
447
446
|
|
|
@@ -469,14 +468,13 @@ cell = neuronum.Cell(
|
|
|
469
468
|
)
|
|
470
469
|
|
|
471
470
|
async def main():
|
|
472
|
-
STX = "{stx}"
|
|
473
471
|
label = "Welcome to Neuronum"
|
|
474
472
|
|
|
475
473
|
while True:
|
|
476
474
|
data = {{
|
|
477
475
|
"message": "Hello, Neuronum!"
|
|
478
476
|
}}
|
|
479
|
-
await cell.stream(label, data
|
|
477
|
+
await cell.stream(label, data)
|
|
480
478
|
|
|
481
479
|
asyncio.run(main())
|
|
482
480
|
""")
|
neuronum/neuronum.py
CHANGED
|
@@ -13,6 +13,7 @@ class Cell:
|
|
|
13
13
|
self.synapse = synapse
|
|
14
14
|
self.queue = asyncio.Queue()
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
def to_dict(self) -> dict:
|
|
17
18
|
return {
|
|
18
19
|
"host": self.host,
|
|
@@ -20,8 +21,98 @@ class Cell:
|
|
|
20
21
|
"synapse": self.synapse
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
|
|
23
25
|
def __repr__(self) -> str:
|
|
24
26
|
return f"Cell(host={self.host}, password={self.password}, network={self.network}, synapse={self.synapse})"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def stream(self, label: str, data: dict, stx: Optional[str] = None, retry_delay: int = 3):
|
|
30
|
+
context = ssl.create_default_context()
|
|
31
|
+
context.check_hostname = True
|
|
32
|
+
context.verify_mode = ssl.CERT_REQUIRED
|
|
33
|
+
|
|
34
|
+
while True:
|
|
35
|
+
try:
|
|
36
|
+
reader, writer = await asyncio.open_connection(self.network, 55555, ssl=context, server_hostname=self.network)
|
|
37
|
+
|
|
38
|
+
credentials = f"{self.host}\n{self.password}\n{self.synapse}\n{stx}\n"
|
|
39
|
+
writer.write(credentials.encode("utf-8"))
|
|
40
|
+
await writer.drain()
|
|
41
|
+
|
|
42
|
+
response = await reader.read(1024)
|
|
43
|
+
response_text = response.decode("utf-8").strip()
|
|
44
|
+
|
|
45
|
+
if "Authentication successful" not in response_text:
|
|
46
|
+
print("Authentication failed, retrying...")
|
|
47
|
+
writer.close()
|
|
48
|
+
await writer.wait_closed()
|
|
49
|
+
await asyncio.sleep(retry_delay)
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
stream_payload = {
|
|
53
|
+
"label": label,
|
|
54
|
+
"data": data,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
writer.write(json.dumps(stream_payload).encode("utf-8"))
|
|
58
|
+
await writer.drain()
|
|
59
|
+
|
|
60
|
+
response = await reader.read(1024)
|
|
61
|
+
response_text = response.decode("utf-8").strip()
|
|
62
|
+
|
|
63
|
+
if response_text == "Sent":
|
|
64
|
+
print(f"Success: {response_text} - {stream_payload}")
|
|
65
|
+
break
|
|
66
|
+
else:
|
|
67
|
+
print(f"Error sending: {stream_payload}")
|
|
68
|
+
|
|
69
|
+
except (ssl.SSLError, ConnectionError) as e:
|
|
70
|
+
print(f"Connection error: {e}, retrying...")
|
|
71
|
+
await asyncio.sleep(retry_delay)
|
|
72
|
+
|
|
73
|
+
except Exception as e:
|
|
74
|
+
print(f"Unexpected error: {e}, retrying...")
|
|
75
|
+
await asyncio.sleep(retry_delay)
|
|
76
|
+
|
|
77
|
+
finally:
|
|
78
|
+
if 'writer' in locals():
|
|
79
|
+
writer.close()
|
|
80
|
+
await writer.wait_closed()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
async def sync(self, stx: Optional[str] = None) -> AsyncGenerator[str, None]:
|
|
84
|
+
full_url = f"wss://{self.network}/sync/{stx}"
|
|
85
|
+
|
|
86
|
+
auth_payload = {
|
|
87
|
+
"host": self.host,
|
|
88
|
+
"password": self.password,
|
|
89
|
+
"synapse": self.synapse,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
async with websockets.connect(full_url) as ws:
|
|
94
|
+
await ws.send(json.dumps(auth_payload))
|
|
95
|
+
print("Listening to Stream...")
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
while True:
|
|
99
|
+
try:
|
|
100
|
+
raw_operation = await ws.recv()
|
|
101
|
+
operation = json.loads(raw_operation)
|
|
102
|
+
yield operation
|
|
103
|
+
|
|
104
|
+
except asyncio.TimeoutError:
|
|
105
|
+
print("No initial data received. Continuing to listen...")
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
except asyncio.CancelledError:
|
|
109
|
+
print("Connection closed.")
|
|
110
|
+
|
|
111
|
+
except websockets.exceptions.WebSocketException as e:
|
|
112
|
+
print(f"WebSocket error occurred: {e}")
|
|
113
|
+
|
|
114
|
+
except Exception as e:
|
|
115
|
+
print(f"An unexpected error occurred: {e}")
|
|
25
116
|
|
|
26
117
|
|
|
27
118
|
async def create_tx(self, descr: str, key_values: dict, stx: str, label: str, partners: list):
|
|
@@ -85,7 +176,17 @@ class Cell:
|
|
|
85
176
|
response.raise_for_status()
|
|
86
177
|
response.raise_for_status()
|
|
87
178
|
data = await response.json()
|
|
88
|
-
|
|
179
|
+
if data["success"] == "activated":
|
|
180
|
+
async for operation in self.sync():
|
|
181
|
+
label = operation.get("label")
|
|
182
|
+
if label == "tx_response":
|
|
183
|
+
operation_id = operation.get("operationID")
|
|
184
|
+
if operation_id == data["operationID"]:
|
|
185
|
+
tx_response = operation.get("data")
|
|
186
|
+
return tx_response
|
|
187
|
+
|
|
188
|
+
else:
|
|
189
|
+
print(data["success"], data["message"])
|
|
89
190
|
|
|
90
191
|
except aiohttp.ClientError as e:
|
|
91
192
|
print(f"Error sending request: {e}")
|
|
@@ -93,6 +194,31 @@ class Cell:
|
|
|
93
194
|
print(f"Unexpected error: {e}")
|
|
94
195
|
|
|
95
196
|
|
|
197
|
+
async def tx_response(self, txID: str, cc: str, operationID: str, data: dict):
|
|
198
|
+
url = f"https://{self.network}/api/tx_response/{txID}"
|
|
199
|
+
|
|
200
|
+
tx_response = {
|
|
201
|
+
"cc": cc,
|
|
202
|
+
"operationID": operationID,
|
|
203
|
+
"data": data,
|
|
204
|
+
"cell": self.to_dict()
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async with aiohttp.ClientSession() as session:
|
|
208
|
+
for attempt in range(5):
|
|
209
|
+
try:
|
|
210
|
+
async with session.post(url, json=tx_response) as response:
|
|
211
|
+
response.raise_for_status()
|
|
212
|
+
data = await response.json()
|
|
213
|
+
|
|
214
|
+
except aiohttp.ClientError as e:
|
|
215
|
+
print(f"Attempt {attempt + 1}: Error sending request: {e}")
|
|
216
|
+
except Exception as e:
|
|
217
|
+
print(f"Attempt {attempt + 1}: Unexpected error: {e}")
|
|
218
|
+
|
|
219
|
+
print(data["message"])
|
|
220
|
+
|
|
221
|
+
|
|
96
222
|
async def create_ctx(self, descr: str, partners: list):
|
|
97
223
|
url = f"https://{self.network}/api/create_ctx"
|
|
98
224
|
|
|
@@ -368,80 +494,4 @@ class Cell:
|
|
|
368
494
|
print(f"Unexpected error: {e}")
|
|
369
495
|
|
|
370
496
|
|
|
371
|
-
async def stream(self, label: str, data: dict, stx: Optional[str] = None):
|
|
372
|
-
context = ssl.create_default_context()
|
|
373
|
-
context.check_hostname = True
|
|
374
|
-
context.verify_mode = ssl.CERT_REQUIRED
|
|
375
|
-
|
|
376
|
-
try:
|
|
377
|
-
reader, writer = await asyncio.open_connection(self.network, 55555, ssl=context, server_hostname=self.network)
|
|
378
|
-
|
|
379
|
-
credentials = f"{self.host}\n{self.password}\n{self.synapse}\n{stx}\n"
|
|
380
|
-
writer.write(credentials.encode("utf-8"))
|
|
381
|
-
await writer.drain()
|
|
382
|
-
|
|
383
|
-
response = await reader.read(1024)
|
|
384
|
-
response_text = response.decode("utf-8")
|
|
385
|
-
|
|
386
|
-
if "Authentication successful" not in response_text:
|
|
387
|
-
print("Authentication failed")
|
|
388
|
-
writer.close()
|
|
389
|
-
await writer.wait_closed()
|
|
390
|
-
return
|
|
391
|
-
|
|
392
|
-
stream_payload = {
|
|
393
|
-
"label": label,
|
|
394
|
-
"data": data,
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
writer.write(json.dumps(stream_payload).encode("utf-8"))
|
|
398
|
-
await writer.drain()
|
|
399
|
-
print(f"Sent: {stream_payload}")
|
|
400
|
-
|
|
401
|
-
except ssl.SSLError as e:
|
|
402
|
-
print(f"SSL error occurred: {e}")
|
|
403
|
-
|
|
404
|
-
except Exception as e:
|
|
405
|
-
print(f"An unexpected error occurred: {e}")
|
|
406
|
-
|
|
407
|
-
finally:
|
|
408
|
-
writer.close()
|
|
409
|
-
await writer.wait_closed()
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
async def sync(self, stx: Optional[str] = None) -> AsyncGenerator[str, None]:
|
|
413
|
-
full_url = f"wss://{self.network}/sync/{stx}"
|
|
414
|
-
|
|
415
|
-
auth_payload = {
|
|
416
|
-
"host": self.host,
|
|
417
|
-
"password": self.password,
|
|
418
|
-
"synapse": self.synapse,
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
try:
|
|
422
|
-
async with websockets.connect(full_url) as ws:
|
|
423
|
-
await ws.send(json.dumps(auth_payload))
|
|
424
|
-
print("Listening to Stream...")
|
|
425
|
-
|
|
426
|
-
try:
|
|
427
|
-
while True:
|
|
428
|
-
try:
|
|
429
|
-
raw_operation = await ws.recv()
|
|
430
|
-
operation = json.loads(raw_operation)
|
|
431
|
-
yield operation
|
|
432
|
-
|
|
433
|
-
except asyncio.TimeoutError:
|
|
434
|
-
print("No initial data received. Continuing to listen...")
|
|
435
|
-
continue
|
|
436
|
-
|
|
437
|
-
except asyncio.CancelledError:
|
|
438
|
-
print("Connection closed.")
|
|
439
|
-
|
|
440
|
-
except websockets.exceptions.WebSocketException as e:
|
|
441
|
-
print(f"WebSocket error occurred: {e}")
|
|
442
|
-
|
|
443
|
-
except Exception as e:
|
|
444
|
-
print(f"An unexpected error occurred: {e}")
|
|
445
|
-
|
|
446
|
-
|
|
447
497
|
__all__ = ['Cell']
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuronum
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: Official client library to interact with the Neuronum Network
|
|
5
5
|
Home-page: https://neuronum.net
|
|
6
6
|
Author: Neuronum Cybernetics
|
|
@@ -42,14 +42,13 @@ Dynamic: summary
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
### **About Neuronum**
|
|
45
|
-
Neuronum is a
|
|
46
|
-
In practice, Neuronum forms an interconnected network of soft- and hardware components (Nodes) exchanging data in real time.
|
|
45
|
+
Neuronum is a framework to build serverless data gateways automating the processing and distribution of data transmission, storage, and streaming.
|
|
47
46
|
|
|
48
47
|
|
|
49
|
-
### **
|
|
48
|
+
### **Neuronum Attributes**
|
|
50
49
|
**Cell & Nodes**
|
|
51
|
-
- Cell: Account to connect and interact with
|
|
52
|
-
- Nodes:
|
|
50
|
+
- Cell: Account to connect and interact with Neuronum
|
|
51
|
+
- Nodes: Soft- and Hardware components hosting data gateways
|
|
53
52
|
|
|
54
53
|
**Data Gateways**
|
|
55
54
|
- Transmitters (TX): Automate data transfer in standardized formats
|
|
@@ -76,83 +75,31 @@ Create Cell:
|
|
|
76
75
|
neuronum create-cell # create Cell / Cell type / Cell network
|
|
77
76
|
```
|
|
78
77
|
|
|
79
|
-
Connect Cell:
|
|
80
|
-
```sh
|
|
81
|
-
neuronum connect-cell # connect Cell
|
|
82
|
-
```
|
|
83
78
|
|
|
84
79
|
View connected Cell:
|
|
85
80
|
```sh
|
|
86
|
-
neuronum view-cell # view Cell / output = Connected Cell: '
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Disconnect Cell:
|
|
90
|
-
```sh
|
|
91
|
-
neuronum disconnect-cell # disconnect Cell
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Delete Cell:
|
|
95
|
-
```sh
|
|
96
|
-
neuronum delete-cell # delete Cell
|
|
81
|
+
neuronum view-cell # view Cell / output = Connected Cell: 'cell_id'"
|
|
97
82
|
```
|
|
98
83
|
|
|
99
84
|
|
|
100
85
|
------------------
|
|
101
86
|
|
|
102
87
|
|
|
103
|
-
|
|
104
88
|
### **Build on Neuronum**
|
|
89
|
+
**Node Examples:**
|
|
90
|
+
Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
|
|
91
|
+
|
|
105
92
|
Initialize Node (default template):
|
|
106
93
|
```sh
|
|
107
94
|
neuronum init-node # initialize a Node with default template
|
|
108
95
|
```
|
|
109
96
|
|
|
110
|
-
Initialize Node (stream template):
|
|
111
|
-
```sh
|
|
112
|
-
neuronum init-node --stream id::stx # initialize a Node with stream template
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Initialize Node (sync template):
|
|
116
|
-
```sh
|
|
117
|
-
neuronum init-node --sync id::stx # initialize a Node with sync template
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
cd to Node folder:
|
|
121
|
-
```sh
|
|
122
|
-
cd node_node_id # change to Node folder
|
|
123
|
-
```
|
|
124
|
-
|
|
125
97
|
Start Node:
|
|
126
98
|
```sh
|
|
127
99
|
neuronum start-node # start Node
|
|
128
100
|
```
|
|
129
101
|
|
|
130
|
-
Start Node (detached mode):
|
|
131
|
-
```sh
|
|
132
|
-
neuronum start-node --d # start Node in "detached" mode
|
|
133
|
-
```
|
|
134
|
-
|
|
135
102
|
Stop Node:
|
|
136
103
|
```sh
|
|
137
104
|
neuronum stop-node # stop Node
|
|
138
105
|
```
|
|
139
|
-
|
|
140
|
-
Connect Node:
|
|
141
|
-
```sh
|
|
142
|
-
neuronum connect-node # connect your Node / Node type / Node description
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Update Node:
|
|
146
|
-
```sh
|
|
147
|
-
neuronum update-node # update your Node
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Disconnect Node:
|
|
151
|
-
```sh
|
|
152
|
-
neuronum disconnect-node # disconnect your Node
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
Delete Node:
|
|
156
|
-
```sh
|
|
157
|
-
neuronum delete-node # delete your Node
|
|
158
|
-
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
cli/main.py,sha256=g7Y-W1G7C1firXHsEnBFyqa52nSk6GVzcax_6up0Ezg,24991
|
|
3
|
+
neuronum/__init__.py,sha256=Drsm263_w3_VWgl1YsKLUr8WwVodqV3TSjqpxLjyq_M,46
|
|
4
|
+
neuronum/neuronum.py,sha256=t1BDzFDzbq9kQN7RSFIagctSGWOoP5MewjpauJxhH5k,17511
|
|
5
|
+
neuronum-5.0.0.dist-info/licenses/LICENSE,sha256=UiZjNHiCyRP6WoZfbYQh9cv4JW96wIofKXmzBJrYSUk,1125
|
|
6
|
+
neuronum-5.0.0.dist-info/METADATA,sha256=KkMqALQtmMd_2gnstSXwjqx2AvkegZr-26c1oBXAHao,2883
|
|
7
|
+
neuronum-5.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
+
neuronum-5.0.0.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
|
|
9
|
+
neuronum-5.0.0.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
|
|
10
|
+
neuronum-5.0.0.dist-info/RECORD,,
|
neuronum-4.0.0.dist-info/RECORD
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
cli/main.py,sha256=SLkV4tmugC7UfnIJs5vUeMWf16An2NQuTnEV6PTNfWQ,25037
|
|
3
|
-
neuronum/__init__.py,sha256=Drsm263_w3_VWgl1YsKLUr8WwVodqV3TSjqpxLjyq_M,46
|
|
4
|
-
neuronum/neuronum.py,sha256=botQ0FJIf5e00MqfUeIcD6aAchys9vSsQ3ymj8YzGMc,15223
|
|
5
|
-
neuronum-4.0.0.dist-info/licenses/LICENSE,sha256=UiZjNHiCyRP6WoZfbYQh9cv4JW96wIofKXmzBJrYSUk,1125
|
|
6
|
-
neuronum-4.0.0.dist-info/METADATA,sha256=ePj9Xk9ypPSBKz7xF0KIVyBgEYVyQJ7djS3HPinScVM,4036
|
|
7
|
-
neuronum-4.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
-
neuronum-4.0.0.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
|
|
9
|
-
neuronum-4.0.0.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
|
|
10
|
-
neuronum-4.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|