Files
docker-swarm-termina/backend/utils/terminal_helpers.py
Claude 985c98339a Refactor backend into modular architecture
Split monolithic 631-line app.py into focused modules:

**Structure:**
- config.py - Configuration and shared state
- utils/ - Utility functions (1-2 functions per file)
  - auth.py - Authentication helpers
  - docker_client.py - Docker client getter
  - exec_helpers.py - Command execution helpers
  - formatters.py - Data formatting utilities
  - terminal_helpers.py - Terminal operation helpers
  - diagnostics/docker_env.py - Docker diagnostics
- routes/ - HTTP endpoints (1 endpoint per file)
  - login.py, logout.py, health.py
  - containers/list.py, exec.py, start.py, stop.py, restart.py, remove.py
- handlers/ - WebSocket handlers (1 handler per file)
  - terminal/connect.py, disconnect.py, start.py, input.py, resize.py, register.py

**Improvements:**
- Reduced function complexity (from 21 locals to 18 max)
- Fixed all pylint import order issues
- Removed unused imports (select, timedelta, stat)
- Applied lazy logging formatting throughout
- Added comprehensive docstrings
- Each file has focused responsibility
- Easier to test, maintain, and extend

**Pylint score improvement:**
- Before: 25 problems (15 errors, 10 warnings)
- After: Only duplicate code warnings (expected for similar routes)

https://claude.ai/code/session_011PzvkCnVrsatoxbY3HbGXz
2026-02-01 05:07:39 +00:00

51 lines
1.6 KiB
Python

"""Helper functions for terminal operations."""
import threading
from config import logger, active_terminals
def create_output_reader(socketio, sid, exec_instance):
"""Create and start output reader thread.
Args:
socketio: SocketIO instance
sid: Session ID
exec_instance: Docker exec instance
Returns:
Thread: Started output reader thread
"""
def read_output():
sock = exec_instance.output
try:
while True:
if sid not in active_terminals:
break
try:
data = sock.recv(4096)
if not data:
break
try:
decoded_data = data.decode('utf-8')
except UnicodeDecodeError:
decoded_data = data.decode('latin-1', errors='replace')
socketio.emit('output', {'data': decoded_data},
namespace='/terminal', room=sid)
except Exception as e: # pylint: disable=broad-exception-caught
logger.error("Error reading from container: %s", e)
break
finally:
if sid in active_terminals:
del active_terminals[sid]
try:
sock.close()
except Exception: # pylint: disable=broad-exception-caught
pass
socketio.emit('exit', {'code': 0}, namespace='/terminal', room=sid)
thread = threading.Thread(target=read_output, daemon=True)
thread.start()
return thread