[tor-commits] [stem/master] Improving our FAQ and making entries more succinct

atagar at torproject.org atagar at torproject.org
Mon Mar 24 05:36:54 UTC 2014


commit 8680265c7e27f1c9bb8c18ca96b1b204f3013003
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Mar 23 22:32:59 2014 -0700

    Improving our FAQ and making entries more succinct
    
    Reordering and rewording our FAQ. This moves examples for the 'How do I connect
    to Tor?' examples to their respective modules to both make the FAQ entry more
    readable, and the modules more informative.
    
    This also dropped the "How do I get information about my exits?" FAQ entry
    since it's largely redundant with the 'Determine The Exit You’re Using' example
    in our tutorials.
---
 docs/faq.rst       |  412 +++++++++++++++++++++-------------------------------
 stem/connection.py |   27 ++++
 stem/control.py    |   62 +++++++-
 stem/socket.py     |   42 +++++-
 4 files changed, 286 insertions(+), 257 deletions(-)

diff --git a/docs/faq.rst b/docs/faq.rst
index cb70ba5..872e5b5 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -6,16 +6,15 @@ Frequently Asked Questions
  * :ref:`what_is_stem`
  * :ref:`does_stem_have_any_dependencies`
  * :ref:`what_python_versions_is_stem_compatible_with`
- * :ref:`what_license_is_stem_under`
- * :ref:`are_there_any_other_controller_libraries`
  * :ref:`can_i_interact_with_tors_controller_interface_directly`
+ * :ref:`are_there_any_other_controller_libraries`
+ * :ref:`what_license_is_stem_under`
  * :ref:`where_can_i_get_help`
 
 * **Usage**
 
  * :ref:`how_do_i_connect_to_tor`
  * :ref:`how_do_i_request_a_new_identity_from_tor`
- * :ref:`how_do_i_get_information_about_my_exits`
  * :ref:`how_do_i_reload_my_torrc`
  * :ref:`what_is_that_with_keyword_i_keep_seeing_in_the_tutorials`
 
@@ -45,61 +44,48 @@ Does Stem have any dependencies?
 
 **No.** All you need in order to use Stem is Python.
 
-When it is available Stem will use `pycrypto <https://www.dlitz.net/software/pycrypto/>`_ to validate descriptor signatures. However, there is no need to install pycrypto unless you need this functionality.
+When it is available Stem will use `pycrypto
+<https://www.dlitz.net/software/pycrypto/>`_ to validate descriptor signatures.
+However, there is no need to install pycrypto unless you need this
+functionality.
 
 .. _what_python_versions_is_stem_compatible_with:
 
 What Python versions is Stem compatible with?
 ---------------------------------------------
 
-Stem works with **Python 2.6 and greater**. This includes the Python 3.x series by installing Stem via python3 (see our `installation instructions <https://pypi.python.org/pypi/stem/>`_ for more information).
-
-.. _what_license_is_stem_under:
-
-What license is Stem under?
----------------------------
-
-Stem is under the `LGPLv3 <https://www.gnu.org/licenses/lgpl>`_.
-
-.. _are_there_any_other_controller_libraries:
-
-Are there any other controller libraries?
------------------------------------------
-
-Yup. The most mature controller libraries are written in Python, but there's a few options in other languages as well. By far the most mature alternative to Stem are `Txtorcon <https://txtorcon.readthedocs.org/>`_ and `TorCtl <https://gitweb.torproject.org/pytorctl.git>`_.
-
-`Txtorcon <https://txtorcon.readthedocs.org/>`_ is an actively maintained controller library written by Meejah for `Twisted <https://twistedmatrix.com/trac/>`_. In the future we plan to `integrate Stem and Txtorcon <https://www.torproject.org/getinvolved/volunteer.html.en#txtorcon-stemIntegration>`_ to some degree, but that is still a ways off.
-
-`TorCtl <https://gitweb.torproject.org/pytorctl.git>`_ was Stem's predecessor and `deprecated in December 2012 <https://blog.torproject.org/blog/torctl-deprecation-and-stem-plans>`_ in favor of Stem. Though no longer actively developed, it's still quite functional and still used for several `TorFlow <https://gitweb.torproject.org/torflow.git>`_ based projects.
-
-The following are the functional controller libraries I'm aware of. Dates are for highly active development. If I missed one then please `let me know <https://www.atagar.com/contact/>`_!
-
-==========================================================  ================    =======================
-Library                                                     Language            Developed
-==========================================================  ================    =======================
-`Stem <https://stem.torproject.org/>`_                      Python              October 2011 - Present
-`Txtorcon <https://txtorcon.readthedocs.org/>`_             Python (Twisted)    February 2012 - Present
-`TorCtl <https://gitweb.torproject.org/pytorctl.git>`_      Python              July 2008 - November 2011
-`PHP TorCtl <https://github.com/dunglas/php-torcontrol/>`_  PHP                 February 2013
-`JTorCtl <https://gitweb.torproject.org/jtorctl.git>`_      Java                June 2005 - May 2009
-==========================================================  ================    =======================
+Stem works with **Python 2.6 and greater**. This includes the Python 3.x series
+by installing Stem via python3 (see our `installation instructions
+<https://pypi.python.org/pypi/stem/>`_ for more information).
 
 .. _can_i_interact_with_tors_controller_interface_directly:
 
 Can I interact with Tor's controller interface directly?
 --------------------------------------------------------
 
-Yup. You don't need a library to interact with Tor's `controller interface <https://gitweb.torproject.org/torspec.git/blob/HEAD:/control-spec.txt>`_, and interacting with it directly is a great way of learning about what it can do. The exact details for how you connect to Tor depend on two things...
+Yup. You don't need a library to interact with Tor's `controller interface
+<https://gitweb.torproject.org/torspec.git/blob/HEAD:/control-spec.txt>`_, and
+interacting with it directly is a great way to learn about what it can do. The
+exact details for how you connect to Tor depend on two things...
 
-* Where is Tor listening for controller connections? This is specified by either the **ControlPort** or **ControlSocket** option in your torrc. If you have neither then Tor will not accept controller connections.
-* What type of authentication is Tor's controller interface using? This is defined by your **CookieAuthentication** or **HashedControlPassword** option. If you have neither then Tor does not restrict access.
+* Where is Tor listening for controller connections? This is specified by
+  either the **ControlPort** or **ControlSocket** option in your torrc. If you
+  have neither then Tor will not accept controller connections.
+
+* What type of authentication is Tor's controller interface using? This is
+  defined by your **CookieAuthentication** or **HashedControlPassword** option.
+  If you have neither then Tor does not restrict access.
 
 We'll tackle each of these scenarios one at a time...
 
 **I'm using a ControlPort**
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If you are using a **ControlPort** then the easiest method of talking with Tor is via **telnet**. You always need to authenticate after connecting, even if Tor does not restrict access. If your torrc doesn't have a **CookieAuthentication** or **HashedControlPassword** then to authenticate you will simply call **AUTHENTICATE** after connecting without any credentials.
+If you are using a **ControlPort** then the easiest method of talking with Tor
+is via **telnet**. You always need to authenticate after connecting, even if
+Tor does not restrict access. If your torrc doesn't have a
+**CookieAuthentication** or **HashedControlPassword** then to authenticate you
+will simply call **AUTHENTICATE** after connecting without any credentials.
 
 ::
 
@@ -122,7 +108,8 @@ If you are using a **ControlPort** then the easiest method of talking with Tor i
 **I'm using a ControlSocket**
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-A **ControlSocket** is a file based socket, so we'll use **socat** to connect to it...
+A **ControlSocket** is a file based socket, so we'll use **socat** to connect
+to it...
 
 ::
 
@@ -141,7 +128,10 @@ A **ControlSocket** is a file based socket, so we'll use **socat** to connect to
 **I'm using cookie authentication**
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Cookie authentication simply means that your credential is the content of a file in Tor's **DataDirectory**. You can learn information about Tor's method of authentication (including the cookie file's location) by calling **PROTOCOLINFO**...
+Cookie authentication simply means that your credential is the content of a
+file in Tor's **DataDirectory**. You can learn information about Tor's method
+of authentication (including the cookie file's location) by calling
+**PROTOCOLINFO**...
 
 ::
 
@@ -159,7 +149,10 @@ Cookie authentication simply means that your credential is the content of a file
   250-VERSION Tor="0.2.5.1-alpha-dev"
   250 OK
 
-Cookie authentication has two flavors: **COOKIE** and **SAFECOOKIE**. Below we'll show you how to authenticate via COOKIE. SAFECOOKIE authentication is a lot more involved, and not something you will want to do by hand (though Stem supports it transparently).
+Cookie authentication has two flavors: **COOKIE** and **SAFECOOKIE**. Below
+we'll show you how to authenticate via COOKIE. SAFECOOKIE authentication is a
+lot more involved, and not something you will want to do by hand (though Stem
+supports it transparently).
 
 To get the credential for your AUTHENTICATE command we will use **hexdump**...
 
@@ -184,7 +177,8 @@ To get the credential for your AUTHENTICATE command we will use **hexdump**...
 **I'm using password authentication**
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Tor's other method of authentication is a credential you know. To use it ask Tor to hash your password, then use that in your torrc...
+Tor's other method of authentication is a credential you know. To use it ask
+Tor to hash your password, then use that in your torrc...
 
 ::
 
@@ -212,12 +206,60 @@ Authenticating with this simply involves giving Tor the credential...
   250 closing connection
   Connection closed by foreign host.
 
+.. _are_there_any_other_controller_libraries:
+
+Are there any other controller libraries?
+-----------------------------------------
+
+Yup. The most mature controller libraries are written in Python, but there's a
+few options in other languages as well. By far the most mature alternative to
+Stem are `Txtorcon <https://txtorcon.readthedocs.org/>`_ and `TorCtl
+<https://gitweb.torproject.org/pytorctl.git>`_.
+
+`Txtorcon <https://txtorcon.readthedocs.org/>`_ is an actively maintained
+controller library written by Meejah for `Twisted
+<https://twistedmatrix.com/trac/>`_. In the future we plan to `integrate Stem
+and Txtorcon
+<https://www.torproject.org/getinvolved/volunteer.html.en#txtorcon-stemIntegration>`_
+to some degree, but that is still a ways off.
+
+`TorCtl <https://gitweb.torproject.org/pytorctl.git>`_ was Stem's predecessor
+and `deprecated in December 2012
+<https://blog.torproject.org/blog/torctl-deprecation-and-stem-plans>`_ in favor
+of Stem. Though no longer actively developed, it's still quite functional and
+still used for several `TorFlow <https://gitweb.torproject.org/torflow.git>`_
+based projects.
+
+The following are the functional controller libraries I'm aware of. Dates are
+for highly active development. If I missed one then please `let me know
+<https://www.atagar.com/contact/>`_!
+
+==========================================================  ================    =======================
+Library                                                     Language            Developed
+==========================================================  ================    =======================
+`Stem <https://stem.torproject.org/>`_                      Python              October 2011 - Present
+`Txtorcon <https://txtorcon.readthedocs.org/>`_             Python (Twisted)    February 2012 - Present
+`TorCtl <https://gitweb.torproject.org/pytorctl.git>`_      Python              July 2008 - November 2011
+`PHP TorCtl <https://github.com/dunglas/php-torcontrol/>`_  PHP                 February 2013
+`JTorCtl <https://gitweb.torproject.org/jtorctl.git>`_      Java                June 2005 - May 2009
+==========================================================  ================    =======================
+
+.. _what_license_is_stem_under:
+
+What license is Stem under?
+---------------------------
+
+Stem is under the `LGPLv3 <https://www.gnu.org/licenses/lgpl>`_.
+
 .. _where_can_i_get_help:
 
 Where can I get help?
 ---------------------
 
-Do you have a Tor related question or project that you would like to discuss? If so then find us on the `tor-dev@ email list <https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev>`_ and `IRC <https://www.torproject.org/about/contact.html.en#irc>`_.
+Do you have a Tor related question or project that you would like to discuss?
+If so then find us on the `tor-dev@ email list
+<https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev>`_ and `IRC
+<https://www.torproject.org/about/contact.html.en#irc>`_.
 
 Usage
 =====
@@ -229,131 +271,39 @@ How do I connect to Tor?
 
 Once you have Tor running and `properly configured <tutorials/the_little_relay_that_could.html>`_ you have a few ways of connecting to it. The following are the most common methods for getting a :class:`~stem.control.Controller` instance, from the highest to lowest level...
 
-#. :func:`stem.connection.connect_port` and :func:`stem.connection.connect_socket_file`
-
-   Writing a commandline script? Then the `connection module <api/connection.html>`_ provide you the quickest and most hassle free method for getting a :class:`~stem.control.Controller`.
-
-   These functions connect and authenticate to the given port or socket, providing you with a :class:`~stem.control.Controller` that's ready to use. If Tor requires a password then the user will be prompted for it. When the connection cannot be established this prints a description of the problem to stdout then returns **None**.
-
-   For instance...
-
-   ::
-
-      import sys 
-
-      from stem.connection import connect_port
+#. `Connection Module <api/connection.html>`_
 
-      if __name__ == '__main__':
-        controller = connect_port()
+   Writing a commandline script? Then the :func:`~stem.connection.connect_port`
+   and :func:`~stem.connection.connect_socket_file` functions provide you the
+   quickest and most hassle free method for getting a
+   :class:`~stem.control.Controller`.
 
-        if not controller:
-          sys.exit(1)  # unable to get a connection
+   These functions connect and authenticate to the given port or socket,
+   providing you a one-line method of getting a
+   :class:`~stem.control.Controller` that's ready to use. If Tor requires a
+   password then the user will be prompted for it. When the connection cannot
+   be established this prints a description of the problem to stdout and
+   returns **None**.
 
-        print "Tor is running version %s" % controller.get_version()
-        controller.close()
+#. `Control Module <api/control.html>`_
 
-   ::
+   The connection module helpers above are all well and good when you need a
+   quick-and-dirty connection for your commandline script, but they're
+   inflexible. In particular their lack of exceptions and direct use of
+   stdin/stdout make them undesirable for more complicated situations. That's
+   where the Controller's :func:`~stem.control.Controller.from_port` and
+   :func:`~stem.control.Controller.from_socket_file` methods come in.
 
-      % python example.py 
-      Tor is running version 0.2.4.10-alpha-dev (git-8be6058d8f31e578)
-
-   ... or if Tor isn't running...
-
-   ::
-
-      % python example.py 
-      [Errno 111] Connection refused
-
-#. :func:`stem.control.Controller.from_port` and :func:`stem.control.Controller.from_socket_file`
-
-   The connection module helpers above are all well and good when you need a quick-and-dirty connection for your commandline script, but they're inflexible. In particular their lack of exceptions and direct use of stdin/stdout make them undesirable for more complicated situations. That's where the Controller's :func:`~stem.control.Controller.from_port` and :func:`~stem.control.Controller.from_socket_file` methods come in.
-
-   These static :class:`~stem.control.Controller` methods return an **unauthenticated** controller you can then authenticate yourself using its :func:`~stem.control.Controller.authenticate` method.
-
-   For instance...
-
-   ::
-
-      import getpass
-      import sys
-
-      import stem
-      import stem.connection
-
-      from stem.control import Controller
-
-      if __name__ == '__main__':
-        try:
-          controller = Controller.from_port()
-        except stem.SocketError as exc:
-          print "Unable to connect to tor on port 9051: %s" % exc
-          sys.exit(1)
-
-        try:
-          controller.authenticate()
-        except stem.connection.MissingPassword:
-          pw = getpass.getpass("Controller password: ")
-
-          try:
-            controller.authenticate(password = pw)
-          except stem.connection.PasswordAuthFailed:
-            print "Unable to authenticate, password is incorrect"
-            sys.exit(1)
-        except stem.connection.AuthenticationFailure as exc:
-          print "Unable to authenticate: %s" % exc
-          sys.exit(1)
-
-        print "Tor is running version %s" % controller.get_version()
-        controller.close()
-
-   If you're fine with allowing your script to raise exceptions then this can be more nicely done as...
-
-   ::
-
-      from stem.control import Controller
-
-      if __name__ == '__main__':
-        with Controller.from_port() as controller:
-          controller.authenticate()
-
-          print "Tor is running version %s" % controller.get_version()
+   These provide the most flexible method of connecting to Tor, and for
+   sophisticated applications is what you'll want.
 
 #. `Socket Module <api/socket.html>`_
 
-   For the diehards among us you can skip the conveniences of a high level :class:`~stem.control.Controller` and work directly with the raw components. At Stem's lowest level your connection with Tor is a :class:`~stem.socket.ControlSocket` subclass. This provides methods to send, receive, disconnect, and reconnect to Tor.
-
-   One level up is the :class:`~stem.control.BaseController`. This wraps the :class:`~stem.socket.ControlSocket` and provides a :func:`~stem.control.BaseController.msg` method so you can send messages and receive their reply in a thread safe manner. Finally comes the :class:`~stem.control.Controller`, which extends :class:`~stem.control.BaseController` to provide more user friendly methods.
-
-   Directly using the :class:`~stem.socket.ControlSocket` is unsafe when it's being managed through a :class:`~stem.control.BaseController`, but if you're interested in dealing with lower level components directly then that is certainly an option...
-
-   ::
-
-      import stem
-      import stem.connection
-      import stem.socket
-
-      if __name__ == '__main__':
-        try:
-          control_socket = stem.socket.ControlPort(port = 9051)
-          stem.connection.authenticate(control_socket)
-        except stem.SocketError as exc:
-          print "Unable to connect to tor on port 9051: %s" % exc
-          sys.exit(1)
-        except stem.connection.AuthenticationFailure as exc:
-          print "Unable to authenticate: %s" % exc
-          sys.exit(1)
-
-        print "Issuing 'GETINFO version' query...\n"
-        control_socket.send('GETINFO version')
-        print control_socket.recv()
-
-   ::
-
-      % python example.py 
-      Issuing 'GETINFO version' query...
-
-      version=0.2.4.10-alpha-dev (git-8be6058d8f31e578)
-      OK
+   For the diehards among us you can skip the conveniences of a high level
+   :class:`~stem.control.Controller` and work directly with the raw components.
+   At Stem's lowest level your connection with Tor is a
+   :class:`~stem.socket.ControlSocket` subclass. This provides methods to send,
+   receive, disconnect, and reconnect to Tor.
 
 .. _how_do_i_request_a_new_identity_from_tor:
 
@@ -394,61 +344,6 @@ And with Stem...
     controller.authenticate()
     controller.signal(Signal.NEWNYM)
 
-For lower level control over Tor's circuits and path selection see the `client usage tutorial <tutorials/to_russia_with_love.html>`_.
-
-.. _how_do_i_get_information_about_my_exits:
-
-How do I get information about my exits?
-----------------------------------------
-
-To learn about the Tor relays you're presently using call :func:`~stem.control.Controller.get_circuits`. The last relay in the circuit's path is your exit...
-
-::
-
-  from stem import CircStatus
-  from stem.control import Controller
-
-  with Controller.from_port(port = 9051) as controller:
-    controller.authenticate()
-
-    for circ in controller.get_circuits():
-      if circ.status != CircStatus.BUILT:
-        continue
-
-      exit_fp, exit_nickname = circ.path[-1]
-
-      exit_desc = controller.get_network_status(exit_fp, None)
-      exit_address = exit_desc.address if exit_desc else 'unknown'
-
-      print "Exit relay"
-      print "  fingerprint: %s" % exit_fp
-      print "  nickname: %s" % exit_nickname
-      print "  address: %s" % exit_address
-      print
-
-::
-
-  % python example.py 
-  Exit relay
-    fingerprint: 94AD3437EC49A31E8D6C17CC3BDE8316C90262BE
-    nickname: davidonet
-    address: 188.165.236.209
-
-  Exit relay
-    fingerprint: 6042CC1C69BBFE83A1DD2BCD4C15000A0DD5E1BC
-    nickname: Gnome5
-    address: 178.209.50.230
-
-  Exit relay
-    fingerprint: 9634F910C2942A2E46720DD161A873E3A619AD90
-    nickname: veebikaamera
-    address: 81.21.246.66
-
-  Exit relay
-    fingerprint: A59E1E7C7EAEE083D756EE1FF6EC31CA3D8651D7
-    nickname: chaoscomputerclub19
-    address: 31.172.30.2
-
 .. _how_do_i_reload_my_torrc:
 
 How do I reload my torrc?
@@ -473,7 +368,9 @@ Tor is configured through its `torrc <https://www.torproject.org/docs/faq.html.e
 What is that 'with' keyword I keep seeing in the tutorials?
 -----------------------------------------------------------
 
-Python's '**with**' keyword is shorthand for a try/finally block. With a :class:`~stem.control.Controller` the following...
+Python's `with <http://effbot.org/zone/python-with-statement.htm>`_ keyword
+is shorthand for a try/finally block. With a :class:`~stem.control.Controller`
+the following...
 
 ::
 
@@ -491,7 +388,11 @@ Python's '**with**' keyword is shorthand for a try/finally block. With a :class:
   finally:
     controller.close()
 
-This helps to make sure that regardless of if your code raises an exception or not the control connection will be cleaned up afterward. Note that this means that if you leave the 'with' scope your :class:`~stem.control.Controller` will be closed. For instance...
+This helps to make sure that regardless of if your code raises an exception or
+not the control connection will be cleaned up afterward. Note that this means
+that if you leave the 'with' scope your :class:`~stem.control.Controller` will
+be closed. The following for instance is a bug common when first learning
+Stem...
 
 ::
 
@@ -510,25 +411,11 @@ This helps to make sure that regardless of if your code raises an exception or n
       reporter = BandwidthReporter(controller)
 
     # The following line is broken because the 'controller' we initialised
-    # above was disconnected once we left the 'with' scope.
+    # above was disconnected once we left the 'with' scope. To fix this the
+    # print_bandwidth() call should be in the 'with' block.
 
     reporter.print_bandwidth()
 
-To fix this we could either move the print_bandwidth() call into the 'with' scope, or simply avoid using 'with' all together...
-
-::
-
-  if __name__ == '__main__':
-    controller = Controller.from_port(port = 9051)
-
-    try:
-      reporter = BandwidthReporter(controller)
-      reporter.print_bandwidth()
-    finally:
-      controller.close()
-
-For more information about the 'with' keyword see `here <http://effbot.org/zone/python-with-statement.htm>`_.
-
 Development
 ===========
 
@@ -537,15 +424,19 @@ Development
 How do I get started?
 ---------------------
 
-The best way of getting involved with any project is to jump right in! Our `bug tracker <https://trac.torproject.org/projects/tor/wiki/doc/stem/bugs>`_ lists several development tasks. In particular look for the 'easy' keyword when getting started.
-
-If you have any questions then I'm always more than happy to help (I'm **atagar** on `oftc <http://www.oftc.net/oftc/>`_ and also available `via email <https://www.atagar.com/contact/>`_).
+The best way of getting involved with any project is to jump right in! Our `bug
+tracker <https://trac.torproject.org/projects/tor/wiki/doc/stem/bugs>`_ lists
+several development tasks. In particular look for the 'easy' keyword when
+getting started. If you have any questions then I'm always more than happy to
+help! I'm **atagar** on `oftc <http://www.oftc.net/oftc/>`_ and also available
+`via email <https://www.atagar.com/contact/>`_.
 
-To start hacking on Stem please do the following and don't hesitate to let me know if you get stuck or would like to discuss anything!
+To start hacking on Stem please do the following and don't hesitate to let me
+know if you get stuck or would like to discuss anything!
 
-1. Clone our `git <http://git-scm.com/>`_ repository: **git clone https://git.torproject.org/stem.git**
-2. Find a `bug or feature <https://trac.torproject.org/projects/tor/wiki/doc/stem/bugs>`_ that sounds interesting.
-3. When you have something that you would like to contribute back do the following...
+#. Clone our `git <http://git-scm.com/>`_ repository: **git clone https://git.torproject.org/stem.git**
+#. Find a `bug or feature <https://trac.torproject.org/projects/tor/wiki/doc/stem/bugs>`_ that sounds interesting.
+#. When you have something that you would like to contribute back do the following...
 
  * If you don't already have a publicly accessible Stem repository then set one up. `GitHub <https://github.com/>`_ in particular is great for this.
  * File a `trac ticket <https://trac.torproject.org/projects/tor/newticket>`_, the only fields you'll need are...
@@ -565,14 +456,20 @@ How do I run the tests?
 
 Stem has three kinds of tests: **unit**, **integration**, and **static**.
 
-**Unit** tests are our most frequently ran tests. They're quick, they're easy, and provide good test coverage...
+**Unit** tests are our most frequently ran tests. They're quick, they're easy,
+and provide good test coverage...
 
 ::
 
   ~$ cd stem/
   ~/stem$ ./run_tests.py --unit
 
-**Integration** tests start a live Tor instance and test against that. This not only provides additional test coverage, but lets us check our continued interoperability with new releases of Tor. Running these require that you have `Tor installed <https://www.torproject.org/download/download.html.en>`_. You can exercise alternate Tor configurations with the ``--target`` argument (see ``run_tests.py --help`` for a list of its options).
+**Integration** tests start a live Tor instance and test against that. This not
+only provides additional test coverage, but lets us check our continued
+interoperability with new releases of Tor. Running these require that you have
+`Tor installed <https://www.torproject.org/download/download.html.en>`_. You
+can exercise alternate Tor configurations with the ``--target`` argument (see
+``run_tests.py --help`` for a list of its options).
 
 ::
 
@@ -580,9 +477,14 @@ Stem has three kinds of tests: **unit**, **integration**, and **static**.
   ~/stem$ ./run_tests.py --integ --tor /path/to/tor
   ~/stem$ ./run_tests.py --integ --target RUN_COOKIE
 
-**Static** tests use `pyflakes <https://launchpad.net/pyflakes>`_ to do static error checking and `pep8 <http://pep8.readthedocs.org/en/latest/>`_ for style checking. If you have them installed then they automatically take place as part of all test runs.
+**Static** tests use `pyflakes <https://launchpad.net/pyflakes>`_ to do static
+error checking and `pep8 <http://pep8.readthedocs.org/en/latest/>`_ for style
+checking. If you have them installed then they automatically take place as part
+of all test runs.
 
-If you have **Python 3** installed then you can test our Python 3 compatibility with the following. *Note that need to still initially execute run_tests.py with a 2.x version of Python.*
+If you have **Python 3** installed then you can test our Python 3 compatibility
+with the following. *Note that need to still initially execute run_tests.py
+with a 2.x version of Python.*
 
 ::
 
@@ -595,14 +497,16 @@ See ``run_tests.py --help`` for more usage information.
 How do I build the site?
 ------------------------
 
-If you have `sphinx <http://sphinx-doc.org/>`_ version 1.1 or later installed then building our site is as easy as...
+If you have `Sphinx <http://sphinx-doc.org/>`_ version 1.1 or later installed
+then building our site is as easy as...
 
 ::
 
   ~$ cd stem/docs
   ~/stem/docs$ make html
 
-When it's finished you can direct your browser to the *_build* directory with a URI similar to...
+When it's finished you can direct your browser to the *_build* directory with a
+URI similar to...
 
 ::
 
@@ -613,7 +517,15 @@ When it's finished you can direct your browser to the *_build* directory with a
 What is the copyright for patches?
 ----------------------------------
 
-Stem is under the LGPLv3 which is a fine license, but poses a bit of a problem for sharing code with our other projects (which are mostly BSD). To share code without needing to hunt down prior contributors we need Tor to have the copyright for the whole Stem codebase. Presently the copyright of Stem is jointly held by its main author (`Damian <https://www.atagar.com/>`_) and the `Tor Project <https://www.torproject.org/>`_.
-
-If you submit a substantial patch I'll ask if you're fine with it being in the public domain. This would mean that there are no legal restrictions for using your contribution, and hence won't pose a problem if we reuse Stem code in other projects.
+Stem is under the LGPLv3 which is a fine license, but poses a bit of a problem
+for sharing code with our other projects (which are mostly BSD). To share code
+without needing to hunt down prior contributors we need Tor to have the
+copyright for the whole Stem codebase. Presently the copyright of Stem is
+jointly held by its main author (`Damian <https://www.atagar.com/>`_) and the
+`Tor Project <https://www.torproject.org/>`_.
+
+If you submit a substantial patch I'll ask if you're fine with it being in the
+public domain. This would mean that there are no legal restrictions for using
+your contribution, and hence won't pose a problem if we reuse Stem code in
+other projects.
 
diff --git a/stem/connection.py b/stem/connection.py
index 82ad25b..769f432 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -11,6 +11,33 @@ applications and the python interactive interpreter, but does several things
 that makes it undesirable for applications (uses stdin/stdout, suppresses
 exceptions, etc).
 
+::
+
+  import sys 
+
+  from stem.connection import connect_port
+
+  if __name__ == '__main__':
+    controller = connect_port()
+
+    if not controller:
+      sys.exit(1)  # unable to get a connection
+
+    print "Tor is running version %s" % controller.get_version()
+    controller.close()
+
+::
+
+  % python example.py 
+  Tor is running version 0.2.4.10-alpha-dev (git-8be6058d8f31e578)
+
+... or if Tor isn't running...
+
+::
+
+  % python example.py 
+  [Errno 111] Connection refused
+
 The :func:`~stem.connection.authenticate` function, however, gives easy but
 fine-grained control over the authentication process. For instance...
 
diff --git a/stem/control.py b/stem/control.py
index bf86135..ddcc5df 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2,11 +2,65 @@
 # See LICENSE for licensing information
 
 """
-Classes for interacting with the tor control socket.
+Module for interacting with the Tor control socket. The
+:class:`~stem.control.Controller` is a wrapper around a
+:class:`~stem.socket.ControlSocket`, retaining many of its methods (connect,
+close, is_alive, etc) in addition to providing its own for working with the
+socket at a higher level.
+
+Stem has `several ways <../faq.html#how-do-i-connect-to-tor>`_ of getting a
+:class:`~stem.control.Controller`, but the most flexible are
+:func:`~stem.control.Controller.from_port` and
+:func:`~stem.control.Controller.from_socket_file`. These static
+:class:`~stem.control.Controller` methods give you an **unauthenticated**
+Controller you can then authenticate yourself using its
+:func:`~stem.control.Controller.authenticate` method. For example...
 
-Controllers are a wrapper around a :class:`~stem.socket.ControlSocket`,
-retaining many of its methods (connect, close, is_alive, etc) in addition to
-providing its own for interacting at a higher level.
+::
+
+  import getpass
+  import sys
+
+  import stem
+  import stem.connection
+
+  from stem.control import Controller
+
+  if __name__ == '__main__':
+    try:
+      controller = Controller.from_port()
+    except stem.SocketError as exc:
+      print "Unable to connect to tor on port 9051: %s" % exc
+      sys.exit(1)
+
+    try:
+      controller.authenticate()
+    except stem.connection.MissingPassword:
+      pw = getpass.getpass("Controller password: ")
+
+      try:
+        controller.authenticate(password = pw)
+      except stem.connection.PasswordAuthFailed:
+        print "Unable to authenticate, password is incorrect"
+        sys.exit(1)
+    except stem.connection.AuthenticationFailure as exc:
+      print "Unable to authenticate: %s" % exc
+      sys.exit(1)
+
+    print "Tor is running version %s" % controller.get_version()
+    controller.close()
+
+If you're fine with allowing your script to raise exceptions then this can be more nicely done as...
+
+::
+
+  from stem.control import Controller
+
+  if __name__ == '__main__':
+    with Controller.from_port() as controller:
+      controller.authenticate()
+
+      print "Tor is running version %s" % controller.get_version()
 
 **Module Overview:**
 
diff --git a/stem/socket.py b/stem/socket.py
index dfdce08..cb74f21 100644
--- a/stem/socket.py
+++ b/stem/socket.py
@@ -2,9 +2,45 @@
 # See LICENSE for licensing information
 
 """
-Supports message based communication with sockets speaking the tor control
-protocol. This lets users send messages as basic strings and receive responses
-as instances of the :class:`~stem.response.ControlMessage` class.
+Supports communication with sockets speaking the Tor control protocol. This
+allows us to send messages as basic strings, and receive responses as
+:class:`~stem.response.ControlMessage` instances.
+
+**This module only consists of low level components, and is not intended for
+users.** See our `tutorials <tutorials.html>`_ and `Control Module
+<api/control.html>`_ if you're new to Stem and looking to get started.
+
+With that aside, these can still be used for raw socket communication with
+Tor...
+
+::
+
+  import stem
+  import stem.connection
+  import stem.socket
+
+  if __name__ == '__main__':
+    try:
+      control_socket = stem.socket.ControlPort(port = 9051)
+      stem.connection.authenticate(control_socket)
+    except stem.SocketError as exc:
+      print "Unable to connect to tor on port 9051: %s" % exc
+      sys.exit(1)
+    except stem.connection.AuthenticationFailure as exc:
+      print "Unable to authenticate: %s" % exc
+      sys.exit(1)
+
+    print "Issuing 'GETINFO version' query...\\n"
+    control_socket.send('GETINFO version')
+    print control_socket.recv()
+
+::
+
+  % python example.py 
+  Issuing 'GETINFO version' query...
+
+  version=0.2.4.10-alpha-dev (git-8be6058d8f31e578)
+  OK
 
 **Module Overview:**
 



More information about the tor-commits mailing list