There isn’t a “release schedule” in any sense. If there is something in main your project depends upon, let me know and I’ll do a release.

txtorcon follows calendar versioning with the major version being the 2-digit year. The second digit will be “non-trivial” releases and the third will be for bugfix releases. So the second release in 2019 would be “19.2.0” and a bug-fix release of that will be “19.2.1”.

See also API Stability.

git main will likely become v24.1.0


November 20, 2023

  • Fix test-failures on Python 3.12

  • Particular GETINFO hanging (#389) (ultra-long lines over 16KiB caused problems in the protocol)

  • Use built-in mock only (from jelly)

  • Remove incremental (from gdrosos)


May 18, 2023

  • twisted.web.client.Agent instances now use the same HTTPS policy by default as twisted.web.client.Agent. It is possible to override this policy with the tls_context_factory argument, the equivalent to Agent’s contextFactory=.

  • Added support for Python 3.11.

  • No more ipaddress dependency


February 15, 2023


March 16, 2022


August 16, 2021


August 7, 2021


April 1, 2020

  • Use real GeoIP database or nothing (#250)

  • Change abstract base classes import in preperation for Python 3.8 (thanks @glowatsk

  • Python 3.4 is no longer supported

  • Python 2 is deprecated; all new code should be Python 3. Support for Python 2 will be removed in a future release.


September 10, 2019

  • txtorcon-19.1.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • TorControlProtocol.on_disconnect is deprecated in favour of TorControlProtocol.when_disconnected()

  • introduce non_anonymous_mode= kwarg in txtorcon.launch() enabling Tor options making Onion Services non-anonymous for the server (but they use a single hop instead of three to the Introduction Point so they’re slightly faster).

  • add an API to listen to individual circuit and stream events (without subclassing anything). Can be used as decorators too. See e.g. TorState.on_circuit_new()

  • fixes to the CI setup to properly test Twisted versions


January 15, 2019

  • txtorcon-19.0.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • add TorControlProtocol.when_disconnected() (will replace .on_disconnect)

  • add detach= kwarg to Tor.create_onion_service()

  • add purpose= kwarg to TorState.build_circuit()



  • txtorcon-18.2.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • add privateKeyFile= option to endpoint parser (ticket 313)

  • use privateKey= option properly in endpoint parser

  • support NonAnonymous mode for ADD_ONION via single_hop= kwarg


September 26, 2018

  • txtorcon-18.1.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • better error-reporting (include REASON and REMOTE_REASON if available) when circuit-builds fail (thanks David Stainton)

  • more-robust detection of “do we have Python3” (thanks Balint Reczey)

  • fix parsing of Unix-sockets for SOCKS

  • better handling of concurrent Web agent requests before SOCKS ports are known

  • allow fowarding to ip:port pairs for Onion services when using the “list of 2-tuples” method of specifying the remote vs local connections.


July 2, 2018


June 30, 2018


June 21, 2018

  • txtorcon-18.0.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • await_all_uploads options when creating Onions

  • properly re-map progress percentages (including descriptor uploads)

  • properly wait for all event-listeners during startup

  • re-work how TorState.event_map works, hopefully reducing reproducible-builds issues

  • txtorcon.TorControlProtocol.add_event_listener() and txtorcon.TorControlProtocol.remove_event_listener() are now async methods returning Deferred – they always should have been; new code can now be assured that the event-listener change is known to Tor by awaiting this Deferred.

  • txtorcon.TorControlProtocol.get_conf_single() method added, which gets and returns (asynchronously) a single GETCONF key (instead of a dict)

  • also txtorcon.TorControlProtocol.get_info_single() similar to above

  • if Tor disconnects while a command is in-progress or pending, the .errback() for the corresponding Deferred is now correctly fired (with a txtorcon.TorDisconnectError

  • tired: get_global_tor() (now deprecated) wired: txtorcon.get_global_tor_instance()

  • Adds a comprehensive set of Onion Services APIs (for all six variations). For non-authenticated services, instances of txtorcon.IOnionService represent services; for authenticated services, instances of txtorcon.IAuthenticatedOnionClients encapsulated named lists of clients (each client is an instance implementing IOnionService).

  • Version 3 (“Proposition 279”) Onion service support (same APIs) as released in latest Tor

  • Four new methods to handle creating endpoints for Onion services (either ephemeral or not and authenticated or not): ** :method:`txtorcon.Tor.create_authenticated_onion_endpoint` ** :method:`txtorcon.Tor.create_authenticated_filesystem_onion_endpoint` ** :method:`txtorcon.Tor.create_onion_endpoint` ** :method:`txtorcon.Tor.create_filesystem_onion_endpoint`

  • see Creating Onion Endpoints for information on how to choose an appropriate type of Onion Service.

  • :method:`txtorcon.Tor.create_onion_service` to add a new ephemeral Onion service to Tor. This uses the ADD_ONION command under the hood and can be version 2 or version 3. Note that there is an endpoint-style API as well so you don’t have to worry about mapping ports yourself (see below).

  • :method:`txtorcon.Tor.create_filesystem_onion_service` to add a new Onion service to Tor with configuration (private keys) stored in a provided directory. These can be version 2 or version 3 services. Note that there is an endpoint-style API as well so you don’t have to worry about mapping ports yourself (see below).

  • Additional APIs to make visiting authenticated Onion services as a client easier:

  • :method:`txtorcon.Tor.add_onion_authentication` will add a client-side Onion service authentication token. If you add a token for a service which already has a token, it is an error if they don’t match. This corresponds to HidServAuth lines in torrc.

  • :method:`txtorcon.Tor.remove_onion_authentication` will remove a previously added client-side Onion service authentication token. Fires with True if such a token existed and was removed or False if no existing token was found.

  • :method:`txtorcon.Tor.onion_authentication` (Python3 only) an async context-manager that adds and removes an Onion authentication token (i.e. adds in on __aenter__ and removes it on __aexit__).

  • onion services support listening on Unix paths.

  • make sure README renders on Warehouse/PyPI


February 22, 2018

  • txtorcon-0.20.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • doc fixes from hotelzululima

  • fix endpoints so .connect on them works properly more than once from Brian Warner

  • allow a CertificateOptions to be passed as tls= to endpoints

  • add method txtorcon.Tor.is_ready()

  • add method txtorcon.Tor.become_ready()

  • fix handling of certain defaults (*PortLines and friends)

  • fix last router (usually) missing with (new) MicroDescriptorParser

  • use OnionOO via Onion service tgel7v4rpcllsrk2.onion for txtorcon.Router.get_onionoo_details()

  • fix parsing of Router started-times

  • Issue 255 removed routers now deleted following NEWCONSENSUS

  • Issue 279 remember proxy endpoint


May 24, 2017


May 11, 2017


April 26, 2017


April 20, 2017

  • txtorcon-0.19.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • Full Python3 support

  • Drop txsocksx and use a custom implementation (this also implements the custom Tor SOCKS5 methods RESOLVE and RESOLVE_PTR

  • Drop support for older Twisted releases (12, 13 and 14 are no longer supported).

  • Add a top-level API object, txtorcon.Tor that abstracts a running Tor. Instances of this class are created with txtorcon.connect() or txtorcon.launch(). These instances are intended to be “the” high-level API and most users shouldn’t need anything else.

  • Integrated support for twisted.web.client.Agent, baked into txtorcon.Tor. This allows simple, straightforward use of treq or “raw” twisted.web.client for making client-type Web requests via Tor. Automatically handles configuration of SOCKS ports. See txtorcon.Tor.web_agent()

  • new high-level API for putting streams on specific Circuits. This adds txtorcon.Circuit.stream_via() and txtorcon.Circuit.web_agent() methods that work the same as the “Tor” equivalent methods except they use a specific circuit. This makes txtorcon.TorState.set_attacher() the “low-level” / “expert” interface. Most users should only need the new API.

  • big revamp / re-write of the documentation, including the new Programming Guide

  • Issue 203

  • new helper: :meth:`txtorcon.Router.get_onionoo_details`_

  • new helper: :func:`txtorcon.util.create_tbb_web_headers`_

  • Issue 72

  • Felipe Dau added specific SocksError subclasses for all the available SOCKS5 errors.

  • (more) Python3 fixes from rodrigc


January 11, 2017


October 4, 2016


August 31, 2016




July 26, 2016

  • txtorcon-0.15.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • added support for NULL control-port-authentication which is often appropriate when used with a UNIX domain socket

  • switched to ipaddress instead of Google’s ipaddr; the API should be the same from a user perspective but packagers and tutorials will want to change their instructions slightly (pip install ipaddress or apt-get install python-ipaddress are the new ways).

  • support the new ADD_ONION and DEL_ONION “ephemeral hidden services” commands in TorConfig

  • a first stealth-authentication implementation (for “normal” hidden services, not ephemeral)

  • bug-fix from david415 to raise ConnectionRefusedError instead of StopIteration when running out of SOCKS ports.

  • new feature from david415 adding a build_timeout_circuit method which provides a Deferred that callbacks only when the circuit is completely built and errbacks if the provided timeout expires. This is useful because txtorcon.TorState.build_circuit() callbacks as soon as a Circuit instance can be provided (and then you’d use txtorcon.Circuit.when_built() to find out when it’s done building).

  • new feature from coffeemakr falling back to password authentication if cookie authentication isn’t available (or fails, e.g. because the file isn’t readable).

  • both TorState and TorConfig now have a .from_protocol class-method.

  • spec-compliant string-un-escaping from coffeemakr

  • a proposed new API: txtorcon.connect()

  • fix issue 176


December 2, 2015


October 25, 2015

  • subtle bug with .is_built on Circuit; changing the API (but with backwards-compatibility until 0.15.0 at least)


September 26, 2015

  • txtorcon-0.14.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • txtorcon.interface.IStreamAttacher handling was missing None and DO_NOT_ATTACH cases if a Deferred was returned.

  • add .is_built Deferred to txtorcon.Circuit that gets `callback()`d when the circuit becomes BUILT

  • david415 ported his tor: endpoint parser so now both client and server endpoints are supported. This means any Twisted program using endpoints can use Tor as a client. For example, to connect to txtorcon’s Web site: ep = clientFromString("tor:fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion:80"). (In the future, I’d like to automatically launch Tor if required, too).

  • Python3 fixes from isis (note: needs Twisted 15.4.0+)


May 10, 2015

  • txtorcon-0.13.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • support basic and stealth hidden service authorization, and parse client_keys files.

  • 2x speedup for TorState parsing (mostly by lazy-parsing timestamps)

  • can now parse ~75000 microdescriptors/second per core of 3.4GHz Xeon E3

  • launch_tor now doesn’t use a temporary torrc (command-line options instead)

  • tons of pep8 cleanups

  • several improvements to hidden-service configuration from sambuddhabasu1.

  • populated valid signals from GETINFO signals/names from sambuddhabasu1.


February 3, 2015

  • txtorcon-0.12.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • doc, code and import cleanups from Kali Kaneko

  • HiddenServiceDirGroupReadable support

  • Issue #80: honour ControlPort 0 in incoming TorConfig instance. The caller owns both pieces: you have to figure out when it’s bootstraped, and are responsible for killing it off.

  • Issue #88: clarify documentation and fix appending to some config lists

  • If GeoIP data isn’t loaded in Tor, it sends protocol errors; if txtorcon also hasn’t got GeoIP data, the queries for country-code fail; this error is now ignored.

  • 100% unit-test coverage! (line coverage)

  • PyPy support (well, at least all tests pass)

  • TCP4HiddenServiceEndpoint now waits for descriptor upload before the listen() call does its callback (this means when using onion: endpoint strings, or any of the endpoints APIs your hidden service is 100% ready for action when you receive the callback)

  • TimeIntervalCommaList from Tor config supported

  • TorControlProtocol now has a .all_routers member (a set() of all Routers)

  • documentation fix from sammyshj


August 16, 2014

  • September 6, 2015. bugfix release: txtorcon-0.11.1.tar.gz (PyPI (local-sig or github-sig) (source)

  • fixed Debian bug 797261 causing 3 tests to fail

  • txtorcon-0.11.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • More control for launch_tor: access stdout, stderr in real-time and control whether we kill Tor on and stderr output. See issue #79.

  • Warning about build_circuit being called without a guard first is now optional (default is still warn) (from arlolra)

  • available_tcp_port() now in util (from arlolra)

  • TorState now has a .routers_by_hash member (from arlolra)


July 20, 2014

  • txtorcon-0.10.1.tar.gz (PyPI (local-sig or github-sig) (source)

  • fix bug incorrectly issuing RuntimeError in brief window of time on event-listeners

  • issue #78: Add tox tests and fix for Twisted 12.0.0 (and prior), as this is what Debian squeeze ships

  • issue #77: properly expand relative and tilde paths for hiddenServiceDir via endpoints


June 15, 2014

  • txtorcon-0.10.0.tar.gz (PyPI (local-sig or github-sig) (source)

  • In collaboration with David Stainton after a pull-request, we have endpoint parser plugins for Twisted! This means code like serverFromString("onion:80").listen(...) is enough to start a service.

  • The above also means that any endpoint-using Twisted program can immediately offer its TCP services via Hidden Service with no code changes. For example, using Twisted Web to serve a WSGI web application would be simply: twistd web --port onion:80 --wsgi

  • switch to a slightly-modified Alabaster Sphinx theme

  • added howtos to documentation


April 23, 2014

  • txtorcon-0.9.2.tar.gz (local-sig or github-sig) (source)

  • add on_disconnect callback for TorControlProtocol (no more monkey-patching Protocol API)

  • add age() method to Circuit

  • add time_created property to Circuit

  • don’t incorrectly listen for NEWDESC events in TorState

  • add .flags dict to track flags in Circuit, Stream

  • build_circuit() can now take hex IDs (as well as Router instances)

  • add unique_name property to Router (returns the hex id, unless Named then return name)

  • add location property to Router

  • TorState.close_circuit now takes either a Circuit ID or Circuit instance

  • TorState.close_stream now takes either a Stream ID or Stream instance

  • support both GeoIP API versions

  • more test-coverage

  • small patch from enriquefynn improving tor binary locating

  • strip OK lines in TorControlProtocol (see issue #8)

  • use TERM not KILL when Tor launch times out (see issue #68) from hellais


January 20, 2014

  • txtorcon-0.9.1.tar.gz (local-sig or github-sig) (source)

  • put test/ directory at the top level

  • using “coverage” tool instead of custom script

  • using and travis-ci for test coverage and continuous integration

  • issue #56: added Circuit.close() and Stream.close() starting from aagbsn’s patch

  • parsing issues with multi-line keyword discovered and resolved

  • preserve router nicks from long-names if consensus lacks an entry (e.g. bridges)

  • using Twine for releases

  • Wheel release now also available

  • issue #57: “python develop” now supported

  • issue #59: if tor_launch() times out, Tor is properly killed (starting with pull-request from Ryman)

  • experimental tests (for HS listening, and tor_launch() timeouts)

  • issue #55: pubkey link on readthedocs

  • issue #63

  • clean up GeoIP handling, and support pygeoip both pre and post 0.3

  • slightly improve unit-test coverage (now at 97%, 61 lines of 2031 missing)

  • added a Walkthrough to the documentation


November 22, 2013


May 13, 2013

  • txtorcon-0.8.1.tar.gz (local-sign or github-sig) (source)

  • fixed improper import in preventing 0.8.0 from installing

  • signatures with proper subkey this time

  • Proper file-flushing in tests and PyPy fixes from Lukas Lueg

  • docs build issue from isis


April 11, 2013 (actually uploaded May 11)

  • Please use 0.8.1; this won’t install due to import problem in (unless you have pypissh).

  • following semantic versioning;

  • slight API change ICircuitListener.circuit_failed(), circuit_closed() and IStreamListener.stream_failed(), stream_closed() and stream_detach() all now include any keywords in the notification method (some of these lacked flags, or only included some) (issue #18);

  • launch_tor() can take a timeout (starting with a patch from hellais);

  • cleanup from aagbsn;

  • more test coverage;

  • run tests cleanly without graphviz (from lukaslueg);

  • issue #26 fix from lukaslueg;

  • pep8 and whitespace targets plus massive cleanup (now pep8 clean, from lukaslueg);

  • issue #30 fix reported by webmeister making ipaddr actually-optional;

  • example using synchronous web server (built-in SimpleHTTPServer) with txtorcon (from lukaslueg);

  • TorState can now create circuits without an explicit path;

  • passwords for non-cookie authenticated sessions use a password callback (that may return a Deferred) instead of a string (issue #44);

  • fixes for AddrMap in case #8596 is implemented;


November 21, 2012

  • txtorcon-0.7.tar.gz (local-sig or github-sig) (source)

  • issue #20 config object now hooked up correctly after launch_tor();

  • patch from hellais for properly handling data_dir given to TCPHiddenServiceEndpoint;

  • .tac example from mmaker;

  • allow TorConfig().hiddenservices.append(hs) to work properly with no attached protocol


October 10, 2012

  • txtorcon-0.6.tar.gz (local-sig or github-sig) (source)

  • debian packaging (mmaker);

  • psutil fully gone;

  • changed API for launch_tor() to use TorConfig instead of args;

  • works properly with no connected Tor;

  • fix incorrect handling of 650 immediately after connect;

  • pep8 compliance;

  • use assertEqual in tests;

  • messages with embdedded keywords work properly;

  • fix bug with + pip;

  • issue #15 reported along with patch by Isis Lovecruft;

  • consolidate requirements (from aagbsn);

  • increased test coverage and various minor fixes;

  • https URIs for ReadTheDocs;


June 20, 2012


June 6, 2012


  • 0.3 was broken when released (docs couldn’t build).


June 1, 2012

  • txtorcon-0.2.tar.gz (txtorcon-0.2.tar.gz.sig)

  • incremental parsing;

  • faster TorState startup;

  • SAFECOOKIE support;

  • several bug fixes;

  • options to example to make it actually-useful;

  • include built documentation + sources in tarball;

  • include tests in tarball;

  • improved logging;

  • patches from mmaker and kneufeld;


march, 2012