Thank you for your interest in contributing to PlotSenseAI! 🎉
We welcome contributions of all kinds: bug fixes, new features, documentation improvements, and more.
- Code of Conduct
- Getting Started
- Development Workflow
- Coding Standards
- Testing Requirements
- Pull Request Process
- Commit Message Guidelines
- Issue Guidelines
Be respectful and inclusive. We're all here to learn and build something great together.
💡 Tip: We recommend using uv for dependency management. It's 10-100x faster than pip and provides better dependency resolution. All commands below show both uv and pip options.
# Fork the repository on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/PlotSenseAI.git
cd PlotSenseAIPython Backend:
Using uv (Recommended - 10-100x faster):
# Install uv if not already installed
# Visit https://docs.astral.sh/uv/getting-started/installation/
# Or run: curl -LsSf https://astral.sh/uv/install.sh | sh
# Sync all dependencies including dev extras
uv sync --all-extras
# Activate the virtual environment
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate
# Install pre-commit hooks
uv run pre-commit installUsing pip (Traditional):
# Create virtual environment
python -m venv venv
# Activate it
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate
# Install in editable mode with dev dependencies
pip install -e .
pip install pytest pytest-cov pytest-mock flake8 autopep8 pre-commit bandit
# Install pre-commit hooks
pre-commit installFrontend (Optional):
cd web
npm install# Create a .env file
echo "GROQ_API_KEY=your-api-key-here" > .envGet your free API key from Groq Cloud.
We use the following branch structure:
main- Production-ready codedev- Active development branchfeature/<feature-name>- New featuresfix/<bug-name>- Bug fixesdocs/<doc-name>- Documentation updates
# Make sure you're on dev and up to date
git checkout dev
git pull origin dev
# Create your feature branch
git checkout -b feature/your-feature-name- Write your code following our coding standards
- Add tests for new functionality
- Run tests to ensure everything works
- Update documentation if needed
- Commit your changes with descriptive messages
We follow PEP 8 with some modifications:
- Line length: 150 characters (configured in
setup.cfg) - Docstrings: Use Google-style docstrings
- Type hints: Add type hints to function signatures
- Imports: Organize imports (stdlib, third-party, local)
Example:
from typing import Optional
import pandas as pd
from plotsense.module import helper
def process_dataframe(
df: pd.DataFrame,
column: str,
threshold: Optional[float] = None
) -> pd.DataFrame:
"""
Process DataFrame by filtering on a column.
Args:
df: Input DataFrame to process.
column: Column name to filter on.
threshold: Optional threshold value for filtering.
Returns:
Filtered DataFrame.
Raises:
ValueError: If column doesn't exist in DataFrame.
"""
if column not in df.columns:
raise ValueError(f"Column '{column}' not found")
# Implementation
return df- Follow ESLint rules (configured in
web/eslint.config.js) - Use functional components with TypeScript
- Prefer const over let
- Use meaningful variable names
Example:
import { useState } from 'react';
interface Props {
title: string;
onAction: () => void;
}
export function Component({ title, onAction }: Props) {
const [isActive, setIsActive] = useState(false);
return (
<div>
<h1>{title}</h1>
<button onClick={onAction}>Click me</button>
</div>
);
}All PRs must include tests. We use pytest.
Using uv:
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=plotsense --cov-report=html
# Run specific test file
uv run pytest test/test_plotgen.py
# Run specific test
uv run pytest test/test_plotgen.py::TestPlotFunctions::test_create_scatter
# Run by marker
uv run pytest -m unit # Unit tests only
uv run pytest -m "not slow" # Skip slow testsUsing pip/pytest directly:
# Run all tests
pytest
# Run with coverage
pytest --cov=plotsense --cov-report=html
# Run specific test file
pytest test/test_plotgen.py
# Run specific test
pytest test/test_plotgen.py::TestPlotFunctions::test_create_scatter
# Run by marker
pytest -m unit # Unit tests only
pytest -m "not slow" # Skip slow testsimport pytest
from plotsense import plotgen
class TestYourFeature:
"""Test suite for your feature."""
@pytest.mark.unit
def test_basic_functionality(self, sample_dataframe):
"""Test that basic functionality works."""
result = your_function(sample_dataframe)
assert result is not None
def test_error_handling(self):
"""Test that errors are raised appropriately."""
with pytest.raises(ValueError):
your_function(invalid_input)Use fixtures from test/conftest.py:
sample_dataframe: Standard 100-row DataFramesmall_dataframe: 20-row DataFramelarge_dataframe: 1000-row DataFramemock_groq_client: Mocked API client
- Minimum: 70% line and branch coverage
- Target: 80%+ for new code
- PRs that decrease coverage may be rejected
Component tests are required for UI changes.
cd web
# Run tests
npm test
# Run with coverage
npm run test:coverage
# Run with UI
npm run test:uiimport { describe, it, expect } from 'vitest'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { YourComponent } from './YourComponent'
describe('YourComponent', () => {
it('should render correctly', () => {
render(<YourComponent title="Test" />)
expect(screen.getByText('Test')).toBeInTheDocument()
})
it('should handle user interaction', async () => {
const user = userEvent.setup()
const handleClick = vi.fn()
render(<YourComponent onClick={handleClick} />)
await user.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
})Before committing, ensure:
Using uv:
# Pre-commit hooks pass
uv run pre-commit run --all-files
# Python linting
uv run flake8 plotsense
# Python security
uv run bandit -r plotsense
# Tests pass
uv run pytest -v
# Frontend (if applicable)
cd web
npm run lint
npx tsc --noEmit
npm testUsing pip:
# Pre-commit hooks pass
pre-commit run --all-files
# Python linting
flake8 plotsense
# Python security
bandit -r plotsense
# Tests pass
pytest -v
# Frontend (if applicable)
cd web
npm run lint
npx tsc --noEmit
npm test- All tests pass locally
- Code follows style guidelines
- Documentation is updated
- Commit messages follow conventions
- Branch is up to date with
dev
- Push your branch to GitHub
- Open a Pull Request against
dev(notmain) - Fill out the PR template completely
- Link related issues
- Request review from maintainers
- CI/CD checks must pass
- At least one maintainer review required
- Address all review comments
- Maintain a respectful dialogue
- Squash commits if requested
- Ensure final tests pass
- Maintainer will merge to
dev - Feature will be included in next release
We follow Conventional Commits.
<type>(<scope>): <subject>
<body>
<footer>
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting, no logic change)
- refactor: Code refactoring
- perf: Performance improvements
- test: Adding/updating tests
- build: Build system changes
- ci: CI/CD changes
- chore: Maintenance tasks
# Good commit messages
feat(recommender): add support for time series data
fix(plotgen): handle NaN values in scatter plots
docs(testing): update pytest configuration guide
test(explainer): add edge case tests for empty plots
# Bad commit messages
update code
fix bug
changes
wip- Use present tense ("add feature" not "added feature")
- Use imperative mood ("move cursor to..." not "moves cursor to...")
- Keep subject line under 72 characters
- Reference issues and PRs in footer: "Closes #123"
- Search existing issues to avoid duplicates
- Check if it's already fixed in
devbranch - Gather all relevant information
Use the bug report template and include:
- Clear description
- Steps to reproduce
- Expected vs actual behavior
- Full error traceback
- Environment details
- Minimal reproducible example
Use the feature request template and include:
- Problem statement
- Proposed solution
- Example usage
- Benefits
- Alternatives considered
Use the question template for:
- Usage questions
- Clarification requests
- Best practices discussions
Using uv:
# Stop on first failure
uv run pytest -x
# Show print statements
uv run pytest -s
# Verbose output
uv run pytest -vvUsing pip:
# Stop on first failure
pytest -x
# Show print statements
pytest -s
# Verbose output
pytest -vvUsing uv:
# Drop into debugger on failure
uv run pytest --pdb
# Show local variables
uv run pytest -lUsing pip:
# Drop into debugger on failure
pytest --pdb
# Show local variables
pytest -lUsing uv:
# Generate HTML coverage report
uv run pytest --cov=plotsense --cov-report=html
# Open htmlcov/index.html in browser
# Show missing lines
uv run pytest --cov=plotsense --cov-report=term-missingUsing pip:
# Generate HTML coverage report
pytest --cov=plotsense --cov-report=html
# Open htmlcov/index.html in browser
# Show missing lines
pytest --cov=plotsense --cov-report=term-missingUsing uv:
# Auto-fix Python formatting issues
uv run autopep8 --in-place --recursive plotsense/
# Auto-fix frontend issues
cd web && npm run lint -- --fixUsing pip:
# Auto-fix Python formatting issues
autopep8 --in-place --recursive plotsense/
# Auto-fix frontend issues
cd web && npm run lint -- --fix- Questions: Open a question issue or discussion
- Bugs: Open a bug report
- Feature Ideas: Open a feature request
- Chat:
Contributors will be:
- Listed in project contributors
- Mentioned in release notes
- Given credit in relevant documentation
Thank you for contributing to PlotSenseAI! 🚀
For detailed testing documentation, see TESTING.md.