Thank you for your interest in contributing! This guide covers everything you need to get started.
- Python 3.11+
- uv -- Package manager (do not use pip directly)
- Node.js -- For frontend build
git clone https://github.com/etoyama/insight-blueprint.git
cd insight-blueprint
# Install all dependencies (--all-extras is REQUIRED for dev tools: ruff, ty, pytest, poe)
uv sync --all-extras
# Set up pre-commit hooks (runs lint, typecheck, and tests before each commit)
uv run pre-commit install
# Build frontend assets
poe build-frontendNote:
uv syncwithout--all-extraswill NOT install development tools. Always useuv sync --all-extrasto get the full development environment.
poe lint # Lint and format check (ruff)
poe format # Auto-fix lint issues and format
poe typecheck # Type check (ty)
poe test # Run tests (pytest)
poe all # Run lint + typecheck + test
poe build-frontend # Install deps and build frontend assets
poe ci # Run the full CI pipeline locally (Python + frontend)- Code (variables, functions, comments, docstrings): English
- Documentation: English preferred, Japanese acceptable for user-facing docs
| Element | Style | Example |
|---|---|---|
| Variables / Functions | snake_case |
user_count, calculate_total() |
| Classes | PascalCase |
AnalysisDesign |
| Constants | UPPER_SNAKE_CASE |
MAX_RETRIES |
- Simplicity first -- Readable code over clever code. Avoid over-abstraction.
- Single responsibility -- One function does one thing. Target 200-400 lines per file (max 800).
- Early return -- Use guard clauses to avoid deep nesting.
- Immutability -- Create new objects instead of mutating existing ones.
- No magic numbers -- Define constants with meaningful names.
All functions must have type annotations:
def call_api(
endpoint: str,
params: dict[str, str] | None = None,
timeout: int = 30,
) -> dict[str, Any]:
...We use ruff for both linting and formatting. Configuration is in pyproject.toml.
# Check for issues
poe lint
# Auto-fix and format
poe formatpoe test # All tests
uv run pytest tests/test_specific.py -v # Specific file
uv run pytest tests/test_specific.py::test_fn # Specific test
uv run pytest --cov=src --cov-report=term-missing # With coverageWe follow the AAA pattern (Arrange / Act / Assert):
def test_create_design_with_valid_data_returns_design():
# Arrange
data = {"title": "Analysis A", "hypothesis": "X causes Y"}
# Act
design = create_design(data)
# Assert
assert design.title == "Analysis A"
assert design.hypothesis == "X causes Y"Naming convention: test_{target}_{condition}_{expected_result}
- Target: 80% or higher
- Test categories: Happy path, boundary values, error cases, edge cases
- Speed: Unit tests should run in < 100ms each
- Mocking: Mock external dependencies (APIs, databases). Use
conftest.pyfor shared fixtures.
Before submitting code, verify:
- No hardcoded API keys, passwords, or secrets
- Sensitive values come from environment variables
-
.envfiles are not committed - External input is validated (use Pydantic models)
- SQL queries use parameterized statements (no string concatenation)
- Error messages shown to users don't expose internal details
- Logs don't contain sensitive information
feat/<short-description> # New features
fix/<short-description> # Bug fixes
docs/<short-description> # Documentation changes
refactor/<short-description> # Code refactoring
- Ensure all checks pass:
poe all
- Write or update tests for your changes
- Keep commits focused -- one logical change per commit
- Use Conventional Commits for commit messages:
feat: add catalog search filtering fix: handle empty hypothesis in validation docs: update installation instructions
- Open a pull request against
main - Fill in the PR description with what changed and why
- CI must pass before merging
- At least one approval is required
By contributing, you agree that your contributions will be licensed under the MIT License.