๐ ๏ธ Development Guide¶
This guide covers everything you need to contribute to Pyvider or set up a development environment for building providers.
๐ค AI-Generated Content
This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.
๐ Prerequisites¶
- Python 3.11 or higher
- Git
- Make (optional but recommended)
- Docker (for integration testing)
๐ Quick Setup¶
# Clone the repository
git clone https://github.com/provide-io/pyvider.git
cd pyvider
# Set up development environment with uv
uv sync
# Verify installation
uv run pyvider --version
uv run pytest --version
uv run ruff --version
๐ Project Structure¶
pyvider/
โโโ src/
โ โโโ pyvider/
โ โโโ __init__.py # Namespace package
โ โโโ capabilities/ # Capability system
โ โโโ cli/ # Command-line interface
โ โโโ common/ # Shared utilities
โ โโโ conversion/ # Type conversion layer
โ โโโ data_sources/ # Data source base classes
โ โโโ ephemerals/ # Ephemeral resource support
โ โโโ exceptions/ # Custom exceptions
โ โโโ functions/ # Provider functions
โ โโโ hub/ # Component registry
โ โโโ protocols/ # Protocol implementation
โ โ โโโ tfprotov6/ # Terraform Protocol v6
โ โโโ providers/ # Provider base classes
โ โโโ resources/ # Resource base classes
โ โโโ schema/ # Schema system
โโโ tests/ # Test suite
โ โโโ unit/ # Unit tests
โ โโโ integration/ # Integration tests
โ โโโ fixtures/ # Test fixtures
โโโ docs/ # Documentation
โโโ examples/ # Example providers
โโโ scripts/ # Build and utility scripts
โโโ pyproject.toml # Project configuration
โโโ README.md # Project README
๐งช Testing¶
Running Tests¶
# Run all tests
pytest
# Run with coverage
pytest --cov=pyvider --cov-report=html
# Run specific test file
pytest tests/test_resources.py
# Run specific test
pytest tests/test_resources.py::test_create_resource
# Run tests in parallel
pytest -n auto
# Run only unit tests
pytest tests/unit/
# Run only integration tests
pytest tests/integration/
Test Categories¶
- Unit Tests: Fast, isolated tests for individual components
- Integration Tests: Test component interactions
- Protocol Tests: Verify protocol implementation
- E2E Tests: Full provider testing with Terraform
Writing Tests¶
# tests/test_my_resource.py
import pytest
from pyvider.resources.context import ResourceContext
from my_provider.resources import MyResource
class TestMyResource:
"""Test suite for MyResource."""
@pytest.fixture
def resource(self) -> MyResource:
return MyResource()
async def test_create_resource(self, resource):
"""Test resource creation."""
ctx = ResourceContext(
config=MyResource.Config(name="test-resource", size=10)
)
state, _ = await resource._create_apply(ctx)
assert state is not None
assert state.id is not None
assert state.name == "test-resource"
async def test_read_missing_resource(self, resource):
"""Test reading non-existent resource."""
ctx = ResourceContext(state=MyResource.State(id="missing", name="", size=0))
assert await resource.read(ctx) is None
Test Fixtures¶
# tests/conftest.py
import pytest
from pyvider.hub import ComponentHub
@pytest.fixture
async def hub():
"""Provide a fresh component hub."""
hub = ComponentHub()
await hub.discover_all()
return hub
@pytest.fixture
def mock_provider():
"""Provide a mock provider instance."""
from tests.mocks import MockProvider
return MockProvider()
๐ Code Quality¶
Linting¶
# Run linter
ruff check
# Auto-fix issues
ruff check --fix
# Format code
ruff format
# Check formatting
ruff format --check
Type Checking¶
# Run mypy
mypy src/pyvider
# Run pyright
pyright
# Type check specific module
mypy src/pyvider/resources
Pre-commit Hooks¶
# Install pre-commit hooks
pre-commit install
# Run hooks manually
pre-commit run --all-files
# Update hooks
pre-commit autoupdate
Configuration in .pre-commit-config.yaml:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.0.0
hooks:
- id: mypy
additional_dependencies: [types-all]
๐๏ธ Building¶
Build Distribution¶
# Build wheel and sdist
python -m build
# Output in dist/
# - pyvider-1.0.0-py3-none-any.whl
# - pyvider-1.0.0.tar.gz
Build Provider Binary¶
# Build with flavor
python scripts/build_provider.py
# Creates standalone binary
# - terraform-provider-pyvider
๐ Development Workflow¶
1. Create Feature Branch¶
2. Make Changes¶
Follow the coding standards:
# Good: Clear, typed, documented
from pyvider.resources import BaseResource
from pyvider.schema import Attribute
import attrs
@register_resource("my_resource")
class MyResource(BaseResource):
"""Manages my custom resource.
This resource provides...
"""
@attrs.define
class Config:
"""Resource configuration."""
name: str = Attribute(
required=True,
description="Resource name"
)
3. Test Your Changes¶
4. Update Documentation¶
5. Commit Changes¶
# Stage changes
git add .
# Commit with descriptive message
git commit -m "feat: add support for custom resources
- Implement BaseCustomResource class
- Add validation for custom attributes
- Update documentation"
6. Push and Create PR¶
๐ Debugging¶
Enable Debug Logging¶
# Set environment variables
export PYVIDER_LOG_LEVEL=DEBUG
export FOUNDATION_LOG_LEVEL=DEBUG
# Run with debug output
pyvider provide --debug
Using Python Debugger¶
# Add breakpoint in code
import pdb; pdb.set_trace()
# Or use breakpoint() in Python 3.7+
breakpoint()
VS Code Debugging¶
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Pyvider",
"type": "python",
"request": "launch",
"module": "pyvider.cli",
"args": ["provide", "--debug"],
"env": {
"PYVIDER_LOG_LEVEL": "DEBUG"
}
},
{
"name": "Debug Tests",
"type": "python",
"request": "launch",
"module": "pytest",
"args": ["-xvs", "${file}"]
}
]
}
Performance Profiling¶
# Profile with cProfile
python -m cProfile -o profile.stats myscript.py
# Analyze with snakeviz
snakeviz profile.stats
# Memory profiling with memray
memray run -o output.bin python myscript.py
memray flamegraph output.bin
๐ง Environment Variables¶
Development Variables¶
| Variable | Description | Default |
|---|---|---|
PYVIDER_LOG_LEVEL |
Logging level | INFO |
PYVIDER_PLUGIN_DIR |
Plugin directory | ~/.terraform.d/plugins |
PYVIDER_PROFILE |
Enable profiling | 0 |
PYVIDER_DEBUG_GRPC |
Debug gRPC calls | 0 |
FOUNDATION_LOG_LEVEL |
Foundation log level | INFO |
FOUNDATION_LOG_FORMAT |
Log format | console |
Testing Variables¶
| Variable | Description | Default |
|---|---|---|
PYTEST_TIMEOUT |
Test timeout | 300 |
PYTEST_PARALLEL |
Parallel workers | auto |
COVERAGE_THRESHOLD |
Min coverage % | 80 |
๐ฆ Dependencies¶
Core Dependencies¶
attrs>=25.1.0- Class definitionsgrpcio>=1.73.0- gRPC communicationcryptography>=42.0.8- State encryptionprovide-foundation- Logging frameworkpyvider-cty>=0.0.113- CTY type systempyvider-rpcplugin>=0.0.112- RPC plugin support
Development Dependencies¶
pytest>=8.3.0- Testing frameworkpytest-asyncio>=0.25.0- Async test supportpytest-cov>=6.0.0- Coverage reportingmypy>=1.9.0- Type checkingruff>=0.9.0- Linting and formattinghypothesis>=6.131.0- Property testing
๐ข Release Process¶
Version Bumping¶
# Update version in pyproject.toml
# version = "1.2.3"
# Update CHANGELOG.md
# Add release notes
# Commit version bump
git commit -m "chore: bump version to 1.2.3"
git tag v1.2.3
Publishing¶
# Build distributions
python -m build
# Upload to TestPyPI (optional)
twine upload --repository testpypi dist/*
# Upload to PyPI
twine upload dist/*
๐ค Contributing Guidelines¶
Code Style¶
- Use type hints everywhere
- Add docstrings to all public functions/classes
- Follow PEP 8 (enforced by ruff)
- Use modern Python features (3.11+)
Commit Messages¶
Follow conventional commits:
feat:- New featurefix:- Bug fixdocs:- Documentationtest:- Testingrefactor:- Code refactoringchore:- Maintenance
Pull Request Process¶
- Create feature branch
- Write tests for new functionality
- Ensure all tests pass
- Update documentation
- Submit PR with description
- Address review feedback
- Squash commits before merge
๐ Useful Links¶
๐ License¶
Apache 2.0 - See LICENSE for details.
Happy coding! ๐