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.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_openedx_plugin_sample(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-contrib-sample/

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

Step 2: Enable Plugin

# Enable the plugin
tutor plugins enable sample

# 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 openedx_plugin_sample.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

# 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": [
                    "openedx_plugin_sample.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.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 openedx_plugin_sample; print('Success')"

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

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

# 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", "openedx_plugin_sample")

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-3.0.1.tar.gz (7.5 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-3.0.1-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file tutor_contrib_sample-3.0.1.tar.gz.

File metadata

  • Download URL: tutor_contrib_sample-3.0.1.tar.gz
  • Upload date:
  • Size: 7.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tutor_contrib_sample-3.0.1.tar.gz
Algorithm Hash digest
SHA256 c46febac5d908037b6efad68f11adf50d6c836997d9f036239257f01569f1907
MD5 39f887cf3aae5d4cc17b71333becaf70
BLAKE2b-256 76af10514f4258d8693f965aad79d3fdeca517c222d9d13e20ee49869c071a6f

See more details on using hashes here.

File details

Details for the file tutor_contrib_sample-3.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for tutor_contrib_sample-3.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8c49e45f8b7693cd3a97186f40256904963b761e3d5e351bf80845ad1dc0cb1f
MD5 63f703f9c2bea56c02c7934fad558a1a
BLAKE2b-256 8369892b6be32088715283b70be0abe2e3026d60b6f4ac0f0f3eb22efe33da96

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