neuronum 8.1.0__tar.gz → 8.2.0__tar.gz
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.
- {neuronum-8.1.0 → neuronum-8.2.0}/PKG-INFO +1 -1
- {neuronum-8.1.0 → neuronum-8.2.0}/cli/main.py +80 -166
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum/neuronum.py +3 -5
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum.egg-info/PKG-INFO +1 -1
- {neuronum-8.1.0 → neuronum-8.2.0}/setup.py +1 -1
- {neuronum-8.1.0 → neuronum-8.2.0}/LICENSE.md +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/README.md +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/cli/__init__.py +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum/__init__.py +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum.egg-info/SOURCES.txt +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum.egg-info/dependency_links.txt +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum.egg-info/entry_points.txt +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum.egg-info/requires.txt +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/neuronum.egg-info/top_level.txt +0 -0
- {neuronum-8.1.0 → neuronum-8.2.0}/setup.cfg +0 -0
|
@@ -534,7 +534,8 @@ f"""{{
|
|
|
534
534
|
"app_metadata": {{
|
|
535
535
|
"name": "{descr}",
|
|
536
536
|
"version": "1.0.0",
|
|
537
|
-
"author": "{host}"
|
|
537
|
+
"author": "{host}",
|
|
538
|
+
"audience": "private"
|
|
538
539
|
}},
|
|
539
540
|
"data_gateways": [
|
|
540
541
|
{{
|
|
@@ -815,107 +816,72 @@ async def async_stop_node():
|
|
|
815
816
|
@click.command()
|
|
816
817
|
def update_node():
|
|
817
818
|
click.echo("Update your Node")
|
|
818
|
-
credentials_folder_path = Path.home() / ".neuronum"
|
|
819
|
-
env_path = credentials_folder_path / ".env"
|
|
820
|
-
env_data = {}
|
|
821
|
-
|
|
822
819
|
try:
|
|
820
|
+
env_path = Path.home() / ".neuronum" / ".env"
|
|
821
|
+
env_data = {}
|
|
823
822
|
with open(env_path, "r") as f:
|
|
824
823
|
for line in f:
|
|
825
|
-
|
|
826
|
-
|
|
824
|
+
if "=" in line:
|
|
825
|
+
key, value = line.strip().split("=", 1)
|
|
826
|
+
env_data[key] = value
|
|
827
827
|
|
|
828
828
|
host = env_data.get("HOST", "")
|
|
829
829
|
|
|
830
|
-
|
|
831
|
-
|
|
830
|
+
with open("config.json", "r") as f:
|
|
831
|
+
config_data = json.load(f)
|
|
832
|
+
|
|
833
|
+
audience = config_data.get("app_metadata", {}).get("audience", "")
|
|
834
|
+
descr = config_data.get("app_metadata", {}).get("name", "")
|
|
835
|
+
|
|
836
|
+
if host.startswith("CMTY_") and audience != "private":
|
|
837
|
+
raise click.ClickException(
|
|
838
|
+
'Community Cells can only create private Nodes. Set audience to "private".'
|
|
839
|
+
)
|
|
840
|
+
if descr and len(descr) > 25:
|
|
841
|
+
raise click.ClickException(
|
|
842
|
+
'Description too long. Max 25 characters allowed.'
|
|
843
|
+
)
|
|
844
|
+
|
|
845
|
+
except FileNotFoundError as e:
|
|
846
|
+
click.echo(f"Error: File not found - {e.filename}")
|
|
832
847
|
return
|
|
833
|
-
except
|
|
834
|
-
click.echo(
|
|
848
|
+
except click.ClickException as e:
|
|
849
|
+
click.echo(e.format_message())
|
|
835
850
|
return
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
node_type = questionary.select(
|
|
839
|
-
"Community Cells can only create private Nodes",
|
|
840
|
-
choices=["private"]
|
|
841
|
-
).ask()
|
|
842
|
-
else:
|
|
843
|
-
node_type = questionary.select(
|
|
844
|
-
"Who can view your Node?:",
|
|
845
|
-
choices=["public", "private", "partners"]
|
|
846
|
-
).ask()
|
|
847
|
-
partners = "None"
|
|
848
|
-
if node_type == "partners":
|
|
849
|
-
prompt_msg = (
|
|
850
|
-
"Enter the list of partners who can view this Node.\n"
|
|
851
|
-
"Format: partner::cell, partner::cell, partner::cell\n"
|
|
852
|
-
"Press Enter to leave the list unchanged"
|
|
853
|
-
)
|
|
854
|
-
partners = click.prompt(
|
|
855
|
-
prompt_msg,
|
|
856
|
-
default="None",
|
|
857
|
-
show_default=False
|
|
858
|
-
).strip()
|
|
859
|
-
descr = click.prompt(
|
|
860
|
-
"Update Node description: Type up to 25 characters, or press Enter to leave it unchanged",
|
|
861
|
-
default="None",
|
|
862
|
-
show_default=False
|
|
863
|
-
).strip()
|
|
864
|
-
if descr and len(descr) > 25:
|
|
865
|
-
click.echo("Description too long. Max 25 characters allowed.")
|
|
851
|
+
except Exception as e:
|
|
852
|
+
click.echo(f"Error reading files: {e}")
|
|
866
853
|
return
|
|
867
|
-
asyncio.run(async_update_node(node_type, descr, partners))
|
|
868
854
|
|
|
869
|
-
|
|
870
|
-
credentials_folder_path = Path.home() / ".neuronum"
|
|
871
|
-
env_path = credentials_folder_path / ".env"
|
|
872
|
-
env_data = {}
|
|
855
|
+
asyncio.run(async_update_node(env_data, config_data, audience, descr))
|
|
873
856
|
|
|
874
|
-
try:
|
|
875
|
-
with open(env_path, "r") as f:
|
|
876
|
-
for line in f:
|
|
877
|
-
key, value = line.strip().split("=")
|
|
878
|
-
env_data[key] = value
|
|
879
857
|
|
|
858
|
+
async def async_update_node(env_data, config_data, audience: str, descr: str):
|
|
859
|
+
try:
|
|
880
860
|
host = env_data.get("HOST", "")
|
|
881
861
|
password = env_data.get("PASSWORD", "")
|
|
882
862
|
network = env_data.get("NETWORK", "")
|
|
883
863
|
synapse = env_data.get("SYNAPSE", "")
|
|
884
864
|
|
|
885
|
-
|
|
886
|
-
data = json.load(f)
|
|
887
|
-
|
|
888
|
-
nodeID = data['data_gateways'][0]['node_id']
|
|
889
|
-
|
|
890
|
-
except FileNotFoundError:
|
|
891
|
-
click.echo("Error: .env with credentials not found")
|
|
892
|
-
return
|
|
893
|
-
except Exception as e:
|
|
894
|
-
click.echo(f"Error reading .env file: {e}")
|
|
895
|
-
return
|
|
865
|
+
node_id = config_data.get("data_gateways", [{}])[0].get("node_id", "")
|
|
896
866
|
|
|
897
|
-
try:
|
|
898
867
|
with open("config.json", "r") as f:
|
|
899
|
-
|
|
868
|
+
config_file_content = f.read()
|
|
900
869
|
|
|
901
870
|
except FileNotFoundError:
|
|
902
|
-
click.echo("Error:
|
|
871
|
+
click.echo("Error: config.json or .env not found")
|
|
903
872
|
return
|
|
904
873
|
except Exception as e:
|
|
905
|
-
click.echo(f"Error reading
|
|
874
|
+
click.echo(f"Error reading files: {e}")
|
|
906
875
|
return
|
|
907
|
-
|
|
908
|
-
if node_type == "partners":
|
|
909
|
-
node_type = partners
|
|
910
876
|
|
|
911
877
|
url = f"https://{network}/api/update_node"
|
|
912
878
|
node = {
|
|
913
|
-
"nodeID":
|
|
879
|
+
"nodeID": node_id,
|
|
914
880
|
"host": host,
|
|
915
881
|
"password": password,
|
|
916
882
|
"synapse": synapse,
|
|
917
|
-
"node_type":
|
|
918
|
-
"config_file":
|
|
883
|
+
"node_type": audience,
|
|
884
|
+
"config_file": config_file_content,
|
|
919
885
|
"descr": descr,
|
|
920
886
|
}
|
|
921
887
|
|
|
@@ -924,120 +890,73 @@ async def async_update_node(node_type: str, descr: str, partners:str) -> None:
|
|
|
924
890
|
async with session.post(url, json=node) as response:
|
|
925
891
|
response.raise_for_status()
|
|
926
892
|
data = await response.json()
|
|
927
|
-
|
|
893
|
+
updated_node_id = data.get("nodeID", node_id)
|
|
894
|
+
click.echo(f"Neuronum Node '{updated_node_id}' updated!")
|
|
928
895
|
except aiohttp.ClientError as e:
|
|
929
896
|
click.echo(f"Error sending request: {e}")
|
|
930
|
-
return
|
|
931
897
|
|
|
932
|
-
if node_type == "public":
|
|
933
|
-
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
934
|
-
else:
|
|
935
|
-
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
936
898
|
|
|
937
899
|
|
|
938
900
|
def update_node_at_start():
|
|
939
901
|
click.echo("Update your Node")
|
|
940
|
-
credentials_folder_path = Path.home() / ".neuronum"
|
|
941
|
-
env_path = credentials_folder_path / ".env"
|
|
942
|
-
env_data = {}
|
|
943
|
-
|
|
944
902
|
try:
|
|
903
|
+
env_path = Path.home() / ".neuronum" / ".env"
|
|
904
|
+
env_data = {}
|
|
945
905
|
with open(env_path, "r") as f:
|
|
946
906
|
for line in f:
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
host = env_data.get("HOST", "")
|
|
951
|
-
|
|
952
|
-
except FileNotFoundError:
|
|
953
|
-
click.echo("Error: .env with credentials not found")
|
|
954
|
-
return
|
|
955
|
-
except Exception as e:
|
|
956
|
-
click.echo(f"Error reading .env file: {e}")
|
|
957
|
-
return
|
|
958
|
-
|
|
959
|
-
if host.startswith("CMTY_"):
|
|
960
|
-
node_type = questionary.select(
|
|
961
|
-
"Community Cells can only create private Nodes",
|
|
962
|
-
choices=["private"]
|
|
963
|
-
).ask()
|
|
964
|
-
else:
|
|
965
|
-
node_type = questionary.select(
|
|
966
|
-
"Who can view your Node?:",
|
|
967
|
-
choices=["public", "private", "partners"]
|
|
968
|
-
).ask()
|
|
969
|
-
partners = "None"
|
|
970
|
-
if node_type == "partners":
|
|
971
|
-
prompt_msg = (
|
|
972
|
-
"Enter the list of partners who can view this Node.\n"
|
|
973
|
-
"Format: partner::cell, partner::cell, partner::cell\n"
|
|
974
|
-
"Press Enter to leave the list unchanged"
|
|
975
|
-
)
|
|
976
|
-
partners = click.prompt(
|
|
977
|
-
prompt_msg,
|
|
978
|
-
default="None",
|
|
979
|
-
show_default=False
|
|
980
|
-
).strip()
|
|
981
|
-
descr = click.prompt(
|
|
982
|
-
"Update Node description: Type up to 25 characters, or press Enter to leave it unchanged",
|
|
983
|
-
default="None",
|
|
984
|
-
show_default=False
|
|
985
|
-
).strip()
|
|
986
|
-
if descr and len(descr) > 25:
|
|
987
|
-
click.echo("Description too long. Max 25 characters allowed.")
|
|
988
|
-
return
|
|
989
|
-
asyncio.run(async_update_node_at_start(node_type, descr, partners))
|
|
990
|
-
|
|
991
|
-
async def async_update_node_at_start(node_type: str, descr: str, partners:str) -> None:
|
|
992
|
-
credentials_folder_path = Path.home() / ".neuronum"
|
|
993
|
-
env_path = credentials_folder_path / ".env"
|
|
994
|
-
env_data = {}
|
|
907
|
+
if "=" in line:
|
|
908
|
+
key, value = line.strip().split("=", 1)
|
|
909
|
+
env_data[key] = value
|
|
995
910
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
for line in f:
|
|
999
|
-
key, value = line.strip().split("=")
|
|
1000
|
-
env_data[key] = value
|
|
911
|
+
with open("config.json", "r") as f:
|
|
912
|
+
config_data = json.load(f)
|
|
1001
913
|
|
|
1002
914
|
host = env_data.get("HOST", "")
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
915
|
+
audience = config_data.get("app_metadata", {}).get("audience", "")
|
|
916
|
+
descr = config_data.get("app_metadata", {}).get("name", "")
|
|
917
|
+
|
|
918
|
+
if host.startswith("CMTY_") and audience != "private":
|
|
919
|
+
raise click.ClickException(
|
|
920
|
+
'Community Cells can only start private Nodes. Node starting "privately".'
|
|
921
|
+
)
|
|
922
|
+
if descr and len(descr) > 25:
|
|
923
|
+
raise click.ClickException(
|
|
924
|
+
'Description too long. Max 25 characters allowed.'
|
|
925
|
+
)
|
|
926
|
+
|
|
927
|
+
asyncio.run(_async_update_node_at_start(env_data, config_data, audience, descr))
|
|
928
|
+
|
|
929
|
+
except FileNotFoundError as e:
|
|
930
|
+
click.echo(f"Error: File not found - {e.filename}")
|
|
931
|
+
except click.ClickException as e:
|
|
932
|
+
click.echo(e.format_message())
|
|
933
|
+
except Exception as e:
|
|
934
|
+
click.echo(f"Unexpected error: {e}")
|
|
1006
935
|
|
|
1007
|
-
with open('config.json', 'r') as f:
|
|
1008
|
-
data = json.load(f)
|
|
1009
936
|
|
|
1010
|
-
|
|
937
|
+
async def _async_update_node_at_start(env_data, config_data, audience, descr):
|
|
938
|
+
host = env_data.get("HOST", "")
|
|
939
|
+
password = env_data.get("PASSWORD", "")
|
|
940
|
+
network = env_data.get("NETWORK", "")
|
|
941
|
+
synapse = env_data.get("SYNAPSE", "")
|
|
1011
942
|
|
|
1012
|
-
|
|
1013
|
-
click.echo("Error: .env with credentials not found")
|
|
1014
|
-
return
|
|
1015
|
-
except Exception as e:
|
|
1016
|
-
click.echo(f"Error reading .env file: {e}")
|
|
1017
|
-
return
|
|
943
|
+
node_id = config_data.get("data_gateways", [{}])[0].get("node_id", "")
|
|
1018
944
|
|
|
1019
945
|
try:
|
|
1020
946
|
with open("config.json", "r") as f:
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
except FileNotFoundError:
|
|
1024
|
-
click.echo("Error: File not found")
|
|
1025
|
-
return
|
|
947
|
+
config_file_content = f.read()
|
|
1026
948
|
except Exception as e:
|
|
1027
|
-
click.echo(f"Error reading
|
|
949
|
+
click.echo(f"Error reading config.json content: {e}")
|
|
1028
950
|
return
|
|
1029
|
-
|
|
1030
|
-
if node_type == "partners":
|
|
1031
|
-
node_type = partners
|
|
1032
951
|
|
|
1033
952
|
url = f"https://{network}/api/update_node"
|
|
1034
953
|
node = {
|
|
1035
|
-
"nodeID":
|
|
954
|
+
"nodeID": node_id,
|
|
1036
955
|
"host": host,
|
|
1037
956
|
"password": password,
|
|
1038
957
|
"synapse": synapse,
|
|
1039
|
-
"node_type":
|
|
1040
|
-
"config_file":
|
|
958
|
+
"node_type": audience,
|
|
959
|
+
"config_file": config_file_content,
|
|
1041
960
|
"descr": descr,
|
|
1042
961
|
}
|
|
1043
962
|
|
|
@@ -1046,15 +965,10 @@ async def async_update_node_at_start(node_type: str, descr: str, partners:str) -
|
|
|
1046
965
|
async with session.post(url, json=node) as response:
|
|
1047
966
|
response.raise_for_status()
|
|
1048
967
|
data = await response.json()
|
|
1049
|
-
|
|
968
|
+
updated_node_id = data.get("nodeID", node_id)
|
|
969
|
+
click.echo(f"Neuronum Node '{updated_node_id}' updated!")
|
|
1050
970
|
except aiohttp.ClientError as e:
|
|
1051
971
|
click.echo(f"Error sending request: {e}")
|
|
1052
|
-
return
|
|
1053
|
-
|
|
1054
|
-
if node_type == "public":
|
|
1055
|
-
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
1056
|
-
else:
|
|
1057
|
-
click.echo(f"Neuronum Node '{nodeID}' updated!")
|
|
1058
972
|
|
|
1059
973
|
|
|
1060
974
|
@click.command()
|
|
@@ -35,6 +35,7 @@ class Node:
|
|
|
35
35
|
"synapse": self.synapse
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
|
|
38
39
|
def _load_private_key(self):
|
|
39
40
|
try:
|
|
40
41
|
with open(self.private_key_path, "rb") as f:
|
|
@@ -43,12 +44,12 @@ class Node:
|
|
|
43
44
|
password=None,
|
|
44
45
|
backend=default_backend()
|
|
45
46
|
)
|
|
46
|
-
print("Private key loaded successfully.")
|
|
47
47
|
return private_key
|
|
48
48
|
except FileNotFoundError:
|
|
49
49
|
print(f"Private key file not found at {self.private_key_path}.")
|
|
50
50
|
return None
|
|
51
51
|
|
|
52
|
+
|
|
52
53
|
def _load_host(self):
|
|
53
54
|
credentials_folder_path = Path.home() / ".neuronum"
|
|
54
55
|
env_path = credentials_folder_path / ".env"
|
|
@@ -130,8 +131,6 @@ class Node:
|
|
|
130
131
|
f.read(),
|
|
131
132
|
backend=default_backend()
|
|
132
133
|
)
|
|
133
|
-
print("Public key loaded successfully.")
|
|
134
|
-
print(public_key)
|
|
135
134
|
return public_key
|
|
136
135
|
except FileNotFoundError:
|
|
137
136
|
print(f"Public key file not found at {self.public_key_path}. Deriving from private key.")
|
|
@@ -147,7 +146,6 @@ class Node:
|
|
|
147
146
|
print("Public key not loaded. Cannot generate JWK.")
|
|
148
147
|
return None
|
|
149
148
|
|
|
150
|
-
print("Public key loaded successfully.")
|
|
151
149
|
public_numbers = public_key.public_numbers()
|
|
152
150
|
|
|
153
151
|
x_bytes = public_numbers.x.to_bytes((public_numbers.x.bit_length() + 7) // 8, 'big')
|
|
@@ -196,7 +194,7 @@ class Node:
|
|
|
196
194
|
try:
|
|
197
195
|
async with websockets.connect(full_url) as ws:
|
|
198
196
|
await ws.send(json.dumps(auth_payload))
|
|
199
|
-
print("
|
|
197
|
+
print("Node syncing...")
|
|
200
198
|
while True:
|
|
201
199
|
try:
|
|
202
200
|
raw_operation = await ws.recv()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|