Contributing Guide
Thank you for your interest in contributing to the Upstox TOTP Python SDK! This guide will help you get started with contributing to the project.
Getting Started
Development Setup
Fork the repository on GitHub
Clone your fork locally:
git clone https://github.com/your-username/upstox-totp.git cd upstox-totp
Install dependencies with uv:
# Install the package in development mode uv sync # Install development dependencies uv sync --group dev # Install documentation dependencies uv sync --group docs
Set up environment for testing:
# Copy example environment file cp example.env .env # Edit .env with your test credentials # (Use test/sandbox credentials, never production)
Project Structure
upstox-totp/
├── src/upstox_totp/ # Main package code
│ ├── __init__.py # Package initialization
│ ├── client.py # Main client class
│ ├── models.py # Data models
│ ├── errors.py # Exception classes
│ ├── cli.py # CLI implementation
│ └── _api/ # API modules
├── docs/ # Documentation
├── examples/ # Usage examples
├── tests/ # Test suite (to be added)
├── pyproject.toml # Project configuration
└── README.md # Main documentation
Contributing Guidelines
Code Style
We use strict coding standards to ensure consistency:
Formatting:
# Format code with black
uv run black src/
# Sort imports with isort
uv run isort src/
# Run both before committing
uv run black src/ && uv run isort src/
Type Hints:
# Always use type hints
def get_token(self, username: str) -> AccessTokenResponse:
"""Get access token for user."""
pass
# Use proper return types
from typing import Optional, List, Dict, Any
Docstrings:
def example_function(param1: str, param2: int = 10) -> bool:
"""Brief description of the function.
Args:
param1: Description of param1
param2: Description of param2, defaults to 10
Returns:
Description of return value
Raises:
ValueError: When param1 is invalid
ConfigurationError: When configuration is missing
Example:
>>> result = example_function("test", 5)
>>> print(result)
True
"""
pass
Pydantic Models
Follow Pydantic v2 best practices:
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional
class ExampleModel(BaseModel):
"""Example model with proper configuration."""
model_config = ConfigDict(
strict=True, # Enable strict mode
extra='forbid', # Forbid extra fields
validate_assignment=True, # Validate on assignment
)
# Required field with validation
id: int = Field(gt=0, description="Unique identifier")
# Optional field with default
name: Optional[str] = Field(None, max_length=100)
# Custom validation
@field_validator('name')
@classmethod
def validate_name(cls, v: Optional[str]) -> Optional[str]:
if v is not None and not v.strip():
raise ValueError('Name cannot be empty')
return v
Error Handling
Use custom exception classes:
from upstox_totp.errors import UpstoxError
class NewFeatureError(UpstoxError):
"""Raised when new feature encounters an error."""
pass
def new_feature():
try:
# Implementation
pass
except SomeException as e:
raise NewFeatureError(f"Feature failed: {e}") from e
Testing
Writing Tests
We use pytest for testing. Create tests in the tests/ directory:
# tests/test_client.py
import pytest
from unittest.mock import patch, Mock
from upstox_totp import UpstoxTOTP, ConfigurationError
class TestUpstoxTOTP:
def test_initialization_success(self):
"""Test successful client initialization."""
with patch.dict('os.environ', {
'UPSTOX_USERNAME': '9876543210',
'UPSTOX_PASSWORD': 'password',
# ... other env vars
}):
client = UpstoxTOTP()
assert client.username == '9876543210'
def test_initialization_missing_env(self):
"""Test initialization with missing environment variables."""
with patch.dict('os.environ', {}, clear=True):
with pytest.raises(ConfigurationError):
UpstoxTOTP()
@patch('requests.Session.post')
def test_token_generation_success(self, mock_post):
"""Test successful token generation."""
# Mock response
mock_response = Mock()
mock_response.status_code = 200
mock_response.json.return_value = {
'status': 'success',
'data': {
'access_token': 'test-token'
}
}
mock_post.return_value = mock_response
client = UpstoxTOTP()
response = client.app_token.get_access_token()
assert response.success
assert response.data.access_token == 'test-token'
Running Tests
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=upstox_totp
# Run specific test file
uv run pytest tests/test_client.py
# Run with verbose output
uv run pytest -v
Test Configuration
Create test fixtures:
# tests/conftest.py
import pytest
from unittest.mock import patch
from upstox_totp import UpstoxTOTP
@pytest.fixture
def mock_env():
"""Mock environment variables for testing."""
env_vars = {
'UPSTOX_USERNAME': '9876543210',
'UPSTOX_PASSWORD': 'test-password',
'UPSTOX_PIN_CODE': '1234',
'UPSTOX_TOTP_SECRET': 'JBSWY3DPEHPK3PXP',
'UPSTOX_CLIENT_ID': 'test-client-id',
'UPSTOX_CLIENT_SECRET': 'test-client-secret',
'UPSTOX_REDIRECT_URI': 'https://test.com/callback'
}
with patch.dict('os.environ', env_vars):
yield env_vars
@pytest.fixture
def upstox_client(mock_env):
"""Create UpstoxTOTP client for testing."""
return UpstoxTOTP()
Documentation
Building Documentation
# Install documentation dependencies
uv sync --group docs
# Build documentation
cd docs
make html
# View documentation
open _build/html/index.html
# Clean build
make clean
Writing Documentation
Follow these guidelines:
Use reStructuredText for documentation files
Include code examples for all features
Add docstrings to all public functions/classes
Update the changelog for user-facing changes
Example documentation:
New Feature
-----------
Description of the new feature and why it's useful.
Usage
~~~~~
.. code-block:: python
from upstox_totp import UpstoxTOTP
# Example usage
upx = UpstoxTOTP()
result = upx.new_feature()
Parameters
~~~~~~~~~~
.. list-table::
:header-rows: 1
* - Parameter
- Type
- Description
* - param1
- str
- Description of param1
Pull Request Process
Before Submitting
Ensure tests pass:
uv run pytest
Format code:
uv run black src/ uv run isort src/
Check type hints:
uv run mypy src/
Update documentation if needed
Add/update tests for new features
Pull Request Template
Use this template for pull requests:
## Description
Brief description of changes made.
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Testing
- [ ] Tests pass locally
- [ ] Added tests for new functionality
- [ ] Manual testing completed
## Documentation
- [ ] Documentation updated
- [ ] Docstrings added/updated
- [ ] Examples provided
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Code is commented where necessary
- [ ] Breaking changes are documented
Review Process
Automated checks must pass (CI/CD)
Code review by maintainers
Testing on different platforms if needed
Documentation review
Approval and merge
Types of Contributions
Bug Fixes
Create an issue first (unless it’s trivial)
Include reproduction steps
Add tests that fail before the fix
Ensure tests pass after the fix
New Features
Discuss the feature in an issue first
Follow existing patterns in the codebase
Add comprehensive tests
Include documentation
Consider backward compatibility
Documentation
Fix typos and grammar
Improve existing examples
Add new examples
Translate documentation
Improve API documentation
Performance Improvements
Benchmark before and after
Include performance tests
Document the improvement
Ensure no breaking changes
Code Review Guidelines
For Reviewers
Be constructive and helpful
Explain the “why” behind suggestions
Test the changes locally if possible
Check documentation is updated
Verify tests are adequate
For Contributors
Respond to feedback promptly
Ask questions if feedback is unclear
Make requested changes or explain why not
Keep discussions focused on the code
Be patient with the review process
Development Workflow
Git Workflow
# 1. Create feature branch
git checkout -b feature/new-feature
# 2. Make changes and commit
git add .
git commit -m "Add new feature: description"
# 3. Keep branch updated
git fetch origin
git rebase origin/master
# 4. Push branch
git push origin feature/new-feature
# 5. Create pull request on GitHub
Commit Messages
Follow conventional commits:
feat: add new token caching mechanism
fix: resolve TOTP timing issue
docs: update installation guide
test: add unit tests for client
refactor: improve error handling
style: format code with black
chore: update dependencies
Branch Naming
Use descriptive branch names:
feature/token-caching
fix/totp-timing-issue
docs/api-reference
refactor/error-handling
Release Process
Version Numbering
We follow semantic versioning (SemVer):
MAJOR.MINOR.PATCH (e.g., 1.2.3)
MAJOR: Breaking changes
MINOR: New features (backward compatible)
PATCH: Bug fixes (backward compatible)
Changelog
Update CHANGELOG.md for all releases:
## [1.1.0] - 2025-01-15
### Added
- New token caching mechanism
- Support for custom timeout values
### Fixed
- TOTP timing synchronization issue
- Memory leak in session management
### Changed
- Improved error messages
- Updated dependencies
### Deprecated
- Old configuration method (use new method)
Communication
GitHub Issues
Use GitHub issues for:
Bug reports with reproduction steps
Feature requests with use cases
Questions about usage
Documentation improvements
Discussions
Use GitHub Discussions for:
General questions about the project
Ideas for new features
Show and tell your projects using the SDK
Community support
Getting Help
If you need help contributing:
Check existing issues and documentation
Create a GitHub issue with your question
Join discussions for community help
Contact maintainers for complex issues
Resources
Useful links for contributors:
GitHub Repository: https://github.com/batpool/upstox-totp
Documentation: https://upstox-totp.readthedocs.io/
PyPI Package: https://pypi.org/project/upstox-totp/
Upstox API Docs: https://upstox.com/developer/api-documentation
Python Packaging: https://packaging.python.org/
pytest Documentation: https://docs.pytest.org/
Sphinx Documentation: https://www.sphinx-doc.org/
Code of Conduct
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. See CODE_OF_CONDUCT.md for details.
License
By contributing to this project, you agree that your contributions will be licensed under the MIT License.
Thank You!
Thank you for contributing to the Upstox TOTP Python SDK! Your contributions help make this project better for everyone. 🎉