Noble TLS

repository·master·Indexed 43 days ago

https://github.com/rawandahmad698/noble-tls

An asynchronous HTTP library built on requests and tls-client for high-fidelity browser emulation. It features auto-updating JA3 fingerprints, HTTP/3 support with protocol racing, and extensive TLS configuration—including ECH, ALPS, and post-quantum curves—to bypass modern bot detection.

Tokens
2.4K
Snippets
9
Records
9
Agent score
5%

What's inside Noble TLS

  1. Manage the Session lifecycle and cookies

    master

    You can explicitly manage cookies at the Go layer and control the lifecycle of the session to free up memory and connections. Use session.get_cookies(url) to retrieve cookies and session.add_cookies(url, list_of_dicts) to inject them. Always call await session.close() when finished, or await Session.close_all() to clean up all active sessions.

    session = noble_tls.Session(client=Client.CHROME_133)
    
    # Do your work...
    res = await session.get("https://example.com")
    
    # Manage cookies in the Go session directly
    cookies = await session.get_cookies("https://example.com")
    await session.add_cookies("https://example.com", [
        {"name": "sid", "value": "abc", "domain": "example.com", "path": "/"},
    ])
    
    # Free Go memory and connections when done
    await session.close()
    
    # Or nuke everything at once
    await Session.close_all()
  2. Include TLS dependencies when using Pyinstaller or Pyarmor

    master

    Because Noble TLS relies on binary dependencies, you must manually include them when freezing your application. Use the --add-binary flag with the correct path and delimiter for your platform.

    # Linux - Ubuntu / x86
    --add-binary '{path_to_library}/tls_client/dependencies/tls-client-x86.so:tls_client/dependencies'
    
    # Linux Alpine / AMD64
    --add-binary '{path_to_library}/tls_client/dependencies/tls-client-amd64.so:tls_client/dependencies'
    
    # MacOS M1 and older
    --add-binary '{path_to_library}/tls_client/dependencies/tls-client-x86.dylib:tls_client/dependencies'
    
    # MacOS M2
    --add-binary '{path_to_library}/tls_client/dependencies/tls-client-arm64.dylib:tls_client/dependencies'
    
    # Windows
    --add-binary '{path_to_library}/tls_client/dependencies/tls-client-64.dll;tls_client/dependencies'
  3. Basic usage with a preset browser profile

    master

    Noble TLS follows a syntax similar to requests. You should call noble_tls.update_if_necessary() to ensure the underlying TLS client libraries are up to date. Use noble_tls.Session with a Client profile to initiate requests.

    import asyncio
    import noble_tls
    from noble_tls import Client
    
    async def main():
        await noble_tls.update_if_necessary()
        session = noble_tls.Session(
            client=Client.CHROME_133,
            random_tls_extension_order=True
        )
        res = await session.get(
            "https://www.example.com/",
            headers={"key1": "value1"},
            proxy="http://user:password@host:port"
        )
        print(res.status_code)
        print(res.used_protocol)
        print(res.text)
    
        await session.close()
    
    asyncio.run(main())
  4. Configure HTTP/3 and protocol racing

    master

    Noble TLS supports HTTP/3 (QUIC) with protocol racing, which mimics Chrome's behavior by giving HTTP/2 a 300ms head start. You can configure h3_settings, h3_settings_order, h3_pseudo_header_order, and h3_send_grease_frames. To disable HTTP/3 entirely, set disable_http3=True in the Session constructor.

    session = noble_tls.Session(
        ja3_string="...",
        protocol_racing=True,
        h3_settings={"QPACK_MAX_TABLE_CAPACITY": 4096},
        h3_settings_order=["QPACK_MAX_TABLE_CAPACITY"],
        h3_pseudo_header_order=":[ :method", ":authority", ":scheme", ":path"],
        h3_send_grease_frames=True,
    )
  5. Use default_headers for multi-value fallback

    master

    The default_headers parameter in Session accepts a dictionary where values are lists (multi-value format). These headers act as a fallback when no specific headers are provided on a request.

    session = noble_tls.Session(
        client=Client.CHROME_133,
        default_headers={"Accept": ["text/html", "application/json"]},
    )
  6. Detect the negotiated protocol

    master

    Every response object includes a used_protocol attribute which returns a Protocol enum indicating the protocol used for the connection (e.g., Protocol.HTTP_2 or Protocol.HTTP_3).

    from noble_tls import Protocol
    
    res = await session.get("https://example.com")
    print(res.used_protocol)  # Protocol.HTTP_2
    
    if res.used_protocol == Protocol.HTTP_3:
        print("Running over QUIC")
  7. Configure advanced TLS settings (ECH, ALPS, and Post-Quantum)

    master

    For highly customized TLS fingerprints, you can provide specific parameters to the Session constructor:

    • ja3_string: A custom JA3 fingerprint.
    • alps_protocols: List of ALPS protocols (e.g., ["h2"]).
    • ech_candidate_payloads: List of ECH candidate payloads.
    • ech_candidate_cipher_suites: List of dicts defining KDF and AEAD IDs.
    • key_share_curves: List of curves, including post-quantum options like X25519MLKEM768.
    • supported_signature_algorithms: List of supported algorithms.
    • cert_compression_algo: e.g., "brotli".
    • pseudo_header_order: Order of HTTP/2 pseudo-headers.
    session = noble_tls.Session(
        ja3_string="...",
        alps_protocols=["h2"],
        ech_candidate_payloads=[256],
        ech_candidate_cipher_suites=[
            {"kdfId": "HKDF_SHA256", "aeadId": "AEAD_AES_128_GCM"},
        ],
        key_share_curves=["GREASE", "X25519MLKEM768", "X25519"],
        supported_signature_algorithms=[
            "ECDSAWithP256AndSHA256",
            "PSSWithSHA256",
            "Ed25519",
        ],
        record_size_limit=16384,
        allow_http=True,
        stream_id=1,
    )
  8. Configure network and security options

    master

    You can set various network and security parameters at the session level or per-request level.

    Session-level options:

    • client: A Client profile.
    • disable_ipv6: Boolean to force IPv4 only.
    • local_address: Bind to a specific interface (host:port).
    • server_name_overwrite: Override TLS SNI.
    • is_rotating_proxy: Force a new connection per request.
    • without_cookie_jar: Disable the cookie jar.
    • certificate_pinning: A dictionary mapping domains to lists of base64 SHA256 pins.

    Per-request options:

    • timeout_milliseconds: Millisecond-precision timeout.
    • request_host_override: Override the host header.
    • stream_output_path: Path to stream the response body to a file.
    • stream_output_block_size: Block size for streaming.
    session = noble_tls.Session(
        client=Client.CHROME_133_PSK,
        disable_ipv6=True,
        local_address="0.0.0.0:0",
        server_name_overwrite="sni.com",
        is_rotating_proxy=True,
        without_cookie_jar=True,
        certificate_pinning={
            "example.com": ["sha256_pin_base64"],
        },
    )
    
    res = await session.get(
        "https://example.com",
        timeout_milliseconds=2500,
        request_host_override="other.host.com",
        stream_output_path="/tmp/response.json",
        stream_output_block_size=4096,
    )