- 
                Notifications
    You must be signed in to change notification settings 
- Fork 0
Code Standards
        Garot Conklin edited this page Dec 8, 2024 
        ·
        1 revision
      
    This document outlines the coding standards and best practices for the fleXRPL Discord Bot project. Following these standards ensures consistency, maintainability, and quality across the codebase.
# pyproject.toml
[tool.black]
line-length = 88
target-version = ['py311']
include = '\.pyx?$'
extend-exclude = '''
# A regex preceded with ^/ will apply only to files and directories
# in the root of the project.
^/tests/
'''[tool.isort]
profile = "black"
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
line_length = 88# Good
user_message = "Hello"
def process_webhook_event(payload: dict) -> None:
    pass
# Bad
userMessage = "Hello"  # Not snake_case
def ProcessWebhookEvent(payload):  # Not snake_case
    pass# Good
class WebhookHandler:
    pass
class GitHubEventProcessor:
    pass
# Bad
class webhookHandler:  # Not PascalCase
    pass# Good
MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30
GITHUB_API_URL = "https://api.github.com"
# Bad
maxRetries = 3  # Not uppercase
default_timeout = 30  # Not uppercasesrc/
├── bot/
│   ├── __init__.py
│   ├── client.py
│   └── cogs/
│       ├── __init__.py
│       └── github.py
├── handlers/
│   ├── __init__.py
│   └── webhook.py
└── utils/
    ├── __init__.py
    └── formatting.py
"""
Module docstring explaining purpose and usage.
"""
# Standard library imports
import asyncio
import json
# Third-party imports
import discord
from fastapi import FastAPI
# Local imports
from bot.client import DiscordBot
from utils.formatting import format_message
# Constants
MAX_RETRIES = 3
# Classes
class WebhookHandler:
    """Class docstring."""
    pass
# Functions
def process_event(payload: dict) -> None:
    """Function docstring."""
    pass
# Main execution (if applicable)
if __name__ == "__main__":
    passdef process_webhook(
    payload: dict,
    retries: int = 3,
    timeout: float = 30.0
) -> bool:
    """
    Process incoming webhook payload with retry mechanism.
    Args:
        payload (dict): The webhook payload to process
        retries (int, optional): Number of retry attempts. Defaults to 3.
        timeout (float, optional): Timeout in seconds. Defaults to 30.0.
    Returns:
        bool: True if processing successful, False otherwise.
    Raises:
        ValueError: If payload is malformed
        TimeoutError: If processing exceeds timeout
    """
    passfrom typing import Optional, List, Dict, Union
def get_repository_events(
    repo_name: str,
    event_types: List[str],
    since: Optional[str] = None
) -> Dict[str, Union[str, List[dict]]]:
    passclass WebhookError(Exception):
    """Base exception for webhook-related errors."""
    pass
class ValidationError(WebhookError):
    """Raised when webhook payload validation fails."""
    pass
def process_webhook(payload: dict) -> None:
    try:
        validate_payload(payload)
    except ValidationError as e:
        logger.error(f"Validation failed: {e}")
        raise
    except Exception as e:
        logger.exception("Unexpected error")
        raise WebhookError(f"Processing failed: {e}") from e# test_webhook.py
import pytest
from handlers.webhook import WebhookHandler
class TestWebhookHandler:
    @pytest.fixture
    def handler(self):
        return WebhookHandler()
    def test_valid_payload(self, handler):
        """Test processing of valid webhook payload."""
        payload = {"action": "opened"}
        assert handler.process(payload) is True
    @pytest.mark.asyncio
    async def test_async_processing(self, handler):
        """Test async webhook processing."""
        passimport logging
logger = logging.getLogger(__name__)
def setup_logging():
    """Configure logging for the application."""
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )# Good
logger.info("Processing webhook payload")
logger.error("Failed to process webhook: %s", str(error))
# Bad
print("Processing webhook payload")  # Don't use print
logger.error(f"Failed to process webhook: {error}")  # Don't use f-strings in logs# Good
from os import environ
token = environ.get("DISCORD_BOT_TOKEN")
# Bad
token = "1234567890"  # Never hardcode secretsfrom typing import TypedDict
class WebhookPayload(TypedDict):
    action: str
    repository: dict
def process_webhook(payload: WebhookPayload) -> None:
    """Process webhook with validated payload."""
    if not isinstance(payload.get("action"), str):
        raise ValidationError("Invalid action type")# Good
async def process_events(events: List[dict]) -> None:
    await asyncio.gather(*[process_event(event) for event in events])
# Bad
def process_events(events: List[dict]) -> None:
    for event in events:  # Should be async
        process_event(event)# Good
async with aiohttp.ClientSession() as session:
    async with session.get(url) as response:
        data = await response.json()
# Bad
session = aiohttp.ClientSession()
response = await session.get(url)  # Session not properly managed# Good
git commit -m "feat: add webhook validation middleware"
git commit -m "fix: handle missing payload attributes"
git commit -m "docs: update webhook configuration guide"
# Bad
git commit -m "updates"  # Not descriptive
git commit -m "fixed bug"  # Not specificThis documentation is maintained by the fleXRP team.