Closing the decade, I’m pleased to announce Stem 1.8, the final release in Stem’s 1.x series, and with it, Python 2.x support.

What is Stem, you ask? For those who aren’t familiar with it, Stem is a Python library for interacting with Tor. With it you can script against your relay, descriptor data, or even write applications like Nyx.

So what’s new in this release?

CollecTor Downloader

Through our descriptor archive, CollecTor, Stem can now read Tor’s network topology at any prior point in time.

For example, listing today’s exits is as simple as…

import datetime import stem.descriptor.collector yesterday = datetime.datetime.utcnow() - datetime.timedelta(days = 1) exits = {} for desc in stem.descriptor.collector.get_server_descriptors(start = yesterday): if desc.exit_policy.is_exiting_allowed(): exits[desc.fingerprint] = desc print('%i relays published an exiting policy today...

' % len(exits)) for fingerprint, desc in exits.items(): print(' %s (%s)' % (desc.nickname, fingerprint))

% python demo.py 1229 relays published an exiting policy today... MrExit (D628F6BB2330B3F78DBB4BED466B0A586D74782E) pangea03 (F21DFB7CCD5EEF3E021086EC96EF7CFCAA72F4F3) MacarenaValdes (5E3FD31B9DC279C06AD051D68BE08914F6CD3B46) TEMPORA (05EAA0696DCB694D6811042348DACD5059FE64AD) Quintex43 (1E5136DDC52FAE1219208F0A6BADB0BA62587EE6)

Bandwidth Metrics

Bandwidth Authorities generate the latency heuristics that govern Tor’s path selection. Guiding circuits to be fast, without overburdening individual relays.

With Stem you can peruse this information…

import stem.descriptor.remote import stem.util.str_tools bandwidth_file = stem.descriptor.remote.get_bandwidth_file().run()[0] print('Bandwidth measurements are...

') for fingerprint, measurement in bandwidth_file.measurements.items(): bandwidth = '%s/s' % stem.util.str_tools.size_label(1024 * int(measurement.get('bw', '0'))) print(' * %s (%s) averaged %s' % (measurement.get('nick', ''), fingerprint, bandwidth))

Bandwidth measurements are... * DigiGesTor1e1 (0111BA9B604669E636FFD5B503F382A4B7AD6E80) averaged 23 MB/s * WonderWoman42 (E5AA85FA69CDC31900C86E6427C7E5DE11DE9E2D) averaged 37 MB/s * alterspalter (B6F0BC2B93CB3EFFFFF724CB4F5E025FB15EFB70) averaged 2 MB/s * blueberry (FE80E192AD48A1BEB02D88EBC7663061176E1A79) averaged 1 KB/s ...

Onion Services v3 Descriptors

With George’s help Stem now reads, decrypts, and even creates HSv3 descriptors. For example…

from stem.descriptor.hidden_service import ( HiddenServiceDescriptorV3, InnerLayer, IntroductionPointV3, ) print(HiddenServiceDescriptorV3.content( inner_layer = InnerLayer.create( introduction_points = [ IntroductionPointV3.create('1.1.1.1', 9001), IntroductionPointV3.create('2.2.2.2', 9001), IntroductionPointV3.create('3.3.3.3', 9001), ], ), ))

% python demo.py hs-descriptor 3 descriptor-lifetime 180 descriptor-signing-key-cert -----BEGIN ED25519 CERT----- AQgABqvHAX8wXzJY+FqoJQPXNZ8u+SQGPZ1WN/r3hUna0R2AXQnEAQAgBAAuqibl ALcKa/4nHtLZn2zKV8L4XIpkRyRm7btWPLpYN5Gseb03H5exL+I3SqfG3uNDw5QK CmPlCQUy3usouSwhO/qWgdy0//bP5kRDma5GDXXWoi3+xTKM6Jez7TGxPAU= -----END ED25519 CERT----- revision-counter 1573695064 superencrypted -----BEGIN MESSAGE----- aDJodcMjhCvz1K7JCJEAH1H24hvoZ7gZw53AhPdvpHu+5d1Ogwio4qcIXEK1pEgy QFF1fE6tnCzsk++eMa2WaKwIJYGLPoCnta78H5Ve6VoMj+Pyb5rE6wPTMTPSVm6M UjllArr7DS8YcofloDxu3iwC3JZYFt/LB6ahq6lBKeot2BD/11pNggkZrZOCLgNQ pUVyQau7K8ynagVlNNESnI3FccOBaBB4Xa5mObK2ylyiLQ08MqaImW7X2gxeZltT /C/xtiJXGm2CzkjPpBpMWm09p7/a97GEWca5e8+fhpmGrN7zjAwjYInTvQHS5AyU 7eUFg8ItrRxAiRq4fbe/zepiq2vgfj1Pt7uxC0KCTcLWpd9O/FIvcFSk27Yrtniw ... etc... -----END MESSAGE----- signature VDDXXLvgU6qjRI4zfJR3GbQuVjz98qO0LI5gsI60LtGXK2POZ4E+3YVVWuVaEkvMsZaku5qCutIcu74/WQMxCQ