3 min read

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.
  • argparse: To handle command-line arguments.
  • ctypes: (Windows only) To check for administrative privileges.

The Code

Save this as hosts_manager.py.

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.

# 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