{"id":9373,"library":"txtorcon","title":"txtorcon","description":"txtorcon is a Twisted-based Tor controller client, with state-tracking and configuration abstractions. As of version 24.8.0, it allows for launching new Tor instances or connecting to existing ones, using Tor as a client via SOCKS5, setting up Onion services, and monitoring live state and configuration. The library follows calendar versioning (YY.MM.0) and typically has frequent releases for new features and bug fixes, often aligned with Twisted's release schedule.","status":"active","version":"24.8.0","language":"en","source_language":"en","source_url":"https://github.com/meejah/txtorcon","tags":["tor","twisted","networking","anonymity","security","control-protocol","onion-services"],"install":[{"cmd":"pip install txtorcon","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core event-driven networking framework that txtorcon is built upon.","package":"Twisted","optional":false},{"reason":"Used for concise, idiomatic Python expression of finite-state automata, a dependency for recent versions.","package":"automat","optional":false},{"reason":"Commonly used 'requests'-like library for Twisted for making web requests over Tor, as shown in examples.","package":"treq","optional":true}],"imports":[{"note":"Primary library import","symbol":"txtorcon","correct":"import txtorcon"},{"note":"Directly available from the top-level package in recent versions for high-level API","wrong":"from txtorcon.controller import connect","symbol":"connect","correct":"from txtorcon import connect"},{"note":"Use the high-level 'launch' from the top-level package; 'launch_tor' is an older/deprecated pattern.","wrong":"from txtorcon.torconfig import launch_tor","symbol":"launch","correct":"from txtorcon import launch"},{"note":"Commonly used for connecting to Tor control port via Unix socket.","symbol":"UNIXClientEndpoint","correct":"from twisted.internet.endpoints import UNIXClientEndpoint"},{"note":"Standard Twisted entry point for running event loops.","symbol":"react","correct":"from twisted.internet.task import react"},{"note":"Decorator for Twisted's coroutine-like Deferred chains.","symbol":"inlineCallbacks","correct":"from twisted.internet.defer import inlineCallbacks"}],"quickstart":{"code":"import os\nfrom twisted.internet.task import react\nfrom twisted.internet.defer import inlineCallbacks, ensureDeferred\nfrom twisted.internet.endpoints import UNIXClientEndpoint, TCP4ClientEndpoint\nimport treq\nimport txtorcon\n\n@react\n@inlineCallbacks\ndef main(reactor):\n    # Connect to a running Tor instance, e.g., Tor Browser Bundle's control port (default 9151)\n    # Or a system-wide Tor daemon (default 9051, or /var/run/tor/control)\n    # You can also use txtorcon.launch(reactor) to start a new Tor process managed by txtorcon.\n    \n    # Example: Connect to a Unix socket (common for system Tor)\n    control_endpoint = UNIXClientEndpoint(reactor, '/var/run/tor/control')\n    # Example: Connect to a TCP port (common for TBB or custom Tor setup)\n    # control_endpoint = TCP4ClientEndpoint(reactor, 'localhost', 9151)\n    \n    # Password for Tor control port, if required. Use environment variable for security.\n    # For a newly launched Tor, this is usually not needed immediately.\n    password = os.environ.get('TOR_CONTROL_PASSWORD', '')\n\n    try:\n        tor = yield txtorcon.connect(\n            reactor,\n            control_endpoint,\n            password_function=lambda: password\n        )\n        print(f\"Connected to Tor version {tor.version}\")\n\n        url = u'https://www.torproject.org:443'\n        print(f\"Downloading {repr(url)} via Tor...\")\n\n        # Use tor.web_agent() to make requests over Tor's general circuit\n        resp = yield treq.get(url, agent=tor.web_agent())\n        body_data = yield resp.text()\n\n        print(f\"Got {len(body_data)} bytes from {url}:\")\n        print(body_data[:200] + ('...' if len(body_data) > 200 else '')) # Print first 200 chars\n\n        print(\"\\nCreating a new Tor circuit...\")\n        state = yield tor.create_state()\n        circ = yield state.build_circuit()\n        yield circ.when_built()\n        print(f\"New circuit built with path: {' -> '.join([r.ip for r in circ.path])}\")\n\n    except Exception as e:\n        print(f\"An error occurred: {e}\")\n        # Handle specific connection errors or Tor failures\n    finally:\n        # It's good practice to disconnect or shut down Tor if launched by txtorcon\n        if hasattr(tor, 'shutdown') and callable(tor.shutdown):\n            print(\"Shutting down Tor (if launched by txtorcon)...\")\n            yield ensureDeferred(tor.shutdown())\n        else:\n            print(\"Not shutting down Tor, it was an external instance.\")","lang":"python","description":"This quickstart demonstrates connecting to an existing Tor instance (either via a Unix socket or TCP), performing a web request through Tor, and building a custom circuit. It uses `txtorcon.connect` for connection and `tor.web_agent()` for HTTP requests with `treq`. It's crucial to handle reactor management (e.g., with `@react`)."},"warnings":[{"fix":"Upgrade your environment to Python 3.8+ and ensure your code is Python 3 compatible. `txtorcon` now requires Python >=3.8.","message":"Python 2 support was completely dropped in `txtorcon` v23.0.0. Earlier versions (v20.0.0) had deprecated it.","severity":"breaking","affected_versions":"<23.0.0"},{"fix":"Replace calls to `TorControlProtocol.on_disconnect` with `TorControlProtocol.when_disconnected` for handling disconnections.","message":"The `TorControlProtocol.on_disconnect` method was deprecated in v19.1.0.","severity":"deprecated","affected_versions":">=19.1.0"},{"fix":"Upgrade `txtorcon` to v23.11.0 or newer. This version includes a fix to handle larger responses gracefully.","message":"Older versions (before v23.11.0) could experience `GETINFO` commands hanging or causing unexpected Tor disconnections if the response from Tor contained ultra-long lines (over 16KiB). This was due to limitations in Twisted's `LineOnlyReceiver`.","severity":"gotcha","affected_versions":"<23.11.0"},{"fix":"If specific HTTPS policy is required, explicitly pass a `tls_context_factory` argument to `Tor.web_agent()` or similar methods to define your desired TLS context.","message":"The default HTTPS policy for `twisted.web.client.Agent` instances used by `txtorcon` changed in v23.5.0 to align with `twisted.web.client.Agent`'s default. While generally safer, if you had custom or less strict TLS contexts, you might need to re-evaluate.","severity":"gotcha","affected_versions":">=23.5.0"},{"fix":"Ensure your project's `requirements.txt` explicitly lists all necessary dependencies. If you were implicitly relying on `txtorcon` to pull in `six` or `incremental`, explicitly add them if needed for compatibility with other parts of your codebase, especially for older Python versions.","message":"Several dependencies like `six`, `incremental`, and `ipaddress` (for Python 2 backport) have been removed in recent versions (v24.8.0, v23.11.0, v23.5.0 respectively). While removal isn't a breaking change for `txtorcon` itself, projects relying on these implicitly via `txtorcon` might need to add them if they still target older Python versions or specific setups.","severity":"deprecated","affected_versions":">=23.5.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Upgrade `txtorcon` to version 23.11.0 or newer. This release addresses the handling of long lines in the control protocol.","cause":"In versions prior to 23.11.0, receiving overly long `GETINFO` responses (e.g., for certain relay descriptors) could cause Twisted's line receiver to exceed its buffer, leading to an unexpected disconnect or hang.","error":"Tor unexpectedly disconnected while running: GETINFO md/id/..."},{"fix":"Replace usage of `protocol.on_disconnect` with `protocol.when_disconnected`. The `when_disconnected` method returns a Deferred that fires when the protocol disconnects.","cause":"You are attempting to use the `on_disconnect` callback on a `TorControlProtocol` instance, which was deprecated in `txtorcon` v19.1.0.","error":"AttributeError: 'TorControlProtocol' object has no attribute 'on_disconnect'"},{"fix":"Ensure your project is running on Python 3.8 or newer. Update your environment and codebase to be fully Python 3 compliant.","cause":"`txtorcon` dropped support for Python 2 entirely in version 23.0.0, and newer features are Python 3-only.","error":"SyntaxError: invalid syntax (on Python 2.x) or other Python 3 specific errors"}]}