I think I made some progress. I needed to add ("RUN_SMTP", False),
to the CONFIG_USER
hooks.Filters.CONFIG_USER.add_items(
[
("EMAIL_BACKEND", "anymail.backends.mailjet.EmailBackend"),
("RUN_SMTP", False),
]
)
And then add the settings
hooks.Filters.ENV_PATCHES.add_items(
[
("cms-env", "EMAIL_BACKEND: anymail.backends.mailjet.EmailBackend"),
("lms-env", "EMAIL_BACKEND: anymail.backends.mailjet.EmailBackend"),
("cms-env", "MAILJET_API_KEY: MAILJET_API_KEY"),
("lms-env", "MAILJET_API_KEY: MAILJET_API_KEY"),
("cms-env", "MAILJET_SECRET_KEY: MAILJET_SECRET_KEY"),
("lms-env", "MAILJET_SECRET_KEY: MAILJET_SECRET_KEY"),
]
)
I have verified that anymail should be installed, it is in the config.yml after I ran tutor config save --append OPENEDX_EXTRA_PIP_REQUIREMENTS=django-anymail[mailjet]==8.6
And a grep of the docker shows it is there, cat ~/.local/share/tutor/env/build/openedx/Dockerfile | grep mail
After a disable, enable of the plugin, re build of the openedx with tutor images build openedx --no-cache
I watch and see that django-anymail is installed.
And I can run the command successfully from command line. This command works and I get the email:
tutor local run --no-deps lms ./manage.py lms shell -c "from django.core.mail import send_mail; send_mail('test subject', 'test message', 'test@test.org', ['me@gmail.com'])"
However, when I bash into the LMS image with sudo docker exec -it tutor_local-lms-1 bash
and go a pip freeze | grep anymail
I get no results like anymail was not installed. Or maybe I misunderstand how the extra pip installation works? And trying to send an email to a user in the frontend results in the error below:
lms-1 | [pid: 1|app: 0|req: 16/33] 172.18.0.7 () {66 vars in 2842 bytes} [Sat Sep 14 19:12:02 2024] POST /courses/course-v1:ThetaTau+TT101+intro/instructor/api/list_instructor_tasks => generated 17 bytes in 67 msecs (HTTP/1.1 200) 10 headers in 607 bytes (1 switches on core 0)
lms-1 | 2024-09-14 19:12:04,835 INFO 15 [tracking] [user 4] [ip 172.110.170.18] logger.py:41 - {"name": "/courses/course-v1:ThetaTau+TT101+intro/instructor/api/students_update_enrollment", "context": {"course_id": "course-v1:ThetaTau+TT101+intro", "course_user_tags": {}, "user_id": 4, "path": "/courses/course-v1:ThetaTau+TT101+intro/instructor/api/students_update_enrollment", "org_id": "ThetaTau", "enterprise_uuid": ""}, "username": "frank.ventura@thetatau.org", "session": "7145a02b62697f10e29542f8242076b3", "ip": "172.110.170.18", "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36", "host": "ed.thetatau.org", "referer": "https://ed.thetatau.org/courses/course-v1:ThetaTau+TT101+intro/instructor", "accept_language": "en-US,en;q=0.9", "event": "{\"GET\": {}, \"POST\": {\"action\": [\"enroll\"], \"identifiers\": [\"frank.ventura+1234@thetatau.org\"], \"auto_enroll\": [\"true\"], \"email_students\": [\"true\"]}}", "time": "2024-09-14T19:12:04.835549+00:00", "event_type": "/courses/course-v1:ThetaTau+TT101+intro/instructor/api/students_update_enrollment", "event_source": "server", "page": null}
lms-1 | 2024-09-14 19:12:04,944 ERROR 15 [lms.djangoapps.instructor.views.api] [user 4] [ip 172.110.170.18] api.py:873 - Error while #{}ing student
lms-1 | Traceback (most recent call last):
lms-1 | File "/openedx/edx-platform/lms/djangoapps/instructor/views/api.py", line 819, in students_update_enrollment
lms-1 | before, after, enrollment_obj = enroll_email(
lms-1 | ^^^^^^^^^^^^^
lms-1 | File "/openedx/edx-platform/lms/djangoapps/instructor/enrollment.py", line 177, in enroll_email
lms-1 | send_mail_to_student(student_email, email_params, language=language)
lms-1 | File "/openedx/edx-platform/lms/djangoapps/instructor/enrollment.py", line 561, in send_mail_to_student
lms-1 | ace.send(message)
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/edx_ace/ace.py", line 53, in send
lms-1 | delivery.deliver(channel, rendered_message, msg)
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/edx_ace/delivery.py", line 51, in deliver
lms-1 | channel.deliver(message, rendered_message)
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/edx_ace/channel/django_email.py", line 68, in deliver
lms-1 | mail.send()
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/mail/message.py", line 299, in send
lms-1 | return self.get_connection(fail_silently).send_messages([self])
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/mail/message.py", line 256, in get_connection
lms-1 | self.connection = get_connection(fail_silently=fail_silently)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/mail/__init__.py", line 50, in get_connection
lms-1 | klass = import_string(backend or settings.EMAIL_BACKEND)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/utils/module_loading.py", line 30, in import_string
lms-1 | return cached_import(module_path, class_name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/utils/module_loading.py", line 15, in cached_import
lms-1 | module = import_module(module_path)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/opt/pyenv/versions/3.11.8/lib/python3.11/importlib/__init__.py", line 126, in import_module
lms-1 | return _bootstrap._gcd_import(name[level:], package, level)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
lms-1 | File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
lms-1 | File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
lms-1 | File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
lms-1 | File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
lms-1 | File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
lms-1 | File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
lms-1 | File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
lms-1 | File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
lms-1 | File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
lms-1 | File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
lms-1 | ModuleNotFoundError: No module named 'anymail'
lms-1 | 2024-09-14 19:12:04,948 ERROR 15 [lms.djangoapps.instructor.views.api] [user 4] [ip 172.110.170.18] api.py:874 - No module named 'anymail'
lms-1 | Traceback (most recent call last):
lms-1 | File "/openedx/edx-platform/lms/djangoapps/instructor/views/api.py", line 819, in students_update_enrollment
lms-1 | before, after, enrollment_obj = enroll_email(
lms-1 | ^^^^^^^^^^^^^
lms-1 | File "/openedx/edx-platform/lms/djangoapps/instructor/enrollment.py", line 177, in enroll_email
lms-1 | send_mail_to_student(student_email, email_params, language=language)
lms-1 | File "/openedx/edx-platform/lms/djangoapps/instructor/enrollment.py", line 561, in send_mail_to_student
lms-1 | ace.send(message)
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/edx_ace/ace.py", line 53, in send
lms-1 | delivery.deliver(channel, rendered_message, msg)
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/edx_ace/delivery.py", line 51, in deliver
lms-1 | channel.deliver(message, rendered_message)
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/edx_ace/channel/django_email.py", line 68, in deliver
lms-1 | mail.send()
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/mail/message.py", line 299, in send
lms-1 | return self.get_connection(fail_silently).send_messages([self])
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/mail/message.py", line 256, in get_connection
lms-1 | self.connection = get_connection(fail_silently=fail_silently)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/mail/__init__.py", line 50, in get_connection
lms-1 | klass = import_string(backend or settings.EMAIL_BACKEND)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/utils/module_loading.py", line 30, in import_string
lms-1 | return cached_import(module_path, class_name)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/openedx/venv/lib/python3.11/site-packages/django/utils/module_loading.py", line 15, in cached_import
lms-1 | module = import_module(module_path)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "/opt/pyenv/versions/3.11.8/lib/python3.11/importlib/__init__.py", line 126, in import_module
lms-1 | return _bootstrap._gcd_import(name[level:], package, level)
lms-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lms-1 | File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
lms-1 | File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
lms-1 | File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
lms-1 | File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
lms-1 | File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
lms-1 | File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
lms-1 | File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
lms-1 | File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
lms-1 | File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
lms-1 | File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
lms-1 | File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
lms-1 | ModuleNotFoundError: No module named 'anymail'
lms-1 | [pid: 15|app: 0|req: 16/34] 172.18.0.7 () {68 vars in 2917 bytes} [Sat Sep 14 19:12:04 2024] POST /courses/course-v1:ThetaTau+TT101+intro/instructor/api/students_update_enrollment => generated 154 bytes in 150 msecs (HTTP/1.1 200) 10 headers in 608 bytes (1 switches on core 0)
What am I doing wrong with the OPENEDX_EXTRA_PIP_REQUIREMENTS and then seeing that in the container of the LMS?