2

The main thing is how to create the dynamic html body content for the email using API only?

Simple mail creation and sending is easy. What I have tried:

import smtplib
from os.path import basename
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate

from flask import Flask, request, jsonify
import re
import csv

app = Flask(__name__)
app.run(debug=True,host='0.0.0.0', port=8085)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

#curl -F 'files=@email_body.html'  -F metadata="{'send_from':'abc@mydomain.com', 'subject':'Hi from massmail api', 'send_to':'xyz2020@gmail.com'}"  -X POST http://localhost:8085/mail


@app.route("/mail", methods=['POST'])
def send_mail():
    server = "127.0.0.1"
    smtp = smtplib.SMTP(server)
    data = request.get_json(force=True)
    files = request.files['files']
    metadata = request.form.get("metadata")
    send_from = None
    mmeta = eval(metadata)
    send_from = mmeta['send_from']
    subject = mmeta["subject"]
    text = 'Hi, how do you do. We are fine mailing'
    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = mmeta["send_to"]
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = mmeta["subject"]
    msg.attach(MIMEText(text))
    #for f in files or []:
    #    print(f,' ---file attachment')
    #    with open(f, "rb") as fil:
        #with app.open_resource(f, "rb") as fil:
   #         part = MIMEApplication(
   #             fil.read(),
   #             Name=basename(f)
   #         )
            # After the file is closed
   #         part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
    #        msg.attach(part)
    smtp.sendmail(send_from, msg["To"], msg.as_string())
    #print('mail sent:', row['email'])

    smtp.close()
    return jsonify({'Mail sent successfully' : subject}), 200


if __name__ == "__main__":
    app.run(debug=True,host='0.0.0.0', port=8085)

I also need to create normal text body for the mail in the same way for the same email. The best option is to upload the text and html body content file. But how to work with the api and the corresponding curl for the same, please guide.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
user956424
  • 1,611
  • 2
  • 37
  • 67
  • Looking at [this answer](https://stackoverflow.com/a/42138331/3920623) may help you... – constt Mar 03 '22 at 07:01
  • @constt I need to uplad the html and txt content dynamically without storing it on the mail server i.e read bytes from the source file and create the body content. Also what is the corresponding curl for the same – user956424 Mar 04 '22 at 09:35
  • 1
    OK, got you! Then, you can upload your `.html` and `.txt` files to the REST API server with a POST request, read files' content into variables and use the `flask.render_template_string` function to create the mail body dynamically, and finally, send the resulting email using `flask_mail`. Does it work for you? – constt Mar 05 '22 at 10:25
  • @constt please can you share the curl for the same ? – user956424 Mar 07 '22 at 05:45
  • Yes, sure! Here it is `curl -X POST -F txt=@email.txt -F html=@email.html http://localhost:8085/mail` – constt Mar 08 '22 at 06:07
  • @constt This uploads the file, how can we stream it without uploading? – user956424 Mar 10 '22 at 05:20
  • I just cannot get you right, sorry... What does it mean "to stream" a file? You just upload it to the server, then you read its contents into a variable. You don't have to save the file on to the disk; just read it, make the mail body, and send it. So simple :) – constt Mar 11 '22 at 07:17

1 Answers1

1

This seems to be the main question you are asking based on the comments below your quesion: How do I upload the html and txt files to your flask app via curl? And my suggestion is to review this answer which is a post via curl using a name field for text and a filedata field for file storage:

From mata's answer:

curl -i -X PUT -F name=Test -F filedata=@SomeFile.pdf "http://localhost:5000/" 

python:

file = request.files['filedata']   # gives you a FileStorage
test = request.form['name']        # gives you the string 'Test'
Allen M
  • 1,423
  • 9
  • 15
  • This should not upload the html file but stream its contents to a variable and create the email body content dynamically. Above curl will upload the file to the server. I dont' want to delete it once the mail is sent – user956424 Mar 08 '22 at 08:12
  • 1
    The curl is hitting your flask app with the file that is then accessible via the request.files['filedata']. So the file contents are in memory in the variable only. You can write the file to disk but you don't have to. You can use the variable containing the uploaded file contents to render the template from string with this call: `flask.render_template_string` – Allen M Mar 10 '22 at 23:26