Skip to content

Third Party Installer - Developer Guide

This guide provides advanced technical information for developers who need to integrate, extend, or customize the Third Party Installer module.

Developer Workflow Integration

Embedding in Applications

The Third Party Installer is designed for seamless integration into larger applications:

from third_party_installer.core.installer import ThirdPartyInstaller, InstallationStatus
from pathlib import Path
import logging

class ApplicationWithDependencies:
    def __init__(self):
        self.installer = ThirdPartyInstaller()
        self.setup_logging()

    def setup_logging(self):
        """Configure logging for installation operations"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('installation.log'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)

    def ensure_dependencies(self) -> bool:
        """Ensure all required tools are installed before proceeding"""
        missing_tools = self.installer.get_missing_required_tools()

        if not missing_tools:
            self.logger.info("All required tools are already installed")
            return True

        self.logger.info(f"Missing required tools: {missing_tools}")

        # Option 1: Automatic installation
        return self._install_missing_tools(missing_tools)

        # Option 2: Prompt user for installation
        # return self._prompt_user_for_installation(missing_tools)

    def _install_missing_tools(self, tools: list) -> bool:
        """Install missing tools automatically"""
        success_count = 0

        for tool_name in tools:
            self.logger.info(f"Installing {tool_name}...")

            try:
                success = self.installer.install_tool(
                    tool_name, 
                    progress_callback=self._log_progress
                )

                if success:
                    success_count += 1
                    self.logger.info(f"Successfully installed {tool_name}")
                else:
                    self.logger.error(f"Failed to install {tool_name}")

            except Exception as e:
                self.logger.error(f"Exception during {tool_name} installation: {e}")

        return success_count == len(tools)

    def _log_progress(self, progress: int, message: str):
        """Log installation progress"""
        if progress % 10 == 0:  # Log every 10%
            self.logger.info(f"Progress: {progress}% - {message}")

    def run_application(self):
        """Main application entry point with dependency checking"""
        if not self.ensure_dependencies():
            self.logger.error("Failed to install required dependencies")
            return False

        self.logger.info("Starting application with all dependencies satisfied")
        # Your application logic here
        return True

# Usage
if __name__ == "__main__":
    app = ApplicationWithDependencies()
    app.run_application()

Custom Tool Definitions

Add support for your own tools by extending the configuration:

from third_party_installer.core.installer import ThirdPartyTool
import json
from pathlib import Path

class CustomToolManager:
    def __init__(self, installer: ThirdPartyInstaller):
        self.installer = installer

    def add_custom_tools(self):
        """Add custom tools to the installer configuration"""

        # Example: Adding OpenSSH as a managed tool
        openssh_tool = ThirdPartyTool(
            name='openssh',
            display_name='OpenSSH Client',
            description='OpenSSH client for secure shell connections',
            download_url='https://github.com/PowerShell/Win32-OpenSSH/releases/latest/download/OpenSSH-Win64.zip',
            executable_paths=[
                'C:\\Program Files\\OpenSSH\\ssh.exe',
                'C:\\Windows\\System32\\OpenSSH\\ssh.exe',
                'C:\\OpenSSH\\ssh.exe'
            ],
            version_command='ssh -V',
            installer_type='zip',
            required=True,
            dependencies=[]
        )

        # Example: Adding a custom monitoring tool
        monitoring_tool = ThirdPartyTool(
            name='custom_monitor',
            display_name='Custom Network Monitor',
            description='Custom tool for network monitoring',
            download_url='https://your-company.com/tools/monitor.exe',
            executable_paths=[
                'C:\\Program Files\\CustomMonitor\\monitor.exe',
                'C:\\Tools\\monitor.exe'
            ],
            version_command='monitor.exe --version',
            installer_type='exe',
            required=False,
            dependencies=['openssh']
        )

        # Add to installer configuration
        self.installer.tools_config['openssh'] = openssh_tool
        self.installer.tools_config['custom_monitor'] = monitoring_tool

        # Save custom configuration
        self._save_custom_config()

    def _save_custom_config(self):
        """Save custom tool configuration to file"""
        config_path = Path(self.installer.config_dir) / 'custom_tools.json'

        custom_tools = {}
        for name, tool in self.installer.tools_config.items():
            if name not in ['psexec', 'vlc', 'ffmpeg', 'px']:  # Skip built-in tools
                custom_tools[name] = {
                    'name': tool.name,
                    'display_name': tool.display_name,
                    'description': tool.description,
                    'download_url': tool.download_url,
                    'executable_paths': tool.executable_paths,
                    'version_command': tool.version_command,
                    'installer_type': tool.installer_type,
                    'required': tool.required,
                    'dependencies': tool.dependencies
                }

        with open(config_path, 'w') as f:
            json.dump(custom_tools, f, indent=2)

    def load_custom_config(self):
        """Load custom tool configuration from file"""
        config_path = Path(self.installer.config_dir) / 'custom_tools.json'

        if not config_path.exists():
            return

        try:
            with open(config_path, 'r') as f:
                custom_tools = json.load(f)

            for name, config in custom_tools.items():
                tool = ThirdPartyTool(**config)
                self.installer.tools_config[name] = tool

        except Exception as e:
            print(f"Failed to load custom tools: {e}")

# Usage
installer = ThirdPartyInstaller()
custom_manager = CustomToolManager(installer)
custom_manager.load_custom_config()
custom_manager.add_custom_tools()

Advanced Proxy Configuration

Handle complex corporate proxy scenarios:

class CorporateProxyManager:
    def __init__(self, installer: ThirdPartyInstaller):
        self.installer = installer

    def setup_corporate_proxy(self):
        """Configure proxy for corporate environment"""

        # Try to detect existing proxy configuration
        if self._detect_system_proxy():
            self.installer.proxy_config['auto_detect'] = True
            return True

        # Try PX proxy tool
        if self._setup_px_proxy():
            return True

        # Fallback to manual configuration
        return self._setup_manual_proxy()

    def _detect_system_proxy(self) -> bool:
        """Detect system proxy settings"""
        try:
            import winreg

            # Check Windows registry for proxy settings
            with winreg.OpenKey(winreg.HKEY_CURRENT_USER, 
                              r"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings") as key:

                proxy_enabled = winreg.QueryValueEx(key, "ProxyEnable")[0]
                if proxy_enabled:
                    proxy_server = winreg.QueryValueEx(key, "ProxyServer")[0]
                    self.installer.proxy_config.update({
                        'enabled': True,
                        'auto_detect': True,
                        'server': proxy_server.split(':')[0],
                        'port': int(proxy_server.split(':')[1]) if ':' in proxy_server else 8080
                    })
                    return True

        except Exception:
            pass

        return False

    def _setup_px_proxy(self) -> bool:
        """Setup PX corporate proxy tool"""
        px_status = self.installer.get_tool_status('px')

        if px_status != InstallationStatus.INSTALLED:
            # Install PX if not available
            success = self.installer.install_tool('px')
            if not success:
                return False

        # Configure PX proxy
        self.installer.proxy_config.update({
            'enabled': True,
            'use_px': True,
            'px_port': 3128
        })

        return True

    def _setup_manual_proxy(self) -> bool:
        """Setup manual proxy configuration"""
        # In a real application, prompt user for proxy details
        # For this example, we'll use environment variables
        import os

        proxy_server = os.getenv('HTTP_PROXY') or os.getenv('HTTPS_PROXY')
        if proxy_server:
            # Parse proxy URL (e.g., http://proxy.company.com:8080)
            from urllib.parse import urlparse
            parsed = urlparse(proxy_server)

            self.installer.proxy_config.update({
                'enabled': True,
                'auto_detect': False,
                'server': parsed.hostname,
                'port': parsed.port or 8080,
                'username': parsed.username,
                'password': parsed.password
            })
            return True

        return False

# Usage
proxy_manager = CorporateProxyManager(installer)
proxy_manager.setup_corporate_proxy()

Debugging and Troubleshooting

Comprehensive Logging Setup

import logging
import sys
from pathlib import Path

class InstallerDebugger:
    def __init__(self, installer: ThirdPartyInstaller):
        self.installer = installer
        self.setup_debug_logging()

    def setup_debug_logging(self):
        """Setup comprehensive logging for debugging"""
        log_dir = Path(self.installer.config_dir) / 'logs'
        log_dir.mkdir(exist_ok=True)

        # Create formatters
        detailed_formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
        )
        simple_formatter = logging.Formatter('%(levelname)s: %(message)s')

        # File handler for detailed logs
        file_handler = logging.FileHandler(log_dir / 'installer_debug.log')
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(detailed_formatter)

        # Console handler for important messages
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(logging.INFO)
        console_handler.setFormatter(simple_formatter)

        # Configure logger
        logger = logging.getLogger('third_party_installer')
        logger.setLevel(logging.DEBUG)
        logger.addHandler(file_handler)
        logger.addHandler(console_handler)

        # Prevent duplicate logs
        logger.propagate = False

        return logger

    def diagnose_installation_issues(self, tool_name: str):
        """Comprehensive diagnosis of installation issues"""
        logger = logging.getLogger('third_party_installer')
        tool = self.installer.tools_config.get(tool_name)

        if not tool:
            logger.error(f"Tool '{tool_name}' not found in configuration")
            return

        logger.info(f"Diagnosing installation issues for {tool.display_name}")

        # Check tool configuration
        self._check_tool_config(tool, logger)

        # Check network connectivity
        self._check_network_connectivity(tool, logger)

        # Check system requirements
        self._check_system_requirements(tool, logger)

        # Check permissions
        self._check_permissions(tool, logger)

        # Check existing installation
        self._check_existing_installation(tool, logger)

    def _check_tool_config(self, tool: ThirdPartyTool, logger):
        """Validate tool configuration"""
        logger.info("Checking tool configuration...")

        required_fields = ['name', 'download_url', 'executable_paths', 'installer_type']
        for field in required_fields:
            value = getattr(tool, field, None)
            if not value:
                logger.error(f"Missing required field: {field}")
            else:
                logger.debug(f"{field}: {value}")

    def _check_network_connectivity(self, tool: ThirdPartyTool, logger):
        """Check network connectivity to download source"""
        logger.info("Checking network connectivity...")

        try:
            import urllib.request
            import ssl

            # Create SSL context that doesn't verify certificates (for testing)
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE

            # Attempt to connect to download URL
            req = urllib.request.Request(tool.download_url)
            req.add_header('User-Agent', 'SSH-Tools-Suite-Installer/1.0')

            with urllib.request.urlopen(req, context=ssl_context, timeout=10) as response:
                if response.getcode() == 200:
                    logger.info(f"Successfully connected to {tool.download_url}")
                    content_length = response.headers.get('Content-Length')
                    if content_length:
                        logger.info(f"Download size: {int(content_length) / 1024 / 1024:.1f} MB")
                else:
                    logger.warning(f"Unexpected response code: {response.getcode()}")

        except Exception as e:
            logger.error(f"Network connectivity test failed: {e}")
            logger.info("Possible issues:")
            logger.info("- No internet connection")
            logger.info("- Corporate firewall blocking access")
            logger.info("- Proxy configuration required")
            logger.info("- Download URL is invalid or moved")

    def _check_system_requirements(self, tool: ThirdPartyTool, logger):
        """Check system requirements for tool installation"""
        logger.info("Checking system requirements...")

        import platform
        import shutil
        import psutil

        # Platform check
        system = platform.system()
        logger.info(f"Operating System: {system} {platform.release()}")

        # Disk space check
        if hasattr(shutil, 'disk_usage'):
            total, used, free = shutil.disk_usage('/')
            free_gb = free / (1024**3)
            logger.info(f"Available disk space: {free_gb:.1f} GB")

            if free_gb < 1.0:  # Less than 1GB free
                logger.warning("Low disk space may cause installation failures")

        # Memory check
        memory = psutil.virtual_memory()
        logger.info(f"Available memory: {memory.available / (1024**3):.1f} GB")

        # Administrator privileges check (Windows)
        if system == 'Windows':
            import ctypes
            is_admin = ctypes.windll.shell32.IsUserAnAdmin()
            logger.info(f"Administrator privileges: {'Yes' if is_admin else 'No'}")

            if not is_admin and tool.installer_type in ['msi', 'exe']:
                logger.warning("Administrator privileges may be required for installation")

    def _check_permissions(self, tool: ThirdPartyTool, logger):
        """Check file system permissions"""
        logger.info("Checking file system permissions...")

        # Check write permissions for installation directories
        for exe_path in tool.executable_paths:
            install_dir = Path(exe_path).parent
            logger.debug(f"Checking directory: {install_dir}")

            try:
                # Try to create a test file
                test_file = install_dir / '.installer_test'
                test_file.touch()
                test_file.unlink()
                logger.info(f"Write access confirmed: {install_dir}")
                break
            except PermissionError:
                logger.warning(f"No write access: {install_dir}")
            except FileNotFoundError:
                logger.info(f"Directory does not exist: {install_dir}")

        # Check temporary directory permissions
        temp_dir = Path(self.installer.temp_dir)
        try:
            test_file = temp_dir / '.installer_test'
            test_file.touch()
            test_file.unlink()
            logger.info(f"Temporary directory accessible: {temp_dir}")
        except Exception as e:
            logger.error(f"Temporary directory issues: {e}")

    def _check_existing_installation(self, tool: ThirdPartyTool, logger):
        """Check for existing installations"""
        logger.info("Checking for existing installations...")

        status = self.installer.get_tool_status(tool.name)
        logger.info(f"Current status: {status.value}")

        # Check each possible installation location
        for exe_path in tool.executable_paths:
            path_obj = Path(exe_path)
            if path_obj.exists():
                logger.info(f"Found existing installation: {exe_path}")

                # Try to get version information
                if tool.version_command:
                    try:
                        import subprocess
                        result = subprocess.run(
                            tool.version_command.split(),
                            capture_output=True,
                            text=True,
                            timeout=5
                        )
                        if result.returncode == 0:
                            logger.info(f"Version info: {result.stdout.strip()}")
                        else:
                            logger.warning(f"Version command failed: {result.stderr}")
                    except Exception as e:
                        logger.warning(f"Could not get version: {e}")
            else:
                logger.debug(f"Not found: {exe_path}")

# Usage for debugging
debugger = InstallerDebugger(installer)
debugger.diagnose_installation_issues('psexec')

Performance Monitoring

import time
import threading
from contextlib import contextmanager

class PerformanceMonitor:
    def __init__(self):
        self.metrics = {}

    @contextmanager
    def time_operation(self, operation_name: str):
        """Context manager for timing operations"""
        start_time = time.time()
        start_memory = self._get_memory_usage()

        try:
            yield
        finally:
            end_time = time.time()
            end_memory = self._get_memory_usage()

            self.metrics[operation_name] = {
                'duration': end_time - start_time,
                'memory_delta': end_memory - start_memory,
                'timestamp': time.time()
            }

    def _get_memory_usage(self):
        """Get current memory usage in MB"""
        try:
            import psutil
            process = psutil.Process()
            return process.memory_info().rss / 1024 / 1024
        except ImportError:
            return 0

    def monitor_installation(self, installer: ThirdPartyInstaller, tool_name: str):
        """Monitor installation performance"""

        with self.time_operation(f'{tool_name}_total'):

            with self.time_operation(f'{tool_name}_download'):
                installer_path = installer.download_tool(tool_name)

            if installer_path:
                with self.time_operation(f'{tool_name}_install'):
                    success = installer.install_tool(tool_name)

        return success if 'installer_path' in locals() and installer_path else False

    def print_report(self):
        """Print performance report"""
        print("\n=== Performance Report ===")
        for operation, metrics in self.metrics.items():
            print(f"{operation}:")
            print(f"  Duration: {metrics['duration']:.2f} seconds")
            print(f"  Memory Delta: {metrics['memory_delta']:.1f} MB")
            print()

# Usage
monitor = PerformanceMonitor()
success = monitor.monitor_installation(installer, 'vlc')
monitor.print_report()

Testing and Validation

Unit Testing Framework

import unittest
from unittest.mock import Mock, patch, MagicMock
from pathlib import Path
import tempfile
import shutil

class TestThirdPartyInstaller(unittest.TestCase):
    def setUp(self):
        """Set up test environment"""
        self.test_dir = Path(tempfile.mkdtemp())
        self.installer = ThirdPartyInstaller()
        self.installer.config_dir = self.test_dir / 'config'
        self.installer.temp_dir = self.test_dir / 'temp'
        self.installer.config_dir.mkdir(parents=True)
        self.installer.temp_dir.mkdir(parents=True)

    def tearDown(self):
        """Clean up test environment"""
        shutil.rmtree(self.test_dir, ignore_errors=True)

    def test_tool_status_detection(self):
        """Test tool status detection logic"""

        # Test case: Tool not installed
        status = self.installer.get_tool_status('nonexistent_tool')
        self.assertEqual(status, InstallationStatus.NOT_INSTALLED)

        # Test case: Mock installed tool
        test_tool = ThirdPartyTool(
            name='test_tool',
            display_name='Test Tool',
            description='A test tool',
            download_url='https://example.com/tool.zip',
            executable_paths=[str(self.test_dir / 'tool.exe')],
            version_command='tool.exe --version',
            installer_type='zip',
            required=True,
            dependencies=[]
        )

        self.installer.tools_config['test_tool'] = test_tool

        # Create mock executable
        (self.test_dir / 'tool.exe').touch()

        with patch('subprocess.run') as mock_run:
            mock_run.return_value.returncode = 0
            mock_run.return_value.stdout = 'Test Tool v1.0'

            status = self.installer.get_tool_status('test_tool')
            self.assertEqual(status, InstallationStatus.INSTALLED)

    @patch('urllib.request.urlretrieve')
    def test_download_tool(self, mock_urlretrieve):
        """Test tool download functionality"""

        # Mock successful download
        test_file = self.test_dir / 'downloaded_tool.exe'
        test_file.touch()
        mock_urlretrieve.return_value = (str(test_file), None)

        # Add test tool to configuration
        test_tool = ThirdPartyTool(
            name='download_test',
            display_name='Download Test',
            description='Tool for testing downloads',
            download_url='https://example.com/tool.exe',
            executable_paths=[str(self.test_dir / 'tool.exe')],
            installer_type='exe',
            required=True,
            dependencies=[]
        )

        self.installer.tools_config['download_test'] = test_tool

        # Test download
        result = self.installer.download_tool('download_test')

        # Verify download was attempted
        mock_urlretrieve.assert_called_once()
        self.assertIsInstance(result, Path)

    def test_missing_required_tools(self):
        """Test identification of missing required tools"""

        # Add required and optional tools
        required_tool = ThirdPartyTool(
            name='required_tool',
            display_name='Required Tool',
            description='A required tool',
            download_url='https://example.com/required.exe',
            executable_paths=['/nonexistent/path'],
            installer_type='exe',
            required=True,
            dependencies=[]
        )

        optional_tool = ThirdPartyTool(
            name='optional_tool',
            display_name='Optional Tool',
            description='An optional tool',
            download_url='https://example.com/optional.exe',
            executable_paths=['/nonexistent/path'],
            installer_type='exe',
            required=False,
            dependencies=[]
        )

        self.installer.tools_config['required_tool'] = required_tool
        self.installer.tools_config['optional_tool'] = optional_tool

        missing = self.installer.get_missing_required_tools()

        self.assertIn('required_tool', missing)
        self.assertNotIn('optional_tool', missing)

    def test_proxy_configuration(self):
        """Test proxy configuration handling"""

        # Test manual proxy configuration
        proxy_config = {
            'enabled': True,
            'auto_detect': False,
            'server': 'proxy.company.com',
            'port': 8080,
            'username': 'testuser',
            'password': 'testpass'
        }

        self.installer.proxy_config = proxy_config

        # Verify proxy configuration is stored correctly
        self.assertTrue(self.installer.proxy_config['enabled'])
        self.assertEqual(self.installer.proxy_config['server'], 'proxy.company.com')
        self.assertEqual(self.installer.proxy_config['port'], 8080)

    @patch('subprocess.run')
    def test_installation_validation(self, mock_run):
        """Test installation validation logic"""

        # Mock successful tool execution
        mock_run.return_value.returncode = 0
        mock_run.return_value.stdout = 'Tool v1.0'

        test_tool = ThirdPartyTool(
            name='validation_test',
            display_name='Validation Test',
            description='Tool for testing validation',
            download_url='https://example.com/tool.exe',
            executable_paths=[str(self.test_dir / 'tool.exe')],
            version_command='tool.exe --version',
            installer_type='exe',
            required=True,
            dependencies=[]
        )

        # Create mock executable
        (self.test_dir / 'tool.exe').touch()

        self.installer.tools_config['validation_test'] = test_tool

        # Test validation
        status = self.installer.get_tool_status('validation_test')
        self.assertEqual(status, InstallationStatus.INSTALLED)

class TestInstallerIntegration(unittest.TestCase):
    """Integration tests for installer components"""

    def setUp(self):
        self.installer = ThirdPartyInstaller()

    def test_real_tool_detection(self):
        """Test detection of real system tools"""

        # Test common Windows tools
        import platform
        if platform.system() == 'Windows':
            # Test if Windows built-in tools are detected
            test_paths = [
                'C:\\Windows\\System32\\ping.exe',
                'C:\\Windows\\System32\\ipconfig.exe'
            ]

            for path in test_paths:
                if Path(path).exists():
                    self.assertTrue(Path(path).is_file())

    @unittest.skipIf(not Path('/usr/bin/which').exists(), "which command not available")
    def test_unix_tool_detection(self):
        """Test detection on Unix-like systems"""

        import subprocess

        # Test common Unix tools
        try:
            result = subprocess.run(['which', 'ls'], 
                                  capture_output=True, text=True)
            if result.returncode == 0:
                ls_path = result.stdout.strip()
                self.assertTrue(Path(ls_path).exists())
        except FileNotFoundError:
            self.skipTest("which command not available")

if __name__ == '__main__':
    # Run specific test suites
    suite = unittest.TestSuite()

    # Add unit tests
    suite.addTest(unittest.makeSuite(TestThirdPartyInstaller))

    # Add integration tests (commented out for normal runs)
    # suite.addTest(unittest.makeSuite(TestInstallerIntegration))

    runner = unittest.TextTestRunner(verbosity=2)
    result = runner.run(suite)

    # Exit with error code if tests failed
    exit(0 if result.wasSuccessful() else 1)

Load Testing

import concurrent.futures
import time
import threading
from collections import defaultdict

class LoadTester:
    def __init__(self, installer: ThirdPartyInstaller):
        self.installer = installer
        self.results = defaultdict(list)
        self.lock = threading.Lock()

    def stress_test_detection(self, iterations: int = 100):
        """Stress test tool detection logic"""

        def detect_all_tools():
            start_time = time.time()
            try:
                for tool_name in self.installer.tools_config.keys():
                    status = self.installer.get_tool_status(tool_name)

                duration = time.time() - start_time
                with self.lock:
                    self.results['detection_times'].append(duration)
                return True

            except Exception as e:
                with self.lock:
                    self.results['detection_errors'].append(str(e))
                return False

        # Run concurrent detection tests
        with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
            futures = [executor.submit(detect_all_tools) for _ in range(iterations)]
            concurrent.futures.wait(futures)

        # Print results
        print(f"\n=== Tool Detection Stress Test ===")
        print(f"Iterations: {iterations}")
        print(f"Successful detections: {len(self.results['detection_times'])}")
        print(f"Errors: {len(self.results['detection_errors'])}")

        if self.results['detection_times']:
            times = self.results['detection_times']
            print(f"Average time: {sum(times) / len(times):.3f}s")
            print(f"Min time: {min(times):.3f}s")
            print(f"Max time: {max(times):.3f}s")

    def concurrent_download_test(self, tool_names: list, max_workers: int = 3):
        """Test concurrent downloads (use with caution)"""

        def download_tool(tool_name):
            start_time = time.time()
            try:
                result = self.installer.download_tool(tool_name)
                duration = time.time() - start_time

                with self.lock:
                    self.results[f'{tool_name}_downloads'].append({
                        'success': result is not None,
                        'duration': duration
                    })

                return result is not None

            except Exception as e:
                with self.lock:
                    self.results[f'{tool_name}_errors'].append(str(e))
                return False

        print(f"\n=== Concurrent Download Test ===")
        print(f"Tools: {tool_names}")
        print(f"Max workers: {max_workers}")

        with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
            futures = {executor.submit(download_tool, tool): tool for tool in tool_names}

            for future in concurrent.futures.as_completed(futures):
                tool_name = futures[future]
                try:
                    success = future.result()
                    print(f"{tool_name}: {'Success' if success else 'Failed'}")
                except Exception as e:
                    print(f"{tool_name}: Exception - {e}")

# Usage
load_tester = LoadTester(installer)
load_tester.stress_test_detection(50)

# Test concurrent downloads (be careful with this - it may overwhelm servers)
# load_tester.concurrent_download_test(['vlc'], max_workers=1)

Configuration and Customization

Configuration File Management

import json
import yaml
from pathlib import Path
from typing import Dict, Any

class ConfigurationManager:
    def __init__(self, installer: ThirdPartyInstaller):
        self.installer = installer
        self.config_file = Path(installer.config_dir) / 'installer_config.json'
        self.user_config_file = Path(installer.config_dir) / 'user_config.yaml'

    def save_configuration(self):
        """Save current configuration to file"""
        config = {
            'tools': {},
            'proxy': self.installer.proxy_config,
            'settings': {
                'temp_dir': str(self.installer.temp_dir),
                'config_dir': str(self.installer.config_dir)
            }
        }

        # Save tool configurations
        for name, tool in self.installer.tools_config.items():
            config['tools'][name] = {
                'name': tool.name,
                'display_name': tool.display_name,
                'description': tool.description,
                'download_url': tool.download_url,
                'executable_paths': tool.executable_paths,
                'version_command': tool.version_command,
                'installer_type': tool.installer_type,
                'required': tool.required,
                'dependencies': tool.dependencies
            }

        # Save to JSON
        with open(self.config_file, 'w') as f:
            json.dump(config, f, indent=2)

    def load_configuration(self) -> bool:
        """Load configuration from file"""
        if not self.config_file.exists():
            return False

        try:
            with open(self.config_file, 'r') as f:
                config = json.load(f)

            # Load proxy configuration
            if 'proxy' in config:
                self.installer.proxy_config.update(config['proxy'])

            # Load tool configurations
            if 'tools' in config:
                for name, tool_config in config['tools'].items():
                    tool = ThirdPartyTool(**tool_config)
                    self.installer.tools_config[name] = tool

            # Load settings
            if 'settings' in config:
                settings = config['settings']
                if 'temp_dir' in settings:
                    self.installer.temp_dir = Path(settings['temp_dir'])
                if 'config_dir' in settings:
                    self.installer.config_dir = Path(settings['config_dir'])

            return True

        except Exception as e:
            print(f"Failed to load configuration: {e}")
            return False

    def load_user_preferences(self) -> Dict[str, Any]:
        """Load user preferences from YAML file"""
        if not self.user_config_file.exists():
            return {}

        try:
            with open(self.user_config_file, 'r') as f:
                return yaml.safe_load(f) or {}
        except Exception as e:
            print(f"Failed to load user preferences: {e}")
            return {}

    def save_user_preferences(self, preferences: Dict[str, Any]):
        """Save user preferences to YAML file"""
        try:
            with open(self.user_config_file, 'w') as f:
                yaml.safe_dump(preferences, f, indent=2)
        except Exception as e:
            print(f"Failed to save user preferences: {e}")

    def create_deployment_config(self, target_dir: Path):
        """Create deployment configuration for enterprise deployment"""
        deployment_config = {
            'installer_settings': {
                'silent_mode': True,
                'required_tools_only': True,
                'skip_optional_tools': True,
                'log_level': 'INFO'
            },
            'proxy_settings': {
                'auto_detect': True,
                'use_px': True,
                'fallback_manual': False
            },
            'installation_paths': {
                'prefer_system_wide': True,
                'fallback_user_dir': True,
                'custom_install_dir': None
            },
            'tool_overrides': {
                'vlc': {
                    'required': False,
                    'download_url': 'https://internal-mirror.company.com/vlc.exe'
                }
            }
        }

        deployment_file = target_dir / 'deployment_config.json'
        with open(deployment_file, 'w') as f:
            json.dump(deployment_config, f, indent=2)

        print(f"Deployment configuration saved to: {deployment_file}")

# Usage
config_manager = ConfigurationManager(installer)
config_manager.save_configuration()

# Load user preferences
user_prefs = config_manager.load_user_preferences()
print(f"User preferences: {user_prefs}")

# Create deployment configuration
config_manager.create_deployment_config(Path('./deployment'))

This comprehensive developer guide provides the advanced technical information needed to effectively work with, extend, and integrate the Third Party Installer module. It covers embedding in applications, custom tool definitions, debugging strategies, testing frameworks, and configuration management for enterprise deployments.