unaiverse 0.1.1__py3-none-any.whl → 0.1.2__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 unaiverse might be problematic. Click here for more details.

@@ -18,6 +18,7 @@ from . import golibp2p
18
18
  from . import lib_types
19
19
  import os
20
20
  import sys
21
+ import json
21
22
  import ctypes
22
23
  import platform
23
24
  import requests
@@ -31,128 +32,159 @@ from .lib_types import TypeInterface # Assuming TypeInterface handles the void*
31
32
 
32
33
  # --- Setup and Pre-build Checks ---
33
34
 
34
- # Define paths and library names
35
- lib_dir = os.path.dirname(__file__)
36
- go_mod_file = os.path.join(lib_dir, "go.mod")
35
+ # Determine the correct library file extension and URL based on the OS
36
+ os_to_ext = {
37
+ "Windows": ".dll",
38
+ "Darwin": ".dylib",
39
+ "Linux": ".so"
40
+ }
41
+ os_to_url = {
42
+ "Windows": "https://raw.githubusercontent.com/collectionlessai/unaiverse-misc/main/precompiled/lib.dll",
43
+ "Darwin": "https://raw.githubusercontent.com/collectionlessai/unaiverse-misc/main/precompiled/lib.dylib",
44
+ "Linux": "https://raw.githubusercontent.com/collectionlessai/unaiverse-misc/main/precompiled/lib.so"
45
+ }
46
+
47
+ current_os = platform.system()
48
+ lib_ext = os_to_ext.get(current_os, ".so")
49
+ lib_url = os_to_url.get(current_os, os_to_url["Linux"])
50
+
51
+ # --- Configuration & Paths ---
52
+ lib_dir = os.path.dirname(os.path.abspath(__file__))
37
53
  go_source_file = os.path.join(lib_dir, "lib.go")
38
- lib_name = "lib"
39
-
40
- # Determine the correct library file extension based on the OS
41
- if platform.system() == "Windows":
42
- lib_url = "https://github.com/collectionlessai/unaiverse-misc/raw/main/precompiled/lib.dll"
43
- lib_ext = ".dll"
44
- elif platform.system() == "Darwin": # MacOS
45
- lib_url = "https://github.com/collectionlessai/unaiverse-misc/raw/main/precompiled/lib.dylib"
46
- lib_ext = ".dylib"
47
- else: # Linux and other Unix-like
48
- lib_url = "https://github.com/collectionlessai/unaiverse-misc/raw/main/precompiled/lib.so"
49
- lib_ext = ".so"
50
-
51
- lib_filename = f"{lib_name}{lib_ext}"
54
+ lib_filename = f"lib{lib_ext}"
52
55
  lib_path = os.path.join(lib_dir, lib_filename)
56
+ go_mod_file = os.path.join(lib_dir, "go.mod")
57
+ version_file = os.path.join(lib_dir, "lib.version.json")
53
58
 
54
- if os.path.getmtime(go_source_file) > os.path.getmtime(lib_path):
55
- print(f"INFO: Found a more recent Go source file, removing the existing library (if any)")
56
- if os.path.exists(lib_path):
57
- os.remove(lib_path)
58
-
59
- # Possible states
60
- shared_lib_was_downloaded = False
61
- shared_lib_was_already_there = os.path.exists(lib_path)
62
- must_recompile = False
63
- reason_to_recompile = ""
64
- _shared_lib = None # This is where the loaded library will stay
65
-
66
- if not shared_lib_was_already_there:
67
- print(f"INFO: '{lib_filename}' not found. Attempting to automatically download it and save to '{lib_dir}'...")
68
- download_was_successful = False
69
- try:
70
- headers = {
71
- "User-Agent": "python-requests/2.31.0" # Any browser-like agent also works
72
- }
73
- response = requests.get(lib_url, headers=headers, allow_redirects=True)
74
- with open(lib_path, "wb") as f:
75
- f.write(response.content)
76
- download_was_successful = True
77
- print(f"INFO: Download complete")
78
- except Exception:
79
- pass
59
+ # --- Helper Functions ---
80
60
 
81
- if download_was_successful:
82
- try:
83
- _shared_lib = ctypes.CDLL(lib_path)
84
- shared_lib_was_downloaded = True
85
- except OSError as e:
86
- _shared_lib = None
87
- if os.path.exists(lib_path):
88
- os.remove(lib_path)
89
- reason_to_recompile = "The downloaded library was not compatible with this platform and was deleted."
90
- must_recompile = True
91
- else:
92
- reason_to_recompile = "Failed to download the library."
93
- must_recompile = True
61
+ def load_shared_library(path):
62
+ """Attempt to load the shared library and return the handle."""
63
+ try:
64
+ print(f"INFO: Attempting to load library from '{path}'...")
65
+ return ctypes.CDLL(path)
66
+ except OSError as e:
67
+ print(f"INFO: Failed to load library: {e}")
68
+ return None
94
69
 
95
- # --- Automatically initialize Go module if needed ---
96
- if must_recompile:
97
- print(f"INFO: {reason_to_recompile}. Recompiling the libray - you need a Go compiler, or this procedure will fail "
98
- f"(install it!)")
70
+ def get_remote_version_info(url):
71
+ """Performs a HEAD request to get ETag from the remote file."""
72
+ try:
73
+ print(f"INFO: Checking remote version at '{url}'...")
74
+ response = requests.head(url, allow_redirects=True, timeout=10)
75
+ response.raise_for_status()
76
+ etag = response.headers.get("ETag")
77
+ return etag
78
+ except Exception as e:
79
+ print(f"INFO: Failed to get remote version info: {e}")
80
+ return None
81
+
82
+ def download_library(url, path, etag):
83
+ """Downloads the shared library and saves version info."""
84
+ print(f"INFO: Downloading new library from '{url}'...")
85
+ try:
86
+ headers = {"User-Agent": "python-requests/2.31.0"}
87
+ response = requests.get(url, headers=headers, allow_redirects=True, timeout=30)
88
+ response.raise_for_status()
89
+ with open(path, "wb") as f:
90
+ f.write(response.content)
91
+
92
+ print("INFO: Download complete.")
93
+ return True
94
+ except Exception as e:
95
+ print(f"INFO: Failed to download library: {e}")
96
+ return False
97
+
98
+ def build_go_library():
99
+ """Build the Go shared library and saves version info."""
100
+ print("INFO: Building library from source...")
99
101
  if not os.path.exists(go_mod_file):
100
- print(f"INFO: 'go.mod' not found. Initializing Go module in '{lib_dir}'...")
102
+ print(f"INFO: 'go.mod' not found. Initializing Go module...")
103
+ module_path = "unaiverse/networking/p2p/lib"
101
104
  try:
102
-
103
- # Define a module path. This can be anything, but a path-like name is conventional.
104
- module_path = "unaiverse/networking/p2p/lib"
105
-
106
- # Run 'go mod init'
107
- subprocess.run(
108
- ["go", "mod", "init", module_path],
109
- cwd=lib_dir, # Run the command in the directory containing lib.go
110
- check=True, # Raise an exception if the command fails
111
- capture_output=True, # Capture stdout/stderr
112
- text=True
113
- )
114
-
115
- # Run 'go mod tidy' to find dependencies and create go.sum
105
+ subprocess.run(["go", "mod", "init", module_path], cwd=lib_dir, check=True, capture_output=True, text=True)
116
106
  print("INFO: Go module initialized. Running 'go mod tidy'...")
117
- subprocess.run(
118
- ["go", "mod", "tidy"],
119
- cwd=lib_dir,
120
- check=True,
121
- capture_output=True,
122
- text=True
123
- )
124
- print("INFO: 'go.mod' and 'go.sum' created successfully.")
107
+ subprocess.run(["go", "mod", "tidy"], cwd=lib_dir, check=True, capture_output=True, text=True)
125
108
  except (subprocess.CalledProcessError, FileNotFoundError) as e:
126
- print("FATAL: Failed to initialize Go module. Please ensure Go is installed and in your system's PATH.",
127
- file=sys.stderr)
109
+ print(f"FATAL: Failed to initialize Go module. Is Go installed? Error: {e}", file=sys.stderr)
128
110
  raise e
129
111
 
130
- # --- Automatically build the shared library if it's missing or outdated ---
131
112
  try:
132
113
  build_command = ["go", "build", "-buildmode=c-shared", "-ldflags", "-s -w", "-o", lib_filename, "lib.go"]
133
- print(f"Running command: {' '.join(build_command)}")
134
- result = subprocess.run(
135
- build_command,
136
- cwd=lib_dir,
137
- check=True,
138
- capture_output=True,
139
- text=True
140
- )
141
- if result.stdout:
142
- print(f"Go build stdout:\n{result.stdout}")
114
+ subprocess.run(build_command, cwd=lib_dir, check=True, capture_output=True, text=True)
115
+
143
116
  print(f"INFO: Successfully built '{lib_filename}'.")
117
+ return True
144
118
  except (subprocess.CalledProcessError, FileNotFoundError) as e:
145
- print("FATAL: Failed to initialize Go module. Please ensure Go is installed and in your system's PATH.",
146
- file=sys.stderr)
147
- raise e
148
-
149
- # --- Library Loading (if not already downloaded and loaded-in-memory) ---
119
+ print(f"FATAL: Failed to build library. Is Go installed? Error: {e}", file=sys.stderr)
120
+ return False
121
+
122
+ # --- Main Logic Flow ---
123
+ _shared_lib = None
124
+ should_update = False
125
+ go_source_time = os.path.getmtime(go_source_file)
126
+
127
+ # Step 1: Check for existing local binary and version info
128
+ if os.path.exists(lib_path):
129
+ print(f"INFO: Found existing library '{lib_filename}'.")
130
+ if os.path.exists(version_file):
131
+ try:
132
+ with open(version_file, "r") as f:
133
+ version_info = json.load(f)
134
+
135
+ if version_info.get("source") == "remote":
136
+ remote_etag = get_remote_version_info(lib_url)
137
+ if remote_etag and remote_etag != version_info.get("etag"):
138
+ print("INFO: Remote binary is newer (different ETag). An update is required.")
139
+ should_update = True
140
+ else:
141
+ print("INFO: Local binary is up-to-date with remote.")
142
+ elif version_info.get("source") == "local":
143
+ if go_source_time > version_info.get("timestamp", 0):
144
+ print("INFO: Go source file is newer than local binary. Re-compilation is required.")
145
+ should_update = True
146
+ else:
147
+ print("INFO: Local binary is up-to-date with source.")
148
+
149
+ except (IOError, json.JSONDecodeError):
150
+ print("INFO: Could not read version file. Assuming outdated.")
151
+ should_update = True
152
+ else:
153
+ print("INFO: No version file found. Assuming outdated.")
154
+ should_update = True
155
+
156
+ if should_update:
157
+ if os.path.exists(lib_path):
158
+ os.remove(lib_path)
159
+ else:
160
+ # Load if it exists and is up-to-date
161
+ _shared_lib = load_shared_library(lib_path)
162
+
163
+ # Step 2: Try to get a library if none is loaded
164
+ if _shared_lib is None: # same as should_update being True
165
+ # Attempt to download the latest binary
166
+ remote_etag = get_remote_version_info(lib_url)
167
+ if remote_etag and download_library(lib_url, lib_path, remote_etag):
168
+ _shared_lib = load_shared_library(lib_path)
169
+ if _shared_lib is not None:
170
+ with open(version_file, "w") as f:
171
+ json.dump({"source": "remote", "etag": remote_etag}, f)
172
+
173
+ # Step 3: Fallback to local build if download failed or the file is invalid
174
+ if _shared_lib is None: # meaning that the download and load failed
175
+ print("INFO: Download failed or produced an invalid library. Building from source...")
176
+ if build_go_library():
177
+ _shared_lib = load_shared_library(lib_path)
178
+ if _shared_lib is not None:
179
+ with open(version_file, "w") as f:
180
+ json.dump({"source": "local", "timestamp": go_source_time}, f)
181
+
182
+ # Final check
150
183
  if _shared_lib is None:
151
- try:
152
- _shared_lib = ctypes.CDLL(lib_path)
153
- except OSError as e:
154
- print(f"Error loading shared library at {lib_path}: {e}", file=sys.stderr)
155
- raise e
184
+ print("FATAL: Critical failure. Could not obtain or load the shared library.", file=sys.stderr)
185
+ sys.exit(1)
186
+ else:
187
+ print("SUCCESS: Library is ready to use.")
156
188
 
157
189
  # --- Function Prototypes (argtypes and restype) ---
158
190
  # Using void* for returned C strings, requiring TypeInterface for conversion/freeing.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unaiverse
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: UNaIVERSE: A Collectionless AI Project. The new web of humans & AI Agents, built on privacy, control, and reduced energy consumption.
5
5
  Author-email: Stefano Melacci <stefano.melacci@unisi.it>, Christian Di Maio <christian.dimaio@phd.unipi.it>, Tommaso Guidi <tommaso.guidi.1998@gmail.com>
6
6
  Maintainer-email: Stefano Melacci <stefano.melacci@unisi.it>, Christian Di Maio <christian.dimaio@phd.unipi.it>, Tommaso Guidi <tommaso.guidi.1998@gmail.com>
@@ -31,9 +31,11 @@ Requires-Dist: Pillow
31
31
  Requires-Dist: protobuf
32
32
  Requires-Dist: psutil
33
33
  Requires-Dist: PyJWT
34
+ Requires-Dist: cryptography
34
35
  Requires-Dist: Requests
35
36
  Requires-Dist: torch
36
37
  Requires-Dist: torchvision
38
+ Requires-Dist: transformers
37
39
  Dynamic: license-file
38
40
 
39
41
  <div align="center">
@@ -21,7 +21,7 @@ unaiverse/networking/node/connpool.py,sha256=hctRoYYGZA2D7sy1elIgE7o4umm8B9dZKq-
21
21
  unaiverse/networking/node/node.py,sha256=q740PylBIqHm6jKN32A1_meYUhbmHdDWmZ9ySJ7sMkY,117733
22
22
  unaiverse/networking/node/profile.py,sha256=lbB35MoI20oDxDqb97zH2NNNUCGJs8-8KIGNjjmnTio,20203
23
23
  unaiverse/networking/node/tokens.py,sha256=UHyPnl6TDvPitrkP2AYAIegSWq4CpvsjRvmio3T-3nA,5281
24
- unaiverse/networking/p2p/__init__.py,sha256=miT4Jp08mUgUFOYh9uyV0ZpTrd3N0trX3GBwTaEpuw8,12027
24
+ unaiverse/networking/p2p/__init__.py,sha256=ikRpQyJa2PRIeCLXcMWLWioJyyu1aS5I6twArCkhGhQ,13599
25
25
  unaiverse/networking/p2p/golibp2p.py,sha256=ibVCLERzM2JgPP_A5FTooCoxYW5Zm2HBbzX28aQIFzo,2450
26
26
  unaiverse/networking/p2p/golibp2p.pyi,sha256=ri7ZL8LQHx2rnwhXmQ9q2RiaTXeU6nitw1lB_L5Bhq4,4079
27
27
  unaiverse/networking/p2p/lib.go,sha256=l40IsZEC4a70LfJr8qzl8YDuh-fAcOaqaMPDLNG7IkI,108699
@@ -38,8 +38,8 @@ unaiverse/utils/lone_wolf.json,sha256=_rHfeqV8gqvPc0h-cZF7mPCG0Z4HuVkV-mKoXXwjbN
38
38
  unaiverse/utils/misc.py,sha256=4J3HotzosgsnEr9MgeuQmdrrISPuKl85oOAuKAfcz-U,12085
39
39
  unaiverse/utils/sandbox.py,sha256=S_eocNIGTyckovYMxmWb56wsCG7M-mxmGHqdLavSWQA,14436
40
40
  unaiverse/utils/server.py,sha256=hCxHTNmYGrgGYrwZ5RaQ9kdmmfqWuIVTUdPYLCwpTQU,21974
41
- unaiverse-0.1.1.dist-info/licenses/LICENSE,sha256=02v7juVPTazXHV7TG9WtaWrtmeC3BAd49itKH_SiHOs,1396
42
- unaiverse-0.1.1.dist-info/METADATA,sha256=wze9o2fuWikX1Bcv8mJq_eduX1-_zaeDKSElyN4-KyI,18212
43
- unaiverse-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
- unaiverse-0.1.1.dist-info/top_level.txt,sha256=0rP09tH9hv17TDQs66OHbJaRSnADpZsDsODy6JVsTtw,10
45
- unaiverse-0.1.1.dist-info/RECORD,,
41
+ unaiverse-0.1.2.dist-info/licenses/LICENSE,sha256=02v7juVPTazXHV7TG9WtaWrtmeC3BAd49itKH_SiHOs,1396
42
+ unaiverse-0.1.2.dist-info/METADATA,sha256=H-V1qkzJhcKhX_tmABnnA1SG2iPHfXY3TlSzyCjMKkI,18268
43
+ unaiverse-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
+ unaiverse-0.1.2.dist-info/top_level.txt,sha256=0rP09tH9hv17TDQs66OHbJaRSnADpZsDsODy6JVsTtw,10
45
+ unaiverse-0.1.2.dist-info/RECORD,,