Metadata-Version: 2.4
Name: auto_proxy_vpn
Version: 0.3.0
Summary: A package to create on demand HTTP(S) proxies in different cloud providers.
License-Expression: MIT
Project-URL: Homepage, https://kithuto.github.io/auto_proxy_vpn/readme.html
Project-URL: Repository, https://github.com/kithuto/auto_proxy_vpn
Project-URL: Documentation, https://kithuto.github.io/auto_proxy_vpn/readme.html
Keywords: proxy,networking,cloud,security,web scrapping
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: Proxy Servers
Classifier: Topic :: Security
Classifier: Topic :: System :: Networking
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Requires-Dist: pytest-mock; extra == "test"
Requires-Dist: responses; extra == "test"
Requires-Dist: python-dotenv; extra == "test"
Provides-Extra: google
Requires-Dist: google-cloud-compute; extra == "google"
Provides-Extra: azure
Requires-Dist: azure-identity; extra == "azure"
Requires-Dist: azure-mgmt-subscription; extra == "azure"
Requires-Dist: azure-mgmt-resource; extra == "azure"
Requires-Dist: azure-mgmt-network; extra == "azure"
Requires-Dist: azure-mgmt-compute; extra == "azure"
Provides-Extra: aws
Requires-Dist: boto3; extra == "aws"
Provides-Extra: all
Requires-Dist: google-cloud-compute; extra == "all"
Requires-Dist: azure-identity; extra == "all"
Requires-Dist: azure-mgmt-subscription; extra == "all"
Requires-Dist: azure-mgmt-resource; extra == "all"
Requires-Dist: azure-mgmt-network; extra == "all"
Requires-Dist: azure-mgmt-compute; extra == "all"
Requires-Dist: boto3; extra == "all"
Dynamic: license-file

<p align="center">
    <img src="https://raw.githubusercontent.com/kithuto/auto_proxy_vpn/main/docs/_static/logo.png" alt="auto_proxy_vpn logo" width="200" />
</p>

<p align="center">
  <h1 align="center">Auto proxy vpn</h1>
  <p align="center">
    On-demand HTTP(S) proxies across multiple cloud providers — from a single Python call.
  </p>
</p>

<p align="center">
  <a href="#installation">Installation</a> &nbsp;·&nbsp;
  <a href="#quick-start">Quick Start</a> &nbsp;·&nbsp;
  <a href="#supported-providers">Providers</a> &nbsp;·&nbsp;
  <a href="#proxy-pool">Proxy Pool</a> &nbsp;·&nbsp;
  <a href="#api-reference">API Reference</a> &nbsp;·&nbsp;
  <a href="#limitations">Limitations</a>
<!-- hide-nav-contributing -->
 &nbsp;·&nbsp;
  <a href="#contributing">Contributing</a>
<!-- /hide-nav-contributing -->
</p>

---

**auto_proxy_vpn** is a Python library that provisions disposable HTTP(S) proxy servers on major cloud platforms. Each proxy runs [Squid](http://www.squid-cache.org/) on a fresh VM/droplet, is accessible in one or two minutes, and is cleaned up automatically when you're done.

**Key features:**

- **Multi-cloud** — spin up proxies on AWS, Google Cloud, Azure, or DigitalOcean with the same API.
- **Zero infrastructure** — no pre-existing VMs, containers, or images required.
- **Context manager support** — resources are created on entry and destroyed on exit.
- **Proxy Pool** — distribute proxy creation across multiple providers with a single call.
- **Multi-account** — use multiple accounts per provider in the same pool to multiply capacity and avoid rate limits.
- **Batch creation** — provision multiple proxies at once with `create_batch()`.
- **Async-friendly** — return faster and poll readiness later.
- **Random region by default** — each proxy is deployed by default to a randomly selected region, maximizing IP diversity out of the box.
- **Basic auth & IP filtering** — optional Squid authentication and source-IP firewall rules.
- **Reconnect** — reload a previously created proxy by name without re-provisioning.

> **⚠️ Responsible Use:** This tool is intended for legitimate purposes such as testing, privacy, and accessing geo-restricted content you have rights to. If you use it for web scraping, please respect each website's `robots.txt`, rate limits, and terms of service. Hammering servers or bypassing protections you're not supposed to bypass isn't cool — and it gives tools like this a bad name.

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Supported Providers](#supported-providers)
- [Provider Setup Guides](#provider-setup-guides)
- [Usage](#usage)
  - [Single Provider](#single-provider)
  - [Proxy Pool (Multi-Provider)](#proxy-pool)
  - [Batch Creation](#batch-creation)
  - [Authentication & IP Filtering](#authentication--ip-filtering)
  - [Asynchronous Creation](#asynchronous-creation)
  - [Reconnecting to Existing Proxies](#reconnecting-to-existing-proxies)
- [API Reference](#api-reference)
  - [ProxyPool](#proxypool)
  - [BaseProxy](#baseproxy)
  - [ProxyBatch](#proxybatch)
  - [Configuration Objects](#configuration-objects)
- [Limitations](#limitations)
- [Project Structure](#project-structure)
- [Contributing](#contributing)

---

## Installation

```bash
pip install auto_proxy_vpn
```

Then install provider-specific optional dependencies (extras):

| Provider | Extra packages |
|---|---|
| **DigitalOcean** | *(none — uses `requests`, already included)* |
| **Google Cloud** | `pip install auto_proxy_vpn[google]` |
| **Azure** | `pip install auto_proxy_vpn[azure]` |
| **AWS** | `pip install auto_proxy_vpn[aws]` |

Install multiple extras together if needed:

```bash
pip install auto_proxy_vpn[google,azure,aws]
```

Install all providers:

```bash
pip install auto_proxy_vpn[all]
```

## Quick Start

### 1. DigitalOcean — simplest setup

```python
from auto_proxy_vpn.providers.digitalocean import ProxyManagerDigitalOcean

manager = ProxyManagerDigitalOcean(
    ssh_key="ssh-rsa AAAAB3...",
    token="dop_v1_xxxx..."          # or set DIGITALOCEAN_API_TOKEN env var
)

with manager.get_proxy() as proxy:
    import requests
    r = requests.get("https://httpbin.org/ip", proxies=proxy.get_proxy())
    print(r.json())
# Droplet is destroyed automatically
```

### 2. Google Cloud

```python
from auto_proxy_vpn.providers.google import ProxyManagerGoogle

manager = ProxyManagerGoogle(
    project="my-gcp-project-id",
    ssh_key="ssh-rsa AAAAB3...",
    credentials="google_credentials.json"   # or set GOOGLE_APPLICATION_CREDENTIALS
)

with manager.get_proxy() as proxy:
    print(proxy.get_proxy_str())   # http://203.0.113.42:38721
```

### 3. Azure

```python
from auto_proxy_vpn.providers.azure import ProxyManagerAzure

manager = ProxyManagerAzure(
    ssh_key="ssh-rsa AAAAB3...",
    credentials={
        "AZURE_SUBSCRIPTION_ID": "xxxx-...",
        "AZURE_CLIENT_ID": "xxxx-...",
        "AZURE_CLIENT_SECRET": "xxxx-...",
        "AZURE_TENANT_ID": "xxxx-...",
    }
    # or set env vars and use: credentials="your-subscription-id"
    # or az login and use: credentials="your-subscription-id"
)

with manager.get_proxy() as proxy:
    print(proxy.get_proxy_str())
```

### 4. AWS

```python
from auto_proxy_vpn.providers.aws import ProxyManagerAws

manager = ProxyManagerAws(
    ssh_key="ssh-rsa AAAAB3...",
    credentials={
        "AWS_ACCESS_KEY_ID": "AKIA...",
        "AWS_SECRET_ACCESS_KEY": "...",
    }
    # or set env vars AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
)

with manager.get_proxy() as proxy:
    print(proxy.get_proxy_str())
```

### 5. Multi-cloud with ProxyPool

```python
from auto_proxy_vpn import ProxyPool, AwsConfig, GoogleConfig, AzureConfig, DigitalOceanConfig

pool = ProxyPool(
    AwsConfig(ssh_key="ssh-rsa AAAA..."),
    GoogleConfig(project="my-project", ssh_key="ssh-rsa AAAA..."),
    AzureConfig(ssh_key="ssh-rsa AAAA..."),
    DigitalOceanConfig(ssh_key="ssh-rsa AAAAB3...", token="dop_v1_xxxx..."),
)

# One proxy from a randomly selected provider
with pool.create_one() as proxy:
    print(proxy.get_proxy_str())

# Batch of 6 proxies distributed evenly across providers
with pool.create_batch(6) as batch:
    for proxy in batch:
        print(proxy)
```

---

## Supported Providers

| Provider | Proxy | Status |
|---|---|---|
| **Google Cloud** | Yes | Stable |
| **Azure** | Yes | Stable |
| **DigitalOcean** | Yes | Stable |
| **AWS** | Yes | Stable |

---

## Provider Setup Guides

Each provider has its own README with step-by-step credential setup, full API reference, and advanced usage examples:

| Provider | Guide |
|---|---|
| Google Cloud | [Google docs](auto_proxy_vpn/providers/google/README.md) |
| Azure | [Azure docs](auto_proxy_vpn/providers/azure/README.md) |
| DigitalOcean | [DigitalOcean docs](auto_proxy_vpn/providers/digitalocean/README.md) |
| AWS | [AWS docs](auto_proxy_vpn/providers/aws/README.md) |

> **Security:** All guides recommend storing credentials in a `.env` file (never via `export` in shell history or committed to version control). See each provider README for details.

---

## Usage

### Single Provider

Every provider exposes a **Manager** class that creates and manages proxy instances:

```python
from auto_proxy_vpn.providers.digitalocean import ProxyManagerDigitalOcean

manager = ProxyManagerDigitalOcean(ssh_key="ssh_keys_files")

# Context manager (recommended) — auto-cleanup on exit
with manager.get_proxy() as proxy:
    response = requests.get("https://example.com", proxies=proxy.get_proxy())

# Manual lifecycle
proxy = manager.get_proxy()
try:
    response = requests.get("https://example.com", proxies=proxy.get_proxy())
finally:
    proxy.close()
```

### Proxy Pool

`ProxyPool` distributes proxy creation across multiple providers **and multiple accounts of the same provider**. Each config object with different credentials creates a separate manager — proxies are then distributed evenly across all of them using round-robin random selection:

```python
from auto_proxy_vpn import ProxyPool, AwsConfig, GoogleConfig, AzureConfig, DigitalOceanConfig

pool = ProxyPool(
    AwsConfig(ssh_key="ssh_keys"),
    GoogleConfig(project="my-project", ssh_key="ssh_keys"),
    DigitalOceanConfig(ssh_key="ssh_keys"),
)

proxy = pool.create_one(size="small", on_exit="destroy")
# do something with the proxy
proxy.close()

# or with context manager
with pool.create_one(size="small", on_exit="destroy") as proxy:
    response = requests.get("https://example.com", proxies=proxy.get_proxy())
```

#### Multi-account per provider

Pass multiple configs for the same provider with different credentials to multiply your capacity and distribute load across accounts. If a config omits credentials, the corresponding environment variable is used as fallback (e.g. `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`, `GOOGLE_APPLICATION_CREDENTIALS`, `AZURE_SUBSCRIPTION_ID`, `DIGITALOCEAN_API_TOKEN`):

```python
pool = ProxyPool(
    # Account 1: explicit credentials
    GoogleConfig(project="project-1", ssh_key="ssh_keys", credentials="creds_1.json"),
    # Account 2: uses GOOGLE_APPLICATION_CREDENTIALS env var
    GoogleConfig(project="project-2", ssh_key="ssh_keys"),
    # Plus AWS and Azure accounts
    AwsConfig(ssh_key="ssh-rsa AAAA..."),
    AzureConfig(ssh_key="ssh-rsa AAAA..."),
)

# 9 proxies distributed across 3 managers (≈3 each)
with pool.create_batch(9) as batch:
    for proxy in batch:
        print(proxy)

running = pool.get_running_proxy_names()
print(running)
# {
#   CloudProvider.GOOGLE: {
#     "account_1": ["proxy1", "proxy2"],
#     "account_2": ["proxy1"],
#   },
#   CloudProvider.AWS: {
#     "account_1": [("proxy1", "proxy2")],
#   },
# }
```

`account_1`, `account_2`, etc. preserve the same order used when configs are passed to `ProxyPool(...)`.

### Batch Creation

Create multiple proxies at once — they are provisioned asynchronously by default:

```python
with pool.create_batch(6) as batch:
    for proxy in batch:
        print(proxy.get_proxy_str())
# All 6 proxies are destroyed on exit

# or
batch = pool.create_batch(6)
for proxy in batch:
    print(proxy.get_proxy_str())
batch.close()
```

Or directly from a single manager:

```python
batch = manager.get_proxies(
    number=3,
    sizes=["small", "medium", "large"],
    is_async=True,
)
# Use batch[0], batch[1], batch[2]
batch.close()
```

`manager.get_proxies(...)` always returns a `ProxyBatch`, regardless of provider (AWS, Azure, Google, DigitalOcean, etc.).

### Authentication & IP Filtering

```python
proxy = manager.get_proxy(
    auth={"user": "myuser", "password": "s3cret"},
    allowed_ips=["203.0.113.10", "198.51.100.0/24"],
)
# Proxy URL: http://myuser:s3cret@<ip>:<port>
# Only listed IPs (+ your current IP, auto-added) can connect
```

### Asynchronous Creation

Return immediately without blocking on VM provisioning:

```python
proxy = manager.get_proxy(is_async=True)

# ... do other work ...

# Block until the proxy is ready
if proxy.is_active(wait=True):
    r = requests.get("https://example.com", proxies=proxy.get_proxy())
```

### Reconnecting to Existing Proxies

If a proxy was created with `on_exit="keep"`, it remains running after `close()`. Reconnect later by name:

```python
# Create and keep alive
proxy = manager.get_proxy(on_exit="keep")
print(proxy.name)   # "proxy1"
proxy.close()       # resources are NOT deleted

# Later session — reconnect
proxy = manager.get_proxy_by_name(
    "proxy1",
    auth={"user": "alice", "password": "secret"},  # only needed for auth proxies
    on_exit="destroy",
)
```

List all running proxies:

```python
names = manager.get_running_proxy_names()
# ["proxy1", "proxy2"]
```

---

## API Reference

### `ProxyPool`

High-level orchestrator that distributes proxy creation across providers.

```python
from auto_proxy_vpn import ProxyPool

pool = ProxyPool(
    *provider_configs,      # AwsConfig, GoogleConfig, AzureConfig, DigitalOceanConfig, ...
    log=True,
    log_file=None,
    log_format="%(asctime)-10s %(levelname)-5s %(message)s",
    logger=None,
)
```

| Method | Returns | Description |
|---|---|---|
| `create_one(...)` | `BaseProxy` | Create one proxy from a randomly selected provider |
| `create_batch(count, ...)` | `ProxyBatch` | Create `count` proxies distributed across providers |
| `get_sizes_and_regions(provider)` | `dict[Literal['small','medium','large'], list[str] \| list[tuple[str, list[str]]]]` | Get all available regions for a provider grouped by size |
| `get_regions_by_size(provider, size)` | `list[str] \| list[tuple[str, list[str]]]` | Get regions for one provider and one size (`small`, `medium`, `large`) |
| `get_running_proxy_names()` | `dict[CloudProvider, dict[str, list[str] \| list[tuple[str, str]]]]` | List running proxies grouped by provider and account (`account_1`, `account_2`, ...) |

Shared options in `create_one(...)` and `create_batch(...)`: `port`/`ports`, `size`/`sizes`, `region`/`regions`, `auth`/`auths`, `allowed_ips`, `is_async`, `retry`, `proxy_name`/`proxy_names`, and `on_exit`.

Inspect available regions to create proxies in specific provider regions:

```python
from auto_proxy_vpn import CloudProvider

sizes_and_regions = pool.get_sizes_and_regions(CloudProvider.AWS)
print(sizes_and_regions["small"])

medium_regions = pool.get_regions_by_size(CloudProvider.AWS, "medium")
print(medium_regions)

# Simple create_one call in a specific AWS region
proxy = pool.create_one(size="medium", region={CloudProvider.AWS: medium_regions[0]})
print(proxy.get_proxy_str())
proxy.close()
```

---

### `BaseProxy`

Common interface shared by all proxy instances (`GoogleProxy`, `AzureProxy`, `DigitalOceanProxy`).

| Property | Type | Description |
|---|---|---|
| `ip` | `str` | Public IPv4 address |
| `port` | `int` | Proxy TCP port |
| `name` | `str` | Instance/droplet name |
| `active` | `bool` | Whether the proxy is confirmed reachable |
| `user` | `str` | Basic-auth username (empty if none) |
| `password` | `str` | Basic-auth password (empty if none) |

| Method | Returns | Description |
|---|---|---|
| `get_proxy_str()` | `str` | Full proxy URL: `http://user:pass@ip:port` |
| `get_proxy()` | `dict \| None` | `{"http": url, "https": url}` for `requests` |
| `is_active(wait=False)` | `bool` | Check or wait for proxy readiness |
| `close(wait=True)` | `None` | Destroy or keep the proxy (depends on `on_exit`) |

**Context manager:**

```python
with manager.get_proxy() as proxy:
    # proxy is guaranteed active
    ...
# resources are cleaned up automatically
```

---

### `ProxyBatch`

Container for multiple proxies with iteration and lifecycle control.

`ProxyBatch` is returned by both `pool.create_batch(...)` and every provider manager `get_proxies(...)` call.

```python
with pool.create_batch(5) as batch:
    print(len(batch))       # 5
    print(batch[0])         # first proxy
    for proxy in batch:
        print(proxy.get_proxy_str())
# All proxies are closed on exit
```

| Method | Returns | Description |
|---|---|---|
| `close()` | `None` | Close all proxies in the batch |
| `len(batch)` | `int` | Number of proxies |
| `batch[i]` | `BaseProxy` | Access by index |
| `for p in batch` | iteration | Iterate over proxies |

---

### Configuration Objects

Dataclass-based configs used with `ProxyPool` or `Manager.from_config()`.

#### `AwsConfig`

```python
from auto_proxy_vpn import AwsConfig

AwsConfig(
    ssh_key="ssh-rsa AAAA...",      # str | dict | list | file path
    credentials={
        "AWS_ACCESS_KEY_ID": "AKIA...",
        "AWS_SECRET_ACCESS_KEY": "...",
    },                               # optional; falls back to env vars
)
```

#### `GoogleConfig`

```python
from auto_proxy_vpn import GoogleConfig

GoogleConfig(
    project="my-gcp-project-id",    # required
    ssh_key="ssh-rsa AAAA...",      # str | dict | list | file path
    credentials="creds.json",       # path to service account JSON (or env var)
)
```

#### `AzureConfig`

```python
from auto_proxy_vpn import AzureConfig

AzureConfig(
    ssh_key="ssh-rsa AAAA...",      # str | dict | list | file path
    credentials="subscription-id",  # str | dict with AZURE_* keys (or env vars)
)
```

#### `DigitalOceanConfig`

```python
from auto_proxy_vpn import DigitalOceanConfig

DigitalOceanConfig(
    ssh_key="ssh-rsa AAAAB3...",      # str | dict | list | file path
    token="dop_v1_xxxx...",         # or env var DIGITALOCEAN_API_TOKEN
    project_name="AutoProxyVPN",
    project_description="On demand proxies",
)
```

---

### Common `get_proxy()` Parameters

All provider managers share the same `get_proxy()` signature:

| Parameter | Type | Default | Description |
|---|---|---|---|
| `port` | `int` | `0` (random) | Proxy TCP port (random 10000–65000 if 0) |
| `size` | `"small" \| "medium" \| "large"` | `"medium"` | VM/droplet size tier |
| `region` | `str` | `""` (random) | Cloud region/zone |
| `auth` | `dict` | `{}` | `{"user": ..., "password": ...}` for basic auth |
| `allowed_ips` | `str \| list[str]` | `[]` | Allowed source IPs (your IP auto-added) |
| `is_async` | `bool` | `False` | Return before VM is fully ready |
| `retry` | `bool` | `True` | Retry in another region on failure |
| `proxy_name` | `str` | `""` | Custom name (auto-generated if empty) |
| `on_exit` | `"destroy" \| "keep"` | `"destroy"` | Cleanup behavior when proxy is closed |

---

## Limitations

Before choosing this tool, keep in mind:

- **Cloud IP blacklists.** Some websites maintain blacklists of IP ranges belonging to major cloud providers (AWS, Google Cloud, Azure, DigitalOcean, etc.). If a target site blocks cloud IPs, proxies created by this library will be blocked too — no matter how many regions or accounts you rotate through. This is a fundamental limitation of cloud-based proxies vs. residential ones.
- **Not a residential proxy.** The IPs you get are datacenter IPs. Services with aggressive anti-bot detection (e.g. some e-commerce sites, social media platforms, or ticket sellers) will likely flag or block them.
- **Provider rate limits.** Each cloud provider imposes quotas on VM/droplet creation. If you spin up many proxies in a short time, you may hit these limits. Using multiple accounts via `ProxyPool` helps, but doesn't eliminate them entirely.
- **Cost.** Every proxy is a real cloud VM. Forgetting to destroy instances will incur charges.

---

## Project Structure

```
auto_proxy_vpn/
├── __init__.py              # CloudProvider enum, public exports
├── configs.py               # AwsConfig, GoogleConfig, AzureConfig, DigitalOceanConfig, ManagerRuntimeConfig
├── manager_register.py      # ProxyManagers registry + provider auto-discovery
├── proxy_pool.py            # ProxyPool, RandomManagerPicker
├── providers/
│   ├── azure/               # Azure VM proxy provider
│   ├── digitalocean/        # DigitalOcean droplet proxy provider
│   ├── google/              # Google Compute Engine proxy provider
│   ├── aws/                 # AWS EC2 proxy provider
└── utils/
    ├── base_proxy.py        # BaseProxy, BaseProxyManager, ProxyBatch
    ├── exceptions.py        # Shared exceptions
    ├── files_utils.py       # Squid config generator
    ├── ssh_client.py        # SSH command execution and file download
    └── util.py              # Public IP detection
```

<!-- hide-contributing -->
---

## Contributing

Contributions are welcome! Please read [contributing docs](CONTRIBUTING.md) guide for detailed information on:

- Reporting bugs and suggesting features
- Development setup and workflow
- Coding guidelines and style conventions
- Adding a new cloud provider (step-by-step)
- Building and updating the Sphinx documentation
- Pull request process
