๐Ÿ” Code Extractor

function main_v56

Maturity: 38

Interactive setup script that configures a Python virtual environment for an email forwarder application, installs dependencies, and verifies the installation.

File:
/tf/active/vicechatdev/email-forwarder/setup_venv.py
Lines:
36 - 173
Complexity:
moderate

Purpose

This function orchestrates the complete setup process for an email forwarder application. It performs directory validation, checks Python/pip installation, creates or recreates a virtual environment, provides activation instructions, installs dependencies from requirements.txt, verifies configuration files (.env), tests Python imports, and displays final usage instructions. It's designed to be run as a standalone setup script to prepare the development/production environment.

Source Code

def main():
    print("=" * 60)
    print("๐Ÿ“ง EMAIL FORWARDER - VIRTUAL ENVIRONMENT SETUP")
    print("=" * 60)
    print()
    
    # Check current directory
    current_dir = Path.cwd()
    print(f"๐Ÿ“ Current directory: {current_dir}")
    
    # Verify we're in the right directory
    if not (Path("requirements.txt").exists() and Path("src").exists()):
        print("โŒ This script must be run from the email-forwarder directory")
        print("   Required files: requirements.txt, src/ directory")
        return False
    
    print("โœ… Project directory structure verified")
    print()
    
    # Step 1: Check Python
    print("๐Ÿ STEP 1: Checking Python installation")
    if not run_command("python3 --version", "Checking Python 3"):
        print("โŒ Python 3 is required. Please install Python 3.8 or higher.")
        return False
    
    if not run_command("pip3 --version", "Checking pip3"):
        print("โŒ pip3 is required. Please install pip3.")
        return False
    
    print()
    
    # Step 2: Virtual Environment Setup
    print("๐ŸŒ STEP 2: Setting up virtual environment")
    
    venv_path = Path("venv")
    if venv_path.exists():
        print("โš ๏ธ  Virtual environment already exists")
        response = input("Do you want to recreate it? (y/N): ").strip().lower()
        if response == 'y':
            shutil.rmtree(venv_path)
            print("๐Ÿ—‘๏ธ  Removed existing virtual environment")
    
    if not venv_path.exists():
        if not run_command("python3 -m venv venv", "Creating virtual environment"):
            return False
    
    print()
    
    # Step 3: Activation Instructions
    print("๐Ÿ”ง STEP 3: Virtual environment activation")
    print("   To activate the virtual environment, run:")
    print("   ๐Ÿ“‹ Linux/Mac: source venv/bin/activate")
    print("   ๐Ÿ“‹ Windows:   venv\\Scripts\\activate")
    print()
    
    # Step 4: Check if we can detect activation
    virtual_env = os.environ.get('VIRTUAL_ENV')
    if virtual_env:
        print(f"โœ… Virtual environment is active: {virtual_env}")
        
        # Install dependencies
        print("๐Ÿ“ฆ STEP 4: Installing dependencies")
        if run_command("pip install --upgrade pip", "Upgrading pip"):
            if run_command("pip install -r requirements.txt", "Installing requirements"):
                print("โœ… Dependencies installed successfully")
            else:
                print("โŒ Failed to install dependencies")
                return False
        else:
            print("โš ๏ธ  pip upgrade failed, but continuing...")
            if not run_command("pip install -r requirements.txt", "Installing requirements"):
                print("โŒ Failed to install dependencies")
                return False
        
        print()
        
        # Step 5: Configuration check
        print("โš™๏ธ  STEP 5: Configuration verification")
        
        if not check_file_exists(".env", ".env configuration file"):
            if check_file_exists(".env.example", ".env.example template"):
                print("๐Ÿ“‹ Copy .env.example to .env and configure with your MS365 credentials:")
                print("   - TENANT_ID=your_tenant_id")
                print("   - CLIENT_ID=your_client_id") 
                print("   - CLIENT_SECRET=your_client_secret")
                print("   - FROM_EMAIL=your_sender@domain.com")
                run_command("cp .env.example .env", "Copying configuration template")
        
        print()
        
        # Step 6: Import test
        print("๐Ÿงช STEP 6: Testing Python imports")
        test_script = """
import sys
sys.path.insert(0, 'src')
try:
    from forwarder.smtp_server import SMTPServer
    from forwarder.o365_client import O365Client
    from forwarder.email_handler import EmailHandler
    from config.settings import Settings
    print("โœ… All imports successful")
except ImportError as e:
    print(f"โŒ Import error: {e}")
    sys.exit(1)
"""
        
        try:
            exec(test_script)
        except SystemExit:
            print("โŒ Import test failed")
            return False
        
        print()
        
        # Step 7: Final instructions
        print("๐Ÿš€ SETUP COMPLETE!")
        print("=" * 40)
        print("To start the email forwarder:")
        print("1. Ensure virtual environment is active:")
        print("   source venv/bin/activate")
        print()
        print("2. Configure .env file with your MS365 credentials")
        print()
        print("3. Start the service:")
        print("   python src/main.py")
        print()
        print("4. Test the service:")
        print("   python send_test_email.py")
        print()
        print("5. Stop with Ctrl+C when done")
        print("=" * 40)
        
    else:
        print("โš ๏ธ  Virtual environment is not currently active")
        print("   Please activate it first with: source venv/bin/activate")
        print("   Then run this script again to complete the setup")
    
    return True

Return Value

Returns a boolean value: True if the setup process completes successfully (all checks pass and dependencies are installed), False if any critical step fails (missing Python, wrong directory, failed dependency installation, or import errors). The return value indicates whether the environment is ready for use.

Dependencies

  • pathlib
  • os
  • sys
  • subprocess
  • shutil

Required Imports

import os
import sys
import subprocess
import shutil
from pathlib import Path

Conditional/Optional Imports

These imports are only needed under specific conditions:

from forwarder.smtp_server import SMTPServer

Condition: only during import testing phase (Step 6), requires virtual environment to be active and dependencies installed

Required (conditional)
from forwarder.o365_client import O365Client

Condition: only during import testing phase (Step 6), requires virtual environment to be active and dependencies installed

Required (conditional)
from forwarder.email_handler import EmailHandler

Condition: only during import testing phase (Step 6), requires virtual environment to be active and dependencies installed

Required (conditional)
from config.settings import Settings

Condition: only during import testing phase (Step 6), requires virtual environment to be active and dependencies installed

Required (conditional)

Usage Example

# This function is typically called as the entry point of a setup script
# Run from the email-forwarder project directory:

if __name__ == '__main__':
    success = main()
    if success:
        print('Setup completed successfully')
        sys.exit(0)
    else:
        print('Setup failed')
        sys.exit(1)

# Expected workflow:
# 1. Navigate to email-forwarder directory
# 2. Run: python setup.py
# 3. If venv not active, activate it: source venv/bin/activate
# 4. Run setup.py again to complete dependency installation
# 5. Configure .env file with MS365 credentials
# 6. Start the application: python src/main.py

Best Practices

  • This function must be run from the email-forwarder project root directory containing requirements.txt and src/
  • Requires helper functions 'run_command' and 'check_file_exists' to be defined in the same module
  • The function should be run twice: once to create the venv, then again after activation to install dependencies
  • Always activate the virtual environment before running the second time to ensure dependencies are installed in the correct location
  • Review and configure the .env file with actual MS365 credentials before starting the application
  • The function uses interactive prompts (input()) so it's not suitable for automated/non-interactive environments
  • Uses exec() to test imports which can be a security concern - ensure the test_script content is trusted
  • The function assumes Unix-like commands (cp) which may not work on Windows without modification
  • Check return value to determine if setup was successful before proceeding with application startup

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function main_v51 63.5% similar

    Entry point function that validates the working directory and starts an email forwarding service.

    From: /tf/active/vicechatdev/email-forwarder/run_service.py
  • function start_service 60.6% similar

    Orchestrates the startup sequence for an email forwarder service by validating environment, dependencies, configuration, and project structure before launching the main application.

    From: /tf/active/vicechatdev/email-forwarder/run_service.py
  • function main_v67 60.2% similar

    Command-line interface function that parses arguments and sends a test email through an SMTP forwarder service, displaying connection details and returning an exit code based on success.

    From: /tf/active/vicechatdev/email-forwarder/send_test_email.py
  • function main_v40 56.9% similar

    Orchestrates and executes a test suite for an email forwarder service, running multiple test functions sequentially and reporting results.

    From: /tf/active/vicechatdev/email-forwarder/test_service.py
  • function main_v7 55.5% similar

    Asynchronous main entry point function that initializes and runs an email forwarding SMTP server with logging, configuration validation, and graceful shutdown handling.

    From: /tf/active/vicechatdev/email-forwarder/src/main.py
โ† Back to Browse