Metadata-Version: 2.4
Name: proxy-builder-sdk
Version: 0.2.0
Summary: Tiny, dependency-free proxy SDK — one clean country/city/session/lifetime API for Aethyn residential proxies (and Bright Data, Oxylabs, Decodo, IPRoyal, SOAX, NetNut), ready for requests, httpx, Playwright and Selenium.
Project-URL: Homepage, https://www.aethyn.io
Project-URL: Documentation, https://www.aethyn.io/docs
Project-URL: Repository, https://github.com/aethynio/proxy-builder-sdk-python
Project-URL: Issues, https://github.com/aethynio/proxy-builder-sdk-python/issues
Author-email: Aethyn <support@aethyn.io>
License: MIT
License-File: LICENSE
Keywords: aethyn,aethyn proxy,httpx,playwright,proxies,proxy,requests,residential proxy,rotating proxy,selenium,socks5,web scraping
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Internet :: Proxy Servers
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == 'dev'
Description-Content-Type: text/markdown

# proxy-builder-sdk

**A tiny, dependency-free Python SDK for [aethyn.io](https://www.aethyn.io/?utm_source=pypi&utm_medium=readme&utm_campaign=proxy-builder-sdk) residential proxies.**
Build correct proxy URLs with country / city / sticky-session / lifetime targeting and hand them straight to `requests`, `httpx`, Playwright, or Selenium — without hand-assembling fragile username strings.

```bash
pip install proxy-builder-sdk
```

```python
import requests
from proxy_builder_sdk import AethynClient

client = AethynClient(username="aethyn-XXXXX", password="secret")   # or env AETHYN_USERNAME / AETHYN_PASSWORD

# rotating residential exit in the US
p = client.proxy(country="us")
r = requests.get("https://api.ipify.org?format=json", proxies=p.proxies)
print(r.json())
```

That's it. No hand-built `aethyn-XXXXX-country-us-session-...-lifetime-...` strings, no off-by-one dashes, no guessing the port.

## Why

Aethyn encodes targeting *inside the proxy username* — country, city, ISP, a sticky-session id, and a lifetime. It's powerful but easy to get subtly wrong (a stray `-` in a session id silently corrupts the whole thing, and city/ISP only work on the Elite tier). This SDK gives you a typed, validated API and keeps the wire format an internal detail, so **if Aethyn ever changes the username scheme, you just upgrade the package — your code doesn't move.**

## Usage

### Sticky sessions

Hold the same exit IP for a multi-step flow (login → cart → checkout):

```python
p = client.session(country="de", session="cart42", ttl=10)   # same IP for 10 minutes
# p.username -> "aethyn-XXXXX-country-de-session-cart42-lifetime-10"
```

`ttl` is minutes (1–1440). Leave `session` off for per-request rotation (the default).

### City / ISP targeting (Elite tier)

```python
p = client.session(country="us", city="chicago", isp="comcast",
                   session="run1", ttl=30, tier="elite")
```

`city`, `state`, `isp`, and `zip` are Elite-only — the SDK raises a clear error if you pass them on Premium.

### httpx

```python
import httpx
p = client.proxy(country="gb")
with httpx.Client(proxy=p.url) as http:
    http.get("https://example.com")
```

### Playwright

```python
from playwright.sync_api import sync_playwright
p = client.session(country="fr", session="s1", ttl=15, tier="elite")
with sync_playwright() as pw:
    browser = pw.chromium.launch(proxy=p.for_playwright())
    ...
```

### Selenium (via SeleniumWire) & SOCKS5

```python
p = client.proxy(country="jp", protocol="socks5")   # -> socks5://...@proxy.aethyn.io:1099
```

### What you get back

```python
p = client.session(country="us", session="run1", ttl=10)
p.username        # "aethyn-XXXXX-country-us-session-run1-lifetime-10"
p.host, p.port    # ("proxy.aethyn.io", 2099)
p.url             # "http://aethyn-XXXXX-...:secret@proxy.aethyn.io:2099"
p.proxies         # {"http": ..., "https": ...}  -> requests/httpx `proxies=`
p.for_playwright()# {"server": ..., "username": ..., "password": ...}
str(p)            # password-redacted, safe to log
```

Ports are picked for you: **Premium** `2099` (HTTP) / `1099` (SOCKS5), **Elite** `5499` (HTTP) / `3499` (SOCKS5). Self-hosting or white-labeling? Pass `AethynClient(..., host="gate.example.com")`.

## Other providers

Aethyn is the default, but the same clean API drives other big residential providers too — use `ProxyClient` with a `provider`:

```python
from proxy_builder_sdk import ProxyClient

# Oxylabs — the SDK emits customer-...-cc-us-sessid-run1-sesstime-10
p = ProxyClient(username="customer-me", password="pw", provider="oxylabs").session(
    country="us", session="run1", ttl=10
)
```

| provider | gateway | notes |
|---|---|---|
| `aethyn` *(default)* | `proxy.aethyn.io` | Premium/Elite tiers, city/ISP/state/zip |
| `brightdata` | `brd.superproxy.io` | pass `brd-customer-<id>-zone-<zone>` as the username |
| `oxylabs` | `pr.oxylabs.io` | `cc`/`sessid`/`sesstime`; state as `us_california` |
| `smartproxy` / `decodo` | `gate.decodo.com` | `sessionduration` (minutes) |
| `iproyal` | `geo.iproyal.com` | targeting goes in the **password** |
| `soax` | `proxy.soax.com` | ⚠️ community-verified; lifetime in seconds |
| `netnut` | `gw.netnut.net` | country + sticky session only |

Every non-Aethyn dialect was verified against the provider's official docs (each provider file records the source URL + a confidence level). `soax` is `medium` confidence — sanity-check it against SOAX's current docs before you lean on it. Each provider maps the same semantic call (`country`, `city`, `state`, `session`, `ttl`) to its own username/password format and raises a clear error for anything it can't express.

## Adding another proxy provider

**Contributions of new providers are welcome.** Most providers are a ~12-line dialect config — drop a file in `src/proxy_builder_sdk/providers/`, register it, and open a PR:

```python
from proxy_builder_sdk.providers.dialect import DialectProvider
from proxy_builder_sdk.providers.base import register_provider

register_provider(DialectProvider(
    name="myprovider", display="My Provider",
    host="gateway.myprovider.com", http_port=8000, socks5_port=None,
    auth_in="username", delim="-",
    keys={"country": "cc", "session": "sess", "ttl": "ttl"},  # our param -> their keyword
    order=["country", "session", "ttl"],
    source="https://docs.myprovider.com/...", confidence="high",
))
```

For anything that doesn't fit the dialect model, implement the one-method `Provider` protocol directly. See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the full walkthrough and PR checklist.

## Links

- [aethyn.io](https://www.aethyn.io/?utm_source=pypi&utm_medium=readme&utm_campaign=proxy-builder-sdk) — residential proxies (Aethyn is the default provider)
- Docs: <https://www.aethyn.io/docs>
- Node version: [`proxy-builder-sdk` on npm](https://www.npmjs.com/package/proxy-builder-sdk)

## License

MIT
