i have a couple issues with sending Email with Python using my own SMTP/IMAP Server.
Here's the code :
import sys
import imaplib
import smtplib
import email
import email.header
import datetime
smtp_session = smtplib.SMTP(mail_server)
try:
smtp_session.ehlo()
except :
err = sys.exc_info()[0]
message = """\
From: %s
To: %s
Subject: %s
%s""" % (email_from, ", ".join([email_to]), "subject", "body")
try:
smtp_session.sendmail(email_from, [email_to], message)
smtp_session.quit()
except:
err = sys.exc_info()[0]
if err != "" or err !=None:
NagiosCode = 2
NagiosMsg = "CRITICAL: Script execution failed : " + str(err)
Ok so for the two issues i have:
When i send a mail from my script i need the mail to appear in the "sent items" diretory of my mail box who send it.
Second issue i have : When sending my mail i catch this exception :
<class 'smtplib.SMTPException'>
EDIT : Exception trace :
File "checkIMAP_client.py", line 153, in <module>
smtp_session.login(login, password)
File "/usr/lib64/python2.6/smtplib.py", line 559, in login
raise SMTPException("SMTP AUTH extension not supported by server.")
smtplib.SMTPException: SMTP AUTH extension not supported by server.
EDIT :
It seems my SMTP server doesn't require authentification.
But the program still returns me an empty exception.
Code is updated.
So for the two issues i had, i found the answers thanks to the above comments :
Putting my sent e-mail via SMTP in the right mailbox in the Sent directory :
https://pymotw.com/2/imaplib/
Look for "Uploading messages"
Exception issue :
I had no auth methods set on my SMTP server.
Related
I'm attempting to create a program that reads the unread emails and responds to the send with the usage of auto-reply which would be triggered by the use of certain phrases. I'm doing this in Mac OSX in Visual Code. I'm able to connect to IMAP and SMTP but then I get the following error,
smtplib.SMTPServerDisconnected: please run connect() first.
I tried to use an exception that was part of the smtplib which should be raised if the SMTP server disconnects, but it doesn't do anything.
def smtp_init():
print("Initializing STMP . . .",end = '')
global s
s = smtplib.SMTP(smtpserver,smtpserverport)
status_code = s.starttls()[0]
if status_code is not 220:
raise Exception('Starting tls failed: '+ str(status_code))
status_code = s.login(radr,pwd)[0]
if status_code is not 235:
raise Exception('SMTP login failed: '+ str(status_code))
print("Done. ")
except smtplib.SMTPServerDisconnected:
smtp_init()
continue
The expected results would be to have the program in a loop checking the emails and responding to them if they have a phrase that corresponds to the auto-reply.
I have a block of code which runs fine in my python application. When the celery worker runs this code, it fails to do so. Here is the code block:
def send_case_complete_email(owner_name, case_name, email):
try:
with open("utility/email/buildCompleteEmail.txt", 'rb') as email_file:
text = email_file.read().decode("utf-8")
text = text.replace("<owner>", owner_name).replace("<caseName>", case_name)
msg = MIMEText(text)
msg['Subject'] = "Case \'" + case_name + "\' is ready"
msg['From'] = config_access.app_configs['email']['from']
msg['To'] = email
server = smtplib.SMTP(config_access.app_configs['email']['host'])
if config_access.app_configs['email']['tls']:
server.starttls()
server.login(config_access.app_configs['email']['user'], config_access.app_configs['email']['password'])
server.sendmail(config_access.app_configs['email']['from'], email, msg.as_string())
print("Case completion email sent to " + email)
except Exception as e:
print(e)
With the error from the celery worker:
[2017-06-02 15:07:19,031: WARNING/PoolWorker-1] (500, b"5.3.3 Unrecognized command 'bm8ucmVwbHlAcGx1cmlsb2NrLmNvbQ==' [BN3PR03CA0080.namprd03.prod.outlook.com]")
Why would this happen?
The message you have posted is just a warning message. Are you sure the error here is from this piece of code. You can use logging here. Python Logging
Or if you are using Django then,Django Logging
. You can use logger.exception to get the full stacktrace. This shall tell you where exactly is the error coming from.
I'm trying to send an email using Python and used the following code:
import smtplib
import datetime
SERVER = "localhost"
PORT = 1025
FROM = "me#mydevice.com"
TO = ["myemailaddress#something.com"]
SUBJECT = "test"
dt = datetime.datetime.now()
TEXT = "blabla bla # " + str(dt)
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ",".join(TO), SUBJECT, TEXT)
server = smtplib.SMTP(SERVER, PORT)
server.sendmail(FROM, TO, message)
server.quit()
Not having any STMP server already installed/setup, I simply used this:
python -m smtpd -n -c DebuggingServer localhost:1025
The code seems to run fine, no errors, and the server even notifies me with this:
---------- MESSAGE FOLLOWS ----------
From: me#mydevice.com
To: myemailaddress#something.com
Subject: test
X-Peer: 127.0.0.1
blabla bla # 2014-01-29 14:44:37.219724
------------ END MESSAGE ------------
'myemailaddress#something.com' is, of course, a representation of a real, existing email address while 'me#mydevice.come' is made up.
But no email arrives at myemailaddress#something.com...
Am I missing something obvious here?
I read somewhere (sorry but cannot find it anymore) that services likes gmail may well block emails coming from non-static IP addresses. Could that be what is going on here?
According to python documentation on the smtpd module:
class smtpd.DebuggingServer(localaddr, remoteaddr)
Create a new debugging server. Arguments are as per SMTPServer.
Messages will be discarded, and printed on stdout.
So the module doesn't actually send an email. It prints it in the terminal.
I'm getting this error:
raise SMTPRecipientsRefused(senderrs) smtplib.SMTPRecipientsRefused:
{'example#hotmail.com': (550, '5.1.1 : Recipient
address rejected: hotmail.com')}
when trying to run my python script.
Regardless of what recipient address I put in, it will still give me the same error. I have postfix's configuration installed as local and it properly recognizes 'localhost' but not any of the sender addresses. This is my code:
import smtplib
def sendEmail(addressFrom, addressTo, msg):
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(addressFrom, addressTo, msg)
server.quit()
msg = "This is the content of the email"
addressFrom = ""
addressTo = "example#hotmail.com"
sendEmail(addressFrom, addressTo, msg)
And this is the main.cf file for postfix. Looking at it now,mydestination is only set to local addresses, could that be the issue?
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
myhostname = user-desktop
**mydomain = hotmail.com**
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
**mydestination = user-desktop, localhost.$mydomain www.$mydomain**
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = loopback-only
default_transport = error
relay_transport = error
inet_protocols = ipv4
Thank you in advance
I faced a similar issue in my python script.
Use the following command to change the configuration of Postfix to Internet Site
sudo dpkg-reconfigure postfix
Change the Postfix configuration to Internet Site. This will resolve your problem and can send mail to any mail address.
Your code looks OK. This is very likely a configuration issue with Postfix.
Hi I had a similar problem. I was getting the error:
(550, '5.7.1 Client does not have permissions to send as this sender')
Turning on TLS, adding the ehlo commands explicitly fixed the problem for me. Hope it helps.
def mail(msg):
email_server = "mail.some-server.com"
sender = "me#some-server.com"
to = "you#some-server.com"
subject = "How about those Mariners!"
headers = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (sender, to, subject)
text = msg
message = headers + text
mailServer = smtplib.SMTP(email_server)
mailServer.set_debuglevel(1)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login('user', 'pass')
mailServer.ehlo()
mailServer.sendmail(sender, to, message)
mailServer.quit()
I'm new to Python, so forgive me if I am missing something obvious.
I am using urllib.FancyURLopener to retrieve a web document. It works fine when authentication is disabled on the web server, but fails when authentication is enabled.
My guess is that I need to subclass urllib.FancyURLopener to override the get_user_passwd() and/or prompt_user_passwd() methods. So I did:
class my_opener (urllib.FancyURLopener):
# Redefine
def get_user_passwd(self, host, realm, clear_cache=0):
print "get_user_passwd() called; host %s, realm %s" % (host, realm)
return ('name', 'password')
Then I attempt to open the page:
try:
opener = my_opener()
f = opener.open ('http://1.2.3.4/whatever.html')
content = f.read()
print "Got it: ", content
except IOError:
print "Failed!"
I expect FancyURLopener to handle the 401, call my get_user_passwd(), and retry the request.
It does not; I get the IOError exception when I call "f = opener.open()".
Wireshark tells me that the request is sent, and that the server is sending a "401 Unauthorized" response with two headers of interest:
WWW-Authenticate: BASIC
Connection: close
The connection is then closed, I catch my exception, and it's all over.
It fails the same way even if I retry the "f = opener.open()" after IOError.
I have verified that my my_opener() class is working by overriding the http_error_401() method with a simple "print 'Got 401 error'". I have also tried to override the prompt_user_passwd() method, but that doesn't happen either.
I see no way to proactively specify the user name and password.
So how do I get urllib to retry the request?
Thanks.
I just tried your code on my webserver (nginx) and it works as expected:
Get from urllib client
HTTP/1.1 401 Unauthorized from server with Headers
Connection: close
WWW-Authenticate: Basic realm="Restricted"
client tries again with Authorization header
Authorization: Basic <Base64encoded credentials>
Server responds with 200 OK + Content
So I guess your code is right (I tried it with python 2.7.1) and maybe the webserver you are trying to access is not working as expected. Here is the code tested using the free http basic auth testsite browserspy.dk (seems they are using apache - the code works as expected):
import urllib
class my_opener (urllib.FancyURLopener):
# Redefine
def get_user_passwd(self, host, realm, clear_cache=0):
print "get_user_passwd() called; host %s, realm %s" % (host, realm)
return ('test', 'test')
try:
opener = my_opener()
f = opener.open ('http://browserspy.dk/password-ok.php')
content = f.read()
print "Got it: ", content
except IOError:
print "Failed!"