Skip to main content

A modern library for managing, leasing, and monitoring proxy pools.

Project description

Pharox Core

Python Versions PyPI Version CI Status License Code style: ruff Docs

The foundational Python toolkit for building robust proxy management systems.

pharox provides pure, domain-agnostic business logic for managing the entire lifecycle of network proxies. The library is designed as a reusable dependency for any Python application that needs to acquire, lease, and monitor proxies without inheriting opinionated service architecture.


Key Features

  • Proxy Leasing System: A powerful system to "lease" proxies to consumers, with support for exclusive, shared (concurrent), and unlimited usage.
  • Pluggable Storage: A clean interface (IStorage) that decouples the core logic from the database, allowing you to "plug in" any storage backend (e.g., in-memory, PostgreSQL, MongoDB).
  • Health Checking Toolkit: A protocol-aware HealthChecker with configurable options for HTTP, HTTPS, and SOCKS proxies.
  • Modern & Type-Safe: Built with Python 3.10+, Pydantic v2, and a 100% type-annotated codebase.
  • Toolkit, Not a Framework: Provides focused utilities that can be embedded inside your own scripts, workers, or services without imposing a runtime.

Installation

You can install pharox directly from PyPI:

pip install pharox

Need the SQL adapter tooling? Install the optional extras:

pip install 'pharox[postgres]'
# or, if you're hacking on the repo:
poetry install --extras postgres

Quickstart Example

Here is a simple example of how to use pharox with the default InMemoryStorage to acquire and release a proxy.

from pharox import (
    InMemoryStorage,
    Proxy,
    ProxyManager,
    ProxyPool,
    ProxyStatus,
)

# 1. Setup the storage and manager
storage = InMemoryStorage()
manager = ProxyManager(storage=storage)

# 2. Seed the storage with necessary data for the example
# In a real application, you would load this from your database.

# The manager uses a "default" consumer if none is specified and will
# auto-register it in the storage when first needed.

# Create a pool and a proxy
pool = ProxyPool(name="latam-residential")
storage.add_pool(pool)

proxy = Proxy(
    host="1.1.1.1",
    port=8080,
    protocol="http",
    pool_id=pool.id,
    status=ProxyStatus.ACTIVE,
)
storage.add_proxy(proxy)

# 3. Acquire a proxy from the pool (without specifying a consumer)
print(f"Attempting to acquire a proxy from pool '{pool.name}'...")
lease = manager.acquire_proxy(pool_name=pool.name, duration_seconds=60)

if lease:
    leased_proxy = storage.get_proxy_by_id(lease.proxy_id)
    print(f"Success! Leased proxy: {leased_proxy.host}:{leased_proxy.port}")
    print(f"Lease acquired by consumer ID: {lease.consumer_id}")

    # ... do some work with the proxy ...

    # 4. Release the lease when done
    print("\nReleasing the lease...")
    manager.release_proxy(lease)
    print("Lease released.")

    proxy_after_release = storage.get_proxy_by_id(lease.proxy_id)
    print(f"Proxy lease count after release: {proxy_after_release.current_leases}")
else:
    print("Failed to acquire a proxy. None available.")

If your worker needs to wait for capacity, call manager.acquire_proxy_with_retry(...) (or the manager.with_retrying_lease context manager) to add exponential backoff without scattering custom loops throughout your codebase.

Filtering and Geospatial Matching

ProxyFilters let you target proxies by provider metadata or geographic proximity. The storage layer handles the matching logic, including radius-based searches using latitude and longitude.

from pharox import ProxyFilters

filters = ProxyFilters(
    country="AR",
    source="fast-provider",
    latitude=-34.6,
    longitude=-58.38,
    radius_km=50,
)

lease = manager.acquire_proxy(
    pool_name="latam-residential",
    consumer_name="team-madrid",
    filters=filters,
)

if lease:
    print("Got a proxy close to Buenos Aires!")

Need to mix logical clauses or add custom checks? Compose filters with any_of/all_of/none_of and an optional predicate:

from pharox import ProxyFilters

filters = ProxyFilters(
    any_of=[
        ProxyFilters(country="AR"),
        ProxyFilters(all_of=[ProxyFilters(source="andina"), ProxyFilters(country="BR")]),
    ],
    none_of=[ProxyFilters(city="forbidden")],
    predicate=lambda proxy: proxy.port >= 8000,
)

The predicate runs in Python against each candidate Proxy, so keep it fast.

Health Checks Across Protocols

Use HealthChecker to verify connectivity through HTTP, HTTPS, or SOCKS proxies. Health checks are configurable via HealthCheckOptions, letting you define target URLs, expected status codes, retry counts, and latency thresholds.

from pharox import HealthCheckOptions, HealthChecker, ProxyStatus

checker = HealthChecker()
options = HealthCheckOptions(
    target_url="https://example.com/status/204",
    expected_status_codes=[204],
    attempts=2,
    slow_threshold_ms=1500,
)

proxy = storage.get_proxy_by_id(lease.proxy_id)
health = await checker.check_proxy(proxy, options=options)

if health.status in {ProxyStatus.ACTIVE, ProxyStatus.SLOW}:
    print("Proxy ready for workloads")
else:
    print(f"Proxy inactive: {health.error_message}")

Embedding the Toolkit

pharox is intentionally agnostic about where it runs. Typical usage includes:

  • Automation scripts and workers leasing proxies with ProxyManager and performing health probes before dispatching workloads.
  • Custom services that provide APIs or dashboards on top of the toolkit by implementing the IStorage contract for their own databases.
  • Standalone applications that rely on the in-memory storage adapter for quick tasks or testing harnesses.

The in-memory adapter included with the package is great for development. For production, implement IStorage to connect the toolkit to your own persistence layer.

Examples

  • pharox.storage.postgres.PostgresStorage provides the reference PostgreSQL adapter. The accompanying examples/postgres/ directory bundles Docker Compose, schema migrations, and customization notes you can copy into your services.

PostgreSQL Adapter Quickstart

Pharox bundles a production-ready SQL adapter so you can persist pools, proxies, and leases without building storage plumbing from scratch.

  1. Install the extras

    pip install 'pharox[postgres]'
    # or
    poetry install --extras postgres
    
  2. Bring up Postgres locally

    docker compose -f examples/postgres/docker-compose.yml up -d
    psql postgresql://pharox:pharox@localhost:5439/pharox \
        -f examples/postgres/migrations/0001_init.sql
    psql postgresql://pharox:pharox@localhost:5439/pharox \
        -f examples/postgres/migrations/0002_selector_state.sql
    
  3. Use the adapter in code

    from sqlalchemy import create_engine
    
    from pharox.manager import ProxyManager
    from pharox import SelectorStrategy
    from pharox.storage.postgres import PostgresStorage
    
    engine = create_engine("postgresql+psycopg://pharox:pharox@localhost:5439/pharox")
    storage = PostgresStorage(engine=engine)
    manager = ProxyManager(storage=storage)
    lease = manager.acquire_proxy(
        pool_name="latam-residential",
        consumer_name="worker-1",
        selector=SelectorStrategy.LEAST_USED,
    )
    if lease:
        print("Got proxy", lease.proxy_id)
    
  4. Run the storage contract suite (optional)

    PHAROX_TEST_POSTGRES_URL=postgresql+psycopg://pharox:pharox@localhost:5439/pharox \
        poetry run pytest tests/test_storage_contract_postgres.py
    

Need more guidance? See the Postgres adapter walkthrough and the storage adapter cookbook.

Contributing

Contributions are welcome! Please see the CONTRIBUTING.md file for details on how to set up your development environment, run tests, and submit a pull request.

License

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pharox-0.11.0.tar.gz (41.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pharox-0.11.0-py3-none-any.whl (52.5 kB view details)

Uploaded Python 3

File details

Details for the file pharox-0.11.0.tar.gz.

File metadata

  • Download URL: pharox-0.11.0.tar.gz
  • Upload date:
  • Size: 41.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.12.13 Linux/6.17.0-1008-azure

File hashes

Hashes for pharox-0.11.0.tar.gz
Algorithm Hash digest
SHA256 3dbd984c654f0ff4a00ad2e1f681e83d29c751330342e5ec087756ab718c7e61
MD5 43f48016010176d00ca00a9d76a10906
BLAKE2b-256 ed52bf153ba05ad84fbd61ad250bb1c1c6188722788bf41ff3a9ebf7337b2f20

See more details on using hashes here.

File details

Details for the file pharox-0.11.0-py3-none-any.whl.

File metadata

  • Download URL: pharox-0.11.0-py3-none-any.whl
  • Upload date:
  • Size: 52.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.12.13 Linux/6.17.0-1008-azure

File hashes

Hashes for pharox-0.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4b7f8758d3ccb093949d0479f3fadcad963cfd160a10991103e10e27d6b9d97e
MD5 0bc68552912789717308fb29f90f4f48
BLAKE2b-256 032192ca46066f819c6386ed7d59567c845081ec481a20fc5342a3ea4cbeda60

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page