mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
remove venv from web v2
This commit is contained in:
23
cleanup_venv.sh
Normal file
23
cleanup_venv.sh
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Cleanup script to remove virtual environment if it exists
|
||||||
|
# This script removes the venv_web_v2 directory if it exists
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
echo "Cleaning up virtual environment..."
|
||||||
|
|
||||||
|
# Check if virtual environment exists and remove it
|
||||||
|
if [ -d "venv_web_v2" ]; then
|
||||||
|
echo "Removing existing virtual environment..."
|
||||||
|
rm -rf venv_web_v2
|
||||||
|
echo "Virtual environment removed successfully"
|
||||||
|
else
|
||||||
|
echo "No virtual environment found to remove"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cleanup complete!"
|
||||||
@@ -9,3 +9,15 @@ freetype-py>=2.3.0
|
|||||||
numpy>=1.21.0
|
numpy>=1.21.0
|
||||||
requests>=2.25.0
|
requests>=2.25.0
|
||||||
python-dateutil>=2.8.0
|
python-dateutil>=2.8.0
|
||||||
|
pytz==2023.3
|
||||||
|
timezonefinder==6.2.0
|
||||||
|
geopy==2.4.1
|
||||||
|
google-auth-oauthlib==1.0.0
|
||||||
|
google-auth-httplib2==0.1.0
|
||||||
|
google-api-python-client==2.86.0
|
||||||
|
spotipy
|
||||||
|
unidecode
|
||||||
|
icalevents
|
||||||
|
python-engineio
|
||||||
|
websockets
|
||||||
|
websocket-client
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# LED Matrix Web Interface V2 Runner
|
# LED Matrix Web Interface V2 Runner
|
||||||
# This script sets up a virtual environment and runs the web interface
|
# This script runs the web interface using system Python
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -11,24 +11,14 @@ cd "$SCRIPT_DIR"
|
|||||||
|
|
||||||
echo "Setting up LED Matrix Web Interface V2..."
|
echo "Setting up LED Matrix Web Interface V2..."
|
||||||
|
|
||||||
# Check if virtual environment exists
|
# Install dependencies using system Python
|
||||||
if [ ! -d "venv_web_v2" ]; then
|
|
||||||
echo "Creating virtual environment..."
|
|
||||||
python3 -m venv venv_web_v2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Activate virtual environment
|
|
||||||
echo "Activating virtual environment..."
|
|
||||||
source venv_web_v2/bin/activate
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
echo "Installing dependencies..."
|
echo "Installing dependencies..."
|
||||||
pip install -r requirements_web_v2.txt
|
python3 -m pip install -r requirements_web_v2.txt
|
||||||
|
|
||||||
# Install rgbmatrix module from local source
|
# Install rgbmatrix module from local source
|
||||||
echo "Installing rgbmatrix module..."
|
echo "Installing rgbmatrix module..."
|
||||||
pip install -e rpi-rgb-led-matrix-master/bindings/python
|
python3 -m pip install -e rpi-rgb-led-matrix-master/bindings/python
|
||||||
|
|
||||||
# Run the web interface
|
# Run the web interface
|
||||||
echo "Starting web interface on http://0.0.0.0:5001"
|
echo "Starting web interface on http://0.0.0.0:5001"
|
||||||
python web_interface_v2.py
|
python3 web_interface_v2.py
|
||||||
@@ -8,45 +8,13 @@ PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|||||||
CONFIG_FILE = os.path.join(PROJECT_DIR, 'config', 'config.json')
|
CONFIG_FILE = os.path.join(PROJECT_DIR, 'config', 'config.json')
|
||||||
WEB_INTERFACE_SCRIPT = os.path.join(PROJECT_DIR, 'web_interface_v2.py')
|
WEB_INTERFACE_SCRIPT = os.path.join(PROJECT_DIR, 'web_interface_v2.py')
|
||||||
|
|
||||||
def setup_virtual_environment():
|
def install_dependencies():
|
||||||
"""Set up a virtual environment for the web interface if it doesn't exist."""
|
"""Install required dependencies using system Python."""
|
||||||
venv_path = Path(PROJECT_DIR) / 'venv_web_v2'
|
|
||||||
|
|
||||||
if not venv_path.exists():
|
|
||||||
print("Creating virtual environment...")
|
|
||||||
try:
|
|
||||||
subprocess.check_call([
|
|
||||||
sys.executable, '-m', 'venv', str(venv_path)
|
|
||||||
])
|
|
||||||
print("Virtual environment created successfully")
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print(f"Failed to create virtual environment: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
return venv_path
|
|
||||||
|
|
||||||
def get_venv_python(venv_path):
|
|
||||||
"""Get the Python executable path from the virtual environment."""
|
|
||||||
if os.name == 'nt': # Windows
|
|
||||||
return venv_path / 'Scripts' / 'python.exe'
|
|
||||||
else: # Unix/Linux
|
|
||||||
return venv_path / 'bin' / 'python'
|
|
||||||
|
|
||||||
def get_venv_pip(venv_path):
|
|
||||||
"""Get the pip executable path from the virtual environment."""
|
|
||||||
if os.name == 'nt': # Windows
|
|
||||||
return venv_path / 'Scripts' / 'pip.exe'
|
|
||||||
else: # Unix/Linux
|
|
||||||
return venv_path / 'bin' / 'pip'
|
|
||||||
|
|
||||||
def install_dependencies(venv_path):
|
|
||||||
"""Install required dependencies in the virtual environment."""
|
|
||||||
print("Installing dependencies...")
|
print("Installing dependencies...")
|
||||||
try:
|
try:
|
||||||
venv_pip = get_venv_pip(venv_path)
|
|
||||||
requirements_file = os.path.join(PROJECT_DIR, 'requirements_web_v2.txt')
|
requirements_file = os.path.join(PROJECT_DIR, 'requirements_web_v2.txt')
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
str(venv_pip), 'install', '-r', requirements_file
|
sys.executable, '-m', 'pip', 'install', '-r', requirements_file
|
||||||
])
|
])
|
||||||
print("Dependencies installed successfully")
|
print("Dependencies installed successfully")
|
||||||
|
|
||||||
@@ -55,7 +23,7 @@ def install_dependencies(venv_path):
|
|||||||
rgbmatrix_path = Path(PROJECT_DIR) / 'rpi-rgb-led-matrix-master' / 'bindings' / 'python'
|
rgbmatrix_path = Path(PROJECT_DIR) / 'rpi-rgb-led-matrix-master' / 'bindings' / 'python'
|
||||||
if rgbmatrix_path.exists():
|
if rgbmatrix_path.exists():
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
str(venv_pip), 'install', '-e', str(rgbmatrix_path)
|
sys.executable, '-m', 'pip', 'install', '-e', str(rgbmatrix_path)
|
||||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
print("rgbmatrix module installed successfully")
|
print("rgbmatrix module installed successfully")
|
||||||
|
|
||||||
@@ -64,18 +32,6 @@ def install_dependencies(venv_path):
|
|||||||
print(f"Failed to install dependencies: {e}")
|
print(f"Failed to install dependencies: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_python_executable():
|
|
||||||
"""Prefer the venv_web_v2 Python if present, else fall back to current interpreter."""
|
|
||||||
project_dir = PROJECT_DIR
|
|
||||||
venv_path = Path(project_dir) / 'venv_web_v2'
|
|
||||||
|
|
||||||
if venv_path.exists():
|
|
||||||
venv_python = get_venv_python(venv_path)
|
|
||||||
if venv_python.exists():
|
|
||||||
return str(venv_python)
|
|
||||||
|
|
||||||
return sys.executable
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
with open(CONFIG_FILE, 'r') as f:
|
with open(CONFIG_FILE, 'r') as f:
|
||||||
@@ -92,21 +48,17 @@ def main():
|
|||||||
if autostart_enabled is True: # Explicitly check for True
|
if autostart_enabled is True: # Explicitly check for True
|
||||||
print("Configuration 'web_display_autostart' is true. Starting web interface...")
|
print("Configuration 'web_display_autostart' is true. Starting web interface...")
|
||||||
|
|
||||||
# Set up virtual environment if it doesn't exist
|
# Install dependencies
|
||||||
venv_path = setup_virtual_environment()
|
if not install_dependencies():
|
||||||
if venv_path:
|
print("Failed to install dependencies. Exiting.")
|
||||||
# Install dependencies
|
sys.exit(1)
|
||||||
if not install_dependencies(venv_path):
|
|
||||||
print("Failed to install dependencies. Exiting.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Replace the current process with web_interface.py
|
# Replace the current process with web_interface.py using system Python
|
||||||
# This is important for systemd to correctly manage the web server process.
|
# This is important for systemd to correctly manage the web server process.
|
||||||
# Ensure PYTHONPATH is set correctly if web_interface.py has relative imports to src
|
# Ensure PYTHONPATH is set correctly if web_interface.py has relative imports to src
|
||||||
# The WorkingDirectory in systemd service should handle this for web_interface.py
|
# The WorkingDirectory in systemd service should handle this for web_interface.py
|
||||||
py_exec = get_python_executable()
|
os.execvp(sys.executable, [sys.executable, WEB_INTERFACE_SCRIPT])
|
||||||
os.execvp(py_exec, [py_exec, WEB_INTERFACE_SCRIPT])
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to exec web interface: {e}")
|
print(f"Failed to exec web interface: {e}")
|
||||||
sys.exit(1) # Failed to start
|
sys.exit(1) # Failed to start
|
||||||
|
|||||||
@@ -22,39 +22,8 @@ logging.basicConfig(
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def setup_virtual_environment():
|
def check_dependencies():
|
||||||
"""Set up a virtual environment for the web interface."""
|
"""Check if required dependencies are installed."""
|
||||||
venv_path = Path(__file__).parent / 'venv_web_v2'
|
|
||||||
|
|
||||||
if not venv_path.exists():
|
|
||||||
logger.info("Creating virtual environment...")
|
|
||||||
try:
|
|
||||||
subprocess.check_call([
|
|
||||||
sys.executable, '-m', 'venv', str(venv_path)
|
|
||||||
])
|
|
||||||
logger.info("Virtual environment created successfully")
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
logger.error(f"Failed to create virtual environment: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
return venv_path
|
|
||||||
|
|
||||||
def get_venv_python(venv_path):
|
|
||||||
"""Get the Python executable path from the virtual environment."""
|
|
||||||
if os.name == 'nt': # Windows
|
|
||||||
return venv_path / 'Scripts' / 'python.exe'
|
|
||||||
else: # Unix/Linux
|
|
||||||
return venv_path / 'bin' / 'python'
|
|
||||||
|
|
||||||
def get_venv_pip(venv_path):
|
|
||||||
"""Get the pip executable path from the virtual environment."""
|
|
||||||
if os.name == 'nt': # Windows
|
|
||||||
return venv_path / 'Scripts' / 'pip.exe'
|
|
||||||
else: # Unix/Linux
|
|
||||||
return venv_path / 'bin' / 'pip'
|
|
||||||
|
|
||||||
def check_dependencies(venv_path):
|
|
||||||
"""Check if required dependencies are installed in the virtual environment."""
|
|
||||||
required_packages = [
|
required_packages = [
|
||||||
'flask',
|
'flask',
|
||||||
'flask_socketio',
|
'flask_socketio',
|
||||||
@@ -64,25 +33,19 @@ def check_dependencies(venv_path):
|
|||||||
'freetype'
|
'freetype'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Use the virtual environment's Python to check imports
|
|
||||||
venv_python = get_venv_python(venv_path)
|
|
||||||
|
|
||||||
missing_packages = []
|
missing_packages = []
|
||||||
for package in required_packages:
|
for package in required_packages:
|
||||||
try:
|
try:
|
||||||
subprocess.check_call([
|
__import__(package)
|
||||||
str(venv_python), '-c', f'import {package}'
|
except ImportError:
|
||||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
missing_packages.append(package)
|
missing_packages.append(package)
|
||||||
|
|
||||||
if missing_packages:
|
if missing_packages:
|
||||||
logger.warning(f"Missing packages: {missing_packages}")
|
logger.warning(f"Missing packages: {missing_packages}")
|
||||||
logger.info("Installing missing packages in virtual environment...")
|
logger.info("Installing missing packages...")
|
||||||
try:
|
try:
|
||||||
venv_pip = get_venv_pip(venv_path)
|
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
str(venv_pip), 'install', '-r', 'requirements_web_v2.txt'
|
sys.executable, '-m', 'pip', 'install', '-r', 'requirements_web_v2.txt'
|
||||||
])
|
])
|
||||||
logger.info("Dependencies installed successfully")
|
logger.info("Dependencies installed successfully")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
@@ -92,10 +55,9 @@ def check_dependencies(venv_path):
|
|||||||
# Install rgbmatrix module from local source
|
# Install rgbmatrix module from local source
|
||||||
logger.info("Installing rgbmatrix module...")
|
logger.info("Installing rgbmatrix module...")
|
||||||
try:
|
try:
|
||||||
venv_pip = get_venv_pip(venv_path)
|
|
||||||
rgbmatrix_path = Path(__file__).parent / 'rpi-rgb-led-matrix-master' / 'bindings' / 'python'
|
rgbmatrix_path = Path(__file__).parent / 'rpi-rgb-led-matrix-master' / 'bindings' / 'python'
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
str(venv_pip), 'install', '-e', str(rgbmatrix_path)
|
sys.executable, '-m', 'pip', 'install', '-e', str(rgbmatrix_path)
|
||||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
logger.info("rgbmatrix module installed successfully")
|
logger.info("rgbmatrix module installed successfully")
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
@@ -125,29 +87,22 @@ def main():
|
|||||||
script_dir = Path(__file__).parent
|
script_dir = Path(__file__).parent
|
||||||
os.chdir(script_dir)
|
os.chdir(script_dir)
|
||||||
|
|
||||||
# Set up virtual environment
|
# Check dependencies
|
||||||
venv_path = setup_virtual_environment()
|
if not check_dependencies():
|
||||||
if not venv_path:
|
|
||||||
logger.error("Failed to set up virtual environment. Exiting.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Check dependencies in virtual environment
|
|
||||||
if not check_dependencies(venv_path):
|
|
||||||
logger.error("Dependency check failed. Exiting.")
|
logger.error("Dependency check failed. Exiting.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Check permissions
|
# Check permissions
|
||||||
check_permissions()
|
check_permissions()
|
||||||
|
|
||||||
# Import and start the web interface using the virtual environment's Python
|
# Import and start the web interface using system Python
|
||||||
try:
|
try:
|
||||||
venv_python = get_venv_python(venv_path)
|
|
||||||
logger.info("Web interface loaded successfully")
|
logger.info("Web interface loaded successfully")
|
||||||
|
|
||||||
# Start the server using the virtual environment's Python
|
# Start the server using system Python
|
||||||
logger.info("Starting web server on http://0.0.0.0:5001")
|
logger.info("Starting web server on http://0.0.0.0:5001")
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
str(venv_python), 'web_interface_v2.py'
|
sys.executable, 'web_interface_v2.py'
|
||||||
])
|
])
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ The script will:
|
|||||||
|
|
||||||
**Note**: The first time the service starts, it will automatically:
|
**Note**: The first time the service starts, it will automatically:
|
||||||
- Create a Python virtual environment (`venv_web_v2`)
|
- Create a Python virtual environment (`venv_web_v2`)
|
||||||
- Install required dependencies (Flask, numpy, requests, etc.)
|
- Install required dependencies (Flask, numpy, requests, Google APIs, Spotify, etc.)
|
||||||
- Install the rgbmatrix module from the local source
|
- Install the rgbmatrix module from the local source
|
||||||
|
|
||||||
This process may take a few minutes on the first run.
|
This process may take several minutes on the first run as it installs all dependencies needed by the LEDMatrix system.
|
||||||
|
|
||||||
### Step 2: Configure Web Interface Autostart
|
### Step 2: Configure Web Interface Autostart
|
||||||
|
|
||||||
@@ -223,7 +223,10 @@ sudo ufw allow 5001
|
|||||||
**Symptoms:**
|
**Symptoms:**
|
||||||
- Service shows as failed in systemctl status
|
- Service shows as failed in systemctl status
|
||||||
- Error messages in logs
|
- Error messages in logs
|
||||||
- Common error: `ModuleNotFoundError: No module named 'numpy'`
|
- Common errors:
|
||||||
|
- `ModuleNotFoundError: No module named 'numpy'`
|
||||||
|
- `ModuleNotFoundError: No module named 'google'`
|
||||||
|
- `ModuleNotFoundError: No module named 'spotipy'`
|
||||||
|
|
||||||
**Diagnosis:**
|
**Diagnosis:**
|
||||||
1. Check service logs:
|
1. Check service logs:
|
||||||
@@ -233,7 +236,7 @@ journalctl -u ledmatrix-web.service -n 50
|
|||||||
|
|
||||||
2. Verify Python dependencies:
|
2. Verify Python dependencies:
|
||||||
```bash
|
```bash
|
||||||
python3 -c "import flask, flask_socketio, PIL, numpy"
|
python3 -c "import flask, flask_socketio, PIL, numpy, google, spotipy"
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Check virtual environment:
|
3. Check virtual environment:
|
||||||
@@ -270,6 +273,31 @@ sudo chown -R ledpi:ledpi /home/ledpi/LEDMatrix
|
|||||||
sudo chmod +x install_web_service.sh
|
sudo chmod +x install_web_service.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Missing Dependencies
|
||||||
|
|
||||||
|
**Symptoms:**
|
||||||
|
- Import errors for specific modules (google, spotipy, numpy, etc.)
|
||||||
|
- Service fails during startup with ModuleNotFoundError
|
||||||
|
|
||||||
|
**Cause:**
|
||||||
|
The web interface imports all LEDMatrix modules, which require the same dependencies as the main system.
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
The updated `requirements_web_v2.txt` now includes all necessary dependencies. If you're still seeing issues:
|
||||||
|
|
||||||
|
1. Ensure you're using the latest requirements file
|
||||||
|
2. Recreate the virtual environment:
|
||||||
|
```bash
|
||||||
|
rm -rf venv_web_v2
|
||||||
|
sudo systemctl restart ledmatrix-web.service
|
||||||
|
```
|
||||||
|
|
||||||
|
3. If specific modules are still missing, install them manually:
|
||||||
|
```bash
|
||||||
|
source venv_web_v2/bin/activate
|
||||||
|
pip install google-auth-oauthlib google-api-python-client spotipy
|
||||||
|
```
|
||||||
|
|
||||||
### Import Errors
|
### Import Errors
|
||||||
|
|
||||||
**Symptoms:**
|
**Symptoms:**
|
||||||
|
|||||||
Reference in New Issue
Block a user