# Host File Manager for Web Development

This utility helps web developers map domain names to specific IP addresses by modifying the system's `hosts` file. This is essential for testing local development environments (e.g., mapping `mysite.local` to `127.0.0.1`) or overriding DNS for staging servers.

**Modules Used:**
*   `os`: To handle file paths and OS detection.
*   [[programming/python/modules/argparse-module|argparse]]: To handle command-line arguments.
*   `ctypes`: (Windows only) To check for administrative privileges.

## The Code

Save this as `hosts_manager.py`.

```python
import os
import sys
import argparse

# Determine hosts file path based on OS
if os.name == 'nt':
    HOSTS_PATH = r"C:\Windows\System32\drivers\etc\hosts"
else:
    HOSTS_PATH = "/etc/hosts"

def is_admin():
    """Checks if the script has admin/root privileges."""
    try:
        if os.name == 'nt':
            import ctypes
            return ctypes.windll.shell32.IsUserAnAdmin() != 0
        else:
            return os.getuid() == 0
    except:
        return False

def add_mapping(domain, ip):
    if not is_admin():
        print("Error: Administrator/Root privileges required.")
        return

    print(f"Mapping {domain} -> {ip}...")
    
    try:
        with open(HOSTS_PATH, 'r') as file:
            lines = file.readlines()

        with open(HOSTS_PATH, 'w') as file:
            for line in lines:
                # Skip existing lines for this domain to avoid duplicates/conflicts
                # Check if line is not a comment and contains the domain
                parts = line.strip().split()
                if not line.strip().startswith("#") and len(parts) >= 2:
                    if domain in parts[1:]:
                        continue
                file.write(line)
            
            # Add new mapping
            file.write(f"{ip} {domain}\n")
            print("Mapping added.")

    except PermissionError:
        print("Permission denied. Please run as Administrator/Root.")
    except Exception as e:
        print(f"Error: {e}")

def remove_mapping(domain):
    if not is_admin():
        print("Error: Administrator/Root privileges required.")
        return

    print(f"Removing mapping for {domain}...")
    
    try:
        with open(HOSTS_PATH, 'r') as file:
            lines = file.readlines()

        with open(HOSTS_PATH, 'w') as file:
            found = False
            for line in lines:
                parts = line.strip().split()
                # Check if line contains the domain
                if not line.strip().startswith("#") and len(parts) >= 2:
                    if domain in parts[1:]:
                        found = True
                        continue # Skip writing this line
                file.write(line)
            
            if found:
                print("Mapping removed.")
            else:
                print("Domain not found in hosts file.")

    except PermissionError:
        print("Permission denied. Please run as Administrator/Root.")

def list_mappings():
    print(f"--- Custom Mappings in {HOSTS_PATH} ---")
    try:
        with open(HOSTS_PATH, 'r') as file:
            for line in file:
                line = line.strip()
                if not line or line.startswith("#"):
                    continue
                print(line)
    except Exception as e:
        print(f"Error reading file: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Host File Manager")
    subparsers = parser.add_subparsers(dest="command", help="Command to run")

    # Add/Update Command
    add_parser = subparsers.add_parser("set", help="Map a domain to an IP")
    add_parser.add_argument("domain", help="Domain name (e.g., dev.local)")
    add_parser.add_argument("ip", help="IP Address (e.g., 127.0.0.1)")

    # Remove Command
    rm_parser = subparsers.add_parser("remove", help="Remove a domain mapping")
    rm_parser.add_argument("domain", help="Domain name to remove")

    # List Command
    subparsers.add_parser("list", help="List current hosts file entries")

    args = parser.parse_args()

    if args.command == "set":
        add_mapping(args.domain, args.ip)
    elif args.command == "remove":
        remove_mapping(args.domain)
    elif args.command == "list":
        list_mappings()
    else:
        parser.print_help()
```

## Usage

**Windows:** Open Command Prompt as Administrator.
**Linux/macOS:** Use `sudo`.

```bash
# Map a local dev domain
python hosts_manager.py set myapp.local 127.0.0.1

# Point a domain to a staging server
python hosts_manager.py set example.com 192.168.1.50

# Remove a mapping
python hosts_manager.py remove myapp.local

# View file
python hosts_manager.py list
```

[[programming/python/python]]