Metadata-Version: 2.4
Name: langchain-proxyhat
Version: 0.1.0
Summary: LangChain document loader and tool that read the web through ProxyHat residential proxies — rotation, geo-targeting, sticky sessions.
Project-URL: Homepage, https://proxyhat.com
Project-URL: Documentation, https://docs.proxyhat.com
Project-URL: Repository, https://github.com/ProxyHatCom/langchain-proxyhat
Author-email: ProxyHat <support@proxyhat.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agent-tool,document-loader,langchain,proxy,proxyhat,residential-proxy,rotating-proxy,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.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: httpx>=0.26
Requires-Dist: langchain-core>=0.3
Requires-Dist: proxyhat>=0.2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# langchain-proxyhat

Read the web in [LangChain](https://python.langchain.com) through [ProxyHat](https://proxyhat.com?utm_source=github&utm_medium=readme&utm_campaign=langchain) residential proxies — a document loader and an agent tool with rotating IPs, geo-targeting, and sticky sessions.

[![CI](https://github.com/ProxyHatCom/langchain-proxyhat/actions/workflows/ci.yml/badge.svg)](https://github.com/ProxyHatCom/langchain-proxyhat/actions/workflows/ci.yml)
[![Compatible with langchain-core latest](https://github.com/ProxyHatCom/langchain-proxyhat/actions/workflows/compat.yml/badge.svg)](https://github.com/ProxyHatCom/langchain-proxyhat/actions/workflows/compat.yml)
[![PyPI](https://img.shields.io/pypi/v/langchain-proxyhat)](https://pypi.org/project/langchain-proxyhat/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

## Why

LLM pipelines that read the open web from datacenter IPs get blocked, rate-limited, and served bot-detection pages instead of content. This package routes LangChain's web reads through ProxyHat's residential IPs (50M+ across 148+ countries) — a fresh IP per page by default, or one pinned IP for a whole multi-page load. Two first-class LangChain components:

- **`ProxyHatLoader`** — a `BaseLoader` that fetches URLs and yields `Document` objects for RAG, indexing, or summarization.
- **`ProxyHatFetchTool`** — a `BaseTool` that lets an agent fetch a page's text from a residential IP.

## Install

```bash
pip install langchain-proxyhat
```

`langchain-core` is a peer — bring your own version (`>=0.3`), the same one your app and other LangChain integrations already use.

## Quick start

Load pages as `Document` objects:

```python
from langchain_proxyhat import ProxyHatLoader

# An API key auto-selects an active residential sub-user:
docs = ProxyHatLoader(
    ["https://example.com", "https://example.org"],
    api_key="ph_your_api_key",
    country="us",
).load()

for doc in docs:
    print(doc.metadata["source"], doc.metadata["status_code"], len(doc.page_content))
```

Give an agent a residential-IP fetch tool:

```python
from langchain_proxyhat import ProxyHatFetchTool

tool = ProxyHatFetchTool(api_key="ph_your_api_key", country="us")

# Use directly...
html = tool.invoke({"url": "https://example.com"})

# ...or hand it to an agent alongside your other tools.
# from langchain.agents import create_agent
# agent = create_agent(model, tools=[tool])
```

Get an API key at [proxyhat.com](https://proxyhat.com?utm_source=github&utm_medium=readme&utm_campaign=langchain).

## Credentials

Pass them explicitly or via environment variables — options win over env:

| Option | Env var | Notes |
|---|---|---|
| `api_key` | `PROXYHAT_API_KEY` | Auto-selects an active sub-user with remaining traffic |
| `sub_user` | `PROXYHAT_SUBUSER` | Pick a specific sub-user by uuid or name (with an API key) |
| `username` | `PROXYHAT_USERNAME` | Explicit gateway `proxy_username` (skips the API) |
| `password` | `PROXYHAT_PASSWORD` | Explicit gateway `proxy_password` |

## Targeting

The same knobs are available on both the loader and the tool:

```python
ProxyHatLoader(
    ["https://example.com"],
    api_key="ph_your_api_key",
    country="us",        # ISO code or "any" (default)
    region="california",
    city="new_york",
    filter="high",       # AI IP-quality tier
    sticky="30m",        # keep one IP across the whole load; omit for rotating
    protocol="http",     # or "socks5"
)
```

### Rotating vs sticky

By default the loader is **rotating**: each page is fetched over a new connection with a stable gateway username, so ProxyHat hands out a fresh residential IP per page. Set `sticky` (e.g. `sticky="30m"` or `sticky=True`) to pin **one** residential IP across every page in the load — the right choice for paginated sites, logged-in sessions, or anything that must look like a single user. On `ProxyHatFetchTool`, `sticky` keeps the same IP across the agent's successive calls.

## How it works

Both components resolve your gateway credentials once (via the official [`proxyhat`](https://pypi.org/project/proxyhat/) SDK — an API key auto-picks an active sub-user, or you supply `username`/`password` directly), then build a ProxyHat gateway connection URL with the SDK's targeting grammar and fetch through it with [`httpx`](https://www.python-httpx.org/). Rotating loads reuse a stable username so the gateway rotates the IP per connection; sticky loads reuse one session id so every request exits from the same IP.

Publishing to the [LangChain integrations registry](https://python.langchain.com/docs/integrations/providers/) is a planned follow-up.

## License

MIT © [ProxyHat](https://proxyhat.com)
