can't send mails using flask, any ideas? - python-2.7

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.

Related

Flask heroku app won't let me assign some config settings

I have a flask MySql app that is working correctly on local, but when I deployed to heroku it gives me below error:
2022-02-12T05:28:26.114583+00:00 app[web.1]: File "/app/app.py", line 38, in <module>
2022-02-12T05:28:26.114583+00:00 app[web.1]: app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
2022-02-12T05:28:26.114584+00:00 app[web.1]: TypeError: 'str' object does not support item assignment
It did the same thing when I used app.debug = False. I tried to fix it my removing it, but now it gives me above error.
I tried commenting each line that gives error and looks like all below lines give the same error:
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_TYPE'] = "filesystem"
Few lines before these lines I have app.config['MAIL_USE_SSL'] = True and some other mail config settings (port, server, username, password) which none of them give error, so I don't understand what the problem is. When I google the error it is related with the immutability of strings, so I don't understand what is the problem on my case.
When I comment all of the above it gives me:
2022-02-12T08:11:34.109191+00:00 app[web.1]: Session(app)
2022-02-12T08:11:34.109196+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.8/site-packages/flask_session/__init__.py", line 54, in __init__
2022-02-12T08:11:34.109196+00:00 app[web.1]: self.init_app(app)
2022-02-12T08:11:34.109196+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.8/site-packages/flask_session/__init__.py", line 61, in init_app
2022-02-12T08:11:34.109197+00:00 app[web.1]: app.session_interface = self._get_interface(app)
2022-02-12T08:11:34.109197+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.8/site-packages/flask_session/__init__.py", line 64, in _get_interface
2022-02-12T08:11:34.109197+00:00 app[web.1]: config = app.config.copy()
2022-02-12T08:11:34.109198+00:00 app[web.1]: AttributeError: 'str' object has no attribute 'copy'
I'm using JawsDB MySQL addon on heroku if that is related with this issue.
Below is the code:
from flask import Flask
from flask_mail import Mail
from os import environ
from flask_session import Session
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.domain.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = "mail#domain.com"
app.config['MAIL_PASSWORD'] = environ.get("MAIL_PASSWORD")
mail = Mail(app)
MY_APP_ENV = environ.get("MY_APP_ENV")
if MY_APP_ENV == 'prod':
app.debug = False
app.config = environ.get("JAWSDB_URL")
else:
app.debug = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:#localhost/my_app'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_TYPE'] = "filesystem"
Session(app)
CORS(app)
db = SQLAlchemy(app)
# rest is the routings etc.
Here's the problem:
app.config = environ.get("JAWSDB_URL")
You are overwriting app.config with a single value from the environment.
Do you mean something like this instead?
app.config["SQLALCHEMY_DATABASE_URI"] = environ.get("JAWSDB_URL")

Not sure why my email script is not sending an email

It was working but after updating my Raspberry Pi, my python script to send an email is not sending and I'm not sure why. It seems to just hang without throwing any error messages and I have to Ctrl+C to stop it every time, otherwise it'll just sit there indefinitely.
Here is my code...
import smtplib, datetime
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
email_send = [sender email]
email_receive = [my email]
password = [password]
subject = 'Test Subject'
#sYMD = datetime.date.today().strftime('%y%m%d')
#lpath = 'C:/Path/to/files/'
files = ['log1.txt', 'log2.txt']
msg = MIMEMultipart()
msg['From'] = email_send
msg['To'] = email_receive
msg['Subject'] = subject
body = """\
Test Message."""
msg.attach(MIMEText(body, 'plain'))
#filename = x.strftime("%y%m%d")+'_log.txt'
for file in files:
part = MIMEBase('application', "octet-stream")
part.set_payload(open(file, "rb").read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',
'attachment; filename="%s"' % file)
msg.attach(part)
text = msg.as_string()
server = smtplib.SMTP('smtp.office365.com', 587)
server.starttls()
server.login(email_send, password)
server.sendmail(email_send, email_receive, text)
server.quit()
Here is what its doing when I run the script...
pi#raspberrypi: python send_email.py
^CTraceback (most recent call last):
File "send_email.py", line 36, in <module>
server = smtplib.SMTP('smtp.office365.com', 587)
File "/usr/lib/python2.7/smtplib.py", line 265, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python2.7/smtplib.py", line 317, in connect
(code, msg) = self.getreply()
File "/usr/lib/python2.7/smtplib.py", line 361, in getreply
line = self.file.readline(_MAXLINE + 1)
File "/usr/lib/python2.7/socket.py", line 480, in readline
data = self._sock.recv(self._rbufsize)
KeyboardInterrupt
Thanks for any help you can give.
Hmm sounds like the connection is timing out. Is it possible the client is unable to connect to the specified server and port? Try connecting directly with nc or telnet to confirm.
You can also pass a timeout value in seconds to the SMTP call:
server = smtplib.SMTP('smtp.office365.com', 587, timeout=5)

ssl.SSLEOFError while sending emails through Django

Settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER = 'no_reply#domain.com'
SERVER_EMAIL = 'no_reply#domain.com'
DEFAULT_DO_NOT_REPLY = 'User <no_reply#domain.com>'
EMAIL_HOST_PASSWORD = 'xxxxxxxxx'
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
Class
class EmailThread(threading.Thread):
def __init__(self, subject, context, recipient, template):
self.subject = subject
self.recipient = recipient
self.message = get_template(template).render(context)
threading.Thread.__init__(self)
def run(self):
msg = EmailMessage(
subject=self.subject,
from_email=settings.DEFAULT_DO_NOT_REPLY,
to=self.recipient,
body=self.message
)
msg.content_subtype = "html"
try:
msg.send(fail_silently=False)
log.info("E-mail triggered. Subject: '%s', to: %s" % (self.subject, self.recipient))
except Exception as e:
log.exception(e)
Usage
def notify_admin_blocked_account(user):
"""
Sends sends an email when the account is blocked
:return:
"""
email = EmailThread(
subject='{}, your account has been blocked'.format(user),
context={
'user': user,
'login_attempts': settings.MAX_STAFF_PWD_ATTEMPTS,
},
recipient=[user.email,],
template='mail/notify_admin_blocked_account.html'
)
email.start()
Error
[ERROR][2017-08-01 10:40:26,835][mail] EOF occurred in violation of protocol (_ssl.c:645)
Traceback (most recent call last):
File "./bin/mail.py", line 27, in run
msg.send(fail_silently=False)
File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/message.py", line 348, in send
return self.get_connection(fail_silently).send_messages([self])
File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 104, in send_messages
new_conn_created = self.open()
File "/home/web/sites/envs/project/lib/python3.5/site-packages/django/core/mail/backends/smtp.py", line 69, in open
self.connection.starttls(keyfile=self.ssl_keyfile, certfile=self.ssl_certfile)
File "/usr/lib/python3.5/smtplib.py", line 766, in starttls
server_hostname=self._host)
File "/usr/lib/python3.5/ssl.py", line 377, in wrap_socket
_context=self)
File "/usr/lib/python3.5/ssl.py", line 752, in __init__
self.do_handshake()
File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
self._sslobj.do_handshake()
File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:645)
I have some weird behavior when I try to send an e-mail (async) with Django. I really wanted to avoid third-party apps being installed to reduce code fragmentation - specially with some of them that seem to use crontab.
It is worth noticing that the error doesn't happen all the time. However, even though it doesn't happen, sometimes e-mails are not sent either. Only some of them manage to go through.
On my development environment it runs fine, and I can send the e-mails. However, on my production environment (EC2 instance) it simply doesn't work.
If I trigger an e-mail through the normal process, it is not sent. If I login to the server, open the manage.py shell, import a project and call the function that sends e-mail, sometimes I receive both triggered and manually-triggered e-mails or get an error (the one bellow).
My solution was to use Django-Mailer. It fragments the project, something I wanted to avoid, but its usage is pretty minimalist.

Problems using Gmail with 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()

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.