Open edX Forum
##############
|ci-badge| |license-badge| |status-badge|
This application provides a forum backend for use within `Open edX <https://openedx.org>`__ courses. Features include: nested comments, voting, instructor endorsements, and others. The frontend is provided by the `frontend-app-discussions <https://github.com/openedx/frontend-app-discussions>`__ microfrontend application.
This project is a drop-in replacement of the legacy `cs_comments_service <https://github.com/openedx/cs_comments_service>`__ application. The legacy application was written in Ruby, while this one is written in Python for direct integration in the edx-platform Django project. Moreover, forum data no longer resides in MongoDB, but in the relational MySQL database. The motivation for this rewrite is described more extensively in the `Axim Funded Contribution Proposal <https://discuss.openedx.org/t/axim-funded-contribution-proposal-forum-rewrite-from-ruby-mongodb-to-python-mysql/12788>`_.
Installation
************
Starting from the Open edX Sumac release, the forum app is distributed via the `Tutor forum plugin <https://github.com/overhangio/tutor-forum>`__.
The only prerequisite for installation is a working Open edX platform with `Tutor <https://docs.tutor.edly.io/>`__, on the Sumac release (v19+) or the `main branch <https://docs.tutor.edly.io/tutorials/main.html>`__. Enable the forum by running::
tutor plugins enable forum
tutor local launch
The forum feature will then be automatically enabled in the Open edX platform, and all API calls will be transparently handled by the new application.
Development
***********
Run tests with::
make test-all # run all tests
make test # run unit tests only
make test-quality # run quality tests only
make test-e2e # run end-to-end tests only
When developing this application, it is recommended to clone this repository locally and mount it within the application containers::
git clone git@github.com:openedx/forum.git
tutor mounts add ./forum/
Check that the forum repository is properly bind-mounted both at build- and run-time by running ``tutor mounts list``. It should output the following::
- name: /home/path/to/forum
build_mounts:
- image: openedx
context: mnt-forum
- image: openedx-dev
context: mnt-forum
compose_mounts:
- service: openedx
container_path: /mnt/forum
- service: openedx-dev
container_path: /mnt/forum
Re-build the openedx-dev image and launch the platform::
tutor images build openedx-dev
tutor dev launch
Administration
**************
Deployment of the forum v2 application is gated by two course waffle flags. In addition, this application provides a few commands to facilitate the transition from the legacy forum app.
Forum v2 toggle
---------------
In edx-platform, forum v2 is not enabled by default and edx-platform will keep communicating with the legacy forum app. To enable forum v2 in your Open edX platform, toggle the ``discussions.enable_forum_v2`` course waffle flag::
./manage.py lms waffle_flag --create --everyone discussions.enable_forum_v2
Note that Tutor enables this flag for all forum plugin users, such that you don't have to run this command yourself. If you wish to migrate your courses one by one to the new forum v2 app, you may create the corresponding "Waffle flag course override" objects in your LMS administration panel, at: ``http(s)://<LMS_HOST>/admin/waffle_utils/waffleflagcourseoverridemodel/``.
⚠️⚠️⚠️ Even if the forum v2 toggle is not enabled, edx-platform will make a call to the forum v2 API in some edge cases. That's because edx-platform needs to determine whether it should use forum v2 or cs_comments_service, based on the value of some course waffle flag. In order to access the course wafffle flag, we need to determine the course ID of the current HTTP request. In some requests, the course ID is not available: only the thread ID or the comment ID is. Thus, edx-platform needs to fetch the course ID that is associated to the thread or comment. That information is stored either in MySQL or in MongoDB. Thus, edx-platform needs to call the forum v2 API.
As a consequence, **the forum v2 app needs to have accurate MongoDB configuration settings even if you don't use forum v2**. In a Tutor installation, these settings are set to the right values. In other environments, the following Django settings must be set::
# Name of the MongoDB database in which forum data is stored
FORUM_MONGODB_DATABASE = "cs_comments_service"
# This setting will be passed to the MongoDB client constructor as follows:
# pymongo.MongoClient(**FORUM_MONGODB_CLIENT_PARAMETERS)
# Documentation: https://pymongo.readthedocs.io/en/4.4.0/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient
FORUM_MONGODB_CLIENT_PARAMETERS = {"host": "mongodb"}
MySQL backend toggle
--------------------
To preserve the legacy behaviour of storing data in MongoDB, the forum v2 app makes it possible to keep using MongoDB as a data backend. However, it is strongly recommended to switch to the MySQL storage backend by toggling the ``forum_v2.enable_mysql_backend`` course waffle flag::
./manage.py lms waffle_flag --create --everyone forum_v2.enable_mysql_backend
Here again, Tutor creates this flag by default, such that you don't have to create it yourself. If you decide to switch to MySQL, you will have to migrate your data from MongoDB -- see instructions below.
Migration from MongoDB to MySQL
-------------------------------
The forum v2 app comes with the ``forum_migrate_courses_to_mysql`` migration command to move data from MongoDB to MySQL. This command will perform the following steps:
1. Migrate data: user, content and read state data from MongoDB to MySQL.
2. Enable the ``forum_v2.enable_mysql_backend`` waffle flag for the specified course(s).
To migrate data for specific courses, run the command with the course IDs as argument::
./manage.py lms forum_migrate_course_from_mongodb_to_mysql <course_id_1> <course_id_2>
To migrate data for all courses, run the command with the ``all`` argument::
./manage.py lms forum_migrate_course_from_mongodb_to_mysql all
To test data migration without actually creating course toggles, use the ``--no-toggle`` option::
./manage.py lms forum_migrate_course_from_mongodb_to_mysql --no-toggle all
⚠️ Note that the command will create toggles only for the processed courses. Courses created in the future will not automatically use the MySQL backend unless you create the global waffle flag with the ``waffle_flag --create`` command indicated above.
MongoDB data deletion
---------------------
After you have successfully migrated your course data from MySQL to MongoDB using the command above, you may delete your MongoDB data using the ``forum_delete_course_from_mongodb`` management command. This command deletes course data from MongoDB for the specified courses.
Run the command with the course ID(s) as an argument::
./manage.py lms forum_delete_course_from_mongodb <course_id_1> <course_id_2>
To delete data for all courses, run the command with the ``all`` argument::
./manage.py lms forum_delete_course_from_mongodb all
To try out changes before applying them, use the ``--dry-run`` option. For instance::
./manage.py lms forum_delete_course_from_mongodb all --dry-run
.. Deploying
.. *********
.. TODO: How can a new user go about deploying this component? Is it just a few
.. commands? Is there a larger how-to that should be linked here?
.. PLACEHOLDER: For details on how to deploy this component, see the `deployment how-to`_.
.. .. _deployment how-to: https://docs.openedx.org/projects/forum/how-tos/how-to-deploy-this-component.html
Getting Help
************
.. Documentation
.. =============
.. PLACEHOLDER: Start by going through `the documentation`_. If you need more help see below.
.. .. _the documentation: https://docs.openedx.org/projects/forum
.. (TODO: `Set up documentation <https://openedx.atlassian.net/wiki/spaces/DOC/pages/21627535/Publish+Documentation+on+Read+the+Docs>`_)
.. More Help
.. =========
If you are having trouble, we have discussion forums at https://discuss.openedx.org where you can connect with others in the community.
Our real-time conversations are on Slack. You can request a `Slack invitation`_, then join our `community Slack workspace`_.
For anything non-trivial, the best path is to open an issue `in this repository <https://github.com/openedx/forum/issues>`__ with as many details about the issue you are facing as you can provide.
For more information about these options, see the `Getting Help <https://openedx.org/getting-help>`__ page.
.. _Slack invitation: https://openedx.org/slack
.. _community Slack workspace: https://openedx.slack.com/
License
*******
The code in this repository is licensed under the AGPL 3.0 unless otherwise noted. See `LICENSE.txt <LICENSE.txt>`_ for details.
Contributing
************
Contributions are very welcome. Please read `How To Contribute <https://openedx.org/r/how-to-contribute>`_ for details.
This project is currently accepting all types of contributions, bug fixes, security fixes, maintenance work, or new features. However, please make sure to discuss your new feature idea with the maintainers before beginning development to maximize the chances of your change being accepted. You can start a conversation by creating a new issue on this repo summarizing your idea.
The Open edX Code of Conduct
****************************
All community members are expected to follow the `Open edX Code of Conduct`_.
.. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/
People
******
The assigned maintainers for this component and other project details may be found in `Backstage`_. Backstage pulls this data from the ``catalog-info.yaml`` file in this repo.
.. _Backstage: https://backstage.openedx.org/catalog/default/component/forum
Reporting Security Issues
*************************
Please do not report security issues in public. Please email security@openedx.org.
.. |ci-badge| image:: https://github.com/openedx/forum/actions/workflows/ci.yml/badge.svg
:target: https://github.com/openedx/forum/actions/workflows/ci.yml
:alt: CI
.. |license-badge| image:: https://img.shields.io/github/license/openedx/forum.svg
:target: https://github.com/openedx/forum/blob/master/LICENSE.txt
:alt: License
.. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen
Change Log
##########
..
All enhancements and patches to forum will be documented
in this file. It adheres to the structure of https://keepachangelog.com/ ,
but in reStructuredText instead of Markdown (for ease of incorporation into
Sphinx documentation and the PyPI description).
This project adheres to Semantic Versioning (https://semver.org/).
.. There should always be an "Unreleased" section for changes pending release.
Unreleased
**********
*
0.1.0 – 2024-11-12
******************
* First release on PyPI.
Raw data
{
"_id": null,
"home_page": "https://github.com/openedx/forum",
"name": "openedx-forum",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "Python edx",
"author": "Open edX Project",
"author_email": "oscm@openedx.org",
"download_url": "https://files.pythonhosted.org/packages/0a/85/ed67004372bc544042cd128817ed859328f71a5b344062f6afb3d5ffcc16/openedx_forum-0.1.5.tar.gz",
"platform": null,
"description": "Open edX Forum\n##############\n\n|ci-badge| |license-badge| |status-badge|\n\nThis application provides a forum backend for use within `Open edX <https://openedx.org>`__ courses. Features include: nested comments, voting, instructor endorsements, and others. The frontend is provided by the `frontend-app-discussions <https://github.com/openedx/frontend-app-discussions>`__ microfrontend application.\n\nThis project is a drop-in replacement of the legacy `cs_comments_service <https://github.com/openedx/cs_comments_service>`__ application. The legacy application was written in Ruby, while this one is written in Python for direct integration in the edx-platform Django project. Moreover, forum data no longer resides in MongoDB, but in the relational MySQL database. The motivation for this rewrite is described more extensively in the `Axim Funded Contribution Proposal <https://discuss.openedx.org/t/axim-funded-contribution-proposal-forum-rewrite-from-ruby-mongodb-to-python-mysql/12788>`_.\n\nInstallation\n************\n\nStarting from the Open edX Sumac release, the forum app is distributed via the `Tutor forum plugin <https://github.com/overhangio/tutor-forum>`__.\n\nThe only prerequisite for installation is a working Open edX platform with `Tutor <https://docs.tutor.edly.io/>`__, on the Sumac release (v19+) or the `main branch <https://docs.tutor.edly.io/tutorials/main.html>`__. Enable the forum by running::\n\n tutor plugins enable forum\n tutor local launch\n\nThe forum feature will then be automatically enabled in the Open edX platform, and all API calls will be transparently handled by the new application.\n\nDevelopment\n***********\n\nRun tests with::\n\n make test-all # run all tests\n make test # run unit tests only\n make test-quality # run quality tests only\n make test-e2e # run end-to-end tests only\n\nWhen developing this application, it is recommended to clone this repository locally and mount it within the application containers::\n\n git clone git@github.com:openedx/forum.git\n tutor mounts add ./forum/\n\nCheck that the forum repository is properly bind-mounted both at build- and run-time by running ``tutor mounts list``. It should output the following::\n\n - name: /home/path/to/forum\n build_mounts:\n - image: openedx\n context: mnt-forum\n - image: openedx-dev\n context: mnt-forum\n compose_mounts:\n - service: openedx\n container_path: /mnt/forum\n - service: openedx-dev\n container_path: /mnt/forum\n\nRe-build the openedx-dev image and launch the platform::\n\n tutor images build openedx-dev\n tutor dev launch\n\nAdministration\n**************\n\nDeployment of the forum v2 application is gated by two course waffle flags. In addition, this application provides a few commands to facilitate the transition from the legacy forum app.\n\nForum v2 toggle\n---------------\n\nIn edx-platform, forum v2 is not enabled by default and edx-platform will keep communicating with the legacy forum app. To enable forum v2 in your Open edX platform, toggle the ``discussions.enable_forum_v2`` course waffle flag::\n\n ./manage.py lms waffle_flag --create --everyone discussions.enable_forum_v2\n\nNote that Tutor enables this flag for all forum plugin users, such that you don't have to run this command yourself. If you wish to migrate your courses one by one to the new forum v2 app, you may create the corresponding \"Waffle flag course override\" objects in your LMS administration panel, at: ``http(s)://<LMS_HOST>/admin/waffle_utils/waffleflagcourseoverridemodel/``.\n\n\u26a0\ufe0f\u26a0\ufe0f\u26a0\ufe0f Even if the forum v2 toggle is not enabled, edx-platform will make a call to the forum v2 API in some edge cases. That's because edx-platform needs to determine whether it should use forum v2 or cs_comments_service, based on the value of some course waffle flag. In order to access the course wafffle flag, we need to determine the course ID of the current HTTP request. In some requests, the course ID is not available: only the thread ID or the comment ID is. Thus, edx-platform needs to fetch the course ID that is associated to the thread or comment. That information is stored either in MySQL or in MongoDB. Thus, edx-platform needs to call the forum v2 API.\n\nAs a consequence, **the forum v2 app needs to have accurate MongoDB configuration settings even if you don't use forum v2**. In a Tutor installation, these settings are set to the right values. In other environments, the following Django settings must be set::\n\n # Name of the MongoDB database in which forum data is stored\n FORUM_MONGODB_DATABASE = \"cs_comments_service\"\n\n # This setting will be passed to the MongoDB client constructor as follows:\n # pymongo.MongoClient(**FORUM_MONGODB_CLIENT_PARAMETERS)\n # Documentation: https://pymongo.readthedocs.io/en/4.4.0/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient\n FORUM_MONGODB_CLIENT_PARAMETERS = {\"host\": \"mongodb\"}\n\nMySQL backend toggle\n--------------------\n\nTo preserve the legacy behaviour of storing data in MongoDB, the forum v2 app makes it possible to keep using MongoDB as a data backend. However, it is strongly recommended to switch to the MySQL storage backend by toggling the ``forum_v2.enable_mysql_backend`` course waffle flag::\n\n ./manage.py lms waffle_flag --create --everyone forum_v2.enable_mysql_backend\n\nHere again, Tutor creates this flag by default, such that you don't have to create it yourself. If you decide to switch to MySQL, you will have to migrate your data from MongoDB -- see instructions below.\n\nMigration from MongoDB to MySQL\n-------------------------------\n\nThe forum v2 app comes with the ``forum_migrate_courses_to_mysql`` migration command to move data from MongoDB to MySQL. This command will perform the following steps:\n\n1. Migrate data: user, content and read state data from MongoDB to MySQL.\n2. Enable the ``forum_v2.enable_mysql_backend`` waffle flag for the specified course(s).\n\nTo migrate data for specific courses, run the command with the course IDs as argument::\n\n ./manage.py lms forum_migrate_course_from_mongodb_to_mysql <course_id_1> <course_id_2>\n\nTo migrate data for all courses, run the command with the ``all`` argument::\n\n ./manage.py lms forum_migrate_course_from_mongodb_to_mysql all\n\nTo test data migration without actually creating course toggles, use the ``--no-toggle`` option::\n\n ./manage.py lms forum_migrate_course_from_mongodb_to_mysql --no-toggle all\n\n\u26a0\ufe0f Note that the command will create toggles only for the processed courses. Courses created in the future will not automatically use the MySQL backend unless you create the global waffle flag with the ``waffle_flag --create`` command indicated above.\n\nMongoDB data deletion\n---------------------\n\nAfter you have successfully migrated your course data from MySQL to MongoDB using the command above, you may delete your MongoDB data using the ``forum_delete_course_from_mongodb`` management command. This command deletes course data from MongoDB for the specified courses.\n\nRun the command with the course ID(s) as an argument::\n\n ./manage.py lms forum_delete_course_from_mongodb <course_id_1> <course_id_2>\n\nTo delete data for all courses, run the command with the ``all`` argument::\n\n ./manage.py lms forum_delete_course_from_mongodb all\n\nTo try out changes before applying them, use the ``--dry-run`` option. For instance::\n\n ./manage.py lms forum_delete_course_from_mongodb all --dry-run\n\n.. Deploying\n.. *********\n\n.. TODO: How can a new user go about deploying this component? Is it just a few\n.. commands? Is there a larger how-to that should be linked here?\n\n.. PLACEHOLDER: For details on how to deploy this component, see the `deployment how-to`_.\n\n.. .. _deployment how-to: https://docs.openedx.org/projects/forum/how-tos/how-to-deploy-this-component.html\n\nGetting Help\n************\n\n.. Documentation\n.. =============\n\n.. PLACEHOLDER: Start by going through `the documentation`_. If you need more help see below.\n\n.. .. _the documentation: https://docs.openedx.org/projects/forum\n\n.. (TODO: `Set up documentation <https://openedx.atlassian.net/wiki/spaces/DOC/pages/21627535/Publish+Documentation+on+Read+the+Docs>`_)\n\n.. More Help\n.. =========\n\nIf you are having trouble, we have discussion forums at https://discuss.openedx.org where you can connect with others in the community.\n\nOur real-time conversations are on Slack. You can request a `Slack invitation`_, then join our `community Slack workspace`_.\n\nFor anything non-trivial, the best path is to open an issue `in this repository <https://github.com/openedx/forum/issues>`__ with as many details about the issue you are facing as you can provide.\n\nFor more information about these options, see the `Getting Help <https://openedx.org/getting-help>`__ page.\n\n.. _Slack invitation: https://openedx.org/slack\n.. _community Slack workspace: https://openedx.slack.com/\n\nLicense\n*******\n\nThe code in this repository is licensed under the AGPL 3.0 unless otherwise noted. See `LICENSE.txt <LICENSE.txt>`_ for details.\n\nContributing\n************\n\nContributions are very welcome. Please read `How To Contribute <https://openedx.org/r/how-to-contribute>`_ for details.\n\nThis project is currently accepting all types of contributions, bug fixes, security fixes, maintenance work, or new features. However, please make sure to discuss your new feature idea with the maintainers before beginning development to maximize the chances of your change being accepted. You can start a conversation by creating a new issue on this repo summarizing your idea.\n\nThe Open edX Code of Conduct\n****************************\n\nAll community members are expected to follow the `Open edX Code of Conduct`_.\n\n.. _Open edX Code of Conduct: https://openedx.org/code-of-conduct/\n\nPeople\n******\n\nThe assigned maintainers for this component and other project details may be found in `Backstage`_. Backstage pulls this data from the ``catalog-info.yaml`` file in this repo.\n\n.. _Backstage: https://backstage.openedx.org/catalog/default/component/forum\n\nReporting Security Issues\n*************************\n\nPlease do not report security issues in public. Please email security@openedx.org.\n\n.. |ci-badge| image:: https://github.com/openedx/forum/actions/workflows/ci.yml/badge.svg\n :target: https://github.com/openedx/forum/actions/workflows/ci.yml\n :alt: CI\n\n.. |license-badge| image:: https://img.shields.io/github/license/openedx/forum.svg\n :target: https://github.com/openedx/forum/blob/master/LICENSE.txt\n :alt: License\n\n.. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen\n\n\nChange Log\n##########\n\n..\n All enhancements and patches to forum will be documented\n in this file. It adheres to the structure of https://keepachangelog.com/ ,\n but in reStructuredText instead of Markdown (for ease of incorporation into\n Sphinx documentation and the PyPI description).\n\n This project adheres to Semantic Versioning (https://semver.org/).\n\n.. There should always be an \"Unreleased\" section for changes pending release.\n\nUnreleased\n**********\n\n*\n\n0.1.0 \u2013 2024-11-12\n******************\n\n* First release on PyPI.\n",
"bugtrack_url": null,
"license": "AGPL 3.0",
"summary": "Open edX forum application",
"version": "0.1.5",
"project_urls": {
"Homepage": "https://github.com/openedx/forum"
},
"split_keywords": [
"python",
"edx"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c801d223a77ce170677fb007a0fc43fcd8bf7046d7841c9eb931d85c9fc137e5",
"md5": "85e6b98b66cc6e40be32f3b2cb6fffa7",
"sha256": "ae279a9adde58597a07e0c7f6d419a70544acb484cc3af4f3140f52283fa6121"
},
"downloads": -1,
"filename": "openedx_forum-0.1.5-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "85e6b98b66cc6e40be32f3b2cb6fffa7",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.8",
"size": 130372,
"upload_time": "2024-12-10T15:04:18",
"upload_time_iso_8601": "2024-12-10T15:04:18.983241Z",
"url": "https://files.pythonhosted.org/packages/c8/01/d223a77ce170677fb007a0fc43fcd8bf7046d7841c9eb931d85c9fc137e5/openedx_forum-0.1.5-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "0a85ed67004372bc544042cd128817ed859328f71a5b344062f6afb3d5ffcc16",
"md5": "13c26ea0ab64514359cd88efe2257169",
"sha256": "92737aa5885b8206c04e85a69a96fe24e4b15efc61699b68ddde5e56bcdca00c"
},
"downloads": -1,
"filename": "openedx_forum-0.1.5.tar.gz",
"has_sig": false,
"md5_digest": "13c26ea0ab64514359cd88efe2257169",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 108286,
"upload_time": "2024-12-10T15:04:20",
"upload_time_iso_8601": "2024-12-10T15:04:20.535135Z",
"url": "https://files.pythonhosted.org/packages/0a/85/ed67004372bc544042cd128817ed859328f71a5b344062f6afb3d5ffcc16/openedx_forum-0.1.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-10 15:04:20",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "openedx",
"github_project": "forum",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "openedx-forum"
}