Of course! Implementing proxy authentication in Python is a common task, especially for web scraping, API interaction, or accessing internal resources. The core idea is to provide a username and password to the proxy server as part of the connection request.

The method you use depends on the library you're working with. I'll cover the most popular ones: requests, urllib, and http.client.
The requests Library (Recommended)
The requests library is the de facto standard for making HTTP requests in Python. It handles proxy authentication in a very straightforward way.
Method A: Using the proxies Dictionary (Most Common)
You provide a dictionary of proxy URLs to the proxies argument. The username and password are embedded directly in the URL using the format http://username:password@host:port.
Important: You should always use https for the proxy URL, even if the proxy itself is http. This ensures your username and password are encrypted during transmission to the proxy server.

import requests
# Your proxy server details
proxy_host = "your.proxy.com"
proxy_port = "8080"
proxy_username = "myuser"
proxy_password = "mypassword"
# Construct the proxy URL with auth
# Note the 'https://' prefix for the URL itself
proxy_url = f"https://{proxy_username}:{proxy_password}@{proxy_host}:{proxy_port}"
# Define the proxies dictionary
proxies = {
"http": proxy_url,
"https": proxy_url, # It's good practice to set both
}
# The URL you want to access through the proxy
target_url = "http://httpbin.org/ip" # This site shows your public IP
try:
# Make the request, passing the proxies dictionary
response = requests.get(target_url, proxies=proxies, timeout=10)
# Raise an exception for bad status codes (4xx or 5xx)
response.raise_for_status()
print("Successfully connected through the proxy!")
print("Response JSON:")
print(response.json())
print("\nThis should be the IP of your proxy server.")
except requests.exceptions.ProxyError as e:
print(f"Proxy Error: {e}")
print("Please check your proxy address, port, and network connectivity.")
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
Method B: Using Environment Variables
For security and convenience, you can set proxies using environment variables. requests automatically checks for these if you don't provide the proxies argument.
Set these variables in your terminal before running the Python script:
On Linux/macOS:
export HTTP_PROXY="https://myuser:mypassword@your.proxy.com:8080" export HTTPS_PROXY="https://myuser:mypassword@your.proxy.com:8080"
On Windows (Command Prompt):

set HTTP_PROXY=https://myuser:mypassword@your.proxy.com:8080 set HTTPS_PROXY=https://myuser:mypassword@your.proxy.com:8080
On Windows (PowerShell):
$env:HTTP_PROXY="https://myuser:mypassword@your.proxy.com:8080" $env:HTTPS_PROXY="https://myuser:mypassword@your.proxy.com:8080"
Now, your Python code becomes much cleaner:
import requests
# The script will automatically use the proxies defined in the environment variables
target_url = "http://httpbin.org/ip"
try:
response = requests.get(target_url, timeout=10)
response.raise_for_status()
print("Successfully connected using environment variables!")
print("Response JSON:")
print(response.json())
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
The urllib Library (Standard Library)
If you're not using external libraries, urllib is part of Python's standard library. The syntax is a bit more verbose.
You need to create a ProxyHandler and install an "opener" for it.
import urllib.request
import urllib.error
# Your proxy server details
proxy_host = "your.proxy.com"
proxy_port = "8080"
proxy_username = "myuser"
proxy_password = "mypassword"
# The URL you want to access
target_url = "http://httpbin.org/ip"
# Create a password manager
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password for the proxy
# The realm can be None, we are using the proxy's host and port as the URI
top_level_url = f"http://{proxy_host}:{proxy_port}"
password_mgr.add_password(None, top_level_url, proxy_username, proxy_password)
# Create a proxy handler
proxy_handler = urllib.request.ProxyHandler({
"http": f"http://{proxy_host}:{proxy_port}",
"https": f"http://{proxy_host}:{proxy_port}"
})
# Create an opener with the proxy handler and auth handler
auth_handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
opener = urllib.request.build_opener(proxy_handler, auth_handler)
# Install the opener. Now all urllib.request calls will use this opener.
urllib.request.install_opener(opener)
try:
# Now you can use urllib.request as usual
with urllib.request.urlopen(target_url, timeout=10) as response:
print("Successfully connected with urllib!")
print("Response:")
print(response.read().decode('utf-8'))
except urllib.error.URLError as e:
print(f"URL Error: {e.reason}")
if "ProxyError" in str(e.reason):
print("Please check your proxy address, port, and network connectivity.")
except Exception as e:
print(f"An error occurred: {e}")
The http.client Library (Low-Level)
This is the lowest-level approach and is useful for understanding the underlying mechanics or when working with other libraries that build on it. You manually construct the CONNECT request.
import http.client
import socket
# Your proxy server details
proxy_host = "your.proxy.com"
proxy_port = 8080
proxy_username = "myuser"
proxy_password = "mypassword"
# The host and port you want to reach (e.g., google.com)
target_host = "httpbin.org"
target_port = 80
# 1. Establish a connection to the proxy server
try:
# Use http.client for HTTP, HTTPSConnection for HTTPS
conn = http.client.HTTPConnection(proxy_host, proxy_port, timeout=10)
# 2. Construct the CONNECT request for the target host
# The 'Proxy-Authorization' header contains the base64 encoded credentials
import base64
credentials = f"{proxy_username}:{proxy_password}"
encoded_credentials = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
connect_request = f"CONNECT {target_host}:{target_port} HTTP/1.1\r\n"
connect_request += f"Host: {target_host}:{target_port}\r\n"
connect_request += f"Proxy-Authorization: Basic {encoded_credentials}\r\n"
connect_request += "\r\n" # Empty line to end headers
print("Sending CONNECT request to proxy...")
conn.send(connect_request.encode('utf-8'))
# 3. Read the proxy's response
response = conn.getresponse()
print(f"Proxy response status: {response.status} {response.reason}")
if response.status != 200:
print(f"Proxy authentication failed or refused. Reason: {response.read().decode()}")
conn.close()
exit()
print("Successfully tunneled through the proxy.")
# 4. Now, the connection is a tunnel. You can send a new request
# to the target host through this connection.
# The host/port for the request is now the target, not the proxy.
conn.putrequest("GET", f"/ip")
conn.putheader("Host", target_host)
conn.endheaders()
response_data = conn.getresponse()
print(f"\nTarget response status: {response_data.status} {response_data.reason}")
print("Target response body:")
print(response_data.read().decode('utf-8'))
conn.close()
except socket.timeout:
print("Connection timed out.")
except ConnectionRefusedError:
print("Connection refused. Check proxy server and port.")
except Exception as e:
print(f"An error occurred: {e}")
Troubleshooting Common Issues
-
requests.exceptions.ProxyError: 407 Proxy Authentication Required- Cause: Your username or password is incorrect, or the proxy server doesn't recognize the credentials.
- Solution: Double-check your credentials. Ensure the format
https://user:pass@...is correct.
-
requests.exceptions.ProxyError: Cannot connect to proxy.- Cause: The proxy server is down, the address is wrong, the port is incorrect, or your machine cannot reach the proxy (e.g., firewall issue).
- Solution: Verify the proxy address and port. Test connectivity using a tool like
telnet your.proxy.com 8080orcurl --proxy http://user:pass@your.proxy.com:8080 http://httpbin.org/ip.
-
requests.exceptions.SSLError(when using a proxy)- Cause: This can happen if the proxy server uses a self-signed certificate or an SSL/TLS configuration that Python's
requestslibrary doesn't trust by default. - Solution: You can disable SSL verification for the proxy request (not recommended for production) using
verify=False. A better approach is to add the proxy's CA certificate to your system's trust store.
- Cause: This can happen if the proxy server uses a self-signed certificate or an SSL/TLS configuration that Python's
