Problems using Gmail with Python 2.7 - python-2.7

New guy here....
I have searched all over this site and tried multiple variations on my code, but I am still receiving a login error when I attempt to send an email through Gmail using Python 2.7. I have enabled the "less secure apps" thing on my Gmail account and I am still receiving this error:
Traceback (most recent call last):
File "T:\OC\Projects\Aquadat\Scripting\RawArcPyScripts\sendEmailWithAttachment_Aquadat.py", line 28, in
svr.login(sender,pwd)
File "C:\Python27\ArcGIS10.3\lib\smtplib.py", line 615, in login
raise SMTPAuthenticationError(code, resp)
SMTPAuthenticationError: (534, '5.7.14 Please log in via your web browser and\n5.7.14 then try again.\n5.7.14 Learn more at\n5.7.14 https://support.google.com/mail/answer/78754 z33sm11383168qta.48 - gsmtp')
Here is the problematic code. I grabbed a lot of it off of this site and tried to adapt it to my application. Any help would be most appreciated.
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
svr = smtplib.SMTP_SSL('smtp.gmail.com',465)
svr.ehlo()
svr.starttls()
svr.ehlo()
sender = 'my_name'
pwd = 'my_pwd'
svr.login(sender,pwd)
rcvr = sender #Change to arcpy.GetParameterAsText(x) when working
def send_mail(send_from,send_to,subject,text,files,
server):
assert isinstance(send_to, list)
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(text))
for f in files or []:
with open(f, "rb") as fil:
part = MIMEApplication(
fil.read(),
Name=basename(f)
)
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)
smtp = smtplib.SMTP_SSL(server)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()

Related

Sending Emails on GAE through smtp.gmail.com in Python

After reading Google's documentation it should be possible to send an email via smtp.gmail.com on port 465 or 587 on GAE standard.
Reference: https://cloud.google.com/appengine/docs/standard/python/sockets/#limitations_and_restrictions_if_lang_is_java_java_7_runtime_only_endif
What is not documented is how to use the socket library.
I am able to send an email via smtplib running the python script locally.
server = smtplib.SMTP_SSL("smtp.gmail.com", 587)
server.ehlo()
server.login(gmail_access["email"], gmail_access["password"])
server.sendmail(gmail_access["email"], report.owner, msg.as_string())
server.close()
When trying to run the code with GAE's dev_appserver I get the nondescript error "[Errno 13] Permission denied"
Any assistance would be greatly appreciated.
Oddly enough the error only occurs when trying to run the code locally with dev_appserver.py. After deploying the code to App Engine it worked.
import socket
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart("alternative")
msg["Subject"] = subject
msg["From"] = gmail_access["email"]
msg["To"] = report.owner
msg.attach(MIMEText(body, "html"))
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server.ehlo()
server.login(gmail_access["email"], gmail_access["password"])
server.sendmail(gmail_access["email"], report.owner, msg.as_string())
server.close()

AWS Lambda - Generate CSV In Memory and send it as an attachment to an Email

I'm trying to write an AWS Lambda service using Python 2.7 that will generate an In-Memory CSV file and email it as an attachment. I feel like I'm close with this script based on what I've learned but I'm not quite there.
# Import smtplib for the actual sending function
import smtplib
import sys
import csv
import cStringIO
from os.path import basename
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
# Import the email modules we'll need
server = smtplib.SMTP('smtp.postmarkapp.com', 587)
server.starttls()
server.login('.....','.....')
list = []
row1 = ["One","Two","Three"]
list.append(row1)
msg = MIMEMultipart()
msg['To'] = "daniel#mydomain.com"
msg['From'] = "noreply#mydomain.com"
msg['Subject'] = "DG Test subject"
msg.attach(MIMEText("Test Message"))
csv_buffer = cStringIO.StringIO()
writer = csv.writer(csv_buffer, lineterminator='\n')
writer.writerow(["1","2","3"])
for row in list:
writer.writerow(row)
print(csv_buffer.getvalue())
msg.attach(csv_buffer)
try:
response = server.sendmail(msg['From'], ["daniel#mydomain.com"],msg.as_string())
server.quit()
except AttributeError as error:
print(error)
else:
print(response)
This gives me the following error:
1,2,3
One,Two,Three
'cStringIO.StringO' object has no attribute 'get_content_maintype'
Basically it comes down to not being sure how to use the csv_buffer object. Assuming I just need to add that attribute to the object somehow but I'm not quite sure how. If I try to add any additional arguments to the .attach() line, it complains that I have too many arguments.
Thanks!
I figured it out, thanks to stitching together a few SO posts.
import cStringIO
import csv
csv_buffer = cStringIO.StringIO()
writer = csv.writer(csv_buffer, delimiter=',', quoting=csv.QUOTE_ALL)
writer.writerow(["1","2","3"])
for row in list:
writer.writerow(row)
print(csv_buffer.getvalue())
# new lines
csv_file = MIMEText(csv_buffer.getvalue())
attachment = csv_file.add_header('Content-Disposition', 'attachment', filename="csv_file.csv")
msg.attach(csv_file)

Getting "LazyImporter object is not callable" error when trying to send email using python smtplib

Getting "LazyImporter' object is not callable" error when trying to send email
with attachments using python smtplib from gmail.
I have enabled allow less security app setting on in sender gmail
Code:
import smtplib
from email import MIMEBase
from email import MIMEText
from email.mime.multipart import MIMEMultipart
from email import Encoders
import os
def send_email(to, subject, text, filenames):
try:
gmail_user = 'xx#gmail.com'
gmail_pwd = 'xxxx'
msg = MIMEMultipart()
msg['From'] = gmail_user
msg['To'] = ", ".join(to)
msg['Subject'] = subject
msg.attach(MIMEText(text))
for file in filenames:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(file, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"'% os.path.basename(file))
msg.attach(part)
mailServer = smtplib.SMTP("smtp.gmail.com:587") #465,587
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
mailServer.close()
print('successfully sent the mail')
except smtplib.SMTPException,error::
print str(error)
if __name__ == '__main__':
attachment_file = ['t1.txt','t2.csv']
to = "xxxxxx#gmail.com"
TEXT = "Hello everyone"
SUBJECT = "Testing sending using gmail"
send_email(to, SUBJECT, TEXT, attachment_file)
Error : File "test_mail.py", line 64, in
send_email(to, SUBJECT, TEXT, attachment_file)
File "test_mail.py", line 24, in send_email
msg.attach(MIMEText(text))
TypeError: 'LazyImporter' object is not callable
Like #How about nope said, with your import statement you are importing the MIMEText module and not the class. I can reproduce the error from your code. When I import from email.mime.text instead, the error disappear.

Paramiko start_server Not Working

I created a program for accessing a server via Paramiko and sockets.
#make imports
from socket import *
from datetime import datetime
from pickle import load, dump
from Crypto.Hash import SHA256
from subprocess import check_output as exeCMD
from sqlite3 import connect as SQLconnect
import paramiko, sys, threading, os
#get password from file
pasword = load(open("usrData/pswd.txt", "rb"))
#class for initiating server connection with client
class Server(paramiko.ServerInterface):
#initialize object
def __init__(self):
self.event = threading.Event()
#check password for user entry
def check_auth_password(self, username, password):
#where the error is
givenpswdHash = SHA256.new(password)
print(givenpswdHash.hexdigest())
if (username in unameList) and (givenpswdHash.hexdigest() == pasword):
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED
#what to execute in command line
def terminal(hostIP, hostPort, hostKeyPath, hostKeyPswd):
#create sockets before this etc...
#create server instance
server = Server()
#get server onto session
#where we call out server function
session.start_server(server=server)
#continue talking to client
When I launch the server, and get a client to connect to it, I get this error :
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "./terminalServer.py", line 212, in <module>
main()
File "./terminalServer.py", line 209, in main
terminal(ip, port, keyPath, keyPswd)
File "./terminalServer.py", line 142, in terminal
session.start_server(server=server)
File "/usr/local/lib/python2.7/dist-packages/paramiko/transport.py", line 471, in start_server
raise e
ValueError: CTR mode needs counter parameter, not IV
It has something to do with the Crypto I added for password authentication. If anyone knows howto solve this issue, please
leave a comment. Thank you in advance.
All I had to do is replace all the alpha versions of pycrypto with the stable version. The current stable version (Sept. 1st 2015) for pycrypto is 2.6.1 and for paramiko it's 1.14.2.

can't send mails using flask, any ideas?

L.T:
Ok now it works. I had to instantiate Mail() class after configuration(ie. app.config) :)
i have this error:
host = smtplib.SMTP(self.mail.server, self.mail.port)
File "C:\Python27\lib\smtplib.py", line 256, in __init__
(code, msg) = self.connect(host, port)
File "C:\Python27\lib\smtplib.py", line 316, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "C:\Python27\lib\smtplib.py", line 291, in _get_socket
return socket.create_connection((host, port), timeout)
File "C:\Python27\lib\socket.py", line 571, in create_connection
raise err
error: [Errno 10061] No connection could be made because the target machine actively refused it
I'm trying to build a site for myself, and i'm stuck at the part of sending e-mails because of the above error. Thing is i opened my port (that's because i'm behind a router). One thing to note is that using 'standalone' smtplib works but the one from flask doesn't. I'll post what works and does not. I don't know what is the problem. I modified address from socket.py to my 'localhost' and port 465 because i thought that was the problem. Hence i tried almost everything i could but in avail. Could someone help me a little bit here? Thanks.
This doesn't work(hello.py):
from flask import Flask
from flask_mail import Mail
from flask_mail import Message
from flask.ext.script import Manager
import os
mail = Mail()
app = Flask(__name__)
mail.init_app(app)
mail = Mail(app)
manager = Manager(app)
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
#app.route('/')
def index():
msg = Message('Hello',
sender = 'my_mail#gmail.com',
recipients = ['my_mail#gmail.com'])
msg.body = 'testing'
msg.html = '<b>testing</b>'
mail.send(msg)
app.debug = True
if __name__ == '__main__':
manager.run()
And tried a more minimalist way to see if this works, and it works, i can send mail to myself(mail.py):
import smtplib
from hello import app
gmail_user = app.config['MAIL_USERNAME']
gmail_pwd = app.config['MAIL_PASSWORD']
FROM = 'my_mail#gmail.com'
TO = ['my_mail#gmail.com']
message = 'test'
server_ssl = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server_ssl.ehlo() # optional, called by login()
server_ssl.login(gmail_user, gmail_pwd)
# ssl server doesn't support or need tls, so don't call server_ssl.starttls()
server_ssl.sendmail(FROM, TO, message)
#server_ssl.quit()
server_ssl.close()
print 'successfully sent the mail'
Bump...
It has nothing to do with objects. Functions are designed the way they return a value, and you can assign that value the same way you put the input into the list.
You just run the function, take the value it returned and put it into the variable.