0

I'm trying to capture the images of charts and attach them to the email template using the img tag. I'm able to send the email local but getting this TypeError: Could not guess image MIME subtype in the server.

I'm using Gramex capture API to capture the images and using email service in Gramex. When I checked in the server, the images are stored in the png format and right path. Not sure where the issue is.

Here's the code I'm using to capture and send the email.

def send_email(handler):
    user = handler.args.get('user', ['None'])[0]
    chart_selector = ['.bar-chart', '.donut-chart', '.world_map', '.headerImg']
    folder = os.path.dirname(os.path.abspath(__file__))
    mailer = service.email["galaxy-email-smtp"]
    try:
        yield service.threadpool.submit(
            load_file, user, chart_selector
        )
    except Exception as e:
        print("An error occurred:", str(e))
    temp_file = gc.open('email.digest.template.formatted.html', 'template')
    file_path_barchart = os.path.join(folder, 'downloaded1.png')
    file_path_donutchart = os.path.join(folder, 'downloaded2.png')
    file_path_worldmap = os.path.join(folder, 'downloaded3.png')
    file_path_header = os.path.join(folder, 'downloaded4.png')
    html_content = temp_file.generate(data={"handler": handler}).decode('utf-8')
    mailer.mail(
        sender=<email>,
        to=user,
        subject=<subject>,
        html=html_content,
        images={
            "headerImg": file_path_header,
            "ricoImg": os.path.join(folder, 'assets/img/rico.png'),
            "bar-chart-img": file_path_barchart,
            "donut-chart-img": file_path_donutchart,
            "world_map": file_path_worldmap,
        },
    )
    return "email has been sent"


def load_file(user, chart_selector):
    url = <url> + user
    for index, each_chart_selector in enumerate(chart_selector):
        file_name = f"downloaded{index+1}.png"  # Generate the file name
        chart_capture = capture.png(
            url, selector=each_chart_selector, scale=2, timeout=60
        )
        with open(file_name, "wb") as f:
            f.write(chart_capture)

Here's the traceback error:

ERROR   13-Jul 12:25:14 tornado.application:web Uncaught exception GET /send?user=<user>
HTTPServerRequest(protocol='https', host=<hostname>, method='GET', uri='/send?user=<user>, version='HTTP/1.1', remote_ip='59.160.48.210')
Traceback (most recent call last):
  File "/root/anaconda3/lib/python3.9/site-packages/tornado/web.py", line 1704, in _execute
    result = await result
  File "/root/anaconda3/lib/python3.9/site-packages/tornado/gen.py", line 769, in run
    yielded = self.gen.throw(*exc_info)  # type: ignore
  File "/root/anaconda3/lib/python3.9/site-packages/gramex/handlers/functionhandler.py", line 53, in get
    item = yield item
  File "/root/anaconda3/lib/python3.9/site-packages/tornado/gen.py", line 762, in run
    value = future.result()
  File "/root/anaconda3/lib/python3.9/site-packages/tornado/gen.py", line 775, in run
    yielded = self.gen.send(value)
  File "/mnt/apps/threat-research-email-digest/email_service.py", line 705, in email_digest_req
    mailer.mail(
  File "/root/anaconda3/lib/python3.9/site-packages/gramex/services/emailer.py", line 147, in mail
    msg = message(**kwargs)
  File "/root/anaconda3/lib/python3.9/site-packages/gramex/services/emailer.py", line 203, in message
    img = MIMEImage(handle.read())
  File "/root/anaconda3/lib/python3.9/email/mime/image.py", line 43, in __init__
    raise TypeError('Could not guess image MIME subtype')
TypeError: Could not guess image MIME subtype

Noticed that in Gramex emailer.py, we are not passing any _subtype value in the below code:

for name, path in images.items():
    with open(path, 'rb') as handle:
         img = MIMEImage(handle.read())
         img.add_header('Content-ID', f'<{name}>')
         html_part.attach(img)

When I tried giving a subtype in this line img = MIMEImage(handle.read(), 'png'), it is working fine. Is there any option to add the subtype in while adding images? Thanks in advance!

Lahari
  • 461
  • 1
  • 3
  • 16

1 Answers1

-1

See below, someone encountered the same issue and resolved it by declaring the subtype on the read/write method: https://github.com/jakewaldron/PlexEmail/issues/6

Ex. msgImage = MIMEImage(fp.read(),_subtype="png")

OR

Ex. msgImage = MIMEImage(fp.read(),_subtype=False)

Albert Einstein
  • 7,472
  • 8
  • 36
  • 71
DayByDay
  • 60
  • 6