For an HTTP proxy provider’s IPv4 format ip:port:user:password, convert the fields before giving the value to Requests:

from ipaddress import IPv4Address
from urllib.parse import quote

def proxy_map(line):
    host, port, user, password = line.rstrip('\r\n').split(':', 3)
    host = str(IPv4Address(host))
    port = int(port)
    if not 1 <= port <= 65535:
        raise ValueError('Proxy port is out of range')
    credentials = quote(user, safe='') + ':' + quote(password, safe='')
    url = f'http://{credentials}@{host}:{port}'
    return {'http': url, 'https': url}

The bounded split preserves any additional colons inside the password. Removing only line endings also avoids silently stripping spaces that might belong to a credential.

Encode the username and password as individual URL components. An @ in a raw password must not be confused with the separator before the proxy host. This function expects raw credentials; passing already encoded text can encode the percent sign again.

The returned map selects this proxy for HTTP and HTTPS destinations. A key such as http://192.0.2.10 has another meaning in Requests: it selects a route for that destination host. It is not an index for a pool of proxy servers.

The parser intentionally accepts the stated IPv4 format. It does not cover colon-containing usernames or unbracketed IPv6 addresses; those need an unambiguous input format. Keep generated credential-bearing URLs out of routine logs.

Artiglyn mynjee