pharox 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pharox-0.3.0/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 José Zacarías Flores
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
pharox-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.3
2
+ Name: pharox
3
+ Version: 0.3.0
4
+ Summary: A modern library for managing, leasing, and monitoring proxy pools.
5
+ License: MIT
6
+ Author: fzaca zaca03zaca@gmail.com
7
+ Requires-Python: >=3.10,<4.0
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Provides-Extra: socks
15
+ Requires-Dist: httpx (>=0.28.1,<0.29.0)
16
+ Requires-Dist: pydantic (>=2.11.7,<3.0.0)
17
+ Project-URL: Repository, https://github.com/fzaca/pharox
18
+ Description-Content-Type: text/markdown
19
+
20
+ # Pharox Core
21
+
22
+ [![Python Versions](https://img.shields.io/pypi/pyversions/pharox.svg)](https://pypi.org/project/pharox/)
23
+ [![PyPI Version](https://img.shields.io/pypi/v/pharox.svg)](https://pypi.org/project/pharox/)
24
+ [![CI Status](https://github.com/fzaca/pharox/actions/workflows/test.yml/badge.svg)](https://github.com/fzaca/pharox/actions/workflows/test.yml)
25
+ [![License](https://img.shields.io/pypi/l/pharox.svg)](https://github.com/fzaca/pharox/blob/main/LICENSE)
26
+ [![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
27
+ [![Docs](https://img.shields.io/badge/docs-shadcn-blue?logo=mkdocs&logoColor=white)](https://fzaca.github.io/pharox/)
28
+
29
+ The foundational Python toolkit for building robust proxy management systems.
30
+
31
+ `pharox` provides pure, domain-agnostic business logic for managing the
32
+ entire lifecycle of network proxies. The library is designed as a reusable
33
+ dependency for any Python application that needs to acquire, lease, and monitor
34
+ proxies without inheriting opinionated service architecture.
35
+
36
+ - 📚 Documentation: <https://fzaca.github.io/pharox/>
37
+
38
+ ---
39
+
40
+ ## Key Features
41
+
42
+ * **Proxy Leasing System:** A powerful system to "lease" proxies to consumers, with support for exclusive, shared (concurrent), and unlimited usage.
43
+ * **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).
44
+ * **Health Checking Toolkit:** A protocol-aware `HealthChecker` with configurable options for HTTP, HTTPS, and SOCKS proxies.
45
+ * **Modern & Type-Safe:** Built with Python 3.10+, Pydantic v2, and a 100% type-annotated codebase.
46
+ * **Toolkit, Not a Framework:** Provides focused utilities that can be embedded inside your own scripts, workers, or services without imposing a runtime.
47
+
48
+ ## Installation
49
+
50
+ You can install `pharox` directly from PyPI:
51
+
52
+ ```bash
53
+ pip install pharox
54
+ ```
55
+
56
+ ## Quickstart Example
57
+
58
+ Here is a simple example of how to use `pharox` with the default `InMemoryStorage` to acquire and release a proxy.
59
+
60
+ ```python
61
+ from pharox import (
62
+ InMemoryStorage,
63
+ Proxy,
64
+ ProxyManager,
65
+ ProxyPool,
66
+ ProxyStatus,
67
+ )
68
+
69
+ # 1. Setup the storage and manager
70
+ storage = InMemoryStorage()
71
+ manager = ProxyManager(storage=storage)
72
+
73
+ # 2. Seed the storage with necessary data for the example
74
+ # In a real application, you would load this from your database.
75
+
76
+ # The manager uses a "default" consumer if none is specified and will
77
+ # auto-register it in the storage when first needed.
78
+
79
+ # Create a pool and a proxy
80
+ pool = ProxyPool(name="latam-residential")
81
+ storage.add_pool(pool)
82
+
83
+ proxy = Proxy(
84
+ host="1.1.1.1",
85
+ port=8080,
86
+ protocol="http",
87
+ pool_id=pool.id,
88
+ status=ProxyStatus.ACTIVE,
89
+ )
90
+ storage.add_proxy(proxy)
91
+
92
+ # 3. Acquire a proxy from the pool (without specifying a consumer)
93
+ print(f"Attempting to acquire a proxy from pool '{pool.name}'...")
94
+ lease = manager.acquire_proxy(pool_name=pool.name, duration_seconds=60)
95
+
96
+ if lease:
97
+ leased_proxy = storage.get_proxy_by_id(lease.proxy_id)
98
+ print(f"Success! Leased proxy: {leased_proxy.host}:{leased_proxy.port}")
99
+ print(f"Lease acquired by consumer ID: {lease.consumer_id}")
100
+
101
+ # ... do some work with the proxy ...
102
+
103
+ # 4. Release the lease when done
104
+ print("\nReleasing the lease...")
105
+ manager.release_proxy(lease)
106
+ print("Lease released.")
107
+
108
+ proxy_after_release = storage.get_proxy_by_id(lease.proxy_id)
109
+ print(f"Proxy lease count after release: {proxy_after_release.current_leases}")
110
+ else:
111
+ print("Failed to acquire a proxy. None available.")
112
+ ```
113
+
114
+ ### Filtering and Geospatial Matching
115
+
116
+ `ProxyFilters` let you target proxies by provider metadata or geographic
117
+ proximity. The storage layer handles the matching logic, including radius-based
118
+ searches using latitude and longitude.
119
+
120
+ ```python
121
+ from pharox import ProxyFilters
122
+
123
+ filters = ProxyFilters(
124
+ country="AR",
125
+ source="fast-provider",
126
+ latitude=-34.6,
127
+ longitude=-58.38,
128
+ radius_km=50,
129
+ )
130
+
131
+ lease = manager.acquire_proxy(
132
+ pool_name="latam-residential",
133
+ consumer_name="team-madrid",
134
+ filters=filters,
135
+ )
136
+
137
+ if lease:
138
+ print("Got a proxy close to Buenos Aires!")
139
+ ```
140
+
141
+ ### Health Checks Across Protocols
142
+
143
+ Use `HealthChecker` to verify connectivity through HTTP, HTTPS, or SOCKS proxies.
144
+ Health checks are configurable via `HealthCheckOptions`, letting you define
145
+ target URLs, expected status codes, retry counts, and latency thresholds.
146
+
147
+ ```python
148
+ from pharox import HealthCheckOptions, HealthChecker, ProxyStatus
149
+
150
+ checker = HealthChecker()
151
+ options = HealthCheckOptions(
152
+ target_url="https://example.com/status/204",
153
+ expected_status_codes=[204],
154
+ attempts=2,
155
+ slow_threshold_ms=1500,
156
+ )
157
+
158
+ proxy = storage.get_proxy_by_id(lease.proxy_id)
159
+ health = await checker.check_proxy(proxy, options=options)
160
+
161
+ if health.status in {ProxyStatus.ACTIVE, ProxyStatus.SLOW}:
162
+ print("Proxy ready for workloads")
163
+ else:
164
+ print(f"Proxy inactive: {health.error_message}")
165
+ ```
166
+
167
+ ## Embedding the Toolkit
168
+
169
+ `pharox` is intentionally agnostic about where it runs. Typical usage
170
+ includes:
171
+
172
+ * **Automation scripts and workers** leasing proxies with `ProxyManager` and
173
+ performing health probes before dispatching workloads.
174
+ * **Custom services** that provide APIs or dashboards on top of the toolkit by
175
+ implementing the `IStorage` contract for their own databases.
176
+ * **Standalone applications** that rely on the in-memory storage adapter for
177
+ quick tasks or testing harnesses.
178
+
179
+ The in-memory adapter included with the package is great for development. For
180
+ production, implement `IStorage` to connect the toolkit to your own persistence
181
+ layer.
182
+
183
+ ## Contributing
184
+
185
+ 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.
186
+
187
+ ## License
188
+
189
+ This project is licensed under the MIT License - see the `LICENSE` file for details.
190
+
pharox-0.3.0/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # Pharox Core
2
+
3
+ [![Python Versions](https://img.shields.io/pypi/pyversions/pharox.svg)](https://pypi.org/project/pharox/)
4
+ [![PyPI Version](https://img.shields.io/pypi/v/pharox.svg)](https://pypi.org/project/pharox/)
5
+ [![CI Status](https://github.com/fzaca/pharox/actions/workflows/test.yml/badge.svg)](https://github.com/fzaca/pharox/actions/workflows/test.yml)
6
+ [![License](https://img.shields.io/pypi/l/pharox.svg)](https://github.com/fzaca/pharox/blob/main/LICENSE)
7
+ [![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
8
+ [![Docs](https://img.shields.io/badge/docs-shadcn-blue?logo=mkdocs&logoColor=white)](https://fzaca.github.io/pharox/)
9
+
10
+ The foundational Python toolkit for building robust proxy management systems.
11
+
12
+ `pharox` provides pure, domain-agnostic business logic for managing the
13
+ entire lifecycle of network proxies. The library is designed as a reusable
14
+ dependency for any Python application that needs to acquire, lease, and monitor
15
+ proxies without inheriting opinionated service architecture.
16
+
17
+ - 📚 Documentation: <https://fzaca.github.io/pharox/>
18
+
19
+ ---
20
+
21
+ ## Key Features
22
+
23
+ * **Proxy Leasing System:** A powerful system to "lease" proxies to consumers, with support for exclusive, shared (concurrent), and unlimited usage.
24
+ * **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).
25
+ * **Health Checking Toolkit:** A protocol-aware `HealthChecker` with configurable options for HTTP, HTTPS, and SOCKS proxies.
26
+ * **Modern & Type-Safe:** Built with Python 3.10+, Pydantic v2, and a 100% type-annotated codebase.
27
+ * **Toolkit, Not a Framework:** Provides focused utilities that can be embedded inside your own scripts, workers, or services without imposing a runtime.
28
+
29
+ ## Installation
30
+
31
+ You can install `pharox` directly from PyPI:
32
+
33
+ ```bash
34
+ pip install pharox
35
+ ```
36
+
37
+ ## Quickstart Example
38
+
39
+ Here is a simple example of how to use `pharox` with the default `InMemoryStorage` to acquire and release a proxy.
40
+
41
+ ```python
42
+ from pharox import (
43
+ InMemoryStorage,
44
+ Proxy,
45
+ ProxyManager,
46
+ ProxyPool,
47
+ ProxyStatus,
48
+ )
49
+
50
+ # 1. Setup the storage and manager
51
+ storage = InMemoryStorage()
52
+ manager = ProxyManager(storage=storage)
53
+
54
+ # 2. Seed the storage with necessary data for the example
55
+ # In a real application, you would load this from your database.
56
+
57
+ # The manager uses a "default" consumer if none is specified and will
58
+ # auto-register it in the storage when first needed.
59
+
60
+ # Create a pool and a proxy
61
+ pool = ProxyPool(name="latam-residential")
62
+ storage.add_pool(pool)
63
+
64
+ proxy = Proxy(
65
+ host="1.1.1.1",
66
+ port=8080,
67
+ protocol="http",
68
+ pool_id=pool.id,
69
+ status=ProxyStatus.ACTIVE,
70
+ )
71
+ storage.add_proxy(proxy)
72
+
73
+ # 3. Acquire a proxy from the pool (without specifying a consumer)
74
+ print(f"Attempting to acquire a proxy from pool '{pool.name}'...")
75
+ lease = manager.acquire_proxy(pool_name=pool.name, duration_seconds=60)
76
+
77
+ if lease:
78
+ leased_proxy = storage.get_proxy_by_id(lease.proxy_id)
79
+ print(f"Success! Leased proxy: {leased_proxy.host}:{leased_proxy.port}")
80
+ print(f"Lease acquired by consumer ID: {lease.consumer_id}")
81
+
82
+ # ... do some work with the proxy ...
83
+
84
+ # 4. Release the lease when done
85
+ print("\nReleasing the lease...")
86
+ manager.release_proxy(lease)
87
+ print("Lease released.")
88
+
89
+ proxy_after_release = storage.get_proxy_by_id(lease.proxy_id)
90
+ print(f"Proxy lease count after release: {proxy_after_release.current_leases}")
91
+ else:
92
+ print("Failed to acquire a proxy. None available.")
93
+ ```
94
+
95
+ ### Filtering and Geospatial Matching
96
+
97
+ `ProxyFilters` let you target proxies by provider metadata or geographic
98
+ proximity. The storage layer handles the matching logic, including radius-based
99
+ searches using latitude and longitude.
100
+
101
+ ```python
102
+ from pharox import ProxyFilters
103
+
104
+ filters = ProxyFilters(
105
+ country="AR",
106
+ source="fast-provider",
107
+ latitude=-34.6,
108
+ longitude=-58.38,
109
+ radius_km=50,
110
+ )
111
+
112
+ lease = manager.acquire_proxy(
113
+ pool_name="latam-residential",
114
+ consumer_name="team-madrid",
115
+ filters=filters,
116
+ )
117
+
118
+ if lease:
119
+ print("Got a proxy close to Buenos Aires!")
120
+ ```
121
+
122
+ ### Health Checks Across Protocols
123
+
124
+ Use `HealthChecker` to verify connectivity through HTTP, HTTPS, or SOCKS proxies.
125
+ Health checks are configurable via `HealthCheckOptions`, letting you define
126
+ target URLs, expected status codes, retry counts, and latency thresholds.
127
+
128
+ ```python
129
+ from pharox import HealthCheckOptions, HealthChecker, ProxyStatus
130
+
131
+ checker = HealthChecker()
132
+ options = HealthCheckOptions(
133
+ target_url="https://example.com/status/204",
134
+ expected_status_codes=[204],
135
+ attempts=2,
136
+ slow_threshold_ms=1500,
137
+ )
138
+
139
+ proxy = storage.get_proxy_by_id(lease.proxy_id)
140
+ health = await checker.check_proxy(proxy, options=options)
141
+
142
+ if health.status in {ProxyStatus.ACTIVE, ProxyStatus.SLOW}:
143
+ print("Proxy ready for workloads")
144
+ else:
145
+ print(f"Proxy inactive: {health.error_message}")
146
+ ```
147
+
148
+ ## Embedding the Toolkit
149
+
150
+ `pharox` is intentionally agnostic about where it runs. Typical usage
151
+ includes:
152
+
153
+ * **Automation scripts and workers** leasing proxies with `ProxyManager` and
154
+ performing health probes before dispatching workloads.
155
+ * **Custom services** that provide APIs or dashboards on top of the toolkit by
156
+ implementing the `IStorage` contract for their own databases.
157
+ * **Standalone applications** that rely on the in-memory storage adapter for
158
+ quick tasks or testing harnesses.
159
+
160
+ The in-memory adapter included with the package is great for development. For
161
+ production, implement `IStorage` to connect the toolkit to your own persistence
162
+ layer.
163
+
164
+ ## Contributing
165
+
166
+ 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.
167
+
168
+ ## License
169
+
170
+ This project is licensed under the MIT License - see the `LICENSE` file for details.
@@ -0,0 +1,73 @@
1
+ [tool.poetry]
2
+ name = "pharox"
3
+ version = "0.3.0"
4
+ description = "A modern library for managing, leasing, and monitoring proxy pools."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ repository = "https://github.com/fzaca/pharox"
8
+ packages = [{ include = "pharox", from = "src" }]
9
+ authors = ["fzaca zaca03zaca@gmail.com"]
10
+
11
+ [tool.poetry.dependencies]
12
+ python = "^3.10"
13
+ pydantic = "^2.11.7"
14
+ httpx = "^0.28.1"
15
+
16
+ [tool.poetry.extras]
17
+ socks = ["httpx-socks"]
18
+
19
+ [tool.poetry.group.dev.dependencies]
20
+ pytest = "^7.4"
21
+ pytest-mock = "^3.10.0"
22
+ pytest-asyncio = "^0.21.0"
23
+ pytest-cov = "^4.1"
24
+ ruff = "^0.1.6"
25
+ pre-commit = "^3.5"
26
+ mypy = "^1.7"
27
+ commitizen = "^4.8.3"
28
+ ipdb = "^0.13.10"
29
+ mkdocs = "^1.6.1"
30
+ mkdocs-shadcn = "^0.5.1"
31
+
32
+ [tool.ruff]
33
+ line-length = 88
34
+ select = [
35
+ "E", # pycodestyle errors
36
+ "W", # pycodestyle warnings
37
+ "F", # pyflakes
38
+ "I", # isort
39
+ "B", # flake8-bugbear
40
+ "C4", # flake8-comprehensions
41
+ "D", # pydocstyle
42
+ ]
43
+ ignore = [
44
+ "D203", # Conflicts with D211
45
+ "D212", # Conflicts with D213
46
+ "D100", # Missing docstring in public module
47
+ "D104", # Missing docstring in public package
48
+ "D107", # Missing docstring in __init__
49
+ ]
50
+ [tool.ruff.pydocstyle]
51
+ convention = "numpy"
52
+
53
+ [tool.ruff.isort]
54
+ known-first-party = ["pharox"]
55
+
56
+ [tool.pytest.ini_options]
57
+ minversion = "7.0"
58
+ addopts = "-ra -q --cov=src/pharox --cov-report=term-missing"
59
+ testpaths = ["tests"]
60
+
61
+ [tool.mypy]
62
+ ignore_missing_imports = true
63
+ disallow_untyped_defs = true
64
+
65
+ [build-system]
66
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
67
+ build-backend = "poetry.core.masonry.api"
68
+
69
+ [tool.commitizen]
70
+ name = "cz_conventional_commits"
71
+ version_provider = "poetry"
72
+ update_changelog_on_bump = true
73
+ major_version_zero = true
@@ -0,0 +1,45 @@
1
+ """Public exports for the Pharox proxy management toolkit."""
2
+
3
+ from .health import HealthChecker, HealthCheckOrchestrator
4
+ from .manager import ProxyManager
5
+ from .models import (
6
+ Consumer,
7
+ HealthCheckOptions,
8
+ HealthCheckResult,
9
+ Lease,
10
+ LeaseStatus,
11
+ Proxy,
12
+ ProxyCredentials,
13
+ ProxyFilters,
14
+ ProxyPool,
15
+ ProxyProtocol,
16
+ ProxyStatus,
17
+ )
18
+ from .storage import InMemoryStorage, IStorage
19
+ from .utils import (
20
+ bootstrap_consumer,
21
+ bootstrap_pool,
22
+ bootstrap_proxy,
23
+ )
24
+
25
+ __all__ = [
26
+ "Consumer",
27
+ "HealthCheckOrchestrator",
28
+ "HealthChecker",
29
+ "HealthCheckOptions",
30
+ "HealthCheckResult",
31
+ "IStorage",
32
+ "InMemoryStorage",
33
+ "Lease",
34
+ "LeaseStatus",
35
+ "Proxy",
36
+ "ProxyCredentials",
37
+ "ProxyFilters",
38
+ "ProxyManager",
39
+ "ProxyPool",
40
+ "ProxyProtocol",
41
+ "ProxyStatus",
42
+ "bootstrap_consumer",
43
+ "bootstrap_pool",
44
+ "bootstrap_proxy",
45
+ ]