<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>stem.response.events — Stem 1.1.0 documentation</title> <link rel="stylesheet" href="../../../_static/haiku.css" type="text/css" /> <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" /> <link rel="stylesheet" href="../../../_static/print.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../../', VERSION: '1.1.0', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../../_static/jquery.js"></script> <script type="text/javascript" src="../../../_static/underscore.js"></script> <script type="text/javascript" src="../../../_static/doctools.js"></script> <script type="text/javascript" src="../../../_static/theme_extras.js"></script> <link rel="shortcut icon" href="../../../_static/favicon.png"/> <link rel="top" title="Stem 1.1.0 documentation" href="../../../index.html" /> <link rel="up" title="stem.response" href="../response.html" /> </head> <body> <div class="header"><img class="rightlogo" src="../../../_static/logo.png" alt="Logo"/><h1 class="heading"><a href="../../../index.html"> <span>Stem Docs</span></a></h1> <h2 class="heading"><span>stem.response.events</span></h2> </div> <div class="topnav"> <p> <ul id="navbar"> <li><a href="../../../index.html">Home</a></li> <li><a href="../../../tutorials.html">Tutorials</a> <ul> <li><a href="../../../tutorials/the_little_relay_that_could.html">Hello World</a></li> <li><a href="../../../tutorials/to_russia_with_love.html">Client Usage</a></li> <li><a href="../../../tutorials/tortoise_and_the_hare.html">Event Listening</a></li> <li><a href="../../../tutorials/mirror_mirror_on_the_wall.html">Tor Descriptors</a></li> <li><a href="../../../tutorials/east_of_the_sun.html">Utilities</a></li> <li><a href="../../../tutorials/double_double_toil_and_trouble.html">Examples</a></li> </ul> </li> <li><a href="../../../api.html">API</a> <ul> <li><a href="../../../api/control.html">stem.control</a></li> <li><a href="../../../api/connection.html">stem.connection</a></li> <li><a href="../../../api/socket.html">stem.socket</a></li> <li><a href="../../../api/process.html">stem.process</a></li> <li><a href="../../../api/response.html">stem.response</a></li> <li><a href="../../../api/exit_policy.html">stem.exit_policy</a></li> <li><a href="../../../api/version.html">stem.version</a></li> <li><a href="../../../api.html#descriptors">Descriptors</a></li> <li><a href="../../../api.html#utilities">Utilities</a></li> </ul> </li> <li><a href="https://trac.torproject.org/projects/tor/wiki/doc/stem">Development</a> <ul> <li><a href="../../../faq.html">FAQ</a></li> <li><a href="../../../change_log.html">Change Log</a></li> <li><a href="https://trac.torproject.org/projects/tor/wiki/doc/stem/bugs">Bug Tracker</a></li> <li><a href="../../../download.html">Download</a></li> </ul> </li> </ul> </p> </div> <div class="content"> <h1>Source code for stem.response.events</h1><div class="highlight"><pre> <span class="c"># Copyright 2012-2013, Damian Johnson and The Tor Project</span> <span class="c"># See LICENSE for licensing information</span> <span class="kn">import</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="nn">io</span> <span class="kn">import</span> <span class="nn">re</span> <span class="kn">import</span> <span class="nn">time</span> <span class="kn">import</span> <span class="nn">stem</span> <span class="kn">import</span> <span class="nn">stem.control</span> <span class="kn">import</span> <span class="nn">stem.descriptor.router_status_entry</span> <span class="kn">import</span> <span class="nn">stem.response</span> <span class="kn">import</span> <span class="nn">stem.version</span> <span class="kn">from</span> <span class="nn">stem.util</span> <span class="kn">import</span> <span class="n">connection</span><span class="p">,</span> <span class="n">log</span><span class="p">,</span> <span class="n">str_tools</span><span class="p">,</span> <span class="n">tor_tools</span> <span class="c"># Matches keyword=value arguments. This can't be a simple "(.*)=(.*)" pattern</span> <span class="c"># because some positional arguments, like circuit paths, can have an equal</span> <span class="c"># sign.</span> <span class="n">KW_ARG</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">"^(.*) ([A-Za-z0-9_]+)=(\S*)$"</span><span class="p">)</span> <span class="n">QUOTED_KW_ARG</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">"^(.*) ([A-Za-z0-9_]+)=</span><span class="se">\"</span><span class="s">(.*)</span><span class="se">\"</span><span class="s">$"</span><span class="p">)</span> <div class="viewcode-block" id="Event"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.Event">[docs]</a><span class="k">class</span> <span class="nc">Event</span><span class="p">(</span><span class="n">stem</span><span class="o">.</span><span class="n">response</span><span class="o">.</span><span class="n">ControlMessage</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Base for events we receive asynchronously, as described in section 4.1 of the</span> <span class="sd"> `control-spec</span> <span class="sd"> <https://gitweb.torproject.org/torspec.git/blob/HEAD:/control-spec.txt>`_.</span> <span class="sd"> :var str type: event type</span> <span class="sd"> :var int arrived_at: unix timestamp for when the message arrived</span> <span class="sd"> :var list positional_args: positional arguments of the event</span> <span class="sd"> :var dict keyword_args: key/value arguments of the event</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">()</span> <span class="c"># attribute names for recognized positional arguments</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{}</span> <span class="c"># map of 'keyword => attribute' for recognized attributes</span> <span class="n">_QUOTED</span> <span class="o">=</span> <span class="p">()</span> <span class="c"># positional arguments that are quoted</span> <span class="n">_OPTIONALLY_QUOTED</span> <span class="o">=</span> <span class="p">()</span> <span class="c"># positional arguments that may or may not be quoted</span> <span class="n">_SKIP_PARSING</span> <span class="o">=</span> <span class="bp">False</span> <span class="c"># skip parsing contents into our positional_args and keyword_args</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Version</span><span class="p">(</span><span class="s">'0.1.1.1-alpha'</span><span class="p">)</span> <span class="c"># minimum version with control-spec V1 event support</span> <span class="k">def</span> <span class="nf">_parse_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arrived_at</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span> <span class="k">if</span> <span class="n">arrived_at</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> <span class="n">arrived_at</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Received a blank tor event. Events must at the very least have a type."</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">arrived_at</span> <span class="o">=</span> <span class="n">arrived_at</span> <span class="c"># if we're a recognized event type then translate ourselves into that subclass</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="ow">in</span> <span class="n">EVENT_TYPE_TO_CLASS</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span> <span class="o">=</span> <span class="n">EVENT_TYPE_TO_CLASS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">positional_args</span> <span class="o">=</span> <span class="p">[]</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyword_args</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_SKIP_PARSING</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_standard_attr</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse</span><span class="p">()</span> <span class="k">def</span> <span class="nf">_parse_standard_attr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Most events are of the form...</span> <span class="sd"> 650 *( positional_args ) *( key "=" value )</span> <span class="sd"> This parses this standard format, populating our **positional_args** and</span> <span class="sd"> **keyword_args** attributes and creating attributes if it's in our event's</span> <span class="sd"> **_POSITIONAL_ARGS** and **_KEYWORD_ARGS**.</span> <span class="sd"> """</span> <span class="c"># Tor events contain some number of positional arguments followed by</span> <span class="c"># key/value mappings. Parsing keyword arguments from the end until we hit</span> <span class="c"># something that isn't a key/value mapping. The rest are positional.</span> <span class="n">content</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="n">match</span> <span class="o">=</span> <span class="n">QUOTED_KW_ARG</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span> <span class="n">match</span> <span class="o">=</span> <span class="n">KW_ARG</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="k">if</span> <span class="n">match</span><span class="p">:</span> <span class="n">content</span><span class="p">,</span> <span class="n">keyword</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groups</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyword_args</span><span class="p">[</span><span class="n">keyword</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> <span class="k">else</span><span class="p">:</span> <span class="k">break</span> <span class="c"># Setting attributes for the fields that we recognize.</span> <span class="bp">self</span><span class="o">.</span><span class="n">positional_args</span> <span class="o">=</span> <span class="n">content</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">1</span><span class="p">:]</span> <span class="n">positional</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">positional_args</span><span class="p">)</span> <span class="k">for</span> <span class="n">attr_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_POSITIONAL_ARGS</span><span class="p">:</span> <span class="n">attr_value</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">if</span> <span class="n">positional</span><span class="p">:</span> <span class="k">if</span> <span class="n">attr_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_QUOTED</span> <span class="ow">or</span> <span class="p">(</span><span class="n">attr_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_OPTIONALLY_QUOTED</span> <span class="ow">and</span> <span class="n">positional</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'"'</span><span class="p">)):</span> <span class="n">attr_values</span> <span class="o">=</span> <span class="p">[</span><span class="n">positional</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)]</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">attr_values</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'"'</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"The </span><span class="si">%s</span><span class="s"> value should be quoted, but didn't have a starting quote: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">attr_name</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">positional</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"The </span><span class="si">%s</span><span class="s"> value should be quoted, but didn't have an ending quote: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">attr_name</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="n">attr_values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">positional</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span> <span class="k">if</span> <span class="n">attr_values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">'"'</span><span class="p">):</span> <span class="k">break</span> <span class="n">attr_value</span> <span class="o">=</span> <span class="s">" "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">attr_values</span><span class="p">)[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="n">attr_value</span> <span class="o">=</span> <span class="n">positional</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr_name</span><span class="p">,</span> <span class="n">attr_value</span><span class="p">)</span> <span class="k">for</span> <span class="n">controller_attr_name</span><span class="p">,</span> <span class="n">attr_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_KEYWORD_ARGS</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyword_args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">controller_attr_name</span><span class="p">))</span> <span class="c"># method overwritten by our subclasses for special handling that they do</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">pass</span> <span class="k">def</span> <span class="nf">_log_if_unrecognized</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">attr_enum</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Checks if an attribute exists in a given enumeration, logging a message if</span> <span class="sd"> it isn't. Attributes can either be for a string or collection of strings</span> <span class="sd"> :param str attr: name of the attribute to check</span> <span class="sd"> :param stem.util.enum.Enum enum: enumeration to check against</span> <span class="sd"> """</span> <span class="n">attr_values</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attr</span><span class="p">)</span> <span class="k">if</span> <span class="n">attr_values</span><span class="p">:</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">attr_values</span><span class="p">,</span> <span class="p">(</span><span class="nb">bytes</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">)):</span> <span class="n">attr_values</span> <span class="o">=</span> <span class="p">[</span><span class="n">attr_values</span><span class="p">]</span> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">attr_values</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">attr_enum</span><span class="p">:</span> <span class="n">log_id</span> <span class="o">=</span> <span class="s">"event.</span><span class="si">%s</span><span class="s">.unknown_</span><span class="si">%s</span><span class="s">.</span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="n">attr</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="n">unrecognized_msg</span> <span class="o">=</span> <span class="s">"</span><span class="si">%s</span><span class="s"> event had an unrecognized </span><span class="si">%s</span><span class="s"> (</span><span class="si">%s</span><span class="s">). Maybe a new addition to the control protocol? Full Event: '</span><span class="si">%s</span><span class="s">'"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="n">attr</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span> <span class="n">log</span><span class="o">.</span><span class="n">log_once</span><span class="p">(</span><span class="n">log_id</span><span class="p">,</span> <span class="n">log</span><span class="o">.</span><span class="n">INFO</span><span class="p">,</span> <span class="n">unrecognized_msg</span><span class="p">)</span> </div> <div class="viewcode-block" id="AddrMapEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.AddrMapEvent">[docs]</a><span class="k">class</span> <span class="nc">AddrMapEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates a new address mapping.</span> <span class="sd"> The ADDRMAP event was one of the first Control Protocol V1 events and was</span> <span class="sd"> introduced in tor version 0.1.1.1-alpha.</span> <span class="sd"> :var str hostname: address being resolved</span> <span class="sd"> :var str destination: destionation of the resolution, this is usually an ip,</span> <span class="sd"> but could be a hostname if TrackHostExits is enabled or **NONE** if the</span> <span class="sd"> resolution failed</span> <span class="sd"> :var datetime expiry: expiration time of the resolution in local time</span> <span class="sd"> :var str error: error code if the resolution failed</span> <span class="sd"> :var datetime utc_expiry: expiration time of the resolution in UTC</span> <span class="sd"> :var bool cached: **True** if the resolution will be kept until it expires,</span> <span class="sd"> **False** otherwise or **None** if undefined</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"hostname"</span><span class="p">,</span> <span class="s">"destination"</span><span class="p">,</span> <span class="s">"expiry"</span><span class="p">)</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"error"</span><span class="p">:</span> <span class="s">"error"</span><span class="p">,</span> <span class="s">"EXPIRES"</span><span class="p">:</span> <span class="s">"utc_expiry"</span><span class="p">,</span> <span class="s">"CACHED"</span><span class="p">:</span> <span class="s">"cached"</span><span class="p">,</span> <span class="p">}</span> <span class="n">_OPTIONALLY_QUOTED</span> <span class="o">=</span> <span class="p">(</span><span class="s">"expiry"</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">destination</span> <span class="o">==</span> <span class="s">"<error>"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">destination</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">expiry</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">expiry</span> <span class="o">==</span> <span class="s">"NEVER"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">expiry</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">else</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">expiry</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">expiry</span><span class="p">,</span> <span class="s">"%Y-%m-</span><span class="si">%d</span><span class="s"> %H:%M:%S"</span><span class="p">)</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Unable to parse date in ADDRMAP event: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">utc_expiry</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">utc_expiry</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">utc_expiry</span><span class="p">,</span> <span class="s">"%Y-%m-</span><span class="si">%d</span><span class="s"> %H:%M:%S"</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached</span> <span class="o">==</span> <span class="s">"YES"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached</span> <span class="o">==</span> <span class="s">"NO"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"An ADDRMAP event's CACHED mapping can only be 'YES' or 'NO': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> </div> <div class="viewcode-block" id="AuthDirNewDescEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.AuthDirNewDescEvent">[docs]</a><span class="k">class</span> <span class="nc">AuthDirNewDescEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event specific to directory authorities, indicating that we just received new</span> <span class="sd"> descriptors. The descriptor type contained within this event is unspecified</span> <span class="sd"> so the descriptor contents are left unparsed.</span> <span class="sd"> The AUTHDIR_NEWDESCS event was introduced in tor version 0.1.1.10-alpha.</span> <span class="sd"> :var stem.AuthDescriptorAction action: what is being done with the descriptor</span> <span class="sd"> :var str message: explanation of why we chose this action</span> <span class="sd"> :var str descriptor: content of the descriptor</span> <span class="sd"> """</span> <span class="n">_SKIP_PARSING</span> <span class="o">=</span> <span class="bp">True</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_AUTHDIR_NEWDESCS</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">lines</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="o"><</span> <span class="mi">5</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"AUTHDIR_NEWDESCS events must contain lines for at least the type, action, message, descriptor, and terminating 'OK'"</span><span class="p">)</span> <span class="k">elif</span> <span class="ow">not</span> <span class="n">lines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s">"OK"</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"AUTHDIR_NEWDESCS doesn't end with an 'OK'"</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">action</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">descriptor</span> <span class="o">=</span> <span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">[</span><span class="mi">3</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> </div> <div class="viewcode-block" id="BandwidthEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.BandwidthEvent">[docs]</a><span class="k">class</span> <span class="nc">BandwidthEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event emitted every second with the bytes sent and received by tor.</span> <span class="sd"> The BW event was one of the first Control Protocol V1 events and was</span> <span class="sd"> introduced in tor version 0.1.1.1-alpha.</span> <span class="sd"> :var long read: bytes received by tor that second</span> <span class="sd"> :var long written: bytes sent by tor that second</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"read"</span><span class="p">,</span> <span class="s">"written"</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">read</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"BW event is missing its read value"</span><span class="p">)</span> <span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">written</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"BW event is missing its written value"</span><span class="p">)</span> <span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">read</span><span class="o">.</span><span class="n">isdigit</span><span class="p">()</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">written</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"A BW event's bytes sent and received should be a positive numeric value, received: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">read</span> <span class="o">=</span> <span class="nb">long</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">read</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">written</span> <span class="o">=</span> <span class="nb">long</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">written</span><span class="p">)</span> </div> <div class="viewcode-block" id="BuildTimeoutSetEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.BuildTimeoutSetEvent">[docs]</a><span class="k">class</span> <span class="nc">BuildTimeoutSetEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event indicating that the timeout value for a circuit has changed. This was</span> <span class="sd"> first added in tor version 0.2.2.7.</span> <span class="sd"> The BUILDTIMEOUT_SET event was introduced in tor version 0.2.2.7-alpha.</span> <span class="sd"> :var stem.TimeoutSetType set_type: way in which the timeout is changing</span> <span class="sd"> :var int total_times: circuit build times tor used to determine the timeout</span> <span class="sd"> :var int timeout: circuit timeout value in milliseconds</span> <span class="sd"> :var int xm: Pareto parameter Xm in milliseconds</span> <span class="sd"> :var float alpha: Pareto parameter alpha</span> <span class="sd"> :var float quantile: CDF quantile cutoff point</span> <span class="sd"> :var float timeout_rate: ratio of circuits that have time out</span> <span class="sd"> :var int close_timeout: duration to keep measurement circuits in milliseconds</span> <span class="sd"> :var float close_rate: ratio of measurement circuits that are closed</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"set_type"</span><span class="p">,)</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"TOTAL_TIMES"</span><span class="p">:</span> <span class="s">"total_times"</span><span class="p">,</span> <span class="s">"TIMEOUT_MS"</span><span class="p">:</span> <span class="s">"timeout"</span><span class="p">,</span> <span class="s">"XM"</span><span class="p">:</span> <span class="s">"xm"</span><span class="p">,</span> <span class="s">"ALPHA"</span><span class="p">:</span> <span class="s">"alpha"</span><span class="p">,</span> <span class="s">"CUTOFF_QUANTILE"</span><span class="p">:</span> <span class="s">"quantile"</span><span class="p">,</span> <span class="s">"TIMEOUT_RATE"</span><span class="p">:</span> <span class="s">"timeout_rate"</span><span class="p">,</span> <span class="s">"CLOSE_MS"</span><span class="p">:</span> <span class="s">"close_timeout"</span><span class="p">,</span> <span class="s">"CLOSE_RATE"</span><span class="p">:</span> <span class="s">"close_rate"</span><span class="p">,</span> <span class="p">}</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_BUILDTIMEOUT_SET</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c"># convert our integer and float parameters</span> <span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'total_times'</span><span class="p">,</span> <span class="s">'timeout'</span><span class="p">,</span> <span class="s">'xm'</span><span class="p">,</span> <span class="s">'close_timeout'</span><span class="p">):</span> <span class="n">param_value</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">param</span><span class="p">)</span> <span class="k">if</span> <span class="n">param_value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">param</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">param_value</span><span class="p">))</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"The </span><span class="si">%s</span><span class="s"> of a BUILDTIMEOUT_SET should be an integer: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">param</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'alpha'</span><span class="p">,</span> <span class="s">'quantile'</span><span class="p">,</span> <span class="s">'timeout_rate'</span><span class="p">,</span> <span class="s">'close_rate'</span><span class="p">):</span> <span class="n">param_value</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">param</span><span class="p">)</span> <span class="k">if</span> <span class="n">param_value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">param</span><span class="p">,</span> <span class="nb">float</span><span class="p">(</span><span class="n">param_value</span><span class="p">))</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"The </span><span class="si">%s</span><span class="s"> of a BUILDTIMEOUT_SET should be a float: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">param</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'set_type'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">TimeoutSetType</span><span class="p">)</span> </div> <div class="viewcode-block" id="CircuitEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.CircuitEvent">[docs]</a><span class="k">class</span> <span class="nc">CircuitEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates that a circuit has changed.</span> <span class="sd"> The fingerprint or nickname values in our 'path' may be **None** if the</span> <span class="sd"> VERBOSE_NAMES feature isn't enabled. The option was first introduced in tor</span> <span class="sd"> version 0.1.2.2, and on by default after 0.2.2.1.</span> <span class="sd"> The CIRC event was one of the first Control Protocol V1 events and was</span> <span class="sd"> introduced in tor version 0.1.1.1-alpha.</span> <span class="sd"> :var str id: circuit identifier</span> <span class="sd"> :var stem.CircStatus status: reported status for the circuit</span> <span class="sd"> :var tuple path: relays involved in the circuit, these are</span> <span class="sd"> **(fingerprint, nickname)** tuples</span> <span class="sd"> :var tuple build_flags: :data:`~stem.CircBuildFlag` attributes</span> <span class="sd"> governing how the circuit is built</span> <span class="sd"> :var stem.CircPurpose purpose: purpose that the circuit is intended for</span> <span class="sd"> :var stem.HiddenServiceState hs_state: status if this is a hidden service circuit</span> <span class="sd"> :var str rend_query: circuit's rendezvous-point if this is hidden service related</span> <span class="sd"> :var datetime created: time when the circuit was created or cannibalized</span> <span class="sd"> :var stem.CircClosureReason reason: reason for the circuit to be closed</span> <span class="sd"> :var stem.CircClosureReason remote_reason: remote side's reason for the circuit to be closed</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"id"</span><span class="p">,</span> <span class="s">"status"</span><span class="p">,</span> <span class="s">"path"</span><span class="p">)</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"BUILD_FLAGS"</span><span class="p">:</span> <span class="s">"build_flags"</span><span class="p">,</span> <span class="s">"PURPOSE"</span><span class="p">:</span> <span class="s">"purpose"</span><span class="p">,</span> <span class="s">"HS_STATE"</span><span class="p">:</span> <span class="s">"hs_state"</span><span class="p">,</span> <span class="s">"REND_QUERY"</span><span class="p">:</span> <span class="s">"rend_query"</span><span class="p">,</span> <span class="s">"TIME_CREATED"</span><span class="p">:</span> <span class="s">"created"</span><span class="p">,</span> <span class="s">"REASON"</span><span class="p">:</span> <span class="s">"reason"</span><span class="p">,</span> <span class="s">"REMOTE_REASON"</span><span class="p">:</span> <span class="s">"remote_reason"</span><span class="p">,</span> <span class="p">}</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">stem</span><span class="o">.</span><span class="n">control</span><span class="o">.</span><span class="n">_parse_circ_path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">))</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_flags</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_flags</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">build_flags</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">))</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">created</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">created</span> <span class="o">=</span> <span class="n">str_tools</span><span class="o">.</span><span class="n">_parse_iso_timestamp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">created</span><span class="p">)</span> <span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Unable to parse create date (</span><span class="si">%s</span><span class="s">): </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">exc</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">tor_tools</span><span class="o">.</span><span class="n">is_valid_circuit_id</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Circuit IDs must be one to sixteen alphanumeric characters, got '</span><span class="si">%s</span><span class="s">': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'status'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircStatus</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'build_flags'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircBuildFlag</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'purpose'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircPurpose</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'hs_state'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">HiddenServiceState</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'reason'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircClosureReason</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'remote_reason'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircClosureReason</span><span class="p">)</span> </div> <div class="viewcode-block" id="CircMinorEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.CircMinorEvent">[docs]</a><span class="k">class</span> <span class="nc">CircMinorEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event providing information about minor changes in our circuits. This was</span> <span class="sd"> first added in tor version 0.2.3.11.</span> <span class="sd"> The CIRC_MINOR event was introduced in tor version 0.2.3.11-alpha.</span> <span class="sd"> :var str id: circuit identifier</span> <span class="sd"> :var stem.CircEvent event: type of change in the circuit</span> <span class="sd"> :var tuple path: relays involved in the circuit, these are</span> <span class="sd"> **(fingerprint, nickname)** tuples</span> <span class="sd"> :var tuple build_flags: :data:`~stem.CircBuildFlag` attributes</span> <span class="sd"> governing how the circuit is built</span> <span class="sd"> :var stem.CircPurpose purpose: purpose that the circuit is intended for</span> <span class="sd"> :var stem.HiddenServiceState hs_state: status if this is a hidden service circuit</span> <span class="sd"> :var str rend_query: circuit's rendezvous-point if this is hidden service related</span> <span class="sd"> :var datetime created: time when the circuit was created or cannibalized</span> <span class="sd"> :var stem.CircPurpose old_purpose: prior purpose for the circuit</span> <span class="sd"> :var stem.HiddenServiceState old_hs_state: prior status as a hidden service circuit</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"id"</span><span class="p">,</span> <span class="s">"event"</span><span class="p">,</span> <span class="s">"path"</span><span class="p">)</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"BUILD_FLAGS"</span><span class="p">:</span> <span class="s">"build_flags"</span><span class="p">,</span> <span class="s">"PURPOSE"</span><span class="p">:</span> <span class="s">"purpose"</span><span class="p">,</span> <span class="s">"HS_STATE"</span><span class="p">:</span> <span class="s">"hs_state"</span><span class="p">,</span> <span class="s">"REND_QUERY"</span><span class="p">:</span> <span class="s">"rend_query"</span><span class="p">,</span> <span class="s">"TIME_CREATED"</span><span class="p">:</span> <span class="s">"created"</span><span class="p">,</span> <span class="s">"OLD_PURPOSE"</span><span class="p">:</span> <span class="s">"old_purpose"</span><span class="p">,</span> <span class="s">"OLD_HS_STATE"</span><span class="p">:</span> <span class="s">"old_hs_state"</span><span class="p">,</span> <span class="p">}</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_CIRC_MINOR</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">stem</span><span class="o">.</span><span class="n">control</span><span class="o">.</span><span class="n">_parse_circ_path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">))</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_flags</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_flags</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">build_flags</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">))</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">created</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">created</span> <span class="o">=</span> <span class="n">str_tools</span><span class="o">.</span><span class="n">_parse_iso_timestamp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">created</span><span class="p">)</span> <span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Unable to parse create date (</span><span class="si">%s</span><span class="s">): </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">exc</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">tor_tools</span><span class="o">.</span><span class="n">is_valid_circuit_id</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Circuit IDs must be one to sixteen alphanumeric characters, got '</span><span class="si">%s</span><span class="s">': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'event'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircEvent</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'build_flags'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircBuildFlag</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'purpose'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircPurpose</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'hs_state'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">HiddenServiceState</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'old_purpose'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">CircPurpose</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'old_hs_state'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">HiddenServiceState</span><span class="p">)</span> </div> <div class="viewcode-block" id="ClientsSeenEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.ClientsSeenEvent">[docs]</a><span class="k">class</span> <span class="nc">ClientsSeenEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Periodic event on bridge relays that provides a summary of our users.</span> <span class="sd"> The CLIENTS_SEEN event was introduced in tor version 0.2.1.10-alpha.</span> <span class="sd"> :var datetime start_time: time in UTC that we started collecting these stats</span> <span class="sd"> :var dict locales: mapping of country codes to a rounded count for the number of users</span> <span class="sd"> :var dict ip_versions: mapping of ip protocols to a rounded count for the number of users</span> <span class="sd"> """</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"TimeStarted"</span><span class="p">:</span> <span class="s">"start_time"</span><span class="p">,</span> <span class="s">"CountrySummary"</span><span class="p">:</span> <span class="s">"locales"</span><span class="p">,</span> <span class="s">"IPVersions"</span><span class="p">:</span> <span class="s">"ip_versions"</span><span class="p">,</span> <span class="p">}</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_CLIENTS_SEEN</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_time</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_time</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">start_time</span><span class="p">,</span> <span class="s">"%Y-%m-</span><span class="si">%d</span><span class="s"> %H:%M:%S"</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">locales</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="n">locale_to_count</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">locales</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="s">'='</span> <span class="ow">in</span> <span class="n">entry</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"The CLIENTS_SEEN's CountrySummary should be a comma separated listing of '<locale>=<count>' mappings: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="n">locale</span><span class="p">,</span> <span class="n">count</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'='</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">locale</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Locales should be a two character code, got '</span><span class="si">%s</span><span class="s">': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">locale</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="k">elif</span> <span class="ow">not</span> <span class="n">count</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Locale count was non-numeric (</span><span class="si">%s</span><span class="s">): </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">count</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="k">elif</span> <span class="n">locale</span> <span class="ow">in</span> <span class="n">locale_to_count</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"CountrySummary had multiple mappings for '</span><span class="si">%s</span><span class="s">': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">locale</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="n">locale_to_count</span><span class="p">[</span><span class="n">locale</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">count</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">locales</span> <span class="o">=</span> <span class="n">locale_to_count</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ip_versions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="n">protocol_to_count</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">ip_versions</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="s">'='</span> <span class="ow">in</span> <span class="n">entry</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"The CLIENTS_SEEN's IPVersions should be a comma separated listing of '<protocol>=<count>' mappings: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="n">protocol</span><span class="p">,</span> <span class="n">count</span> <span class="o">=</span> <span class="n">entry</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'='</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">count</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"IP protocol count was non-numeric (</span><span class="si">%s</span><span class="s">): </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">count</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="n">protocol_to_count</span><span class="p">[</span><span class="n">protocol</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">count</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">ip_versions</span> <span class="o">=</span> <span class="n">protocol_to_count</span> </div> <div class="viewcode-block" id="ConfChangedEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.ConfChangedEvent">[docs]</a><span class="k">class</span> <span class="nc">ConfChangedEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates that our configuration changed, either in response to a</span> <span class="sd"> SETCONF or RELOAD signal.</span> <span class="sd"> The CONF_CHANGED event was introduced in tor version 0.2.3.3-alpha.</span> <span class="sd"> :var dict config: mapping of configuration options to their new values</span> <span class="sd"> (**None** if the option is being unset)</span> <span class="sd"> """</span> <span class="n">_SKIP_PARSING</span> <span class="o">=</span> <span class="bp">True</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_CONF_CHANGED</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span> <span class="o">=</span> <span class="p">{}</span> <span class="c"># Skip first and last line since they're the header and footer. For</span> <span class="c"># instance...</span> <span class="c">#</span> <span class="c"># 650-CONF_CHANGED</span> <span class="c"># 650-ExitNodes=caerSidi</span> <span class="c"># 650-ExitPolicy</span> <span class="c"># 650-MaxCircuitDirtiness=20</span> <span class="c"># 650 OK</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span> <span class="k">if</span> <span class="s">'='</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'='</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">line</span><span class="p">,</span> <span class="bp">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> </div> <div class="viewcode-block" id="DescChangedEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.DescChangedEvent">[docs]</a><span class="k">class</span> <span class="nc">DescChangedEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates that our descriptor has changed.</span> <span class="sd"> The DESCCHANGED event was introduced in tor version 0.1.2.2-alpha.</span> <span class="sd"> """</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_DESCCHANGED</span> </div> <div class="viewcode-block" id="GuardEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.GuardEvent">[docs]</a><span class="k">class</span> <span class="nc">GuardEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates that our guard relays have changed. The 'endpoint' could</span> <span class="sd"> be either a...</span> <span class="sd"> * fingerprint</span> <span class="sd"> * 'fingerprint=nickname' pair</span> <span class="sd"> The derived 'endpoint_*' attributes are generally more useful.</span> <span class="sd"> The GUARD event was introduced in tor version 0.1.2.5-alpha.</span> <span class="sd"> :var stem.GuardType guard_type: purpose the guard relay is for</span> <span class="sd"> :var str endpoint: relay that the event concerns</span> <span class="sd"> :var str endpoint_fingerprint: endpoint's finterprint</span> <span class="sd"> :var str endpoint_nickname: endpoint's nickname if it was provided</span> <span class="sd"> :var stem.GuardStatus status: status of the guard relay</span> <span class="sd"> """</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_GUARD</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"guard_type"</span><span class="p">,</span> <span class="s">"endpoint"</span><span class="p">,</span> <span class="s">"status"</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_fingerprint</span> <span class="o">=</span> <span class="bp">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_nickname</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_fingerprint</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_nickname</span> <span class="o">=</span> \ <span class="n">stem</span><span class="o">.</span><span class="n">control</span><span class="o">.</span><span class="n">_parse_circ_entry</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span><span class="p">)</span> <span class="k">except</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"ORCONN's endpoint doesn't match a ServerSpec: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'guard_type'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">GuardType</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'status'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">GuardStatus</span><span class="p">)</span> </div> <div class="viewcode-block" id="LogEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.LogEvent">[docs]</a><span class="k">class</span> <span class="nc">LogEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Tor logging event. These are the most visible kind of event since, by</span> <span class="sd"> default, tor logs at the NOTICE :data:`~stem.Runlevel` to stdout.</span> <span class="sd"> The logging events were some of the first Control Protocol V1 events</span> <span class="sd"> and were introduced in tor version 0.1.1.1-alpha.</span> <span class="sd"> :var stem.Runlevel runlevel: runlevel of the logged message</span> <span class="sd"> :var str message: logged message</span> <span class="sd"> """</span> <span class="n">_SKIP_PARSING</span> <span class="o">=</span> <span class="bp">True</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">runlevel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'runlevel'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">Runlevel</span><span class="p">)</span> <span class="c"># message is our content, minus the runlevel and ending "OK" if a</span> <span class="c"># multi-line message</span> <span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)[</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">runlevel</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">:]</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">OK"</span><span class="p">)</span> </div> <div class="viewcode-block" id="NetworkStatusEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.NetworkStatusEvent">[docs]</a><span class="k">class</span> <span class="nc">NetworkStatusEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event for when our copy of the consensus has changed. This was introduced in</span> <span class="sd"> tor version 0.1.2.3.</span> <span class="sd"> The NS event was introduced in tor version 0.1.2.3-alpha.</span> <span class="sd"> :var list desc: :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV3` for the changed descriptors</span> <span class="sd"> """</span> <span class="n">_SKIP_PARSING</span> <span class="o">=</span> <span class="bp">True</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_NS</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">content</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s">"NS</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">OK"</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">stem</span><span class="o">.</span><span class="n">descriptor</span><span class="o">.</span><span class="n">router_status_entry</span><span class="o">.</span><span class="n">_parse_file</span><span class="p">(</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">str_tools</span><span class="o">.</span><span class="n">_to_bytes</span><span class="p">(</span><span class="n">content</span><span class="p">)),</span> <span class="bp">True</span><span class="p">,</span> <span class="n">entry_class</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">descriptor</span><span class="o">.</span><span class="n">router_status_entry</span><span class="o">.</span><span class="n">RouterStatusEntryV3</span><span class="p">,</span> <span class="p">))</span> </div> <div class="viewcode-block" id="NewConsensusEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.NewConsensusEvent">[docs]</a><span class="k">class</span> <span class="nc">NewConsensusEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event for when we have a new consensus. This is similar to</span> <span class="sd"> :class:`~stem.response.events.NetworkStatusEvent`, except that it contains</span> <span class="sd"> the whole consensus so anything not listed is implicitly no longer</span> <span class="sd"> recommended.</span> <span class="sd"> The NEWCONSENSUS event was introduced in tor version 0.2.1.13-alpha.</span> <span class="sd"> :var list desc: :class:`~stem.descriptor.router_status_entry.RouterStatusEntryV3` for the changed descriptors</span> <span class="sd"> """</span> <span class="n">_SKIP_PARSING</span> <span class="o">=</span> <span class="bp">True</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_NEWCONSENSUS</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">content</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s">"NEWCONSENSUS</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">OK"</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">stem</span><span class="o">.</span><span class="n">descriptor</span><span class="o">.</span><span class="n">router_status_entry</span><span class="o">.</span><span class="n">_parse_file</span><span class="p">(</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">str_tools</span><span class="o">.</span><span class="n">_to_bytes</span><span class="p">(</span><span class="n">content</span><span class="p">)),</span> <span class="bp">True</span><span class="p">,</span> <span class="n">entry_class</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">descriptor</span><span class="o">.</span><span class="n">router_status_entry</span><span class="o">.</span><span class="n">RouterStatusEntryV3</span><span class="p">,</span> <span class="p">))</span> </div> <div class="viewcode-block" id="NewDescEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.NewDescEvent">[docs]</a><span class="k">class</span> <span class="nc">NewDescEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates that a new descriptor is available.</span> <span class="sd"> The fingerprint or nickname values in our 'relays' may be **None** if the</span> <span class="sd"> VERBOSE_NAMES feature isn't enabled. The option was first introduced in tor</span> <span class="sd"> version 0.1.2.2, and on by default after 0.2.2.1.</span> <span class="sd"> The NEWDESC event was one of the first Control Protocol V1 events and was</span> <span class="sd"> introduced in tor version 0.1.1.1-alpha.</span> <span class="sd"> :var tuple relays: **(fingerprint, nickname)** tuples for the relays with</span> <span class="sd"> new descriptors</span> <span class="sd"> """</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">relays</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">([</span><span class="n">stem</span><span class="o">.</span><span class="n">control</span><span class="o">.</span><span class="n">_parse_circ_entry</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">1</span><span class="p">:]])</span> </div> <div class="viewcode-block" id="ORConnEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.ORConnEvent">[docs]</a><span class="k">class</span> <span class="nc">ORConnEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates a change in a relay connection. The 'endpoint' could be</span> <span class="sd"> any of several things including a...</span> <span class="sd"> * fingerprint</span> <span class="sd"> * nickname</span> <span class="sd"> * 'fingerprint=nickname' pair</span> <span class="sd"> * address:port</span> <span class="sd"> The derived 'endpoint_*' attributes are generally more useful.</span> <span class="sd"> The ORCONN event was one of the first Control Protocol V1 events and was</span> <span class="sd"> introduced in tor version 0.1.1.1-alpha.</span> <span class="sd"> :var str endpoint: relay that the event concerns</span> <span class="sd"> :var str endpoint_fingerprint: endpoint's finterprint if it was provided</span> <span class="sd"> :var str endpoint_nickname: endpoint's nickname if it was provided</span> <span class="sd"> :var str endpoint_address: endpoint's address if it was provided</span> <span class="sd"> :var int endpoint_port: endpoint's port if it was provided</span> <span class="sd"> :var stem.ORStatus status: state of the connection</span> <span class="sd"> :var stem.ORClosureReason reason: reason for the connection to be closed</span> <span class="sd"> :var int circ_count: number of established and pending circuits</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"endpoint"</span><span class="p">,</span> <span class="s">"status"</span><span class="p">)</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"REASON"</span><span class="p">:</span> <span class="s">"reason"</span><span class="p">,</span> <span class="s">"NCIRCS"</span><span class="p">:</span> <span class="s">"circ_count"</span><span class="p">,</span> <span class="p">}</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_fingerprint</span> <span class="o">=</span> <span class="bp">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_nickname</span> <span class="o">=</span> <span class="bp">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_address</span> <span class="o">=</span> <span class="bp">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_port</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">try</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_fingerprint</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_nickname</span> <span class="o">=</span> \ <span class="n">stem</span><span class="o">.</span><span class="n">control</span><span class="o">.</span><span class="n">_parse_circ_entry</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span><span class="p">)</span> <span class="k">except</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="s">':'</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"ORCONN endpoint is neither a relay nor 'address:port': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="n">address</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">is_valid_port</span><span class="p">(</span><span class="n">port</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"ORCONN's endpoint location's port is invalid: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_address</span> <span class="o">=</span> <span class="n">address</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint_port</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">port</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">circ_count</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">circ_count</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"ORCONN event got a non-numeric circuit count (</span><span class="si">%s</span><span class="s">): </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">circ_count</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">circ_count</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">circ_count</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'status'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">ORStatus</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'reason'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">ORClosureReason</span><span class="p">)</span> </div> <div class="viewcode-block" id="SignalEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.SignalEvent">[docs]</a><span class="k">class</span> <span class="nc">SignalEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates that tor has received and acted upon a signal being sent</span> <span class="sd"> to the process. As of tor version 0.2.4.6 the only signals conveyed by this</span> <span class="sd"> event are...</span> <span class="sd"> * RELOAD</span> <span class="sd"> * DUMP</span> <span class="sd"> * DEBUG</span> <span class="sd"> * NEWNYM</span> <span class="sd"> * CLEARDNSCACHE</span> <span class="sd"> The SIGNAL event was introduced in tor version 0.2.3.1-alpha.</span> <span class="sd"> :var stem.Signal signal: signal that tor received</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"signal"</span><span class="p">,)</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_SIGNAL</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c"># log if we recieved an unrecognized signal</span> <span class="n">expected_signals</span> <span class="o">=</span> <span class="p">(</span> <span class="n">stem</span><span class="o">.</span><span class="n">Signal</span><span class="o">.</span><span class="n">RELOAD</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">Signal</span><span class="o">.</span><span class="n">DUMP</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">Signal</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">Signal</span><span class="o">.</span><span class="n">NEWNYM</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">Signal</span><span class="o">.</span><span class="n">CLEARDNSCACHE</span><span class="p">,</span> <span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'signal'</span><span class="p">,</span> <span class="n">expected_signals</span><span class="p">)</span> </div> <div class="viewcode-block" id="StatusEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.StatusEvent">[docs]</a><span class="k">class</span> <span class="nc">StatusEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Notification of a change in tor's state. These are generally triggered for</span> <span class="sd"> the same sort of things as log messages of the NOTICE level or higher.</span> <span class="sd"> However, unlike :class:`~stem.response.events.LogEvent` these contain well</span> <span class="sd"> formed data.</span> <span class="sd"> The STATUS_GENERAL, STATUS_CLIENT, STATUS_SERVER events were introduced</span> <span class="sd"> in tor version 0.1.2.3-alpha.</span> <span class="sd"> :var stem.StatusType status_type: category of the status event</span> <span class="sd"> :var stem.Runlevel runlevel: runlevel of the logged message</span> <span class="sd"> :var str message: logged message</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"runlevel"</span><span class="p">,</span> <span class="s">"action"</span><span class="p">)</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_STATUS</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s">'STATUS_GENERAL'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">status_type</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">StatusType</span><span class="o">.</span><span class="n">GENERAL</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s">'STATUS_CLIENT'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">status_type</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">StatusType</span><span class="o">.</span><span class="n">CLIENT</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s">'STATUS_SERVER'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">status_type</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">StatusType</span><span class="o">.</span><span class="n">SERVER</span> <span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">"BUG: Unrecognized status type (</span><span class="si">%s</span><span class="s">), likely an EVENT_TYPE_TO_CLASS addition without revising how 'status_type' is assigned."</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'runlevel'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">Runlevel</span><span class="p">)</span> </div> <div class="viewcode-block" id="StreamEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.StreamEvent">[docs]</a><span class="k">class</span> <span class="nc">StreamEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event that indicates that a stream has changed.</span> <span class="sd"> The STREAM event was one of the first Control Protocol V1 events and was</span> <span class="sd"> introduced in tor version 0.1.1.1-alpha.</span> <span class="sd"> :var str id: stream identifier</span> <span class="sd"> :var stem.StreamStatus status: reported status for the stream</span> <span class="sd"> :var str circ_id: circuit that the stream is attached to</span> <span class="sd"> :var str target: destination of the stream</span> <span class="sd"> :var str target_address: destination address (ip, hostname, or '(Tor_internal)')</span> <span class="sd"> :var int target_port: destination port</span> <span class="sd"> :var stem.StreamClosureReason reason: reason for the stream to be closed</span> <span class="sd"> :var stem.StreamClosureReason remote_reason: remote side's reason for the stream to be closed</span> <span class="sd"> :var stem.StreamSource source: origin of the REMAP request</span> <span class="sd"> :var str source_addr: requester of the connection</span> <span class="sd"> :var str source_address: requester address (ip or hostname)</span> <span class="sd"> :var int source_port: requester port</span> <span class="sd"> :var stem.StreamPurpose purpose: purpose for the stream</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"id"</span><span class="p">,</span> <span class="s">"status"</span><span class="p">,</span> <span class="s">"circ_id"</span><span class="p">,</span> <span class="s">"target"</span><span class="p">)</span> <span class="n">_KEYWORD_ARGS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"REASON"</span><span class="p">:</span> <span class="s">"reason"</span><span class="p">,</span> <span class="s">"REMOTE_REASON"</span><span class="p">:</span> <span class="s">"remote_reason"</span><span class="p">,</span> <span class="s">"SOURCE"</span><span class="p">:</span> <span class="s">"source"</span><span class="p">,</span> <span class="s">"SOURCE_ADDR"</span><span class="p">:</span> <span class="s">"source_addr"</span><span class="p">,</span> <span class="s">"PURPOSE"</span><span class="p">:</span> <span class="s">"purpose"</span><span class="p">,</span> <span class="p">}</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"STREAM event didn't have a target: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="s">':'</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Target location must be of the form 'address:port': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="n">address</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s">':'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">is_valid_port</span><span class="p">(</span><span class="n">port</span><span class="p">,</span> <span class="n">allow_zero</span> <span class="o">=</span> <span class="bp">True</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Target location's port is invalid: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">target_address</span> <span class="o">=</span> <span class="n">address</span> <span class="bp">self</span><span class="o">.</span><span class="n">target_port</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">port</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_addr</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_address</span> <span class="o">=</span> <span class="bp">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_port</span> <span class="o">=</span> <span class="bp">None</span> <span class="k">else</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="s">':'</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_addr</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Source location must be of the form 'address:port': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="n">address</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_addr</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">is_valid_port</span><span class="p">(</span><span class="n">port</span><span class="p">,</span> <span class="n">allow_zero</span> <span class="o">=</span> <span class="bp">True</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Source location's port is invalid: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_address</span> <span class="o">=</span> <span class="n">address</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_port</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">port</span><span class="p">)</span> <span class="c"># spec specifies a circ_id of zero if the stream is unattached</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">circ_id</span> <span class="o">==</span> <span class="s">"0"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">circ_id</span> <span class="o">=</span> <span class="bp">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'reason'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">StreamClosureReason</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'remote_reason'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">StreamClosureReason</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_log_if_unrecognized</span><span class="p">(</span><span class="s">'purpose'</span><span class="p">,</span> <span class="n">stem</span><span class="o">.</span><span class="n">StreamPurpose</span><span class="p">)</span> </div> <div class="viewcode-block" id="StreamBwEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.StreamBwEvent">[docs]</a><span class="k">class</span> <span class="nc">StreamBwEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event (emitted approximately every second) with the bytes sent and received</span> <span class="sd"> by the application since the last such event on this stream.</span> <span class="sd"> The STREAM_BW event was introduced in tor version 0.1.2.8-beta.</span> <span class="sd"> :var str id: stream identifier</span> <span class="sd"> :var long written: bytes sent by the application</span> <span class="sd"> :var long read: bytes received by the application</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"id"</span><span class="p">,</span> <span class="s">"written"</span><span class="p">,</span> <span class="s">"read"</span><span class="p">)</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_STREAM_BW</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">tor_tools</span><span class="o">.</span><span class="n">is_valid_stream_id</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Stream IDs must be one to sixteen alphanumeric characters, got '</span><span class="si">%s</span><span class="s">': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span> <span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">written</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"STREAM_BW event is missing its written value"</span><span class="p">)</span> <span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">read</span><span class="p">:</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"STREAM_BW event is missing its read value"</span><span class="p">)</span> <span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">read</span><span class="o">.</span><span class="n">isdigit</span><span class="p">()</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">written</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"A STREAM_BW event's bytes sent and received should be a positive numeric value, received: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">read</span> <span class="o">=</span> <span class="nb">long</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">read</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">written</span> <span class="o">=</span> <span class="nb">long</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">written</span><span class="p">)</span> </div> <div class="viewcode-block" id="TransportLaunchedEvent"><a class="viewcode-back" href="../../../api/response.html#stem.response.events.TransportLaunchedEvent">[docs]</a><span class="k">class</span> <span class="nc">TransportLaunchedEvent</span><span class="p">(</span><span class="n">Event</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Event triggered when a pluggable transport is launched.</span> <span class="sd"> The TRANSPORT_LAUNCHED event was introduced in tor version 0.2.5.0-alpha.</span> <span class="sd"> :var str type: 'server' or 'client'</span> <span class="sd"> :var str name: name of the pluggable transport</span> <span class="sd"> :var str address: IPv4 or IPv6 address where the transport is listening for</span> <span class="sd"> connections</span> <span class="sd"> :var int port: port where the transport is listening for connections</span> <span class="sd"> """</span> <span class="n">_POSITIONAL_ARGS</span> <span class="o">=</span> <span class="p">(</span><span class="s">"type"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">,</span> <span class="s">"address"</span><span class="p">,</span> <span class="s">"port"</span><span class="p">)</span> <span class="n">_VERSION_ADDED</span> <span class="o">=</span> <span class="n">stem</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">Requirement</span><span class="o">.</span><span class="n">EVENT_TRANSPORT_LAUNCHED</span> <span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'server'</span><span class="p">,</span> <span class="s">'client'</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Transport type should either be 'server' or 'client': </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">is_valid_ipv4_address</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">address</span><span class="p">)</span> <span class="ow">and</span> \ <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">is_valid_ipv6_address</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">address</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Transport address isn't a valid IPv4 or IPv6 address: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">is_valid_port</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">):</span> <span class="k">raise</span> <span class="n">stem</span><span class="o">.</span><span class="n">ProtocolError</span><span class="p">(</span><span class="s">"Transport port is invalid: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">)</span> </div> <span class="n">EVENT_TYPE_TO_CLASS</span> <span class="o">=</span> <span class="p">{</span> <span class="s">"ADDRMAP"</span><span class="p">:</span> <span class="n">AddrMapEvent</span><span class="p">,</span> <span class="s">"AUTHDIR_NEWDESCS"</span><span class="p">:</span> <span class="n">AuthDirNewDescEvent</span><span class="p">,</span> <span class="s">"BUILDTIMEOUT_SET"</span><span class="p">:</span> <span class="n">BuildTimeoutSetEvent</span><span class="p">,</span> <span class="s">"BW"</span><span class="p">:</span> <span class="n">BandwidthEvent</span><span class="p">,</span> <span class="s">"CIRC"</span><span class="p">:</span> <span class="n">CircuitEvent</span><span class="p">,</span> <span class="s">"CIRC_MINOR"</span><span class="p">:</span> <span class="n">CircMinorEvent</span><span class="p">,</span> <span class="s">"CLIENTS_SEEN"</span><span class="p">:</span> <span class="n">ClientsSeenEvent</span><span class="p">,</span> <span class="s">"CONF_CHANGED"</span><span class="p">:</span> <span class="n">ConfChangedEvent</span><span class="p">,</span> <span class="s">"DEBUG"</span><span class="p">:</span> <span class="n">LogEvent</span><span class="p">,</span> <span class="s">"DESCCHANGED"</span><span class="p">:</span> <span class="n">DescChangedEvent</span><span class="p">,</span> <span class="s">"ERR"</span><span class="p">:</span> <span class="n">LogEvent</span><span class="p">,</span> <span class="s">"GUARD"</span><span class="p">:</span> <span class="n">GuardEvent</span><span class="p">,</span> <span class="s">"INFO"</span><span class="p">:</span> <span class="n">LogEvent</span><span class="p">,</span> <span class="s">"NEWCONSENSUS"</span><span class="p">:</span> <span class="n">NewConsensusEvent</span><span class="p">,</span> <span class="s">"NEWDESC"</span><span class="p">:</span> <span class="n">NewDescEvent</span><span class="p">,</span> <span class="s">"NOTICE"</span><span class="p">:</span> <span class="n">LogEvent</span><span class="p">,</span> <span class="s">"NS"</span><span class="p">:</span> <span class="n">NetworkStatusEvent</span><span class="p">,</span> <span class="s">"ORCONN"</span><span class="p">:</span> <span class="n">ORConnEvent</span><span class="p">,</span> <span class="s">"SIGNAL"</span><span class="p">:</span> <span class="n">SignalEvent</span><span class="p">,</span> <span class="s">"STATUS_CLIENT"</span><span class="p">:</span> <span class="n">StatusEvent</span><span class="p">,</span> <span class="s">"STATUS_GENERAL"</span><span class="p">:</span> <span class="n">StatusEvent</span><span class="p">,</span> <span class="s">"STATUS_SERVER"</span><span class="p">:</span> <span class="n">StatusEvent</span><span class="p">,</span> <span class="s">"STREAM"</span><span class="p">:</span> <span class="n">StreamEvent</span><span class="p">,</span> <span class="s">"STREAM_BW"</span><span class="p">:</span> <span class="n">StreamBwEvent</span><span class="p">,</span> <span class="s">"TRANSPORT_LAUNCHED"</span><span class="p">:</span> <span class="n">TransportLaunchedEvent</span><span class="p">,</span> <span class="s">"WARN"</span><span class="p">:</span> <span class="n">LogEvent</span><span class="p">,</span> <span class="c"># accounting for a bug in tor 0.2.0.22</span> <span class="s">"STATUS_SEVER"</span><span class="p">:</span> <span class="n">StatusEvent</span><span class="p">,</span> <span class="p">}</span> </pre></div> </div> <div class="bottomnav"> </div> <div class="footer"> </div> </body> </html>