[Python] Open edX Tutor Plugin: ModuleNotFoundError for custom OAuth2 backend despite proper...

Discussão em 'Python' iniciado por Stack, Maio 19, 2025.

  1. Stack

    Stack Membro Participativo

    I'm developing a custom Tutor plugin for Open edX that implements a WordPress OAuth2 authentication backend. Despite following the Tutor plugin development guidelines and ensuring proper installation (cf https://github.com/cookiecutter-openedx/edx-oauth2-wordpress-backend), I'm encountering a ModuleNotFoundError when Django tries to load the module.

    Here is the structure of my plugin:

    edx-oauth2-wordpress-backend/
    ├── setup.py
    ├── requirements.txt
    └── edx_oauth2_wordpress_backend/
    ├── __init__.py
    ├── plugin.py
    └── wp_oauth.py

    wp_oauth.py


    """
    Custom WordPress OAuth2 backend for Open edX.
    """
    from social_core.backends.oauth import BaseOAuth2


    class WordPressOAuth2(BaseOAuth2):
    """
    Custom WordPress OAuth2 backend for Open edX.
    This class implements the WordPress OAuth2 authentication.
    """
    name = "wordpress-oauth"

    # Base URL of your WordPress site (without trailing slash)
    BASE_URL = "https://your-wordpress-site.com"

    # OAuth endpoints
    PATH = "wp-json/moserver/"
    AUTHORIZATION_ENDPOINT = "authorize"
    TOKEN_ENDPOINT = "token"
    USERINFO_ENDPOINT = "resource"

    def get_user_details(self, response):
    """
    Extract user details from the OAuth response.
    """
    return {
    'username': response.get('username', ''),
    'email': response.get('email', ''),
    'fullname': response.get('name', ''),
    'first_name': response.get('first_name', ''),
    'last_name': response.get('last_name', ''),
    }

    def user_data(self, access_token, *args, **kwargs):
    """
    Get user data from the OAuth provider.
    """
    url = f"{self.BASE_URL}/{self.PATH}{self.USERINFO_ENDPOINT}"
    return self.get_json(url, headers={'Authorization': f'Bearer {access_token}'})

    setup.py


    from setuptools import setup, find_packages

    setup(
    name="edx-oauth2-wordpress-backend",
    version="0.1.0",
    packages=find_packages(),
    install_requires=[
    "tutor>=16.0.0",
    "social-auth-core>=4.3.0",
    "social-auth-app-django>=5.0.0",
    ],
    entry_points={
    "tutor.plugin.v1": [
    "wordpress-oauth = edx_oauth2_wordpress_backend.plugin"
    ]
    },
    python_requires=">=3.8",
    )

    requirements.txt


    edx-oauth2-wordpress-backend>=1.0.8

    plugin.py


    from tutor import hooks

    # Plugin configuration
    hooks.Filters.CONFIG_DEFAULTS.add_items([
    ("WPOAUTH_BACKEND_BASE_URL", ""),
    ("WPOAUTH_BACKEND_CLIENT_ID", ""),
    ("WPOAUTH_BACKEND_CLIENT_SECRET", ""),
    ])

    # Add environment patches
    hooks.Filters.ENV_PATCHES.add_item(
    (
    "lms-env",
    """
    # WordPress OAuth Backend Settings
    WPOAUTH_BACKEND_BASE_URL: "{{ WPOAUTH_BACKEND_BASE_URL }}"
    WPOAUTH_BACKEND_CLIENT_ID: "{{ WPOAUTH_BACKEND_CLIENT_ID }}"
    WPOAUTH_BACKEND_CLIENT_SECRET: "{{ WPOAUTH_BACKEND_CLIENT_SECRET }}"
    ADDL_INSTALLED_APPS: ["edx_oauth2_wordpress_backend"]
    THIRD_PARTY_AUTH_BACKENDS: ["edx_oauth2_wordpress_backend.wp_oauth.WordPressOAuth2"]
    ENABLE_REQUIRE_THIRD_PARTY_AUTH: true
    """
    )
    )

    # Install the package in the Open edX environment
    hooks.Filters.ENV_PATCHES.add_item(
    (
    "lms-dockerfile-post-install",
    """
    # Install WordPress OAuth backend
    COPY edx-oauth2-wordpress-backend /openedx/edx-oauth2-wordpress-backend
    RUN cd /openedx/edx-oauth2-wordpress-backend && \
    pip install -e . && \
    pip install social-auth-core>=4.3.0 social-auth-app-django>=5.0.0
    """
    )
    )

    # Add the package to requirements
    hooks.Filters.ENV_PATCHES.add_item(
    (
    "lms-requirements",
    """
    edx-oauth2-wordpress-backend @ file:///openedx/edx-oauth2-wordpress-backend
    """
    )
    )

    Installation Steps


    1. Install the plugin:

      cd edx-oauth2-wordpress-backend pip install -e . tutor plugins enable wordpress-oauth


    2. Configure the plugin:

      tutor config save --set WPOAUTH_BACKEND_BASE_URL="https://your-wordpress-site.com"
      --set WPOAUTH_BACKEND_CLIENT_ID="your-client-id"
      --set WPOAUTH_BACKEND_CLIENT_SECRET="your-client-secret"


    3. Rebuild and restart:

      tutor config save tutor images build openedx tutor local launch
    Error Message


    Loading settings lms.envs.tutor.production
    Traceback (most recent call last):
    File "/openedx/edx-platform/./manage.py", line 103, in <module>
    startup.run()
    File "/openedx/edx-platform/lms/startup.py", line 20, in run
    django.setup()
    File "/openedx/venv/lib/python3.11/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
    File "/openedx/venv/lib/python3.11/site-packages/django/apps/registry.py", line 91, in populate
    app_config = AppConfig.create(entry)
    File "/openedx/venv/lib/python3.11/site-packages/django/apps/config.py", line 193, in create
    import_module(entry)
    File "/opt/pyenv/versions/3.11.8/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
    ModuleNotFoundError: No module named 'edx_oauth2_wordpress_backend'

    What I've Tried

    1. Verified the package structure and all necessary files are present
    2. Ensured the package is installed in editable mode
    3. Added the package to both INSTALLED_APPS and THIRD_PARTY_AUTH_BACKENDS
    4. Added the package to the LMS requirements
    5. Verified the package installation in the container
    Environment

    • Open edX version: Latest (Tutor 16.0.0+)
    • Python version: 3.11
    • Operating System: Linux

    The error occurs during Django's app initialization, specifically when trying to load the custom OAuth2 backend module. Despite the package being installed and configured, Django cannot find the module.

    Any insights or suggestions on how to resolve this issue would be greatly appreciated.

    Continue reading...

Compartilhe esta Página