# 🔥 Surf TLS

[![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-310/)

Surf TLS is an advanced async HTTP library based on [surf](https://github.com/enetx/surf) (Go HTTP client) with TLS fingerprinting support.

## Installation

```bash
pip install surf-tls
```

The library will automatically download the correct binary for your platform on first use. No manual building required!

### Features
- [x] Auto-updating: Downloads latest binaries from GitHub releases
- [x] Async support
- [x] Proxy support
- [x] Custom JA3 string
- [x] Custom JA3 Hello ID
- [x] Custom H2 settings
- [x] Custom header order
- [x] HTTP/1.1, HTTP/2, and HTTP/3 support
- [x] `requests`'s `history` support
- [x] `requests`'s `allow_redirects` support
- [x] much more...

## Quick Start

```python
import asyncio
import surf_tls

async def main():
    # Auto-download latest binaries (optional, happens automatically)
    await surf_tls.download_if_necessary()
    
    # Or check for updates
    await surf_tls.update_if_necessary()
    
    session = surf_tls.Session(ja3_hello_id="chrome_144")
    res = await session.get("https://www.example.com/")
    print(res.text)

asyncio.run(main())
```

## Local Development

If you want to build locally for development:

```bash
# Build the shared library
./build.sh

# Install in development mode
pip install -e .
```

## Examples

Example 1 - Basic usage:

```python
import surf_tls

async def main():
    session = surf_tls.Session(
        ja3_hello_id="chrome_144"
    )
    res = await session.get(
        "https://www.example.com/",
        headers={
            "key1": "value1",
        },
        proxy="http://user:password@host:port"
    )
    print(res.text)

asyncio.run(main())
```

Example 2 - Custom JA3:

```python
import surf_tls

async def main():
    session = surf_tls.Session(
        ja3_string="771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0",
        h2_settings={
            "HEADER_TABLE_SIZE": 65536,
            "MAX_CONCURRENT_STREAMS": 1000,
            "INITIAL_WINDOW_SIZE": 6291456,
            "MAX_HEADER_LIST_SIZE": 262144
        },
        header_order=[
            "accept",
            "user-agent",
            "accept-encoding",
            "accept-language"
        ]
    )

    res = await session.post(
        "https://www.example.com/",
        headers={
            "key1": "value1",
        },
        proxy="http://user:password@host:port"
    )
    print(res.text)

asyncio.run(main())
```

## Acknowledgments

Big shout out to [enetx](https://github.com/enetx) for open sourcing [surf](https://github.com/enetx/surf), an excellent Go HTTP client library.
