wreq-python Documentation

repository·main·Indexed 23 days ago

https://github.com/0x676e67/wreq-python

An ergonomic, privacy-aware Python HTTP client (v0.12.1) designed for high-fidelity protocol matching. It utilizes BoringSSL to provide fine-grained control over TLS, JA3/JA4, and HTTP/2 signatures, enabling the emulation of over 100 browser device profiles to bypass anti-bot systems. Supports both asynchronous and blocking clients, WebSocket upgrades, and advanced connection management including rotating proxies and cookie storage.

Tokens
23.3K
Snippets
55
Records
121
Agent score
79%

What's inside wreq-python

  1. Overview of wreq

    main

    wreq is an ergonomic and modular Python HTTP Client designed for high-fidelity protocol matching. It is specifically built to bridge the gap between standard Python HTTP clients (like requests or httpx) and web browsers by allowing users to customize TLS, JA3/JA4, and HTTP/2 fingerprints. This makes it a specialized tool for web scraping, penetration testing, and security research where avoiding network fingerprint detection is critical.

    Key features include:

    • Support for both Async and Blocking Clients.
    • High-fidelity browser emulation via BoringSSL.
    • Advanced HTTP features: JSON, urlencoded, multipart, HTTP Trailers, and WebSocket upgrades.
    • Connection management: Connection pooling, rotating proxies, and cookie storage.
    • Performance: Zero-copy transfers and streaming transfers.
  2. Core components of the wreq module

    main
    The wreq module serves as the primary entry point for the library, providing the core classes and types required for network communication. The central abstraction is the wreq.Client, which manages connections and requests, and wreq.Response, which encapsulates the data returned from a server.
  3. Configure TLS/SSL settings with wreq.tls

    main
    The wreq.tls module provides capabilities for managing TLS/SSL configurations. It allows developers to handle custom certificates, implement key logging for debugging, and perform TLS fingerprinting. Use this module when your application requires specific security constraints, custom CA bundles, or when you need to inspect TLS handshakes.
  4. Apply proxies per-client or per-request

    main

    You can apply proxy settings at two different scopes:

    1. Per-client: Pass a list of proxies to the Client constructor. This applies the proxy to every request made by that specific client instance.
    2. Per-request: Pass a proxy argument to top-level functions like wreq.get(). This overrides or sets a proxy for that single request only.
  5. How wreq handles cookie protocol behavior

    main

    wreq automatically handles cookie header formatting based on the HTTP version being used:

    • HTTP/1.1: All cookies are folded into a single Cookie header (per RFC 9112).
    • HTTP/2 and above: Each cookie is sent as an individual header field (per RFC 9113).

    This behavior is transparent to the user; no manual configuration is required.

  6. Use wreq.emulation to bypass detection and fingerprinting

    main
    The wreq.emulation module provides settings for browser and client emulation. These settings are designed to help users bypass detection and fingerprinting mechanisms by making requests appear as if they are coming from a standard browser or specific client environment.
  7. Use the wreq.blocking synchronous client

    main
    The wreq.blocking module provides a synchronous (blocking) version of the wreq client. It offers the same functionality as the asynchronous client but uses a synchronous API, making it suitable for scripts or environments where async/await is not desired or supported.
  8. How wreq handles TLS and HTTP/2 emulation

    main

    Instead of using simple fingerprint strings for JA3, JA4, or Akamai, wreq provides fine-grained control over TLS and HTTP/2 extensions and settings. This allows for precise browser behavior emulation.

    Because TLS and HTTP/2 fingerprints evolve slower than browser release cycles, they are often identical across different browser models. wreq maintains over 100 browser device emulation profiles to handle these nuances.

  9. How wreq emulates browser fingerprints

    main

    Unlike standard HTTP clients that may be blocked by servers due to distinct network fingerprints, wreq provides fine-grained control over TLS and HTTP/2 extensions and settings.

    Instead of attempting to parse and emulate string-based fingerprints (like JA3 or JA4), wreq uses the BoringSSL library to precisely control the underlying protocol behavior. This allows for accurate emulation of HTTP/2 over TLS characteristics, which are essential for matching the fingerprints of modern browsers.

  10. Configure HTTP/HTTPS proxies with authentication

    main

    To use a proxy that requires credentials, you can either include them in the URL string or provide them as separate arguments to the Proxy constructor.

    Using URL syntax:

    proxy = Proxy.all("http://username:password@proxy.example.com:8080")

    Using separate arguments:

    proxy = Proxy.all(
        url="http://proxy.example.com:8080",
        username="username",
        password="password"
    )
    import asyncio
    from wreq import Client, Proxy
    
    async def main():
        # Basic usage with a client
        client = Client(
            proxies=[Proxy.all("http://proxy.example.com:8080")]
        )
    
        resp = await client.get("https://httpbin.io/ip")
        print(await resp.text())
    
    asyncio.run(main())
  11. Perform simple browser emulation

    main

    You can emulate specific browser versions by passing an Emulation constant to the Client constructor. This is useful for quickly mimicking the fingerprint of a known browser like Firefox.

    import asyncio
    from wreq import Client
    from wreq.emulation import Emulation
    
    
    async def main():
        client = Client(
            emulation=Emulation.Firefox135,
        )
        resp = await client.get("https://tls.peet.ws/api/all")
        print(f"Status: {resp.status}")
        print(f"Content: {await resp.text()}")
    
    
    if __name__ == "__main__":
        asyncio.run(main())