2012-09-23 44 views
6

Estoy usando smtplib y estoy enviando correos electrónicos de notificación desde mi aplicación. Sin embargo, noté que a veces (especialmente cuando hay mucho tiempo de inactividad entre el envío del correo) recibo un error de SMTPServerDisconnected.python. ¿Puedo verificar si el Servidor SMTP está desconectado (para que pueda volver a conectarme?)

supongo que hay 2 soluciones para este saber (ninguno de ellos, aunque)

  1. aumentar el tiempo de inactividad entre el envío de correos
  2. reconexión cuando la conexión se ha reducido.

Creo que la segunda solución parece más elegante. ¿Pero cómo puedo hacer eso?

editar: Estoy añadiendo el código

from smtplib import SMTP 
smtp = SMTP() 
smtp.connect('smtp.server.com') 
smtp.login('username','password') 

def notifyUser(): 
    smtp.sendmail(from_email, to_email, msg.as_string()) 
+0

¿Está utilizando 'SMTP.sendmail' para enviar los correos electrónicos? Eso debería encapsular todos los comandos de nivel inferior a partir de 'connect'. ¿O intenta mantener una sesión SMTP abierta y volver a utilizarla para varios correos electrónicos? –

+0

He agregado el código que solicitó. Espero que aclare la pregunta un poco más. :-) – xpanta

Respuesta

4

Si su caso de uso es el envío de un único mensaje a la vez, la solución que parece más correcta para mí, sería la creación de una nueva sesión SMTP para cada mensaje:

from smtplib import SMTP 

smtp = SMTP('smtp.server.com') 

def notifyUser(smtp, smtp_user, smtp_password, from_email, to_email, msg): 
    smtp.login(smtp_user, smtp_password) 
    smtp.sendmail(from_email, to_email, msg.as_string()) 
    smtp.quit() 

Si el servidor SMTP no requiere que se autentique (un caso común), esto se puede simplificar aún más a:

from smtplib import SMTP 

smtp = SMTP('smtp.server.com') 

def notifyUser(smtp, from_email, to_email, msg): 
    smtp.sendmail(from_email, to_email, msg.as_string()) 
    smtp.quit() 

Si es común tener más de un mensaje para enviar a la vez, y desea optimizar este caso al reutilizar la misma sesión SMTP para el grupo de mensajes (se puede simplificar como arriba si no necesita iniciar sesión al servidor SMTP):

from smtplib import SMTP 

smtp = SMTP('smtp.server.com') 

def notifyUsers(smtp, smtp_user, smtp_password, from_to_msgs): 
    """ 
    :param from_to_msgs: iterable of tuples with `(from_email, to_email, msg)` 
    """ 
    smtp.login(smtp_user, smtp_password) 
    for from_email, to_email, msg in from_to_msgs: 
     smtp.sendmail(from_email, to_email, msg.as_string()) 
    smtp.quit() 
+0

gracias. Eso sería suficiente. Una cosa más. Is es 'smtp.close()' o 'smtp.quit()'? – xpanta

+1

De acuerdo con la documentación [quit()] (http://docs.python.org/library/smtplib.html#smtplib.SMTP.quit). –

+0

Usa una instrucción 'with' en lugar de' quit' explícita. –

7

Sí, puede verificar si la conexión está abierta. Para hacer esto, emita un comando de NOOP y pruebe el estado == 250. De lo contrario, abra la conexión antes de enviar su correo.

def test_conn_open(conn): 
    try: 
     status = conn.noop()[0] 
    except: # smtplib.SMTPServerDisconnected 
     status = -1 
    return True if status == 250 else False 

def send_email(conn, from_email, to_email, msg): 
    if not test_conn_open(conn): 
     conn = create_conn() 
    conn.sendmail(from_email, to_email, msg.as_string()) 
    return conn # as you want are trying to reuse it. 

Tenga en cuenta que usted está haciendo esto como la apertura de una conexión, por ejemplo con Gmail, consume tiempo, como 2-3 segundos. Posteriormente, para optimizar al enviar múltiples correos electrónicos que pueda tener a mano, también debe seguir la respuesta de Pedro (última parte).

Cuestiones relacionadas