Thank you for your interest in contributing to PARTs WebAPI! This document provides guidelines and best practices for contributing to this project.
- Python 3.11 or higher
- Poetry (for dependency management) - See Poetry Setup Guide
- Git
-
Clone the repository:
git clone https://github.com/3492PARTs/PARTs_WebAPI.git cd PARTs_WebAPI -
Install dependencies:
poetry install --with dev
π Need help with Poetry? See our Poetry Setup Guide for detailed instructions on:
- Installing Poetry
- Understanding dependency groups
- Common commands and troubleshooting
-
Set up environment variables:
cp .env.example .env # Edit .env with your configuration -
Run migrations:
cd src python manage.py migrate -
Run tests to ensure everything works:
cd .. # Back to root poetry run pytest
git checkout -b feature/your-feature-nameUse descriptive branch names:
feature/add-user-export- for new featuresbugfix/fix-login-issue- for bug fixesrefactor/improve-views- for refactoringdocs/update-readme- for documentation
- Follow PEP 8 style guide for Python code
- Use 4 spaces for indentation (not tabs)
- Maximum line length: 100 characters
- Use meaningful variable and function names
- Add docstrings to all public functions and classes
- See DJANGO_BEST_PRACTICES.md for detailed guidelines
- Always use explicit imports (no
from module import *) - Add
app_nameto allurls.pyfiles - Name all URL patterns for easy reversal
- Write tests for new functionality
- Update documentation when changing behavior
All new features must include tests. We maintain high test coverage.
# tests/your_app/test_your_feature.py
import pytest
from rest_framework.test import APIClient
@pytest.mark.django_db
def test_your_feature(api_client, test_user):
"""Test description of what this tests."""
api_client.force_authenticate(user=test_user)
response = api_client.get('/api/endpoint/')
assert response.status_code == 200Before committing, ensure all tests pass:
# Run all tests
poetry run pytest
# Run specific test file
poetry run pytest tests/user/test_views.py
# Run with coverage report
poetry run pytest --cov=src --cov-report=term-missingWrite clear, descriptive commit messages:
git add .
git commit -m "Add user export functionality
- Add export view and serializer
- Add tests for export functionality
- Update documentation"Commit Message Guidelines:
- Use present tense ("Add feature" not "Added feature")
- First line: brief summary (50 chars or less)
- Blank line
- Detailed description (if needed)
- Reference issues: "Fixes #123" or "Related to #456"
git push origin feature/your-feature-nameThen create a Pull Request on GitHub with:
- Clear title describing the change
- Description of what changed and why
- Reference to related issues
- Screenshots (if UI changes)
- Code follows project conventions and best practices
- Tests are included and passing
- Documentation is updated
- No security vulnerabilities introduced
- Performance considerations addressed
- Code is maintainable and readable
- Be open to constructive criticism
- Address all review comments
- Ask questions if feedback is unclear
- Update PR based on feedback
- Re-request review when ready
-
Create the app:
cd src python manage.py startapp app_name -
Follow the structure:
app_name/ βββ __init__.py βββ admin.py # Django admin configuration βββ apps.py # App configuration βββ models.py # Data models βββ serializers.py # DRF serializers βββ urls.py # URL patterns βββ views.py # View logic βββ util.py # Helper functions (optional) βββ migrations/ # Database migrations -
Add to INSTALLED_APPS:
# src/parts_webapi/settings/base.py INSTALLED_APPS = [ # ... "app_name.apps.AppNameConfig", ]
-
Create URL configuration:
# src/app_name/urls.py from django.urls import path from .views import MyView app_name = "app_name" urlpatterns = [ path('endpoint/', MyView.as_view(), name='endpoint'), ]
-
Register URLs:
# src/parts_webapi/urls.py urlpatterns = [ # ... path("app_name/", include("app_name.urls")), ]
-
Create tests directory:
mkdir tests/app_name touch tests/app_name/test_views.py
When adding new API endpoints:
-
Define the model (if needed):
# app_name/models.py from django.db import models class MyModel(models.Model): name = models.CharField(max_length=255) created_at = models.DateTimeField(auto_now_add=True)
-
Create serializer:
# app_name/serializers.py from rest_framework import serializers from .models import MyModel class MyModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel fields = ['id', 'name', 'created_at'] read_only_fields = ['id', 'created_at']
-
Create view:
# app_name/views.py from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from rest_framework_simplejwt.authentication import JWTAuthentication class MyView(APIView): """API endpoint for managing MyModel objects.""" authentication_classes = (JWTAuthentication,) permission_classes = (IsAuthenticated,) def get(self, request): """List all MyModel objects.""" # Implementation pass
-
Write tests:
# tests/app_name/test_views.py import pytest @pytest.mark.django_db def test_myview_get(api_client, test_user): """Test MyView GET endpoint.""" api_client.force_authenticate(user=test_user) response = api_client.get('/app_name/endpoint/') assert response.status_code == 200
- Unit Tests: Test individual functions/methods
- Integration Tests: Test multiple components together
- API Tests: Test API endpoints end-to-end
Use fixtures from tests/conftest.py:
@pytest.mark.django_db
def test_with_user(test_user, api_client):
"""test_user and api_client are fixtures."""
api_client.force_authenticate(user=test_user)
# Your test codeAlways mock external services (Cloudinary, email, Discord):
def test_with_mock(mocker):
mock_send = mocker.patch('general.send_message.send_email')
# Your test code
mock_send.assert_called_once()- API keys
- Passwords
- Database credentials
- Secret keys
Use environment variables instead!
- Use serializer validation
- Sanitize data before database operations
- Validate file uploads
Always check user permissions:
from general.security import has_access
if not has_access(request.user.id, "admin"):
return Response({"error": "Permission denied"}, status=403)- Add docstrings to all public functions and classes
- Use type hints where appropriate
- Comment complex logic
Update API documentation when:
- Adding new endpoints
- Changing endpoint behavior
- Modifying request/response format
Update README.md when:
- Changing setup process
- Adding new dependencies
- Modifying deployment process
- Create an issue on GitHub
- Contact team lead
- Check existing documentation
- Poetry Setup Guide - Dependency management guide
- Django Documentation
- Django REST Framework
- Project Best Practices
- Testing Guide
- Test Organization
- Documentation Index
By contributing to PARTs WebAPI, you agree that your contributions will be licensed under the same license as the project.
Your contributions help make PARTs WebAPI better for everyone. Thank you for taking the time to contribute!