Clone
2
Development
Eaven Kimura edited this page 2025-11-12 15:58:33 +00:00

Development

Development Environment Setup

Prerequisites

  • Python: 3.9, 3.10, or 3.11
  • Git: For version control
  • Docker: (Optional) For containerized testing
  • IDE: VS Code, PyCharm, or similar with Python support

Initial Setup

  1. Clone the repository:

    git clone https://git.serendipity.systems/k.eaven/pterodactyl-discord-bot.git
    cd pterodactyl-discord-bot
    
  2. Create virtual environment:

    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
  3. Install dependencies:

    # Production dependencies
    pip install -r requirements.txt
    
    # Development and testing dependencies
    pip install -r requirements-test.txt
    
  4. Set up pre-commit hooks (optional but recommended):

    pip install pre-commit
    pre-commit install
    
  5. Create development configuration:

    cp config.ini.example config.ini
    # Edit config.ini with your development credentials
    

Project Structure

pterodactyl-discord-bot/
├── .gitea/
│   └── workflows/
│       ├── test.yml              # Test-only CI workflow
│       ├── ci-cd.yml             # Complete CI/CD pipeline
│       └── docker-build.yml      # Docker build workflow
├── embed/
│   └── embed_locations.json     # Persistent embed tracking
├── logs/
│   └── pterodisbot.log          # Application logs
├── tests/
│   └── test_pterodisbot.py      # Test suite
├── pterodisbot.py               # Main bot application
├── server_metrics_graphs.py     # Metrics and graphing module
├── generate_config.py           # Config generator from env vars
├── requirements.txt             # Production dependencies
├── requirements-test.txt        # Testing dependencies
├── pytest.ini                   # Pytest configuration
├── Makefile                     # Development shortcuts
├── run_tests.sh                 # Test runner script
├── Dockerfile                   # Container definition
├── docker-compose.yml           # Docker Compose configuration
├── config.ini.example           # Example configuration
├── README.md                    # Application Features Documentation
└── LICENSE                      # GPL-3.0 License

Development Workflow

1. Feature Development

# Create feature branch
git checkout -b feature/your-feature-name

# Make changes and test frequently
python pterodisbot.py  # Manual testing
make test              # Automated testing

# Check code quality
make lint
make format

# Commit changes
git add .
git commit -m "feat: add your feature description"

# Push and create PR
git push origin feature/your-feature-name

2. Bug Fixes

# Create bugfix branch
git checkout -b fix/bug-description

# Write test that reproduces bug
# (in test_pterodisbot.py)

# Verify test fails
pytest test_pterodisbot.py::TestClass::test_new_bug -v

# Fix the bug
# (in pterodisbot.py or server_metrics_graphs.py)

# Verify test passes
pytest test_pterodisbot.py::TestClass::test_new_bug -v

# Run full test suite
make test

# Commit both test and fix
git add .
git commit -m "fix: resolve bug description"

3. Testing Changes

# Run all tests
make test

# Run specific test class
pytest test_pterodisbot.py::TestConfigValidation -v

# Run with coverage
make test-coverage

# Quick test (no coverage)
make test-quick

# Watch mode (requires pytest-watch)
make watch

Testing Infrastructure

Test Suite Organization

# test_pterodisbot.py structure
├── Fixtures (reusable test setup)
   ├── mock_config
   ├── mock_pterodactyl_api
   ├── sample_server_data
   ├── sample_resources_data
   └── mock_discord_interaction

├── TestConfigValidation
   ├── test_valid_config
   ├── test_missing_sections
   ├── test_invalid_api_keys
   └── test_invalid_urls

├── TestPterodactylAPI
   ├── test_initialization
   ├── test_request_success
   ├── test_request_error
   ├── test_get_servers
   ├── test_get_server_resources
   └── test_send_power_action

├── TestServerMetricsGraphs
   ├── test_add_data_point
   ├── test_data_rotation
   ├── test_cpu_scale_calculation
   ├── test_generate_graphs
   └── test_get_data_summary

├── TestServerMetricsManager
   ├── test_server_creation
   ├── test_cleanup_old_servers
   └── test_get_summary

├── TestServerStatusView
   ├── test_authorization
   └── test_button_interactions

├── TestPterodactylBot
   ├── test_embed_tracking
   ├── test_load_save_locations
   └── test_state_management

└── TestIntegration
    ├── test_complete_workflow
    └── test_metrics_collection

Running Tests Locally

# Using Makefile (recommended)
make test                 # Full test suite with coverage
make test-quick           # Fast run without coverage
make test-unit            # Only unit tests
make test-integration     # Only integration tests
make ci                   # Simulate full CI pipeline

# Using shell script
./run_tests.sh            # Interactive full test run
./run_tests.sh --quick    # Skip linting and security
./run_tests.sh --coverage-only  # Just coverage report

# Direct pytest
pytest test_pterodisbot.py -v
pytest test_pterodisbot.py::TestClass::test_method -v
pytest -m "not slow" -v   # Skip slow tests
pytest --lf               # Run last failed tests only

Coverage Goals

  • Minimum: 70% overall coverage
  • Target: 85% overall coverage
  • Critical Modules: 90%+ coverage
    • Configuration validation
    • Pterodactyl API client
    • Metrics tracking system

Viewing Coverage Reports

# Generate HTML report
make test-coverage

# Open in browser
python -m http.server --directory htmlcov 8000
# Navigate to http://localhost:8000

# Terminal report
pytest --cov=pterodisbot --cov-report=term-missing

Code Quality Standards

Linting and Formatting

# Check all quality standards
make lint

# Auto-format code
make format

# Individual tools
flake8 pterodisbot.py --max-line-length=120
pylint pterodisbot.py --max-line-length=120
black --check --line-length=120 pterodisbot.py
isort --check-only --profile black pterodisbot.py

Style Guidelines

PEP 8 Compliance:

  • Maximum line length: 120 characters
  • 4 spaces for indentation
  • Snake_case for functions and variables
  • PascalCase for classes
  • UPPER_CASE for constants

Type Hints:

def function_name(param1: str, param2: int) -> Optional[dict]:
    """Function docstring."""
    return result

Docstrings:

def complex_function(arg1: str, arg2: int) -> dict:
    """
    Brief description of function purpose.
    
    Detailed explanation of what the function does,
    including any important behavior or side effects.
    
    Args:
        arg1: Description of first argument
        arg2: Description of second argument
        
    Returns:
        Description of return value
        
    Raises:
        ValueError: When invalid input is provided
        APIError: When API request fails
    """
    pass

Comments:

  • Use comments to explain why, not what
  • Complex algorithms should have explanatory comments
  • TODO comments should include ticket references

Security Best Practices

Running Security Scans

# All security checks
make security

# Individual tools
bandit -r . -ll                    # Code security
safety check                       # Dependency vulnerabilities
pip-audit                          # Package auditing

Security Checklist

  • No hardcoded credentials in code
  • API keys stored in config.ini (gitignored)
  • All user input validated
  • SQL injection prevention (N/A - no database)
  • Rate limiting on API calls
  • Error messages don't leak sensitive info
  • Logs don't contain API keys or tokens

Debugging Tips

Logging Levels

# Add debug logging
logger.debug(f"Processing server {server_id}")

# Log important state changes
logger.info(f"Server {name} changed state to {new_state}")

# Log warnings
logger.warning(f"API rate limit approaching")

# Log errors with context
logger.error(f"Failed to update embed: {str(e)}")

Common Debugging Commands

# View logs in real-time
tail -f logs/pterodisbot.log

# Search logs for errors
grep ERROR logs/pterodisbot.log

# Run bot with verbose logging
PYTHONUNBUFFERED=1 python pterodisbot.py

# Debug specific test
pytest test_pterodisbot.py::test_name --pdb  # Drop into debugger on failure
pytest test_pterodisbot.py -vv --showlocals  # Show local variables

VS Code Launch Configuration

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Bot",
      "type": "python",
      "request": "launch",
      "program": "${workspaceFolder}/pterodisbot.py",
      "console": "integratedTerminal",
      "env": {
        "PYTHONUNBUFFERED": "1"
      }
    },
    {
      "name": "Python: Current Test",
      "type": "python",
      "request": "launch",
      "module": "pytest",
      "args": [
        "${file}",
        "-v"
      ],
      "console": "integratedTerminal"
    }
  ]
}

CI/CD Integration

Automated Workflows

The project uses Gitea Actions for continuous integration and deployment:

1. Test Workflow (.gitea/workflows/test.yml)

  • Triggers: Push to any branch, PRs to main
  • Matrix testing: Python 3.9, 3.10, 3.11
  • Steps: Lint → Test → Security Scan → Coverage Report

2. CI/CD Workflow (.gitea/workflows/ci-cd.yml)

  • Triggers: Push to main/experimental/dev, version tags, manual dispatch
  • Steps: Test → Build Docker → Push Registry → Report
  • Features: Multi-arch builds, automatic versioning

Local CI Simulation

# Run full CI pipeline locally
make ci

# This executes:
# 1. Clean previous artifacts
# 2. Install dependencies
# 3. Run all tests with coverage
# 4. Run linting checks
# 5. Run security scans
# 6. Generate reports

Branch Protection Rules

Recommended settings for main branch:

  • Require status checks to pass
    • Unit Tests (Python 3.11)
    • Code Quality
    • Security Scan
  • Require branches to be up to date
  • Require pull request reviews (1+ approvals)
  • Dismiss stale reviews on new commits

Performance Testing

# Profile the application
python -m cProfile -o profile.stats pterodisbot.py

# Analyze profile
python -m pstats profile.stats
> sort cumtime
> stats 20

# Memory profiling
pip install memory_profiler
python -m memory_profiler pterodisbot.py

Documentation

Generating API Documentation

# Install documentation tools
pip install pdoc3

# Generate HTML documentation
pdoc --html --output-dir docs pterodisbot.py server_metrics_graphs.py

# View documentation
python -m http.server --directory docs 8080

Updating Documentation

When adding new features:

  1. Update inline code comments
  2. Update function/class docstrings
  3. Update README.md if user-facing
  4. Add architecture diagrams if complex