Thank you for your interest in contributing to RFP Analyzer! This document provides guidelines and information for contributors.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Coding Standards
- Testing
- Submitting Changes
- Reporting Issues
This project adheres to a code of conduct. By participating, you are expected to uphold this code. Please be respectful and inclusive in all interactions.
Before contributing, ensure you have:
- Python 3.13 or higher
- UV package manager
- Azure CLI
- An Azure subscription with appropriate services
- Git
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR-USERNAME/rfp-analyzer.git cd rfp-analyzer - Add the upstream remote:
git remote add upstream https://github.com/ORIGINAL-ORG/rfp-analyzer.git
cd app
uv synccp .env.example .env
# Edit .env with your Azure credentialsaz loginuv run streamlit run main.pyThe application will be available at http://localhost:8501
uv run streamlit run main.py --server.runOnSave trueUse descriptive branch names following this convention:
feature/- New features (e.g.,feature/export-pdf)fix/- Bug fixes (e.g.,fix/scoring-calculation)docs/- Documentation updates (e.g.,docs/api-reference)refactor/- Code refactoring (e.g.,refactor/agent-structure)test/- Test additions/updates (e.g.,test/comparison-agent)
# Ensure you're on main and up to date
git checkout main
git pull upstream main
# Create your feature branch
git checkout -b feature/your-feature-name- Write clear, concise commit messages
- Use present tense ("Add feature" not "Added feature")
- Reference issues when applicable (
Fixes #123)
Example commit messages:
Add PDF export functionality for evaluation reports
- Implement WeasyPrint integration for PDF generation
- Add CSS styling for professional output
- Include table formatting and charts
Fixes #45
We follow PEP 8 with the following tools:
# Format code
uv run ruff format .
# Check for linting issues
uv run ruff check .
# Fix auto-fixable issues
uv run ruff check . --fixfrom typing import List, Optional
from pydantic import BaseModel, Field
class EvaluationResult(BaseModel):
"""Result of a proposal evaluation.
Attributes:
vendor_name: Name of the vendor being evaluated
total_score: Overall weighted score (0-100)
recommendations: List of actionable recommendations
"""
vendor_name: str = Field(description="Name of the vendor")
total_score: float = Field(ge=0, le=100, description="Total score")
recommendations: List[str] = Field(default_factory=list)
def get_grade(self) -> str:
"""Calculate letter grade from total score.
Returns:
Letter grade (A, B, C, D, or F)
"""
if self.total_score >= 90:
return "A"
elif self.total_score >= 80:
return "B"
elif self.total_score >= 70:
return "C"
elif self.total_score >= 60:
return "D"
return "F"- Use docstrings for all public modules, classes, and functions
- Follow Google-style docstrings
- Include type hints in function signatures
- Document exceptions that may be raised
When adding new files, follow the existing structure:
app/
├── main.py # Streamlit application
├── services/
│ ├── __init__.py
│ ├── document_processor.py # Document handling
│ ├── scoring_agent_v2.py # Scoring agents
│ ├── comparison_agent.py # Comparison agent
│ └── your_new_service.py # New services go here
└── tests/
├── __init__.py
├── test_scoring_agent.py
└── test_your_service.py # Tests for your service
cd app
uv run pytestuv run pytest --cov=services --cov-report=html- Place tests in the
app/tests/directory - Use descriptive test names that explain what is being tested
- Include both positive and negative test cases
- Mock external services (Azure AI) in unit tests
Example test:
import pytest
from services.scoring_agent_v2 import CriteriaExtractionAgent, ExtractedCriteria
class TestCriteriaExtractionAgent:
"""Tests for the Criteria Extraction Agent."""
def test_weights_sum_to_100(self, sample_criteria: ExtractedCriteria):
"""Verify that all criteria weights sum to 100%."""
total_weight = sum(c.weight for c in sample_criteria.criteria)
assert abs(total_weight - 100.0) < 0.01, f"Weights sum to {total_weight}, expected 100"
def test_criterion_has_required_fields(self, sample_criteria: ExtractedCriteria):
"""Verify each criterion has all required fields populated."""
for criterion in sample_criteria.criteria:
assert criterion.criterion_id, "Criterion ID is required"
assert criterion.name, "Criterion name is required"
assert criterion.weight > 0, "Criterion weight must be positive"-
Update your branch with the latest upstream changes:
git fetch upstream git rebase upstream/main
-
Push your changes to your fork:
git push origin feature/your-feature-name
-
Create a Pull Request on GitHub:
- Use a descriptive title
- Fill out the PR template
- Reference any related issues
Before submitting, ensure:
- Code follows the project's style guidelines
- All tests pass locally
- New functionality includes tests
- Documentation is updated (if applicable)
- Commit messages are clear and descriptive
- Branch is up to date with main
## Description
Brief description of the changes made.
## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation update
## How Has This Been Tested?
Describe the tests you ran to verify your changes.
## Related Issues
Fixes #(issue number)
## Checklist
- [ ] My code follows the style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have added tests that prove my fix/feature works
- [ ] New and existing tests pass locally- A maintainer will review your PR
- Address any feedback or requested changes
- Once approved, your PR will be merged
- Delete your feature branch after merge
When reporting bugs, include:
- Description: Clear description of the bug
- Steps to Reproduce: Detailed steps to reproduce the issue
- Expected Behavior: What you expected to happen
- Actual Behavior: What actually happened
- Environment:
- Python version
- OS
- Browser (if applicable)
- Azure service versions
- Screenshots/Logs: If applicable
For feature requests, include:
- Problem Statement: What problem does this solve?
- Proposed Solution: Your suggested implementation
- Alternatives Considered: Other approaches you've thought of
- Additional Context: Any other relevant information
If you have questions about contributing, feel free to:
- Open a GitHub Discussion
- Review existing issues and PRs for context
- Check the Architecture Documentation
Thank you for contributing to RFP Analyzer! 🎉