When sending any message via Flask-Mail, such as below, the last line with mail.send(msg) will also result in the mail headers and content being logged.
Message("Hello", sender="from#example.com", recipients=["to#example.com"])
msg.body = 'anything'
mail.send(msg)
As my mail may contain sensitive information, I want to disable this logging entirely. Yet, playing around with the logging module, I could not find a logger configured for Flask-Mail.
How do I disable logging in Flask-Mail?
Figured this one out:
Flask-Mail uses Python's smtplib to send mail. smtplib does not use the logging module, but it prints information for debugging to stderr.
smtplib includes following method:
def set_debuglevel(self, debuglevel):
"""Set the debug output level.
A non-false value results in debug messages for connection and for all
messages sent to and received from the server.
"""
self.debuglevel = debuglevel
If we use Flask-Mail, we can set this variable when we initialize our app like this:
app = Flask(__name__)
mail = Mail(app)
app.extensions['mail'].debug = 0
Any output is now suppressed.
Related
I am trying to setup AI similar to how it is being done here
I am using Python 3.9.13 and following packages: opencensus==0.11.0, opencensus-ext-azure==1.1.7, opencensus-context==0.1.3
My code looks something like this:
import logging
import time
from opencensus.ext.azure.log_exporter import AzureLogHandler
# create the logger
app_insights_logger = logging.getLogger(__name__)
# set the handler
app_insights_logger.addHandler(AzureLogHandler(
connection_string='InstrumentationKey=00000000-0000-0000-0000-000000000000')
)
# set the logging level
app_insights_logger.setLevel(logging.INFO)
# this prints 'logging level = 20'
print('logging level = ',app_insights_logger.getEffectiveLevel())
# try to log an exception
try:
result = 1 / 0
except Exception:
app_insights_logger.exception('Captured a math exception.')
app_insights_logger.handlers[0].flush()
time.sleep(5)
However the exception does not get logged, I tried adding the explicit flush as mentioned in this post
Additionally, I tried adding the instrumentation key as mentioned in the docs, when that didn't work I tried with the entire connection string(the one with the ingestion key)
So,
How can I debug if my app is indeed sending requests to Azure ?
How can I check on the Azure portal if it is a permission issue ?
You can set the severity level before logging any kind of telemetry information to Application Insights.
Note: By default, root logger can be configured with warning severity. if you want to add other severity information you have to set like (logger.setLevel(logging.INFO)).
I am using below code to log the telemetry information in Application Insights
import logging
from logging import Logger
from opencensus.ext.azure.log_exporter import AzureLogHandler
AI_conn_string= '<Your AI Connection string>'
handler = AzureLogHandler(connection_string=AI_conn_string)
logger = logging.getLogger()
logger.addHandler(handler)
#by default root logger can be configured with warning severity.
logger.warning('python console app warning log in AI ')
# setting severity for information level logging.
logger.setLevel(logging.INFO)
logger.info('Test Information log')
logger.info('python console app information log in AI')
try:
logger.warning('python console app Try block warning log in AI')
result = 1 / 0
except Exception:
logger.setLevel(logging.ERROR)
logger.exception('python console app error log in AI')
Results
Warning and Information log
Error log in AI
How can I debug if my app is indeed sending requests to Azure ?
We cannot debug the information whether the telemetry data send to Application Insights or not. But we can see the process like below
How can I check on the Azure portal if it is a permission issue ?
Instrumentation key and connection string has the permission to access the Application Insights resource.
I'm using SMTPHandler to log my caught exceptions in my python script which requests new data to my backend.
Here's how I initialized my SMTPHandler:
# write errors to email
error_mail_subject = "ERROR: Script error in %s" % sys.argv[0]
error_mail_handler = logging.handlers.SMTPHandler(mailhost=("smtp.gmail.com", 587),
fromaddr="test#gmail.com",
toaddrs="test#gmail.com",
subject=error_mail_subject)
error_mail_handler.setLevel(logging.ERROR)
error_mail_handler.setFormatter(debug_format)
# Build the logger
logger = logging.getLogger()
logger.addHandler(error_mail_handler)
But unfortunately, I get this following error during handling of a script exception
smtplib.SMTPSenderRefused: (530, b'5.7.0 Must issue a STARTTLS command first. w15sm3562054qta.16 - gsmtp', 'test#gmail.com')
When the script calls:
logger.exception(e)
This successfully sent an email from my gmail, tested just now:
import logging.handlers
error_mail_subject = "hello, it's me"
error_mail_handler = logging.handlers.SMTPHandler(mailhost=("smtp.gmail.com", 587),
fromaddr="email",
toaddrs="email",
subject=error_mail_subject,
credentials=('email', 'password'),
secure=())
error_mail_handler.setLevel(logging.ERROR)
logger = logging.getLogger()
logger.addHandler(error_mail_handler)
logger.exception(Exception("hey"))
I also had to sign into gmail and then go here to allow access to less secure apps: https://www.google.com/settings/security/lesssecureapps
I am trying to send Email with Flask-Mail,
This is the link of tutorial: https://www.twilio.com/blog/2018/03/send-email-programmatically-with-gmail-python-and-flask.html
EMAIL_USER and EMAIL_PASSWORD are environment variables, so I try to modify ~/.bashrc file(sudo vim ~/.bashrc) and add relevant information into them (in PyCharm Terminal), but it doesn't work, that is, it cannot echo something.
How to solve this problem?
Here is the email sending code:
from flask import Flask
from flask_mail import Mail, Message
import os
app = Flask(__name__)
mail_settings = {
"MAIL_SERVER": 'smtp.gmail.com',
"MAIL_PORT": 465,
"MAIL_USE_TLS": False,
"MAIL_USE_SSL": True,
"MAIL_USERNAME": os.environ['EMAIL_USER'],
"MAIL_PASSWORD": os.environ['EMAIL_PASSWORD']
}
app.config.update(mail_settings)
mail = Mail(app)
if __name__ == '__main__':
with app.app_context():
msg = Message(subject="Hello",
sender=app.config.get("MAIL_USERNAME"),
recipients=["<example#gmail.com>"], # replace with your email for testing
body="This is a test email I sent with Gmail and Python!")
mail.send(msg)
After adding the variable to the .bashrc file you may need to restart your terminal to see it echo out. Try closing a reopening your pycharm terminal or pycharm itself.
I am attempting to get an email sent to me any time an error occurs in my Flask application. The email is not being sent despite the handler being registered. I used smtplib to verify that my SMTP login details are correct. The error is displayed in Werkzeug's debugger, but no emails are sent. How do I log exceptions that occur in my app?
import logging
from logging.handlers import SMTPHandler
from flask import Flask
app = Flask(__name__)
app.debug = True
app.config['PROPAGATE_EXCEPTIONS'] = True
if app.debug:
logging.basicConfig(level=logging.INFO)
# all of the $ names have actual values
handler = SMTPHandler(
mailhost = 'smtp.mailgun.org',
fromaddr = 'Application Bug Reporter <$mailgun_email_here>',
toaddrs = ['$personal_email_here'],
subject = 'Test Application Logging Email',
credentials = ('$mailgun_email_here', '$mailgun_password_here')
)
handler.setLevel(logging.ERROR)
app.logger.addHandler(handler)
#app.route('/')
def index():
raise Exception('Hello, World!') # should trigger an email
app.run()
The issue was which logger the handler was added to. Flask uses the werkzeug logger to log exceptions during view functions, not the base app.logger. I had to register my handler with the werkzeug logger:
logging.getLogger('werkzeug').addHandler(handler)
In addition, I had to include the port in mailhost:
handler = SMTPHandler(
mailhost=('smtp.mailgun.org', 587),
fromaddr='Application Bug Reporter <$mailgun_email_here>',
toaddrs=['$personal_email_here'],
subject='Test Application Logging Email',
credentials=('$mailgun_email_here', '$mailgun_password_here')
)
Below is a simple app to send mesg to the browser. if there is a new mesg from the redis channel it will be sent other wise send the last know value in a non-blocking way.
But i am doing something wrong. can someone please help me understand
from gevent import monkey, Greenlet
monkey.patch_all()
from flask import Flask,render_template,request,redirect,url_for,abort,session,Response,jsonify
app = Flask(__name__)
myglobaldict = {'somedata':''}
class RedisLiveData:
def __init__(self, channel_name):
self.channel_name = channel_name
self.redis_conn = redis.Redis(host='localhost', port=6379, db=0)
pubsub = self.redis_conn.pubsub()
gevent.spawn(self.sub, pubsub)
def sub(self,pubsub):
pubsub.subscribe(self.channel_name)
for message in pubsub.listen():
gevent.spawn(process_rcvd_mesg, message['data'])
def process_rcvd_mesg(mesg):
print "Received new message %s " % mesg
myglobaldict['somedata'] = mesg
g = RedisLiveData("test_channel")
#app.route('/latestmessage')
def latestmessage():
return Response(myglobaldict,mimetype="application/json")
if __name__ == '__main__':
app.run()
on the javascript side i am just using a simple $.ajax get to view the messages.
but the client http://localhost:5000/latestmessage has the old message even after the redis update.
It should be the cache issue.
You can add a timestamp or a random number to the request http://localhost:5000/latestmessage?t=timestamp sent from the ajax.
I suggest you to use POST instead of GET as http method, you eliminate the caching problem and some annoying behaviour from browsers like chrome where the requests after the first will wait for the first to complete before being sent to the webserver.
If you want to keep the GET method then you can ask jquery to make the request non cache-able by the browser with the setting parameter cache
$.ajax(..., {cache:false})