We welcome contributions to the NUI Python Shared Utilities project! This document provides guidelines for contributing.
- Python 3.9 or higher
- Git
- Virtual environment tool (venv, virtualenv, etc.)
-
Fork the repository on GitHub
-
Clone your fork locally:
git clone https://github.com/your-username/nui-python-shared-utils.git cd nui-python-shared-utils -
Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install development dependencies:
pip install -e .[dev]
# Run all tests
pytest
# Run tests with coverage
pytest --cov=nui_shared_utils --cov-report=html
# Run specific test categories
pytest -m unit # Unit tests only
pytest -m integration # Integration tests (requires AWS access)We use several tools to maintain code quality:
# Format code
black nui_shared_utils tests
# Type checking
mypy nui_shared_utils
# Run all quality checks
make lint # If Makefile exists- Follow PEP 8 style guidelines
- Use Black for code formatting (line length: 88 characters)
- Add type hints where appropriate
- Write docstrings for all public functions and classes
- Keep functions small and focused
-
Create a new branch for your feature/fix:
git checkout -b feature/your-feature-name
-
Make your changes and ensure:
- All tests pass
- Code is properly formatted
- New functionality includes tests
- Documentation is updated
-
Commit your changes:
git commit -m "Add: brief description of your changes" -
Push to your fork:
git push origin feature/your-feature-name
-
Create a Pull Request on GitHub
- Title: Use a clear, descriptive title
- Description: Explain what your changes do and why
- Testing: Include information about how you tested your changes
Use conventional commits format:
feat:for new featuresfix:for bug fixesdocs:for documentation changestest:for test additions/changesrefactor:for code refactoringchore:for maintenance tasks
Examples:
feat: add retry decorator for database operationsfix: handle missing environment variables gracefullydocs: update configuration examples in README
When adding new utilities to the package:
- Create the module in the
nui_shared_utils/directory - Add comprehensive tests in the
tests/directory - Update
__init__.pyto export new functions/classes - Update documentation with usage examples
- Consider backward compatibility - don't break existing APIs
- Add optional dependencies to
pyproject.tomlif needed
# nui_shared_utils/my_utility.py
"""
My utility for doing something useful.
"""
from typing import Dict, Optional
import logging
log = logging.getLogger(__name__)
class MyUtility:
"""A utility that does something useful."""
def __init__(self, config: Optional[Dict] = None):
"""Initialize the utility."""
self.config = config or {}
def do_something(self, data: str) -> str:
"""
Process some data.
Args:
data: Input data to process
Returns:
Processed data
Raises:
ValueError: If data is invalid
"""
if not data:
raise ValueError("Data cannot be empty")
# Implementation here
return f"processed: {data}"- Unit tests: Test individual functions/methods in isolation
- Integration tests: Test interactions with external services
- Mock external dependencies: Use
unittest.mockfor AWS services, etc.
- Use descriptive test names that explain what is being tested
- Group related tests in classes
- Use
test_<functionality>_<condition>_<expected_result>pattern
Example:
class TestSlackClient:
def test_send_message_success_returns_true(self):
"""Test that send_message returns True on successful API call."""
# Test implementationWhen testing code that interacts with AWS services:
from moto import mock_secretsmanager
from unittest.mock import patch
@mock_secretsmanager
def test_secret_retrieval():
"""Test secret retrieval from mocked AWS Secrets Manager."""
# Use moto to mock AWS services
# Test your codeUse Google-style docstrings:
def example_function(param1: str, param2: Optional[int] = None) -> Dict[str, Any]:
"""
Brief description of what the function does.
More detailed description if needed. Explain the purpose,
behavior, and any important notes.
Args:
param1: Description of the first parameter
param2: Description of the optional second parameter
Returns:
Description of what the function returns
Raises:
ValueError: When param1 is empty
ConnectionError: When unable to connect to service
Example:
>>> result = example_function("hello")
>>> print(result)
{'status': 'success', 'data': 'hello'}
"""When adding new functionality, update the README.md with:
- Usage examples
- Configuration options
- Any new dependencies
When reporting issues:
- Search existing issues first
- Use a clear title that describes the problem
- Provide details:
- Python version
- Package version
- Steps to reproduce
- Expected vs. actual behavior
- Error messages/stack traces
- Minimal reproduction case if possible
- Be respectful and constructive in discussions
- Help others learn and grow
- Focus on the code and ideas, not the person
- When in doubt, ask questions
By contributing to this project, you agree that your contributions will be licensed under the MIT License.
If you have questions about contributing, please:
- Open an issue with the "question" label
- Check the existing documentation
- Look at similar implementations in the codebase
Thank you for contributing! 🎉