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!