Thank you for your interest in contributing to bozo! This document provides guidelines and instructions for contributing.
Please read our Code of Conduct before participating in this project.
Before creating bug reports, check the issue list to avoid duplicates.
When reporting a bug, include:
- Python version (
python --version) - bozo version (
pip show bozo) - Operating system
- Steps to reproduce the issue
- Expected behavior
- Actual behavior
- Relevant log output or error messages
- Minimal reproducible example if possible
Enhancements are tracked as GitHub issues.
When suggesting an enhancement, include:
- Clear description of the enhancement
- Why it would be useful
- Examples of how it would be used
- Possible alternative implementations
We actively welcome pull requests.
To submit a PR:
- Fork the repository and create a branch from
main - Make your changes
- Run the test suite:
make test - Run linting and formatting:
make lintandmake format - Run type checking:
make type-check - Commit with clear, descriptive messages
- Push to your fork and open a pull request
- Request review from maintainers
- Python 3.13 or later
uvpackage manager (install)
# Clone the repository
git clone https://github.com/tejus3131/bozo.git
cd bozo
# Install dependencies (all dev dependencies included)
uv sync
# Activate virtual environment
source .venv/bin/activate # On Windows: .venv\Scripts\activate# Run tests
make test # Run all tests
make test-fast # Run without coverage
make test-watch # Run in watch mode
# Code quality
make lint # Check with ruff
make format # Format with black
make format-check # Check formatting
make type-check # Check types with mypy
# Run everything
make check # lint, format, type-check, test
# Clean build artifacts
make cleanOr use uv run directly:
uv run pytest tests/ -xvv
uv run ruff check src/ tests/
uv run black --check src/ tests/
uv run mypy src/- Follow PEP 8 guidelines
- Use type hints for all functions and variables
- 88-character line length (black default)
- Docstrings for public functions and classes
- Format code:
black src/ tests/ - Lint code:
ruff check src/ tests/ --fix - Type check:
mypy src/
Use clear, descriptive commit messages:
Fix: handler cleanup for resource warnings
Properly close file handlers instead of clearing the list
to prevent unclosed file ResourceWarnings.
Fixes #123
Prefixes:
feat:- New featurefix:- Bug fixdocs:- Documentationrefactor:- Code refactoringperf:- Performance improvementtest:- Test changeschore:- Build, CI, dependencies
Tests should:
- Be located in
tests/bozo/mirroring thesrc/bozo/structure - Use pytest fixtures for setup/teardown
- Have descriptive names:
test_<function>_<scenario> - Include docstrings explaining what is tested
- Aim for high coverage (target: >75%)
import pytest
import bozo
def test_setup_creates_logger():
"""Test that setup() initializes logging correctly."""
bozo.setup("test_app", enable_file=False)
log = bozo.get("test_module")
assert log is not None
@pytest.mark.asyncio
async def test_log_context_propagates():
"""Test that log context persists across async operations."""
bozo.setup("test_app", enable_file=False)
log = bozo.get(__name__)
with bozo.log_context(request_id="123"):
# Context should be present here
pass# Run all tests
uv run pytest tests/
# Run specific test file
uv run pytest tests/bozo/test_main.py
# Run with coverage
uv run pytest tests/ --cov=bozo --cov-report=html
# Run in watch mode (with pytest-watch)
uv run ptwUse Google-style docstrings:
def setup(
app_name: str,
*,
environment: Environment = Environment.DEVELOPMENT,
) -> None:
"""Setup logging with sensible defaults.
This is the main entry point for configuring bozo. Call this once
at application startup before creating any loggers.
Args:
app_name: Application name (used for log file naming).
environment: 'development' (colored) or 'production' (plain).
Example:
>>> import bozo
>>> bozo.setup("myapp")
"""README.md- Main project documentationCHANGELOG.md- Release notes and changesCONTRIBUTING.md- This filedocs/- Jekyll site (if expanded)
src/bozo/
├── _main.py # Public API functions
├── _models.py # Pydantic configuration models
├── _handlers.py # Log handler implementations
├── _formatters.py # Log formatting functions
├── _context.py # Thread-local context management
├── _state.py # Global state management
├── _types.py # Type definitions and aliases
├── _cleanup.py # Log file cleanup utilities
├── _viewer/ # Optional web viewer
│ ├── _main.py # Viewer lifecycle
│ ├── _server.py # FastAPI server
│ ├── _routes.py # API routes
│ ├── _queue.py # Bounded log queue
│ └── _reader.py # File pagination
└── __init__.py # Public API exports
- Singleton state: Global configuration via
_state.py - Thread-local context: Safe concurrent context in
_context.py - Pydantic validation: Configuration validation in
_models.py - Bounded queue: Memory-efficient viewer queue in
_viewer/_queue.py - Cursor-based pagination: Efficient file reading in
_viewer/_reader.py
When contributing:
- Avoid synchronous I/O in hot paths
- Use bounded queues for streaming features
- Profile changes with
cProfileif performance-critical - Consider memory usage in long-running applications
By contributing to bozo, you agree that your contributions will be licensed under its MIT License.
Feel free to:
- Open an issue with the
questionlabel - Start a discussion
- Contact the maintainer
Thank you for contributing! 🎉