Skip to main content

Tutor plugin for the Open edX Sample Plugin

Project description

Tutor Plugin Configuration Guide

This directory contains Tutor plugin configuration for easy deployment of both backend and frontend plugins in a Tutor-based Open edX deployment.

Table of Contents

Overview

This Tutor plugin simplifies the deployment of the sample plugin by:

  • Backend Integration: Automatically installs the Django app plugin
  • Frontend Integration: Configures MFE slots for the custom components
  • Environment Setup: Handles configuration across different deployment environments
  • Dependency Management: Ensures all required packages are installed

What is Tutor?: Tutor is the official Docker-based deployment method for Open edX, providing simple commands for installation, configuration, and maintenance.

Official Documentation:

Plugin Configuration

File: sample_plugin.py

Current Configuration

The current configuration demonstrates basic Tutor plugin structure:

from tutormfe.hooks import PLUGIN_SLOTS

PLUGIN_SLOTS.add_items([
    # Replace the course_list
    (
        "learner-dashboard",
        "custom_course_list",
        """
        {
          op: PLUGIN_OPERATIONS.Insert,
          type: DIRECT_PLUGIN,
          priority: 50,
          RenderWidget: CourseList
        }"""
    ),
])

Note: The current implementation is a basic template. For full functionality, this needs to be expanded with proper backend installation and frontend package management.

Complete Plugin Structure

A fully functional Tutor plugin should include:

from tutor import hooks

# Plugin metadata
__version__ = "1.0.0"

# Backend plugin installation
@hooks.Filters.IMAGES_BUILD_MOUNTS.add()
def _mount_sample_plugin(mounts):
    """Mount the sample plugin source code for development."""
    mounts.append(("sample-plugin-backend", "/openedx/sample-plugin-backend"))
    return mounts

@hooks.Filters.LMS_ENV.add()
@hooks.Filters.CMS_ENV.add()
def _add_plugin_settings(env):
    """Add plugin-specific environment variables."""
    env["SAMPLE_PLUGIN_ENABLED"] = True
    return env

# Install backend plugin
@hooks.Filters.IMAGES_BUILD.add()
def _install_backend_plugin(build_config):
    """Install the backend plugin during image build."""
    build_config.add_dockerfile_commands(
        "RUN pip install -e /openedx/sample-plugin-backend"
    )
    return build_config

# Frontend plugin configuration  
from tutormfe.hooks import PLUGIN_SLOTS

PLUGIN_SLOTS.add_items([
    (
        "learner-dashboard",
        "course_list_slot", 
        """
        {
          op: PLUGIN_OPERATIONS.Replace,
          widget: {
            id: 'custom_course_list',
            type: DIRECT_PLUGIN,
            priority: 50,
            RenderWidget: CourseList
          }
        }"""
    ),
])

Installation Steps

Prerequisites

  1. Tutor Installation: Follow Tutor installation guide
  2. Plugin Source: Have the sample plugin source code available
  3. Tutor MFE Plugin: Install tutor-mfe plugin if customizing frontend

Step 1: Install Tutor Plugin

# Method 1: Install from local directory
pip install -e /path/to/sample-plugin/tutor/

# Method 2: Copy plugin file (simpler for development)
mkdir -p "$(tutor plugins printroot)"
cp sample_plugin.py "$(tutor plugins printroot)/sample_plugin.py"

Step 2: Enable Plugin

# Enable the plugin
tutor plugins enable sample_plugin

# Verify plugin is enabled
tutor plugins list

Step 3: Deploy Backend Plugin

# For development deployment
tutor dev launch

# For production deployment  
tutor local launch

Step 4: Configure Frontend (if using MFE customization)

# If using tutor-mfe plugin for frontend customization
tutor plugins enable mfe
tutor local launch

Step 5: Verify Installation

# Check backend plugin
tutor dev exec lms python manage.py shell -c "from sample_plugin.models import CourseArchiveStatus; print('Backend plugin loaded')"

# Check frontend plugin (visit learner dashboard in browser)
# Should see custom course list with archive functionality

Development vs Production

Development Mode

Characteristics:

  • Uses tutor dev commands
  • Mounts source code for live editing
  • Faster iteration cycles
  • Debug logging enabled

Setup Pattern:

# Mount backend plugin source
tutor dev mount /path/to/sample-plugin/backend:/openedx/sample-plugin-backend

# Start development environment
tutor dev launch

# Install plugin in development mode
tutor dev exec lms pip install -e ../sample-plugin-backend
tutor dev exec lms python manage.py migrate
tutor dev restart lms

Production Mode

Characteristics:

  • Uses tutor local commands
  • Builds plugins into Docker images
  • Optimized for performance
  • Production logging levels

Setup Pattern:

# Enable plugin
tutor plugins enable sample_plugin

# Build and deploy
tutor local launch

Key Differences

Aspect Development Production
Installation pip install -e (editable) Built into image
Code Changes Live reload Requires rebuild
Performance Slower (debug mode) Optimized
Database SQLite/development DB Production database
Logging Verbose Production level

Configuration Options

Backend Plugin Configuration

# In tutor plugin
@hooks.Filters.LMS_ENV.add()
def _add_backend_settings(env):
    """Configure backend plugin settings."""
    env.update({
        # Plugin-specific settings
        "SAMPLE_PLUGIN_API_RATE_LIMIT": "100/minute",
        "SAMPLE_PLUGIN_ARCHIVE_RETENTION": "365",
        
        # Open edX Filters configuration
        "OPEN_EDX_FILTERS_CONFIG": {
            "org.openedx.learning.course.about.render.started.v1": {
                "pipeline": [
                    "sample_plugin.pipeline.ChangeCourseAboutPageUrl"
                ],
                "fail_silently": False,
            }
        }
    })
    return env

Frontend Plugin Configuration

# Configure MFE slots
PLUGIN_SLOTS.add_items([
    (
        "learner-dashboard",      # Target MFE
        "course_list_slot",       # Slot identifier  
        """
        {
          op: PLUGIN_OPERATIONS.Replace,  // Operation type
          widget: {
            id: 'custom_course_list',     // Unique widget ID
            type: DIRECT_PLUGIN,          // Plugin type
            priority: 50,                 // Load priority
            RenderWidget: CourseList      // Component reference
          }
        }"""
    ),
])

Environment-Specific Configuration

# Different settings for different environments
@hooks.Filters.LMS_ENV.add() 
def _configure_by_environment(env):
    """Apply environment-specific configuration."""
    if env.get("TUTOR_DEV", False):
        # Development settings
        env["SAMPLE_PLUGIN_DEBUG"] = True
        env["SAMPLE_PLUGIN_API_RATE_LIMIT"] = "1000/minute"
    else:
        # Production settings
        env["SAMPLE_PLUGIN_DEBUG"] = False
        env["SAMPLE_PLUGIN_API_RATE_LIMIT"] = "60/minute"
    
    return env

Troubleshooting

Common Issues

Plugin Not Loading:

# Check if plugin is enabled
tutor plugins list

# Check plugin syntax
python -m py_compile sample_plugin.py

# Verify plugin location
tutor plugins printroot
ls -la "$(tutor plugins printroot)/"

Backend Plugin Not Installing:

# Check build logs
tutor images build lms

# Manual installation for debugging
tutor dev exec lms pip install -e ../sample-plugin-backend
tutor dev exec lms python -c "import sample_plugin; print('Success')"

# Check migrations
tutor dev exec lms python manage.py showmigrations sample_plugin

Frontend Plugin Not Appearing:

# Check MFE configuration
tutor dev exec learner-dashboard env | grep PLUGIN

# Verify plugin slots
tutor dev logs learner-dashboard

# Check browser console for JavaScript errors

Settings Not Applied:

# Check environment variables
tutor dev exec lms env | grep SAMPLE_PLUGIN

# Verify Django settings
tutor dev exec lms python manage.py shell -c "from django.conf import settings; print(getattr(settings, 'SAMPLE_PLUGIN_DEBUG', 'Not set'))"

Debug Commands

# View plugin configuration
tutor plugins show sample_plugin

# Check generated configuration
tutor config printvalue PLUGINS

# Inspect environment variables  
tutor dev exec lms env | grep -E "(SAMPLE_PLUGIN|OPEN_EDX)"

# Check plugin installation
tutor dev exec lms pip list | grep sample

# View logs
tutor dev logs lms
tutor dev logs learner-dashboard

Getting Help

  1. Tutor Documentation: Plugin Development Guide
  2. Community: Tutor Community Forum
  3. GitHub: Tutor Repository Issues

Advanced Configuration

Multi-MFE Plugin Configuration

# Configure multiple MFEs
PLUGIN_SLOTS.add_items([
    # Learner Dashboard
    (
        "learner-dashboard",
        "course_list_slot",
        """{ /* CourseList configuration */ }"""
    ),
    
    # Course Authoring (if applicable)
    (
        "course-authoring", 
        "course_outline_slot",
        """{ /* Course outline customization */ }"""
    ),
])

Custom Image Building

@hooks.Filters.IMAGES_BUILD.add()
def _build_custom_image(build_config):
    """Build custom image with additional dependencies."""
    
    # Add system packages
    build_config.add_dockerfile_commands(
        "RUN apt-get update && apt-get install -y your-package"
    )
    
    # Install Python packages
    build_config.add_dockerfile_commands(
        "RUN pip install your-python-package"
    )
    
    # Copy additional files
    build_config.add_dockerfile_commands(
        "COPY custom-config.yml /openedx/config/"
    )
    
    return build_config

Database Migrations

@hooks.Actions.LMS_READY.add()
@hooks.Actions.CMS_READY.add() 
def _run_plugin_migrations():
    """Run plugin migrations when platform is ready."""
    from django.core.management import call_command
    call_command("migrate", "sample_plugin")

Plugin Dependencies

# In setup.py or pyproject.toml for your Tutor plugin
dependencies = [
    "tutor>=15.0.0",
    "tutor-mfe",  # If using MFE customization
]

Environment Validation

@hooks.Filters.CONFIG_UNIQUE.add()
def _validate_plugin_config(config):
    """Validate plugin configuration."""
    
    # Check required settings
    if not config.get("SAMPLE_PLUGIN_API_KEY"):
        raise ValueError("SAMPLE_PLUGIN_API_KEY is required")
    
    # Validate setting values
    rate_limit = config.get("SAMPLE_PLUGIN_API_RATE_LIMIT", "60/minute")
    if not re.match(r"^\d+/(minute|hour|day)$", rate_limit):
        raise ValueError(f"Invalid rate limit format: {rate_limit}")
    
    return config

This Tutor plugin configuration provides a foundation for deploying the sample plugin in production Open edX environments. The modular approach allows you to adapt the configuration for different deployment scenarios while maintaining consistency across environments.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tutor_contrib_sample_plugin-1.4.0.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tutor_contrib_sample_plugin-1.4.0-py3-none-any.whl (7.1 kB view details)

Uploaded Python 3

File details

Details for the file tutor_contrib_sample_plugin-1.4.0.tar.gz.

File metadata

File hashes

Hashes for tutor_contrib_sample_plugin-1.4.0.tar.gz
Algorithm Hash digest
SHA256 d4fe4d647dd04f7f052786024adf923b8b5b9a96d4f0d0532b40f5ecf46240c0
MD5 23593bff75f94a5c179000c7d4644bf2
BLAKE2b-256 1a1c27c88af6767f22d1a0c1a89133bf7dcc7ceb717c72fcc58d4b03f1d2cf48

See more details on using hashes here.

File details

Details for the file tutor_contrib_sample_plugin-1.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for tutor_contrib_sample_plugin-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 496153e722bca6e1c714a89e48142672c31f1d95ea7ac3c9cab5ed28c0920e5f
MD5 42c2f4ce09ce5f2b6fed340b91300005
BLAKE2b-256 71ccef602151ec54f74e1de27818b5b8c3d0e1ac065540162e3526d2f5114ede

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page