neuronum 4.0.1__py3-none-any.whl → 5.1.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 +84 -13
- neuronum/neuronum.py +123 -79
- {neuronum-4.0.1.dist-info → neuronum-5.1.0.dist-info}/METADATA +29 -9
- neuronum-5.1.0.dist-info/RECORD +10 -0
- neuronum-4.0.1.dist-info/RECORD +0 -10
- {neuronum-4.0.1.dist-info → neuronum-5.1.0.dist-info}/WHEEL +0 -0
- {neuronum-4.0.1.dist-info → neuronum-5.1.0.dist-info}/entry_points.txt +0 -0
- {neuronum-4.0.1.dist-info → neuronum-5.1.0.dist-info}/licenses/LICENSE +0 -0
- {neuronum-4.0.1.dist-info → neuronum-5.1.0.dist-info}/top_level.txt +0 -0
cli/main.py
CHANGED
|
@@ -249,10 +249,11 @@ def delete_cell():
|
|
|
249
249
|
@click.command()
|
|
250
250
|
@click.option('--sync', multiple=True, default=None, help="Optional stream IDs for sync.")
|
|
251
251
|
@click.option('--stream', multiple=True, default=None, help="Optional stream ID for stream.")
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
@click.option('--app', is_flag=True, help="Generate a Node with app template")
|
|
253
|
+
def init_node(sync, stream, app):
|
|
254
|
+
asyncio.run(async_init_node(sync, stream, app))
|
|
254
255
|
|
|
255
|
-
async def async_init_node(sync, stream):
|
|
256
|
+
async def async_init_node(sync, stream, app):
|
|
256
257
|
credentials_folder_path = Path.home() / ".neuronum"
|
|
257
258
|
env_path = credentials_folder_path / ".env"
|
|
258
259
|
|
|
@@ -319,13 +320,35 @@ async def async_init_node(sync, stream):
|
|
|
319
320
|
await asyncio.to_thread(gitignore_path.write_text, ".env\n")
|
|
320
321
|
|
|
321
322
|
nodemd_path = project_path / "NODE.md"
|
|
322
|
-
await asyncio.to_thread(nodemd_path.write_text, """###
|
|
323
|
-
### Use this .md file to add instructions on how to interact with your Node
|
|
323
|
+
await asyncio.to_thread(nodemd_path.write_text, """### NODE.md: How to interact with this Node
|
|
324
324
|
|
|
325
325
|
```json
|
|
326
326
|
{
|
|
327
|
-
"
|
|
328
|
-
|
|
327
|
+
"info": {
|
|
328
|
+
"use_case": "This Node...",
|
|
329
|
+
"github": "https://github.com/user"
|
|
330
|
+
},
|
|
331
|
+
"gateways": [
|
|
332
|
+
{
|
|
333
|
+
"type": "stream",
|
|
334
|
+
"id": "id::stx",
|
|
335
|
+
"link": "https://neuronum.net/stream/id::stx"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"type": "transmitter",
|
|
339
|
+
"id": "id::tx",
|
|
340
|
+
"link": "https://neuronum.net/tx/id::tx",
|
|
341
|
+
}
|
|
342
|
+
{
|
|
343
|
+
"type": "circuit",
|
|
344
|
+
"id": "id::ctx",
|
|
345
|
+
"link": "https://neuronum.net/circuit/id::ctx",
|
|
346
|
+
}
|
|
347
|
+
],
|
|
348
|
+
"initialization": {
|
|
349
|
+
"command": "neuronum init-node --sync id::stx"
|
|
350
|
+
},
|
|
351
|
+
"requirements": [
|
|
329
352
|
{
|
|
330
353
|
"name": "Python",
|
|
331
354
|
"version": ">= 3.8",
|
|
@@ -333,12 +356,10 @@ async def async_init_node(sync, stream):
|
|
|
333
356
|
},
|
|
334
357
|
{
|
|
335
358
|
"name": "neuronum",
|
|
336
|
-
"version": ">=
|
|
359
|
+
"version": ">= 5.1.0",
|
|
337
360
|
"link": "https://pypi.org/project/neuronum/"
|
|
338
361
|
}
|
|
339
|
-
]
|
|
340
|
-
"Installation": "pip install neuronum",
|
|
341
|
-
"Initialization": "neuronum init-node"
|
|
362
|
+
]
|
|
342
363
|
}
|
|
343
364
|
```"""
|
|
344
365
|
)
|
|
@@ -418,7 +439,7 @@ async def main():
|
|
|
418
439
|
asyncio.run(main())
|
|
419
440
|
""")
|
|
420
441
|
|
|
421
|
-
if not sync and not stream:
|
|
442
|
+
if not sync and not stream and not app:
|
|
422
443
|
sync_path = project_path / f"sync_{stx.replace('::stx', '')}.py"
|
|
423
444
|
sync_path.write_text(f"""\
|
|
424
445
|
import asyncio
|
|
@@ -476,6 +497,56 @@ async def main():
|
|
|
476
497
|
}}
|
|
477
498
|
await cell.stream(label, data)
|
|
478
499
|
|
|
500
|
+
asyncio.run(main())
|
|
501
|
+
""")
|
|
502
|
+
|
|
503
|
+
if app:
|
|
504
|
+
app_path = project_path / "app.py"
|
|
505
|
+
app_path.write_text(f"""\
|
|
506
|
+
import asyncio
|
|
507
|
+
import neuronum
|
|
508
|
+
import os
|
|
509
|
+
from dotenv import load_dotenv
|
|
510
|
+
|
|
511
|
+
load_dotenv()
|
|
512
|
+
host = os.getenv("HOST")
|
|
513
|
+
password = os.getenv("PASSWORD")
|
|
514
|
+
network = os.getenv("NETWORK")
|
|
515
|
+
synapse = os.getenv("SYNAPSE")
|
|
516
|
+
|
|
517
|
+
cell = neuronum.Cell(
|
|
518
|
+
host=host,
|
|
519
|
+
password=password,
|
|
520
|
+
network=network,
|
|
521
|
+
synapse=synapse
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
async def main():
|
|
525
|
+
STX = "id::stx"
|
|
526
|
+
async for operation in cell.sync(STX):
|
|
527
|
+
txID = operation.get("txID")
|
|
528
|
+
|
|
529
|
+
if txID == "id::tx":
|
|
530
|
+
client = operation.get("operator")
|
|
531
|
+
data = {{
|
|
532
|
+
"response": "TX activated!"
|
|
533
|
+
}}
|
|
534
|
+
await cell.tx_response(txID, client, data)
|
|
535
|
+
|
|
536
|
+
if txID == "id::tx":
|
|
537
|
+
client = operation.get("operator")
|
|
538
|
+
data = {{
|
|
539
|
+
"response": "TX activated!"
|
|
540
|
+
}}
|
|
541
|
+
await cell.tx_response(txID, client, data)
|
|
542
|
+
|
|
543
|
+
if txID == "id::tx":
|
|
544
|
+
client = operation.get("operator")
|
|
545
|
+
data = {{
|
|
546
|
+
"response": "TX activated!"
|
|
547
|
+
}}
|
|
548
|
+
await cell.tx_response(txID, client, data)
|
|
549
|
+
|
|
479
550
|
asyncio.run(main())
|
|
480
551
|
""")
|
|
481
552
|
|
|
@@ -488,7 +559,7 @@ def start_node(d):
|
|
|
488
559
|
click.echo("Starting Node...")
|
|
489
560
|
|
|
490
561
|
project_path = Path.cwd()
|
|
491
|
-
script_files = glob.glob("sync_*.py") + glob.glob("stream_*.py")
|
|
562
|
+
script_files = glob.glob("sync_*.py") + glob.glob("stream_*.py") + glob.glob("app.py")
|
|
492
563
|
|
|
493
564
|
processes = []
|
|
494
565
|
system_name = platform.system()
|
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):
|
|
@@ -73,7 +164,6 @@ class Cell:
|
|
|
73
164
|
|
|
74
165
|
async def activate_tx(self, txID: str, data: dict):
|
|
75
166
|
url = f"https://{self.network}/api/activate_tx/{txID}"
|
|
76
|
-
|
|
77
167
|
TX = {
|
|
78
168
|
"data": data,
|
|
79
169
|
"cell": self.to_dict()
|
|
@@ -82,10 +172,40 @@ class Cell:
|
|
|
82
172
|
async with aiohttp.ClientSession() as session:
|
|
83
173
|
try:
|
|
84
174
|
async with session.post(url, json=TX) as response:
|
|
85
|
-
response.raise_for_status()
|
|
86
175
|
response.raise_for_status()
|
|
87
176
|
data = await response.json()
|
|
88
|
-
|
|
177
|
+
if data["success"] == "activated":
|
|
178
|
+
async for operation in self.sync():
|
|
179
|
+
label = operation.get("label")
|
|
180
|
+
if label == "tx_response":
|
|
181
|
+
operation_txID = operation.get("txID")
|
|
182
|
+
if operation_txID == txID:
|
|
183
|
+
return operation.get("data")
|
|
184
|
+
else:
|
|
185
|
+
print(data["success"], data["message"])
|
|
186
|
+
|
|
187
|
+
except aiohttp.ClientError as e:
|
|
188
|
+
print(f"Error sending request: {e}")
|
|
189
|
+
except Exception as e:
|
|
190
|
+
print(f"Unexpected error: {e}")
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
async def tx_response(self, txID: str, client: str, data: dict):
|
|
194
|
+
url = f"https://{self.network}/api/tx_response/{txID}"
|
|
195
|
+
|
|
196
|
+
tx_response = {
|
|
197
|
+
"client": client,
|
|
198
|
+
"data": data,
|
|
199
|
+
"cell": self.to_dict()
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async with aiohttp.ClientSession() as session:
|
|
203
|
+
try:
|
|
204
|
+
for _ in range(2):
|
|
205
|
+
async with session.post(url, json=tx_response) as response:
|
|
206
|
+
response.raise_for_status()
|
|
207
|
+
data = await response.json()
|
|
208
|
+
print(data["message"])
|
|
89
209
|
|
|
90
210
|
except aiohttp.ClientError as e:
|
|
91
211
|
print(f"Error sending request: {e}")
|
|
@@ -368,80 +488,4 @@ class Cell:
|
|
|
368
488
|
print(f"Unexpected error: {e}")
|
|
369
489
|
|
|
370
490
|
|
|
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
491
|
__all__ = ['Cell']
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuronum
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.1.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
|
|
@@ -35,23 +35,23 @@ Dynamic: summary
|
|
|
35
35
|
[](https://neuronum.net) [](https://github.com/neuronumcybernetics/neuronum)
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
## **Getting Started Goals**
|
|
39
39
|
- Learn about Neuronum
|
|
40
40
|
- Connect to Neuronum
|
|
41
41
|
- Build on Neuronum
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
### **About Neuronum**
|
|
45
|
-
Neuronum is a framework to build serverless data gateways automating the processing and distribution of data transmission, storage, and streaming.
|
|
45
|
+
Neuronum is a framework to build serverless connected app & data gateways automating the processing and distribution of data transmission, storage, and streaming.
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
### **
|
|
48
|
+
### **Features**
|
|
49
49
|
**Cell & Nodes**
|
|
50
50
|
- Cell: Account to connect and interact with Neuronum
|
|
51
|
-
- Nodes: Soft- and Hardware components hosting
|
|
51
|
+
- Nodes: Soft- and Hardware components hosting gateways
|
|
52
52
|
|
|
53
|
-
**
|
|
54
|
-
- Transmitters (TX):
|
|
53
|
+
**Gateways**
|
|
54
|
+
- Transmitters (TX): Securely transmit and receive data packages
|
|
55
55
|
- Circuits (CTX): Store data in cloud-based key-value-label databases
|
|
56
56
|
- Streams (STX): Stream, synchronize, and control data in real time
|
|
57
57
|
|
|
@@ -75,6 +75,12 @@ Create Cell:
|
|
|
75
75
|
neuronum create-cell # create Cell / Cell type / Cell network
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
or
|
|
79
|
+
|
|
80
|
+
Connect Cell:
|
|
81
|
+
```sh
|
|
82
|
+
neuronum connect-cell # connect Cell
|
|
83
|
+
```
|
|
78
84
|
|
|
79
85
|
View connected Cell:
|
|
80
86
|
```sh
|
|
@@ -86,11 +92,25 @@ neuronum view-cell # view Cell / output = Connected Cell: '
|
|
|
86
92
|
|
|
87
93
|
|
|
88
94
|
### **Build on Neuronum**
|
|
95
|
+
**Node Examples:**
|
|
96
|
+
Visit: https://github.com/neuronumcybernetics/neuronum/tree/main/how_tos/nodes
|
|
97
|
+
|
|
89
98
|
Initialize Node (default template):
|
|
90
99
|
```sh
|
|
91
100
|
neuronum init-node # initialize a Node with default template
|
|
92
101
|
```
|
|
93
102
|
|
|
103
|
+
Start Node:
|
|
104
|
+
```sh
|
|
105
|
+
neuronum start-node # start Node
|
|
106
|
+
```
|
|
94
107
|
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
Stop Node:
|
|
109
|
+
```sh
|
|
110
|
+
neuronum stop-node # stop Node
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Connect Node to Neuronum:
|
|
114
|
+
```sh
|
|
115
|
+
neuronum connect-node # connect Node
|
|
116
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
cli/main.py,sha256=tklC9GhJCB-zR26djn9D3ke6P6SGR2Jq66mG1a1Si3g,26848
|
|
3
|
+
neuronum/__init__.py,sha256=Drsm263_w3_VWgl1YsKLUr8WwVodqV3TSjqpxLjyq_M,46
|
|
4
|
+
neuronum/neuronum.py,sha256=qzxc9csSEnGX8wRC_14vzjJPQsCTC8wswhXno1Ih_Xw,17166
|
|
5
|
+
neuronum-5.1.0.dist-info/licenses/LICENSE,sha256=UiZjNHiCyRP6WoZfbYQh9cv4JW96wIofKXmzBJrYSUk,1125
|
|
6
|
+
neuronum-5.1.0.dist-info/METADATA,sha256=zgR264a9Ukp5wE7tIfNkbqCOpGB_vdA3vWqvJSnYZZc,3060
|
|
7
|
+
neuronum-5.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
+
neuronum-5.1.0.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
|
|
9
|
+
neuronum-5.1.0.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
|
|
10
|
+
neuronum-5.1.0.dist-info/RECORD,,
|
neuronum-4.0.1.dist-info/RECORD
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
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=botQ0FJIf5e00MqfUeIcD6aAchys9vSsQ3ymj8YzGMc,15223
|
|
5
|
-
neuronum-4.0.1.dist-info/licenses/LICENSE,sha256=UiZjNHiCyRP6WoZfbYQh9cv4JW96wIofKXmzBJrYSUk,1125
|
|
6
|
-
neuronum-4.0.1.dist-info/METADATA,sha256=SVe3ktDGVnjOpjl4PXi0QtIFOgW84Mr0TzfDJpivwsY,2725
|
|
7
|
-
neuronum-4.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
-
neuronum-4.0.1.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
|
|
9
|
-
neuronum-4.0.1.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
|
|
10
|
-
neuronum-4.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|