Contributing & Development Workflow
Relevant source files
The following files were used as context for generating this wiki page:
ProxyBroker2 uses a modernized asynchronous stack for proxy management and requires specific development practices to maintain production stability. This workflow ensures that all contributions follow the project's contract-based testing philosophy and strict code quality standards.
Sources: README.md:1-15, CLAUDE.md:143-152
Development Environment Setup
Poetry serves as the canonical dependency manager for this project. If you prefer uv, use it only as a runner pointing to the Poetry-managed environment to ensure compatibility with poetry.lock.
Initial Setup
- Fork the repository on GitHub.
- Clone your fork locally.
- Install dependencies by running
poetry install. - (Optional) Activate the virtual environment with
poetry shell. - Install pre-commit hooks using
pre-commit installto automate formatting during commits.
Sources: README.md:464-482, CLAUDE.md:21-35, pyproject.toml:1-50
Toolchain Configuration
The project utilizes several tools to maintain code health:
- Ruff: Handles both linting and formatting, replacing legacy tools like flake8 and isort.
- Pytest: Manages the test suite with
pytest-asynciofor asynchronous testing. - Sphinx: Generates documentation using the MyST-Parser for Markdown support.
Sources: pyproject.toml:68-100, CLAUDE.md:164-175
Development Workflow
Follow this sequence to contribute changes:
- Create a feature branch from the latest
masterbranch. - Implement your changes or bug fixes.
- Format and lint your code using Ruff.
- Run the test suite to verify behavior.
- Commit your changes using Conventional Commits.
- Push to your fork and submit a Pull Request.
Sources: README.md:484-500
Local Verification Flow
This diagram illustrates the mandatory local verification steps before submitting code.
A flowchart showing the progression from local code edits through formatting, linting, and testing before final commit and submission.
Sources: README.md:484-500, CLAUDE.md:42-45
Testing Philosophy
ProxyBroker2 implements contract-based testing. This approach protects public APIs and user-visible behavior while allowing internal implementation details to evolve without breaking tests.
What to Test
- Public API signatures: Ensure method parameters and return types remain stable.
- Protocol support: Verify compatibility for HTTP, HTTPS, and SOCKS4/5.
- Anonymity levels: Validate the logic that detects IP leaks.
- Error contracts: Confirm that appropriate exceptions (e.g.,
NoProxyError) are raised under specific conditions.
What Not to Test
- Internal algorithms: Avoid testing private methods or specific internal loops.
- Exact protocol bytes: Do not overfit tests to specific byte sequences, which allows for protocol improvements like IPv6 support.
- Provider specifics: Site-specific parsing details should be flexible as external sources change frequently.
Sources: CLAUDE.md:143-162, tests/README.md:1-50, tests/test_integration.py:202-225
Test Categories
| Category | Scope | Key Files |
|---|---|---|
| Unit Tests | Individual components (Broker, Checker, ProxyPool) | tests/test_api.py, tests/test_server.py |
| Integration | End-to-end workflows and component interaction | tests/test_integration.py |
| Error Handling | Timeout scenarios, DNS failures, malformed input | tests/test_integration.py |
| CLI Tests | Command parsing and output format verification | tests/test_cli.py |
Sources: tests/README.md:38-65
Code Standards & Requirements
Formatting and Linting
Run the following command to automatically fix linting issues and format code:
poetry run ruff check . --fix && poetry run ruff format .
Ruff is configured to enforce rules including E4, E7, E9, F, and PLW1514 (mandatory encoding for text-mode file operations).
Sources: CLAUDE.md:42-45, pyproject.toml:88-95
Commit Messages
Use the Conventional Commits format. This enables automated changelog generation and versioning.
feat: ...for new features.fix: ...for bug fixes.docs: ...for documentation changes.refactor: ...for code changes that neither fix a bug nor add a feature.
Sources: README.md:493-497, CHANGELOG.md:1-50
IPv6 Implementation Standards
When working with IP addresses, you must follow these invariants:
- Use
proxybroker.utils.canonicalize_ip(s)to convert IPs to RFC 5952 canonical form (lowercase, leading zeros stripped). - Always bracket IPv6 hosts in URIs (e.g.,
[::1]:8080) per RFC 3986. - Use
Socks5NgtrwithATYP=0x04for IPv6 destinations.
Sources: CLAUDE.md:105-125, CHANGELOG.md:15-45
Build and Release Process
The project uses pyproject.toml as the single source of truth for versioning.
Versioning Flow
The setup.py and proxybroker/__init__.py files dynamically read the version from pyproject.toml. When preparing a release:
- Update the version in
pyproject.toml. - Update
CHANGELOG.mdfollowing the "Keep a Changelog" standard. - Use
docker-build.shto build multi-platform images and push git tags.
Sources: setup.py:10-25, proxybroker/init.py:36-50, docker-build.sh:1-35
A sequence diagram showing how a developer's push triggers automated testing and how tagging leads to official releases.
Sources: README.md:15-30, docker-build.sh:20-35, readthedocs.yml:1-25
Summary
Contributing to ProxyBroker2 requires adhering to a Poetry-based environment and behavior-focused testing. All code must pass Ruff linting and Pytest validation before submission. By using Conventional Commits and canonical IP handling, developers maintain the project's production-ready status and broad protocol compatibility.