Stem - Tor Controller Library
Stem is a Python controller library that provides a high-level API for interacting with the Tor daemon. It allows applications to query Tor's status, manage circuits and streams, and retrieve information about Tor relays. The current stable version is 1.8.2, with releases occurring as needed for bug fixes and minor enhancements.
Common errors
-
stem.SocketClosed: [Errno 111] Connection refused
cause Tor's control port is not listening or is blocked, or Tor is not running.fixVerify that Tor is running and that its `ControlPort` is configured and accessible (e.g., `ControlPort 9051`). Check firewall rules. If launching Tor with `stem.process`, ensure `tor_path` is correct and Tor starts successfully. -
stem.ProtocolError: Keyword authentication failed
cause Incorrect password provided for Tor's control port.fixProvide the correct `HashedControlPassword` to `controller.authenticate(password='your_password')`. Double-check your `torrc` file for the password setting. -
stem.SocketClosed: connection was closed (cookie authentication did not provide a response)
cause Tor is configured for cookie authentication, but stem cannot find or read the authentication cookie file.fixEnsure `CookieAuthentication 1` is set in `torrc` and the `CookieAuthFile` is in a default or accessible location. If manually specifying, pass `controller.authenticate(private_key='/path/to/control_auth_cookie')`.
Warnings
- gotcha Stem requires a running Tor daemon to connect to its control port. If Tor is not running or its control port (e.g., 9051) is not accessible, you will get connection errors like `SocketClosed`.
- gotcha Authentication failures are common, especially when Tor is configured with a `HashedControlPassword` or `CookieAuthentication` and stem can't find the correct credentials.
- gotcha The `stem.process` module to launch Tor can be tricky. It requires the `tor` executable to be in your PATH or explicitly specified, and managing its lifecycle (starting, stopping, cleaning up) is crucial to avoid orphaned processes.
Install
-
pip install stem
Imports
- Controller
from stem import Controller
from stem.control import Controller
- launch_tor_with_config
from stem import launch_tor_with_config
from stem.process import launch_tor_with_config
- SocketClosed
from stem import SocketClosed
Quickstart
import stem.control
import os
# Default Tor control port is 9051. Authenticate with password or cookie.
try:
with stem.control.Controller.from_port(port=9051) as controller:
# Attempt authentication. If TOR_CONTROL_PASSWORD env var is set, use it.
# Otherwise, authenticate() without arguments tries cookie authentication.
auth_password = os.environ.get('TOR_CONTROL_PASSWORD', '')
if auth_password:
controller.authenticate(password=auth_password)
else:
controller.authenticate() # Attempts cookie authentication by default
print("Successfully connected to Tor controller!")
print(f"Tor version: {controller.get_version()}")
# Example: Get all active circuits
circuits = controller.get_circuits()
print(f"Number of active Tor circuits: {len(circuits)}")
except stem.SocketClosed:
print("Error: Could not connect to Tor's control port. Is Tor running?")
print("Check your Tor configuration (torrc) for ControlPort and authentication settings.")
except Exception as e:
print(f"An unexpected error occurred: {e}")