Q:

Flask email API, getting information from form tags

I have a contact page, where I want some information sent to my email account when a user submits a message. I have a file send.py set up with the configuration so far just as a test.
send.py
from flask import Flask
from flask_mail import Mail, Message

app =Flask(__name__)
mail=Mail(app)

app.config.update(
DEBUG=True,
#EMAIL SETTINGS
MAIL_SERVER='smtp.gmail.com',
MAIL_PORT=465,
MAIL_USE_SSL=True,
MAIL_USERNAME = '(myemailaccount)',
MAIL_PASSWORD = '(mypassword)'
)

mail=Mail(app)

@app.route("/")
def index():
    msg = Message(
          'Hello',
       sender='(myemailaccount)',
       recipients=
           ['(myemailaccount('])
    msg.body = "This is the email body"
    mail.send(msg)
    return "Sent"

if __name__ == "__main__":
    app.run()

On my routes.py, I have an About page, where I render an HTML template, with some <form> tags, that I want to display in the email, how can I render the HTML code into my send.py. Should I save it as arguments in my routes.py first? I should I add my send.py information inside of my routes.py?

A:

According to the docs for flask-mail, the Message class also accepts and html argument. All you need to do is assign a value of render_template("home.html") to send the rendered html page to the body of the email, assuming home.html is the About page. You must also make sure that home.html is inside the templates folder as Flask renders all html templates from this folder. 
I present a small example. Note that I haven't used a separate send.py as I wanted to call the send_message function on a different route, so I added it to the same routes.py file:
Project structure:
root
└───templates
    |___ home.html
|___ routes.py

home.html
<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Send Message</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="">
</head>
<body>
    <form class="form-inline" action="/send_message" method="POST">
        <label>Enter name:</label>
        <input type="text" name="name">
        <input type="submit" value="Send Message" class="btn btn-primary">
        <p>{{confirm_msg}}</p>
    </form>
    <script></script>
</body>
</html>

routes.py
from flask import Flask, render_template, request
from flask_mail import Mail, Message

app =Flask(__name__)

app.config.update(
DEBUG=True,
#EMAIL SETTINGS
MAIL_SERVER='smtp.gmail.com',
MAIL_PORT=465,
MAIL_USE_SSL=True,
MAIL_USERNAME = 'myemailaccount',
MAIL_PASSWORD = 'mypassword'
)

mail=Mail(app)

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/send_message", methods=['POST'])
def send_message():
    name = request.form.get('name')
    msg = Message(
       subject='Hello ' + name,
       sender='myemailaccount',
       recipients=
           ['myemailaccount'],
       html=render_template("home.html"))
    mail.send(msg)
    confirm_msg = "Your message has been sent!"
    return render_template("home.html", confirm_msg=confirm_msg)

    if __name__ == "__main__":
        app.run(debug=True, port=5000)

Explanation:
The home.html page renders a simple form that accepts a name. This name is sent to the send_message() function using Flask's request.form.get() function. The name is then sent in the Subject line of the email. Notice the html argument in the Message() class, this sends the rendered form in the body of the email. Finally, a message is displayed confirming the message was sent. As this is a POST request(sending email), we must specify the method both in the <form> tag and the route /send_message. The <form> tag also has an action attribute that makes the function call to the send_message() function in the /send_message route when the form is submitted.
Caveats:
Make sure mail=Mail(app) is called after app.config.update() as shown in above code. This is to make sure the config settings are applied successfully before the mail object is created. Next, you may have to enable a security setting in your gmail account to be able to send the email(I had to do this) for testing purposes. This is because gmail will block any less secure apps that try to authenticate on your account. More details here.
I have tested the above code and successfully received the simple html form rendered in the body of the email.

