Search code examples
pythonsmtplib

Send a list of dictionaries, formatted with indents, as a string through email using smtplib?


I'm trying to send a list of dictionaries formatted with indentations to my email. At the moment, this is the resulting email I receive based on my code:

[{
        'post_id': '3524',
        'text': '🥕\n.\n▪️10/3 9 PM\n 9:00 ~ 11:45 Special host\n \n.\n▪️\n ~\n.\n▪️10/5 8PM More\n',
        'time': datetime.datetime(2019, 6, 13, 18, 31, 36),
        'image': ‘’,
        'link': 'https://bit.ly/'
    }, { {
            'post_id': '3524',
            'text': '🥕\n.\n▪️10/3 9 PM\n 9:00 ~ 11:45 Special host\n \n.\n▪️\n ~\n.\n▪️10/5 8PM More\n',
            'time': datetime.datetime(2019, 6, 13, 18, 31, 36),
            'image': ‘’,
            'link': None
        }
        ]

My code sends the email as a single line, with the "\n" appearing as letters and unformatted with tabs.

I need to keep the emojis, special characters (different language), while including the line breaks. How do I achieve this?

Current code:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart


print(type(posts))  # <class 'list'>
print(posts)  # [{'post_id': '3524', 'text': '🥕\n.\n▪️10/3 9 PM\n 9:00 ~ 11:45 Special host\n \n.\n▪️\n ~\n.\n▪️10/5 8PM More\n', 'time': datetime.datetime(2019, 6, 13, 18, 31, 36), 'image': ‘’, 'link': 'https://bit.ly/'}, {{'post_id': '3524', 'text': '🥕\n.\n▪️10/3 9 PM\n 9:00 ~ 11:45 Special host\n \n.\n▪️\n ~\n.\n▪️10/5 8PM More\n', 'time': datetime.datetime(2019, 6, 13, 18, 31, 36), 'image': ‘’, 'link': None}]

posts = str(posts)  # otherwise error: msg.attach(MIMEText(message_content)) File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/email/mime/text.py", line 34, in __init__ _text.encode('us-ascii') AttributeError: 'list' object has no attribute 'encode'

recipients = ["recipient_id@yahoo.com"]
sender = "sender_id@gmail.com"
subject = "report reminder"
body = posts

msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = ", ".join(recipients)
msg.attach(MIMEText(body, 'plain'))

# sending
session = smtplib.SMTP('smtp.gmail.com', 587)
session.starttls()
session.login(sender, 'my password')
send_it = session.sendmail(sender, recipients, msg.as_string())
session.quit()

To clarify, I would like to send the entire list of dictionaries as a string, brackets and all, formatted (active tabs/newlines).


Solution

  • If you want formated JSON in email then you need to use json.dumps() in body data. For that, you need to provide the indent argument in the function. Check out the code

    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    import json
    
    posts = [{"latlng":[77.7355421,12.985924],"name":"International Tech Park Bangalore 2.5 km","type":"work","icon":"suitcase"},{"latlng":[77.7515038,12.9829723],"name":"H M Tech Park 2.3 km","type":"work","icon":"suitcase"},{"latlng":[77.721544,12.981423],"name":"Prestige Featherlite Techapark 4.7km","type":"work","icon":"suitcase"}]
    
    
    recipients = ["reciever@demo.com"]
    sender = "sender@demo.com"
    subject = "report reminder"
    body = json.dumps(posts, indent=4) #changed code line
    
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = ", ".join(recipients)
    msg.attach(MIMEText(body, 'plain'))
    
    # sending
    session = smtplib.SMTP('smtp.office365.com', 587)
    session.starttls()
    session.login(sender, 'your password')
    send_it = session.sendmail(sender, recipients, msg.as_string())
    session.quit()
    

    Email content comes as:

    [
        {
            "latlng": [
                77.7355421,
                12.985924
            ],
            "name": "International Tech Park Bangalore 2.5 km",
            "type": "work",
            "icon": "suitcase"
        },
        {
            "latlng": [
                77.7515038,
                12.9829723
            ],
            "name": "H M Tech Park 2.3 km",
            "type": "work",
            "icon": "suitcase"
        },
        {
            "latlng": [
                77.721544,
                12.981423
            ],
            "name": "Prestige Featherlite Techapark 4.7km",
            "type": "work",
            "icon": "suitcase"
        }
    ]