# High Level API

This is the recommended API. See the Programming Guide for “prose” documentation of these (and other) APIs.

## Tor

class txtorcon.Tor(reactor, control_protocol, _tor_config=None, _process_proto=None, _non_anonymous=None)

  I represent a single instance of Tor and act as a Builder/Factory for several useful objects you will probably want. There are two ways to create a Tor instance:

  > - `txtorcon.connect()` to connect to a Tor that is already running (e.g. Tor Browser Bundle, a system Tor, …).

  > - `txtorcon.launch()` to launch a fresh Tor instance

  The stable API provided by this class is `txtorcon.interface.ITor`

  If you desire more control, there are “lower level” APIs which are the very ones used by this class. However, this “highest level” API should cover many use-cases:

      import txtorcon

      @inlineCallbacks
      def main(reactor):
          # tor = yield txtorcon.connect(UNIXClientEndpoint(reactor, "/var/run/tor/control"))
          tor = yield txtorcon.launch(reactor)

          onion_ep = tor.create_onion_endpoint(port=80)
          port = yield onion_ep.listen(Site())
          print(port.getHost())

  don’t instantiate this class yourself – instead use the factory methods `txtorcon.launch()` or `txtorcon.connect()`

## connect

controller.connect(control_endpoint=None, password_function=None)

  Creates a `txtorcon.Tor` instance by connecting to an already-running tor’s control port. For example, a common default tor uses is UNIXClientEndpoint(reactor, ‘/var/run/tor/control’) or TCP4ClientEndpoint(reactor, ‘localhost’, 9051)

  If only password authentication is available in the tor we connect to, the `password_function` is called (if supplied) to retrieve a valid password. This function can return a Deferred.

  For example:

      import txtorcon
      from twisted.internet.task import react
      from twisted.internet.defer import inlineCallbacks

      @inlineCallbacks
      def main(reactor):
          tor = yield txtorcon.connect(
              TCP4ClientEndpoint(reactor, "localhost", 9051)
          )
          state = yield tor.create_state()
          for circuit in state.circuits:
              print(circuit)

  Parameters:

    - control_endpoint – None, an IStreamClientEndpoint to connect to, or a Sequence of IStreamClientEndpoint instances to connect to. If None, a list of defaults are tried.

    - password_function – See `txtorcon.TorControlProtocol`

  Returns:

    a Deferred that fires with a `txtorcon.Tor` instance

## launch

controller.launch(progress_updates=None, control_port=None, data_directory=None, socks_port=None, non_anonymous_mode=None, stdout=None, stderr=None, timeout=None, tor_binary=None, user=None, connection_creator=None, kill_on_stderr=True, _tor_config=None)

  launches a new Tor process, and returns a Deferred that fires with a new `txtorcon.Tor` instance. From this instance, you can create or get any “interesting” instances you need: the `txtorcon.TorConfig` instance, create endpoints, create `txtorcon.TorState` instance(s), etc.

  Note that there is NO way to pass in a config; we only expost a couple of basic Tor options. If you need anything beyond these, you can access the `TorConfig` instance (via `.config`) and make any changes there, reflecting them in tor with `.config.save()`.

  You can igore all the options and safe defaults will be provided. However, it is recommended to pass data_directory especially if you will be starting up Tor frequently, as it saves a bunch of time (and bandwidth for the directory authorities). “Safe defaults” means:

  > - a tempdir for a `DataDirectory` is used (respecting `TMP`) and is deleted when this tor is shut down (you therefore probably want to supply the `data_directory=` kwarg);

  > - a random, currently-unused local TCP port is used as the `SocksPort` (specify `socks_port=` if you want your own). If you want no SOCKS listener at all, pass `socks_port=0`

  > - we set `__OwningControllerProcess` and call `TAKEOWNERSHIP` so that if our control connection goes away, tor shuts down (see control-spec 3.23).

  > - the launched Tor will use `COOKIE` authentication.

  Parameters:

    - reactor – a Twisted IReactorCore implementation (usually twisted.internet.reactor)

    - progress_updates – a callback which gets progress updates; gets 3 args: percent, tag, summary (FIXME make an interface for this).

    - data_directory – set as the `DataDirectory` option to Tor, this is where tor keeps its state information (cached relays, etc); starting with an already-populated state directory is a lot faster. If `None` (the default), we create a tempdir for this and delete it on exit. It is recommended you pass something here.

    - non_anonymous_mode – sets the Tor options HiddenServiceSingleHopMode and HiddenServiceNonAnonymousMode to 1 and un-sets any SOCKSPort config, thus putting this Tor client into “non-anonymous mode” which allows starting so-called Single Onion services – which use single-hop circuits to rendezvous points. See WARNINGs in Tor manual! Also you need Tor 0.3.4.1 or later (e.g. any 0.3.5.* or newer) for this to work properly.

    - stdout – a file-like object to which we write anything that Tor prints on stdout (just needs to support write()).

    - stderr – a file-like object to which we write anything that Tor prints on stderr (just needs .write()). Note that we kill Tor off by default if anything appears on stderr; pass “kill_on_stderr=False” if you don’t want this behavior.

    - tor_binary – path to the Tor binary to run. If None (the default), we try to find the tor binary.

    - kill_on_stderr – When True (the default), if Tor prints anything on stderr we kill off the process, close the TorControlProtocol and raise an exception.

    - connection_creator – is mostly available to ease testing, so you probably don’t want to supply this. If supplied, it is a callable that should return a Deferred that delivers an IProtocol or ConnectError. See twisted.internet.interfaces.IStreamClientEndpoint.connect Note that this parameter is ignored if config.ControlPort == 0

  Returns:

    a Deferred which callbacks with `txtorcon.Tor` instance, from which you can retrieve the TorControlProtocol instance via the `.protocol` property.

  HACKS:

  > 1. It’s hard to know when Tor has both (completely!) written its authentication cookie file AND is listening on the control port. It seems that waiting for the first ‘bootstrap’ message on stdout is sufficient. Seems fragile…and doesn’t work 100% of the time, so FIXME look at Tor source.

  XXX this “User” thing was, IIRC, a feature for root-using scripts (!!) that were going to launch tor, but where tor would drop to a different user. Do we still want to support this? Probably relevant to Docker (where everything is root! yay!)

  `User`: if this exists, we attempt to set ownership of the tempdir to this user (but only if our effective UID is 0).