API reference¶
Generated from the source. The names below are re-exported from the top-level torquests
package.
Functional API¶
api
¶
The module-level functional API, mirroring requests.
Each verb runs through an ephemeral :class:Session over a process-global
:class:TorClient. The client bootstraps a verified consensus of the Tor network
on first use and is shared across calls, so repeated requests do not re-bootstrap.
request(method: str, url: str, **kwargs: Any) -> requests.Response
¶
Send a request over Tor and return the response.
get(url: str, **kwargs: Any) -> requests.Response
¶
Send a GET request over Tor. See :func:request.
head(url: str, **kwargs: Any) -> requests.Response
¶
Send a HEAD request over Tor (redirects off by default). See :func:request.
post(url: str, **kwargs: Any) -> requests.Response
¶
Send a POST request over Tor. See :func:request.
put(url: str, **kwargs: Any) -> requests.Response
¶
Send a PUT request over Tor. See :func:request.
patch(url: str, **kwargs: Any) -> requests.Response
¶
Send a PATCH request over Tor. See :func:request.
delete(url: str, **kwargs: Any) -> requests.Response
¶
Send a DELETE request over Tor. See :func:request.
options(url: str, **kwargs: Any) -> requests.Response
¶
Send an OPTIONS request over Tor. See :func:request.
new_identity() -> None
¶
Rotate the global client's circuits, if it has been created.
close() -> None
¶
Tear down the global client (mainly for tests and clean shutdown).
Sessions¶
Session(*, tor: TorConnector | None = None, isolation: IsolationPolicy = 'host', isolation_token: object | None = None, onion_auth: Mapping[str, bytes] | None = None)
¶
Bases: Session
A requests session whose transport is Tor.
new_identity() -> None
¶
Rotate circuits and clear session state so later requests are unlinkable.
Drops the pooled circuits, so subsequent requests take fresh paths and exits, and clears the cookie jar, so a site cannot relink the new identity to the old one through a stored cookie.
MixedSession(*, tor: TorConnector | None = None, isolation: IsolationPolicy = 'host', isolation_token: object | None = None, onion_auth: Mapping[str, bytes] | None = None)
¶
Bases: Session
Routes .onion hosts through Tor and clearnet hosts directly.
Clearnet requests leave over the real IP by design. So that an onion
browsing session does not leak, a redirect from an onion service to a
clearnet host is refused rather than followed directly (see :meth:send).
send(request: requests.PreparedRequest, **kwargs: Any) -> requests.Response
¶
Send a request, refusing any onion-to-clearnet redirect hop.
requests follows redirects by re-entering send once per hop. This
remembers the previous hop's host, so a hop that crosses from an onion
service to a clearnet host is rejected with
:class:~torquests.exceptions.OnionRedirectError before it can be fetched
directly over the real IP. The check is per-hop, so it holds at any point
in a redirect chain, not only when the chain began at an onion service.
Client¶
TorClient(config: TorConfig | None = None, *, path_provider: PathProvider, transport_factory: TransportFactory | None = None, directory: LiveDirectory | None = None, onion_auth: Mapping[str, bytes] | None = None)
¶
Owns guard channels and a circuit pool; hands out connected streams.
bootstrap(config: TorConfig | None = None, *, timeout: float = 60.0, onion_auth: Mapping[str, bytes] | None = None) -> TorClient
classmethod
¶
Build a client on a live, verified consensus of the Tor network.
Fetches the consensus once per process (shared across clients) and selects
real relays over TLS. The consensus and key-certificate fetches are not
anonymized, but the subsequent per-circuit microdescriptor fetches are
tunneled over Tor (see :meth:_install_dir_tunnel), and the traffic the
client then carries always is. onion_auth maps an onion host to the
x25519 client-authorization private key used to reach an authorized-only
v3 service.
new_identity() -> None
¶
Drop all pooled circuits so subsequent requests take fresh paths.
TorConfig(connect_timeout: float = 60.0, read_timeout: float | None = 60.0, circuit_build_attempts: int = 3, cache_dir: Path | None = None)
dataclass
¶
Tunable parameters for a :class:~torquests._client.torclient.TorClient.
Transport¶
TorAdapter(connector: TorConnector, *, isolation: IsolationPolicy = 'host', owns_connector: bool = False, isolation_token: object | None = None)
¶
Bases: BaseAdapter
Routes requests traffic over Tor.
IsolationPolicy = Literal['session', 'host', 'request']
module-attribute
¶
Stealth¶
stealth_session(*, impersonate: str = DEFAULT_IMPERSONATE, tor: TorConnector | None = None) -> requests.Session
¶
Return a :class:requests.Session that speaks a browser's TLS over Tor.
Requests go out with curl_cffi's impersonated TLS/HTTP fingerprint (Tor
Browser by default) tunneled through torquests' Tor circuits, and come back
as ordinary :class:requests.Response objects. Pass impersonate to choose
another profile (for example "firefox" or "chrome"), or tor to
reuse an existing client. Circuits are isolated per destination host. Needs
the torquests[stealth] extra.
StealthTorAdapter(*, impersonate: str = DEFAULT_IMPERSONATE, tor: TorConnector | None = None, connect_timeout: float = 60.0)
¶
Bases: BaseAdapter
A requests adapter that speaks a browser's TLS fingerprint over Tor.
Each request is issued with curl_cffi (impersonating impersonate) through
an in-process SOCKS5-over-Tor proxy on 127.0.0.1, then repackaged as a
:class:requests.Response. Names, .onion included, resolve at the exit
(socks5h), so nothing reaches the local resolver. The proxy isolates
circuits per destination host.
Exceptions¶
exceptions
¶
Exception hierarchy.
Every Tor-specific error subclasses the marker :class:TorError and the
matching requests exception, so code written against requests keeps
working (except requests.exceptions.ConnectionError) while callers who want
to distinguish Tor failures can catch :class:TorError. This mirrors how
requests itself composes exceptions (for example ConnectTimeout is both a
ConnectionError and a Timeout).
This module imports only requests, so it sits outside the package's internal
layering and may be raised from anywhere.
TorError
¶
Bases: RequestException
Base class for every error raised by torquests.
TorBootstrapError
¶
Bases: TorError, ConnectionError
The client could not bootstrap a usable view of the Tor network.
ConsensusError
¶
Bases: TorBootstrapError
The network consensus could not be fetched, parsed, or verified.
DirectoryError
¶
Bases: TorBootstrapError
A directory document (microdescriptors, certificates) could not be fetched.
LinkAuthError
¶
Bases: ChannelError
The guard's CERTS chain did not authenticate its identity.
CircuitBuildTimeout
¶
Bases: CircuitError, ConnectTimeout
A circuit did not finish building within the connect budget.
CircuitDestroyed
¶
Bases: CircuitError
A DESTROY cell tore the circuit down while it was in use.
StreamConnectError
¶
Bases: StreamError
RELAY_BEGIN was refused (exit policy, unreachable host, or no route).
StreamConnectTimeout
¶
Bases: StreamError, ConnectTimeout
RELAY_BEGIN did not produce a RELAY_CONNECTED within the connect budget.
A timeout is a distinct failure from a refusal, so it maps to the requests
ConnectTimeout (a ConnectionError and a Timeout) rather than to a
bare :class:StreamConnectError.
TorReadTimeout
¶
Bases: TorError, ReadTimeout, TimeoutError
No data arrived on a stream within the read budget.
It also subclasses :class:TimeoutError (socket.timeout) so that when it
surfaces while urllib3 is reading a response body, urllib3's _error_catcher
classifies it as a read timeout (ReadTimeoutError) exactly as it would a
real socket timeout, which requests then maps to the same exception a
vanilla body-read timeout produces instead of a ChunkedEncodingError.
TorTLSError
¶
Bases: TorError, SSLError
The TLS handshake with the destination host failed.
HTTPS-over-Tor runs the destination handshake in TlsStreamSocket. A failure
there (a certificate that does not verify, a plaintext port answering the
ClientHello, a protocol-version mismatch) raises a bare ssl.SSLError, which
is not a requests exception. Wrapping it keeps the hierarchy's contract:
a caller's except requests.exceptions.SSLError and except TorError both
catch it, exactly as they would a direct requests HTTPS failure.
DescriptorError
¶
Bases: OnionServiceError
An onion-service descriptor could not be fetched, verified, or decrypted.
DescriptorNotFound
¶
Bases: DescriptorError
No responsible HSDir returned a descriptor for the address.
IntroductionError
¶
Bases: OnionServiceError
The introduction step failed for every introduction point.
RendezvousError
¶
Bases: OnionServiceError
The rendezvous step failed (no RENDEZVOUS2, or the handshake did not verify).
OnionClientAuthRequired
¶
Bases: OnionServiceError
The descriptor is client-authorized and no matching key was supplied.
InvalidOnionAddress
¶
Bases: TorError, InvalidURL
A .onion address failed length, version, checksum, or torsion validation.