[tor-commits] [stem/master] Shorthand functions for stem.descriptor.remote

atagar at torproject.org atagar at torproject.org
Sun Mar 6 22:02:20 UTC 2016


commit a96ec510539f2918bf93c50d63ce68e919f71209
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Mar 6 13:55:21 2016 -0800

    Shorthand functions for stem.descriptor.remote
    
    Damn stem.descriptor.remote is useful! This has become our best method of
    fetching descriptors but its usage is a bit formulaic...
    
      import stem.descriptor.remote
    
      downloader = stem.descriptor.remote.DescriptorDownloader()
    
      for desc in downloader.get_server_descriptors():
        ... do stuff...
    
    Why make users get a downloader object? It's useful for power users that need
    to customize how descriptors are downloaded, but 95% of users don't care. They
    simply want the bloody descriptors, so providing shorthand methods that do
    just that!
    
      import stem.descriptor.remote
    
      for desc in stem.descriptor.remote.get_server_descriptors():
        ... do stuff...
---
 docs/_static/example/current_descriptors.py        |   6 +-
 .../example/saving_and_loading_descriptors.py      |   5 +-
 docs/_static/example/tor_descriptors.py            |   7 +-
 docs/change_log.rst                                |   1 +
 stem/cached_tor_manual.cfg                         |   4 +-
 stem/descriptor/fallback_directories.cfg           |   2 +-
 stem/descriptor/remote.py                          | 101 +++++++++++++++++++--
 stem/settings.cfg                                  |   1 +
 test/integ/descriptor/remote.py                    |  20 ++++
 9 files changed, 123 insertions(+), 24 deletions(-)

diff --git a/docs/_static/example/current_descriptors.py b/docs/_static/example/current_descriptors.py
index f86b5b9..44c9ac3 100644
--- a/docs/_static/example/current_descriptors.py
+++ b/docs/_static/example/current_descriptors.py
@@ -1,9 +1,7 @@
-from stem.descriptor.remote import DescriptorDownloader
-
-downloader = DescriptorDownloader()
+import stem.descriptor.remote
 
 try:
-  for desc in downloader.get_consensus().run():
+  for desc in stem.descriptor.remote.get_consensus().run():
     print("found relay %s (%s)" % (desc.nickname, desc.fingerprint))
 except Exception as exc:
   print("Unable to retrieve the consensus: %s" % exc)
diff --git a/docs/_static/example/saving_and_loading_descriptors.py b/docs/_static/example/saving_and_loading_descriptors.py
index bb2703e..42e3ffe 100644
--- a/docs/_static/example/saving_and_loading_descriptors.py
+++ b/docs/_static/example/saving_and_loading_descriptors.py
@@ -1,7 +1,6 @@
-from stem.descriptor.remote import DescriptorDownloader
+import stem.descriptor.remote
 
-downloader = DescriptorDownloader()
-server_descriptors = downloader.get_server_descriptors().run()
+server_descriptors = stem.descriptor.remote.get_server_descriptors().run()
 
 with open('/tmp/descriptor_dump', 'wb') as descriptor_file:
   descriptor_file.write(''.join(map(str, server_descriptors)))
diff --git a/docs/_static/example/tor_descriptors.py b/docs/_static/example/tor_descriptors.py
index 0ec0666..708e5fc 100644
--- a/docs/_static/example/tor_descriptors.py
+++ b/docs/_static/example/tor_descriptors.py
@@ -1,16 +1,15 @@
 import sys
 
-from stem.descriptor.remote import DescriptorDownloader
+import stem.descriptor.remote
+
 from stem.util import str_tools
 
 # provides a mapping of observed bandwidth to the relay nicknames
 def get_bw_to_relay():
   bw_to_relay = {}
 
-  downloader = DescriptorDownloader()
-
   try:
-    for desc in downloader.get_server_descriptors().run():
+    for desc in stem.descriptor.remote.get_server_descriptors().run():
       if desc.exit_policy.is_exiting_allowed():
         bw_to_relay.setdefault(desc.observed_bandwidth, []).append(desc.nickname)
   except Exception as exc:
diff --git a/docs/change_log.rst b/docs/change_log.rst
index 4f688aa..3ce6df2 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -59,6 +59,7 @@ The following are only available within Stem's `git repository
 
  * **Descriptors**
 
+  * `Shorthand functions for stem.descriptor.remote <api/descriptor/remote.html#stem.descriptor.remote.get_instance>`_
   * Added `fallback directory information <api/descriptor/remote.html#stem.descriptor.remote.FallbackDirectory>`_.
   * Lessened dirauth load of `stem.descriptor.remote <api/descriptor/remote.html>`_ by using fallback directories as well
   * Support for ed25519 descriptor fields (:spec:`5a79d67`)
diff --git a/stem/cached_tor_manual.cfg b/stem/cached_tor_manual.cfg
index a2dbaf7..e57167c 100644
--- a/stem/cached_tor_manual.cfg
+++ b/stem/cached_tor_manual.cfg
@@ -7,7 +7,7 @@ description
 |
 |By default, tor will only act as a client only. To help the network by providing bandwidth as a relay, change the ORPort configuration option -- see below. Please also consult the documentation on the Tor Project's website.
 man_commit af88e8f23742c810f478410fba60c43812dde85d
-stem_commit 988aeb121b762f58712bda078d1f13ffa0819bfb
+stem_commit 7fceffac0f988670f4fd6b5eb061b2ebeee9e560
 commandline_options -f FILE => Specify a new configuration file to contain further Tor configuration options OR pass - to make Tor read its configuration from standard input. (Default: @CONFDIR@/torrc, or $HOME/.torrc if that file is not found)
 commandline_options --ignore-missing-torrc => Specifies that Tor should treat a missing torrc file as though it were empty. Ordinarily, Tor does this for missing default torrc files, but not for those specified on the command line.
 commandline_options --list-fingerprint => Generate your keys and output your nickname and fingerprint.
@@ -1614,7 +1614,7 @@ config_options.TestingClientBootstrapConsensusMaxDownloadTries.description Try t
 config_options.TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries.category Testing
 config_options.TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries.name TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries
 config_options.TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries.usage NUM
-config_options.TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries.summary 
+config_options.TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries.summary Number of times to attempt downloading consensus from authorities
 config_options.TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries.description Try this many times to download a consensus while bootstrapping using authorities before giving up. Changing this requires that TestingTorNetwork is set. (Default: 4)
 config_options.TestingClientBootstrapConsensusMaxInProgressTries.category Testing
 config_options.TestingClientBootstrapConsensusMaxInProgressTries.name TestingClientBootstrapConsensusMaxInProgressTries
diff --git a/stem/descriptor/fallback_directories.cfg b/stem/descriptor/fallback_directories.cfg
index 91fd02a..faf6105 100644
--- a/stem/descriptor/fallback_directories.cfg
+++ b/stem/descriptor/fallback_directories.cfg
@@ -1,5 +1,5 @@
 tor_commit e2202146d16af22502fd4166ac926fefa6528dff
-stem_commit 988aeb121b762f58712bda078d1f13ffa0819bfb
+stem_commit 7fceffac0f988670f4fd6b5eb061b2ebeee9e560
 Doedel22.address 178.254.44.135
 Doedel22.or_port 9001
 Doedel22.dir_port 9030
diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index 13b49ab..1afa70a 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -3,9 +3,20 @@
 
 """
 Module for remotely retrieving descriptors from directory authorities and
-mirrors. This is most easily done through the
+mirrors. This is the simplest method for getting current tor descriptor
+information...
+
+::
+
+  import stem.descriptor.remote
+
+  for desc in stem.descriptor.remote.get_server_descriptors():
+    if desc.exit_policy.is_exiting_allowed():
+      print '  %s (%s)' % (desc.nickname, desc.fingerprint)
+
+More custom downloading behavior can be done through the
 :class:`~stem.descriptor.remote.DescriptorDownloader` class, which issues
-:class:`~stem.descriptor.remote.Query` instances to get you the descriptor
+:class:`~stem.descriptor.remote.Query` instances to get you descriptor
 content. For example...
 
 ::
@@ -31,16 +42,13 @@ content. For example...
   except Exception as exc:
     print 'Unable to retrieve the server descriptors: %s' % exc
 
-If you don't care about errors then you can also simply iterate over the query
-itself...
-
 ::
 
-  for desc in downloader.get_server_descriptors():
-    if desc.exit_policy.is_exiting_allowed():
-      print '  %s (%s)' % (desc.nickname, desc.fingerprint)
-
-::
+  get_instance - Provides a singleton DescriptorDownloader used for...
+    |- get_server_descriptors - provides present server descriptors
+    |- get_extrainfo_descriptors - provides present extrainfo descriptors
+    |- get_microdescriptors - provides present microdescriptors
+    +- get_consensus - provides the present consensus or router status entries
 
   get_authorities - Provides tor directory information.
 
@@ -105,6 +113,79 @@ MAX_MICRODESCRIPTOR_HASHES = 92
 GITWEB_FALLBACK_DIR_URL = 'https://gitweb.torproject.org/tor.git/plain/src/or/fallback_dirs.inc'
 CACHE_PATH = os.path.join(os.path.dirname(__file__), 'fallback_directories.cfg')
 
+SINGLETON_DOWNLOADER = None
+
+
+def get_instance():
+  """
+  Provides the singleton :class:`~stem.descriptor.remote.DescriptorDownloader`
+  used for the following functions...
+
+    * :func:`stem.descriptor.remote.get_server_descriptors`
+    * :func:`stem.descriptor.remote.get_extrainfo_descriptors`
+    * :func:`stem.descriptor.remote.get_microdescriptors`
+    * :func:`stem.descriptor.remote.get_consensus`
+
+  .. versionadded:: 1.5.0
+
+  :returns: singleton :class:`~stem.descriptor.remote.DescriptorDownloader` instance
+  """
+
+  global SINGLETON_DOWNLOADER
+
+  if SINGLETON_DOWNLOADER is None:
+    SINGLETON_DOWNLOADER = DescriptorDownloader()
+
+  return SINGLETON_DOWNLOADER
+
+
+def get_server_descriptors(fingerprints = None, **query_args):
+  """
+  Shorthand for
+  :func:`~stem.descriptor.remote.DescriptorDownloader.get_server_descriptors`
+  on our singleton instance.
+
+  .. versionadded:: 1.5.0
+  """
+
+  return get_instance().get_server_descriptors(fingerprints, **query_args)
+
+
+def get_extrainfo_descriptors(fingerprints = None, **query_args):
+  """
+  Shorthand for
+  :func:`~stem.descriptor.remote.DescriptorDownloader.get_extrainfo_descriptors`
+  on our singleton instance.
+
+  .. versionadded:: 1.5.0
+  """
+
+  return get_instance().get_extrainfo_descriptors(fingerprints, **query_args)
+
+
+def get_microdescriptors(hashes, **query_args):
+  """
+  Shorthand for
+  :func:`~stem.descriptor.remote.DescriptorDownloader.get_microdescriptors`
+  on our singleton instance.
+
+  .. versionadded:: 1.5.0
+  """
+
+  return get_instance().get_microdescriptors(hashes, **query_args)
+
+
+def get_consensus(authority_v3ident = None, **query_args):
+  """
+  Shorthand for
+  :func:`~stem.descriptor.remote.DescriptorDownloader.get_consensus`
+  on our singleton instance.
+
+  .. versionadded:: 1.5.0
+  """
+
+  return get_instance().get_consensus(authority_v3ident, **query_args)
+
 
 def _guess_descriptor_type(resource):
   # Attempts to determine the descriptor type based on the resource url. This
diff --git a/stem/settings.cfg b/stem/settings.cfg
index cc90be6..6395a5d 100644
--- a/stem/settings.cfg
+++ b/stem/settings.cfg
@@ -341,6 +341,7 @@ manual.summary.TestingClientMaxIntervalWithoutRequest Maximum time to wait to ba
 manual.summary.TestingDirConnectionMaxStall Duration to let directory connections stall before timing out
 manual.summary.TestingConsensusMaxDownloadTries Retries for downloading the consensus
 manual.summary.TestingClientBootstrapConsensusMaxDownloadTries Number of times to attempt downloading consensus
+manual.summary.TestingClientBootstrapConsensusAuthorityOnlyMaxDownloadTries Number of times to attempt downloading consensus from authorities
 manual.summary.TestingClientBootstrapConsensusMaxInProgressTries Number of consensus download requests to allow in-flight at once
 manual.summary.TestingDescriptorMaxDownloadTries Retries for downloading server descriptors
 manual.summary.TestingMicrodescMaxDownloadTries Retries for downloading microdescriptors
diff --git a/test/integ/descriptor/remote.py b/test/integ/descriptor/remote.py
index a73bb0e..ef556ae 100644
--- a/test/integ/descriptor/remote.py
+++ b/test/integ/descriptor/remote.py
@@ -22,6 +22,26 @@ from test.runner import (
 class TestDescriptorDownloader(unittest.TestCase):
   @require_online
   @only_run_once
+  def test_shorthand_aliases(self):
+    """
+    Quick sanity test that we can call our shorthand aliases for getting
+    descriptors.
+    """
+
+    desc = list(stem.descriptor.remote.get_server_descriptors('9695DFC35FFEB861329B9F1AB04C46397020CE31'))[0]
+    self.assertEqual('moria1', desc.nickname)
+
+    desc = list(stem.descriptor.remote.get_extrainfo_descriptors('9695DFC35FFEB861329B9F1AB04C46397020CE31'))[0]
+    self.assertEqual('moria1', desc.nickname)
+
+    desc = list(stem.descriptor.remote.get_microdescriptors('6dCl6ab8CLo0LeMjxi/MZgVJiZgWN8WKTesWPBMtyTo'))[0]
+    self.assertEqual('moria1', desc.digest)
+
+    consensus = list(stem.descriptor.remote.get_consensus())
+    self.assertTrue(len(consensus) > 50)
+
+  @require_online
+  @only_run_once
   def test_authorities_are_up_to_date(self):
     """
     Check that our hardcoded directory authority data matches the present



More information about the tor-commits mailing list