Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to send email as Jinja template with image? #173

Open
morento101 opened this issue Jan 7, 2023 · 3 comments
Open

How to send email as Jinja template with image? #173

morento101 opened this issue Jan 7, 2023 · 3 comments

Comments

@morento101
Copy link

I use FastAPI-Mail and Celery to send notifications in the background. I want to place the static image in the template and send it to the customer.

I discovered that a url_for function returns an absolute URL and can be used in img tag as src.

image

The problem is that I get such an error, and I don't know how to solve it:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
    return self.run(*args, **kwargs)
  File "/code/app/tasks/worker.py", line 17, in create_task
    send_birthday_reminder(
  File "/usr/local/lib/python3.10/site-packages/asgiref/sync.py", line 218, in __call__
    return call_result.result()
  File "/usr/local/lib/python3.10/concurrent/futures/_base.py", line 451, in result
    return self.__get_result()
  File "/usr/local/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.10/site-packages/asgiref/sync.py", line 284, in main_wrap
    result = await self.awaitable(*args, **kwargs)
  File "/code/app/email/email.py", line 29, in send_birthday_reminder
    await fm.send_message(
  File "/usr/local/lib/python3.10/site-packages/fastapi_mail/fastmail.py", line 105, in send_message
    msg = await self.__prepare_message(message, template)
  File "/usr/local/lib/python3.10/site-packages/fastapi_mail/fastmail.py", line 71, in __prepare_message
    message.template_body = await self.__template_message_builder(
  File "/usr/local/lib/python3.10/site-packages/fastapi_mail/fastmail.py", line 85, in __template_message_builder
    return template.render(**template_data)
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/code/app/templates/email/birthday_reminder.html", line 1, in top-level template code
    {% extends './base.html' %}
  File "/code/app/templates/base.html", line 11, in top-level template code
    {% block content %} {% endblock %}
  File "/code/app/templates/email/birthday_reminder.html", line 4, in block 'content'
    <img src="{{ url_for('static', path='img/birthday_alarm.png') }}" />
  File "/usr/local/lib/python3.10/site-packages/jinja2/utils.py", line 83, in from_obj
    if hasattr(obj, "jinja_pass_arg"):
jinja2.exceptions.UndefinedError: 'url_for' is undefined

How can I solve this issue?
Is there a better way to send a template with an image?

@morento101
Copy link
Author

Celery worker file
worker.py

from celery import Celery

from app.core.config import settings
from app.email.email import send_birthday_reminder

celery = Celery(__name__)
celery.conf.broker_url = settings.CELERY_BROKER_URL
celery.conf.result_backend = settings.CELERY_RESULT_BACKEND


@celery.task(name="create_task")
def create_task():
    send_birthday_reminder(
        'customer@gmail.com', {"subject": "hi"}
    )

File for sending emails
email.py

from asgiref.sync import async_to_sync
from fastapi_mail import ConnectionConfig, FastMail, MessageSchema

from app.core.config import BASE_DIR, settings

conf = ConnectionConfig(
    MAIL_USERNAME=settings.MAIL_USERNAME,
    MAIL_PASSWORD=settings.MAIL_PASSWORD,
    MAIL_FROM=settings.MAIL_FROM,
    MAIL_PORT=settings.MAIL_PORT,
    MAIL_SERVER=settings.MAIL_SERVER,
    MAIL_STARTTLS=False,
    MAIL_SSL_TLS=False,
    USE_CREDENTIALS=True,
    TEMPLATE_FOLDER=BASE_DIR / 'templates'
)


@async_to_sync
async def send_birthday_reminder(email_to: str, content: dict):
    message = MessageSchema(
        subject='Birthday Reminder',
        recipients=[email_to],
        template_body=content,
        subtype='html',
    )

    fm = FastMail(conf)
    await fm.send_message(
        message, template_name='email/birthday_reminder.html'
    )

@sabuhish
Copy link
Owner

Hi @morento101, I would suggest you use S3 or any other bucket that way it is much more useful I feel.

@LuckyLub
Copy link

LuckyLub commented Oct 24, 2023

@morento101 I am adding images to templates as described here: Customizing attachments by headers and MIME type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants