torpy icon indicating copy to clipboard operation
torpy copied to clipboard

AttributeError: 'TorHttpAdapter' object has no attribute '_tor_info'

Open MatthewUpdike opened this issue 4 years ago • 3 comments

Hi @jbrown299, I'm a big fan of your work!

Torpy works perfectly fine with Python 3.8 and this error occurs when trying to serialize the TOR session, basically saving the tor session object to a file in order to reuse it once the circuit is successfully built, e.g.:

from torpy.http.requests import tor_requests_session

start = time.time()

try:
    with open('session.pkl', 'rb') as f:
        session = pickle.load(f)
except IOError:
    session = tor_requests_session()

with session as s:
    print(s.get('https://httpbin.org/get').text)
    end = time.time()
    print(end - start)

# Persist the session by serializing
with open('session.pkl', 'wb') as f:
    pickle.dump(s, f)

The first run dumps the session, but when run again pickle.load(f) shoots the AttributeError.

pprint(vars(s)):

{'_pool_block': False,
 '_pool_connections': 10,
 '_pool_maxsize': 10,
 '_tor_info': <torpy.http.base.TorInfo object at 0x10d8762e0>,
 'config': {},
 'max_retries': Retry(total=0, connect=None, read=False, redirect=None, status=None),
 'poolmanager': <torpy.http.adapter.MyPoolManager object at 0x10d8761c0>,
 'proxy_manager': {}}

The attribute _tor_info is there (as an object), so I don't quite understand why this doesn't work. pickle doesn't support generator objects, and tor_requests_session() returns nested objects. Maybe you could add "save session" as a functionality to the package or perhaps indicate how to solve this issue.

Thanks in advance!

MatthewUpdike avatar Dec 04 '20 15:12 MatthewUpdike

What are you trying to do in such way? There is no way to save built circuit/socket connection to files. If you trying to save some cookies information you can do this somehow in different.

jbrown299 avatar Dec 13 '20 20:12 jbrown299

Thanks for the feedback @jbrown299 . To answer your question I'm kinda new to python and somehow am trying to speed up the connections, as it's kind of redundant opening and closing connections when TCP can be set keepalive. Sometimes it takes up to 30s on the the first run, afterwards the time varies between 4s to 7s in some cases even more depending on the latency between the node hops or if the circuit has to be rebuilt.

_thread.lock objects are not pickable:

class TorInfo:
    def __init__(self, guard, hops_count):
        self._guard = guard
        self._hops_count = hops_count
        self._circuits = {}
        self._lock = threading.Lock()

Sorry for posting this as an issue, this wasn't clear to me a few weeks ago.

The resumption of the socket session via cache should be the right way to go. The class TorCacheStorage seems promising, but I can't find a way to get it working.

  • Where is the cache stored?
  • How can a circuit be transparently cached for it run instantly on next launch?

Maybe you could provide an example, thanks again for your help!

MatthewUpdike avatar Dec 23 '20 23:12 MatthewUpdike

Sometimes it takes up to 30s on the the first run, afterwards the time varies between 4s to 7s in some cases even more depending on the latency between the node hops or if the circuit has to be rebuilt.

Can you provide verbose logs of first and second run? BTW you can use master source code to test with.

jbrown299 avatar Jan 15 '21 08:01 jbrown299