Files
prezenta_work/dependencies_module.py
Developer eedf3a1c69 Optimize: Reduce dependencies to minimal set for headless RFID client
REMOVED:
- aiohttp, multidict, aiosignal, frozenlist, attrs, yarl, propcache (Flask async dependencies)
- flask, chart (not needed for headless device)
- selenium (web automation not needed)

KEPT (7 core dependencies only):
- rdm6300: RFID reader library
- requests: HTTP communication to server
- gpiozero: GPIO/system access
- urllib3, certifi, charset_normalizer, idna: requests dependencies

IMPROVEMENTS:
- Skip trying to install wrong-architecture wheels (aarch64)
- Let pip download correct ARM32/ARM64 version for device
- Much faster startup on resource-constrained Raspberry Pi
- Pure Python wheels installed from local repository
- Removes 11+ unnecessary packages
2025-12-18 14:29:27 +02:00

131 lines
5.7 KiB
Python

"""
Dependency management
Handles package installation and verification
"""
import sys
import subprocess
import importlib.util
from config_settings import REQUIRED_PACKAGES, REPOSITORY_PATH
def install_package_from_wheel(wheel_path, package_name):
"""Install a Python package from a wheel file"""
try:
print(f"Installing {package_name} from {wheel_path}...")
result = subprocess.run([
sys.executable, "-m", "pip", "install", wheel_path,
"--no-index", "--no-deps", "--break-system-packages",
"--no-warn-script-location", "--force-reinstall"
], capture_output=True, text=True, timeout=60)
if result.returncode == 0:
print(f"{package_name} installed successfully")
return True
else:
print(f"✗ Failed to install {package_name}: {result.stderr}")
return False
except Exception as e:
print(f"✗ Error installing {package_name}: {e}")
return False
def check_and_install_dependencies():
"""Check if required packages are installed and install them from local repository if needed"""
print("Checking and installing dependencies...")
repository_path = str(REPOSITORY_PATH)
missing_packages = []
# Check each required package
for package_name, wheel_file in REQUIRED_PACKAGES.items():
try:
spec = importlib.util.find_spec(package_name)
if spec is not None:
print(f"{package_name} is already installed")
else:
raise ImportError(f"Package {package_name} not found")
except ImportError:
print(f"{package_name} is not installed")
missing_packages.append((package_name, wheel_file))
except Exception as e:
print(f"✗ Error checking {package_name}: {e}")
missing_packages.append((package_name, wheel_file))
# Install missing packages
if missing_packages:
print(f"\nInstalling {len(missing_packages)} missing packages...")
for package_name, wheel_file in missing_packages:
if wheel_file is None:
# Try to install via pip from internet (for system packages)
try:
print(f"Attempting to install {package_name} via pip...")
result = subprocess.run([
sys.executable, "-m", "pip", "install", package_name,
"--break-system-packages", "--no-warn-script-location"
], capture_output=True, text=True, timeout=120)
if result.returncode == 0:
print(f"{package_name} installed via pip")
else:
print(f"⚠ pip install failed, trying apt...")
if package_name in ['gpiozero']:
try:
print(f"Attempting to install {package_name} via apt...")
result = subprocess.run([
'sudo', 'apt', 'install', '-y', f'python3-{package_name}',
'--no-install-recommends'
], capture_output=True, text=True, timeout=120)
if result.returncode == 0:
print(f"{package_name} installed via apt")
else:
print(f"✗ Could not install {package_name} via apt")
except Exception as apt_e:
print(f"✗ apt install failed: {apt_e}")
except Exception as pip_e:
print(f"✗ pip install failed: {pip_e}")
else:
# Try to install from wheel file (pure Python wheels like rdm6300, certifi, etc.)
wheel_path = f"{repository_path}/{wheel_file}"
# Only try wheel files that are pure Python (not architecture-specific)
if not ('aarch64' in wheel_file or 'armv' in wheel_file):
install_package_from_wheel(wheel_path, package_name)
else:
# For architecture-specific wheels, try pip to get the right arch
print(f"Skipping wheel {package_name} (wrong architecture), trying pip...")
try:
result = subprocess.run([
sys.executable, "-m", "pip", "install", package_name,
"--break-system-packages", "--no-warn-script-location"
], capture_output=True, text=True, timeout=120)
if result.returncode == 0:
print(f"{package_name} installed via pip")
else:
print(f"✗ Could not install {package_name}: {result.stderr}")
except Exception as e:
print(f"✗ Error installing {package_name}: {e}")
def verify_dependencies():
"""Verify that all required dependencies are available"""
print("Verifying dependencies...")
available = True
for package_name in REQUIRED_PACKAGES.keys():
try:
spec = importlib.util.find_spec(package_name)
if spec is not None:
print(f"{package_name} verified")
else:
print(f"{package_name} not available")
available = False
except Exception as e:
print(f"✗ Error verifying {package_name}: {e}")
available = False
return available