Thank you for your interest in contributing to AsyncPlatform! This guide will help you get started with contributing to the project.
- Code of Conduct
- Getting Started
- Development Setup
- Development Workflow
- Project Architecture
- Code Standards
- Testing
- Documentation
- Submitting Changes
- Release Process
This project adheres to a code of conduct that promotes a welcoming and inclusive environment. Please be respectful and professional in all interactions.
- Python 3.10 or higher (we test on 3.10, 3.11, 3.12)
- uv package manager
- Git
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/your-username/asyncplatform.git cd asyncplatform - Add the upstream repository:
git remote add upstream https://github.com/itential/asyncplatform.git
# Install all dependencies including development tools
uv sync
# Verify installation
uv run python --version
uv run pytest --versionInstall pre-commit hooks to automatically check code quality:
uv run pre-commit installThis will run linting, formatting, and security checks before each commit.
devel- Main development branchfeature/your-feature- Feature branchesfix/issue-description- Bug fix branchessecurity/security-improvement- Security-related changes
git checkout devel
git pull upstream devel
git checkout -b feature/your-feature-name- Make your changes in small, logical commits
- Follow the code standards
- Add or update tests as needed
- Update documentation if required
- Run the development checks frequently
# Run all linting checks
uv run ruff check src/asyncplatform tests
# Auto-format code
uv run ruff format src/asyncplatform tests
# Auto-fix linting issues where possible
uv run ruff check --fix src/asyncplatform tests
# Run tests
uv run pytest tests
# Run tests with coverage
uv run pytest --cov=src/asyncplatform --cov-report=term --cov-report=html tests/
# Run security analysis
uv run bandit -r src/asyncplatform --configfile pyproject.toml
# Run type checking
uv run mypy src/asyncplatform# Test specific Python version
uv run --python 3.10 pytest tests
uv run --python 3.11 pytest tests
uv run --python 3.12 pytest tests
# Test all supported versions
for version in 3.10 3.11 3.12; do
echo "Testing Python $version"
uv run --python $version pytest tests
doneAsyncPlatform uses a plugin-based architecture for organizing code:
- Located in
src/asyncplatform/services/ - Each service provides functionality for specific Itential Platform APIs
- Services inherit from
ServiceBasewhich provides HTTP method helpers - Services are automatically loaded and attached to the client instance
- Example:
client.automation_studio.get_projects()
- Located in
src/asyncplatform/resources/ - Resources combine multiple services to provide high-level operations
- Resources inherit from
ResourceBaseand have access to all services - Resources are loaded on-demand using
client.resource("name") - Example:
client.resource("projects").importer(...)
Contextclass provides shared state between services- Includes the underlying ipsdk client connection
- Provides async-safe caching with TTL support
- Context is properly cleaned up on client close
Loaderclass handles dynamic module loading with caching- Thread-safe for asyncio (single-threaded event loop) applications
- Not thread-safe for multi-threaded environments
- Follow PEP 8 for Python code style
- Use Black-compatible formatting (88 character line length)
- Code is automatically formatted using Ruff
- Linting: We use Ruff with comprehensive rule sets
- Type Hints: All public APIs must include type hints using Python 3.10+ syntax
- Use
from __future__ import annotationsat the top of all modules - Prefer
str | NoneoverOptional[str] - Prefer
dict,list,tupleovertyping.Dict,List,Tuple
- Use
- Docstrings: Use Google-style docstrings for all public functions and classes
- Security: All code is scanned with Bandit and Ruff security rules
- Async Code: This is an async library - follow asyncio best practices
- Error Handling: Always use
raise ... from excto preserve exception context
All Python files must include the GPL-3.0 license header:
# Copyright (c) 2025 Itential, Inc
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotationsdef example_function(param1: str, param2: int = 10) -> bool:
"""Brief description of what the function does.
Longer description if needed, explaining the function's behavior,
usage patterns, or important considerations.
Args:
param1: Description of the first parameter.
param2: Description of the second parameter with default value.
Returns:
Description of the return value and its type.
Raises:
ValueError: When param1 is invalid.
ConnectionError: When unable to connect to the server.
Example:
>>> result = example_function("test", 20)
>>> print(result)
True
"""- Follow the import order: standard library, third-party, local
- Use absolute imports
- One import per line
- Always include
from __future__ import annotationsas the first import
from __future__ import annotations
# Standard library
from pathlib import Path
from typing import Any
# Third-party
import ipsdk
# Local
from asyncplatform import exceptions
from asyncplatform.context import Context- Tests are located in the
tests/directory - Test files follow the pattern
test_<module>.py - Each module should have comprehensive test coverage
import pytest
import asyncplatform
@pytest.mark.asyncio
async def test_client_initialization():
"""Test basic client initialization."""
cfg = {
"host": "test.example.com",
"user": "test_user",
"password": "test_pass"
}
async with asyncplatform.client(**cfg) as client:
assert client is not None
@pytest.mark.asyncio
async def test_service_loading():
"""Test that services are loaded correctly."""
cfg = {
"host": "test.example.com",
"user": "test_user",
"password": "test_pass"
}
async with asyncplatform.client(**cfg) as client:
assert hasattr(client, "automation_studio")
assert hasattr(client, "authorization")- High test coverage is required
- All new code must include tests
- Tests should cover both success and failure scenarios
- Tests should cover edge cases and error conditions
- Use mocks appropriately for external dependencies
# Run all tests
uv run pytest tests
# Run specific test file
uv run pytest tests/unit/test_loader.py
# Run specific test function
uv run pytest tests/unit/test_loader.py::TestLoaderInitialization::test_loader_init_with_valid_path
# Run with verbose output
uv run pytest -v tests
# Run with coverage reporting
uv run pytest --cov=src/asyncplatform --cov-report=term tests
# Run async tests specifically
uv run pytest -m asyncio tests- All public APIs must have docstrings
- Use Google-style docstrings
- Include examples in docstrings where helpful
- Document all parameters, return values, and exceptions
- Update README.md if your changes affect:
- Installation instructions
- Usage examples
- API changes
- New features
- The project uses conventional commits for automatic changelog generation
- Changelog is generated automatically using git-cliff
- Use descriptive commit messages following the conventional format:
feat:for new featuresfix:for bug fixesdocs:for documentation changestest:for test improvementsci:for CI/CD changesrefactor:for code refactoring
- Ensure all tests pass:
uv run pytest tests - Run linting:
uv run ruff check src/asyncplatform tests - Run type checking:
uv run mypy src/asyncplatform - Format code:
uv run ruff format src/asyncplatform tests - Update documentation if needed
- Write descriptive commit messages
-
Push your feature branch to your fork:
git push origin feature/your-feature-name
-
Create a pull request against the
develbranch -
Fill out the pull request template with:
- Clear description of changes
- Testing performed
- Any breaking changes
- Related issues
- All tests must pass
- All linting checks must pass
- Type checking must pass
- Code must be properly formatted
- At least one maintainer approval required
- All conversations must be resolved
Use conventional commit format:
type(scope): description
Longer explanation if needed.
- List any breaking changes
- Reference related issues
- Uses Semantic Versioning
- Version is automatically determined from git tags using uv-dynamic-versioning
- Format:
v<major>.<minor>.<patch>(e.g.,v1.0.0)
Releases are managed by project maintainers:
- Ensure all tests pass and code quality checks succeed
- Update CHANGELOG.md if needed
- Create and push a version tag:
git tag v1.0.0 git push upstream v1.0.0
To test the build process locally:
# Build distribution packages
uv run python -m build
# Verify the build artifacts
ls -l dist/- Create an issue for bugs or feature requests
- Use discussions for questions and community interaction
- Follow the security policy for security-related issues
If you encounter issues with the development environment:
- Ensure you have the latest version of uv
- Try cleaning and reinstalling dependencies:
rm -rf .venv uv sync
- Check that all required Python versions are available
- Verify pre-commit hooks are installed
Thank you for contributing to AsyncPlatform! Your contributions help make the project better for everyone.