Skip to main content

pia-ctl-sdk

PyPI - Version PyPI - Downloads License: MIT Python - Version CI - Release Code Style - Ruff Type Checking - mypy Docs - GitHub Pages

A typed Python SDK for the Private Internet Access (PIA) VPN CLI (piactl) with comprehensive environment management, proxy adapters, and automation capabilities.

🚀 Features

  • 🔒 VPN Management: Connect, disconnect, and monitor PIA VPN connections
  • ⚙️ Environment Configuration: Pydantic v2 settings with .env file support
  • 🌐 Proxy Adapters: Built-in support for Playwright, httpx, and Selenium
  • 📊 Status Monitoring: Real-time VPN status and connection monitoring
  • 🎯 Smart Connection: Strategy-based connection (preferred → random → default regions)
  • 🔌 Plugin System: Extensible plugin architecture for custom functionality
  • 🛠️ CLI Tools: Command-line interface for VPN management
  • 📝 Type Safety: Full type hints and mypy support

📦 Installation

pip install pia-ctl-sdk

Development Installation

# Clone the repository
git clone https://github.com/pr1m8/pia-ctl.git
cd pia-ctl

# Install with PDM
pdm install -G docs -G dev

# Or install with pip
pip install -e ".[dev,docs]"

🚀 Quick Start

Basic Python Usage

from pypia_ctl import init_settings, connect_vpn, get_status

# Initialize with environment settings
settings = init_settings(create_env=True)

# Connect to VPN with preferred region
result = connect_vpn(region="us-east")
print(f"Connected: {result.success}")

# Check VPN status
status = get_status()
print(f"VPN Status: {status.connected}")
print(f"Current Region: {status.region}")
print(f"IP Address: {status.ip_address}")

Advanced Python Examples

from pypia_ctl import PiaSettings, connect_with_strategy, monitor_connection
import asyncio

# Custom settings
settings = PiaSettings(
    protocol="wireguard",
    default_region="auto",
    preferred_regions=["us-east", "us-west", "europe"],
    randomize_region=True
)

# Connect with fallback strategy
result = connect_with_strategy(
    preferred=["us-east", "us-west"],
    fallback="random",
    timeout=30
)

# Async monitoring
async def monitor_vpn():
    async for status in monitor_connection():
        print(f"Status: {status.connected} - Region: {status.region}")
        if not status.connected:
            print("VPN disconnected, attempting reconnection...")
            connect_vpn()

# Run monitoring
asyncio.run(monitor_vpn())

Proxy Integration Examples

from pypia_ctl import PiaSettings
from pypia_ctl.adapters import PlaywrightAdapter, HttpxAdapter
import httpx
from playwright.async_api import async_playwright

# Configure proxy settings
settings = PiaSettings(
    proxy={
        "kind": "socks5",
        "host": "127.0.0.1",
        "port": 1080,
        "username": "user",
        "password": "pass"
    }
)

# Use with httpx
async with HttpxAdapter(settings) as client:
    response = await client.get("https://httpbin.org/ip")
    print(f"IP: {response.json()['origin']}")

# Use with Playwright
async with async_playwright() as p:
    browser = await p.chromium.launch()
    page = await browser.new_page()

    # Configure proxy
    await page.context.set_extra_http_headers({
        "Proxy-Authorization": "Basic dXNlcjpwYXNz"
    })

    await page.goto("https://httpbin.org/ip")
    content = await page.content()
    print("Page loaded with proxy")

CLI Usage

# Initialize environment configuration
pypia env-init

# Connect to VPN with specific region
pypia connect --region us-east

# Connect with fallback strategy
pypia connect --preferred us-east,us-west --fallback random

# Check detailed status
pypia status --verbose

# Monitor connection in real-time
pypia monitor

# Disconnect
pypia disconnect

# List available regions
pypia regions

# Print environment configuration
pypia env-print

Environment Configuration

Create a .env file with your preferences:

# Copy the example file
cp .env.example .env

# Edit with your settings
PIA_PROTOCOL=wireguard
PIA_DEFAULT_REGION=auto
PIA_RANDOMIZE_REGION=true
PIA_PREFERRED_REGIONS=["us-east", "us-west", "europe"]

📖 API Reference

Core Functions

from pypia_ctl import (
    init_settings,           # Initialize settings from env/.env
    connect_vpn,            # Connect to VPN
    disconnect_vpn,         # Disconnect VPN
    get_status,             # Get current VPN status
    connect_with_strategy,  # Connect with fallback strategy
    monitor_connection,     # Async connection monitoring
    ensure_env_file,        # Create/merge .env file
    generate_env_text,      # Generate .env content
)

# Settings and Configuration
from pypia_ctl import PiaSettings, EnvStatus

# Adapters for proxy integration
from pypia_ctl.adapters import PlaywrightAdapter, HttpxAdapter, SeleniumAdapter

# Exceptions
from pypia_ctl.exceptions import PiaError, ConnectionError, TimeoutError

Settings Configuration

from pypia_ctl import PiaSettings

# Full configuration example
settings = PiaSettings(
    # VPN Protocol
    protocol="wireguard",  # or "openvpn"

    # Region Settings
    default_region="auto",
    randomize_region=True,
    preferred_regions=["us-east", "us-west", "europe"],

    # Region Filtering
    region_filters={
        "include_streaming": False,
        "include_countries": ["US", "CA", "GB"],
        "exclude_countries": ["CN", "RU"]
    },

    # Proxy Configuration
    proxy={
        "kind": "socks5",
        "host": "127.0.0.1",
        "port": 1080,
        "username": "user",
        "password": "pass"
    },

    # Plugin Configuration
    plugins=["custom_plugin", "monitoring_plugin"]
)

🎯 Use Cases

1. Web Scraping with VPN

from pypia_ctl import connect_vpn, HttpxAdapter
import httpx

# Connect to VPN
connect_vpn(region="us-east")

# Use with httpx for web scraping
async with HttpxAdapter() as client:
    response = await client.get("https://example.com")
    print(f"Scraped content: {response.text[:100]}...")

2. Automated Testing with Playwright

from pypia_ctl import connect_vpn
from playwright.async_api import async_playwright

# Connect to VPN before testing
connect_vpn(region="europe")

async def test_with_vpn():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()

        # Test from different geographic location
        await page.goto("https://httpbin.org/ip")
        ip_info = await page.text_content("body")
        print(f"Testing from IP: {ip_info}")

        await browser.close()

# Run test
import asyncio
asyncio.run(test_with_vpn())

3. CI/CD Pipeline Integration

# .github/workflows/test-with-vpn.yml
name: Test with VPN
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.13"

      - name: Install dependencies
        run: pip install pia-ctl-sdk

      - name: Connect to VPN and test
        run: |
          pypia connect --region us-east
          python -m pytest tests/
          pypia disconnect

4. Monitoring and Alerting

import asyncio
from pypia_ctl import monitor_connection, connect_vpn
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

async def vpn_monitor():
    """Monitor VPN connection and auto-reconnect if needed."""
    async for status in monitor_connection():
        if not status.connected:
            logger.warning("VPN disconnected! Attempting reconnection...")
            try:
                connect_vpn()
                logger.info("VPN reconnected successfully")
            except Exception as e:
                logger.error(f"Failed to reconnect VPN: {e}")
        else:
            logger.info(f"VPN connected: {status.region} ({status.ip_address})")

# Run monitoring
asyncio.run(vpn_monitor())

🔧 Troubleshooting

Common Issues

1. VPN Connection Fails

from pypia_ctl import connect_vpn, get_status
from pypia_ctl.exceptions import ConnectionError

try:
    result = connect_vpn(region="us-east")
    if not result.success:
        print(f"Connection failed: {result.error}")

        # Try alternative region
        result = connect_vpn(region="us-west")

except ConnectionError as e:
    print(f"Connection error: {e}")

    # Check if piactl is installed
    status = get_status()
    if not status.piactl_available:
        print("piactl not found. Please install PIA client.")

2. Environment Configuration Issues

from pypia_ctl import ensure_env_file, generate_env_text

# Create .env file with defaults
ensure_env_file(".env")

# Check generated configuration
env_content = generate_env_text()
print("Generated .env content:")
print(env_content)

3. Proxy Configuration Problems

from pypia_ctl import PiaSettings, HttpxAdapter

# Test proxy configuration
settings = PiaSettings(
    proxy={
        "kind": "socks5",
        "host": "127.0.0.1",
        "port": 1080
    }
)

try:
    async with HttpxAdapter(settings) as client:
        response = await client.get("https://httpbin.org/ip")
        print(f"Proxy working: {response.json()}")
except Exception as e:
    print(f"Proxy error: {e}")

📚 Documentation

Local Development

# Serve documentation locally
pdm run docs

# Or with mkdocs directly
mkdocs serve

Online Documentation

🛠️ Development

Setup Development Environment

# Clone and setup
git clone https://github.com/pr1m8/pia-ctl.git
cd pia-ctl

# Install development dependencies
pdm install -G dev -G docs -G test

# Run tests
pdm run test

# Run linting
pdm run lint

# Run type checking
pdm run typecheck

Building Documentation

# MkDocs (recommended)
pdm run docs

# Sphinx (alternative)
pip install sphinx furo myst-parser
(cd sphinx-docs && make html)

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

👨‍💻 Author

William R. Astley (@pr1m8)

🔗 Links

⭐ Support

If you find this project helpful, please consider giving it a star on GitHub!

Metadata

Release files for pia-ctl-sdk 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pia-ctl-sdk 0.1.3
File Size Uploaded
pia_ctl_sdk-0.1.3.tar.gz 27.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pia-ctl-sdk 0.1.3
File Interpreter ABI Platform
pia_ctl_sdk-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 52.8 kB

Release files / pia_ctl_sdk-0.1.3.tar.gz

Download URL pia_ctl_sdk-0.1.3.tar.gz
Size 27.8 kB
Tags Source
SHA-256 checksum
How to use checksums
a35da8a59facb19f51cdc879bb7a7532f121858d6906b4065fa3ea1ca595ab76
BLAKE2b-256 checksum
How to use checksums
87de511e80f8d835f65093c9fdfdbafbda03f8baae057198c3ae94d51dd09109
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / pia_ctl_sdk-0.1.3-py3-none-any.whl

Download URL pia_ctl_sdk-0.1.3-py3-none-any.whl
Size 25.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a7cf974a33a5feb72629f01ca94ae562b9b05a7a8f037605511f913f611fe639
BLAKE2b-256 checksum
How to use checksums
8bdf7ae496a4819538edc795cf1f54f38387346fdb704b0d4bc1118fe3eb76e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page