Позволяет ли imaplib Python устанавливать тайм-аут?

#python #imaplib

#python #imaplib

Вопрос:

Я смотрю на API для imaplib Python.

Из того, что я могу сказать, нет способа настроить тайм-аут, как вы можете с помощью smtplib.

Это правильно? Как бы вы обработали недопустимый хост, если вы не хотите, чтобы он блокировался?

Ответ №1:

imaplib Модуль не предоставляет способа установить тайм-аут, но вы можете установить тайм-аут по умолчанию для новых подключений к сокетам через socket.setdefaulttimeout :

 import socket
import imaplib
socket.setdefaulttimeout(10)
imap = imaplib.IMAP4('test.com', 666)
 

Или вы также можете переопределить imaplib.IMAP4 класс с некоторыми знаниями из imaplib исходного кода и документов, что обеспечивает лучший контроль:

 import imaplib
import socket

class IMAP(imaplib.IMAP4):
    def __init__(self, host='', port=imaplib.IMAP4_PORT, timeout=None):
        self.timeout = timeout
        # no super(), it's an old-style class
        imaplib.IMAP4.__init__(self, host, port)

    def open(self, host='', port=imaplib.IMAP4_PORT):
        self.host = host
        self.port = port
        self.sock = socket.create_connection((host, port), timeout=self.timeout)
        # clear timeout for socket.makefile, needs blocking mode
        self.sock.settimeout(None)
        self.file = self.sock.makefile('rb')
 

Обратите внимание, что после создания соединения мы должны установить тайм-аут сокета обратно None , чтобы перевести его в режим блокировки для последующего socket.makefile вызова, как указано в документации по методу:

… Сокет должен находиться в режиме блокировки (у него не может быть тайм-аута). …

Комментарии:

1. Пожалуйста, удалите self.sock.settimeout(нет), это позволяет тайм-ауту не работать и всегда блокировать.

Ответ №2:

 import imaplib
...
# ssl and timeout are config values
# connection to IMAP server
if ssl:
    imapResource = imaplib.IMAP4_SSL(server, port)
else:
    imapResource = imaplib.IMAP4(server, port)
# communications timeout
sock=imapResource.socket()
timeout = 60 * 5 # 5 minutes
sock.settimeout(timeout)
 

Ответ №3:

Если вы хотите IMAP4_SSL , мы можем изменить ответ famousgarkin, обернув сокет контекстом ssl ssl_context.wrap_socket()

 import imaplib
import socket

class IMAP(imaplib.IMAP4_SSL):
    def __init__(self, host='', port=imaplib.IMAP4_SSL_PORT, timeout=None):
        self.timeout = timeout
        # no super(), it's an old-style class
        imaplib.IMAP4_SSL.__init__(self, host, port)

    def open(self, host='', port=imaplib.IMAP4_SSL_PORT):

        sock = socket.create_connection((host, port), timeout=self.timeout)
        self.sock = self.ssl_context.wrap_socket(sock, server_hostname=host)

        # clear timeout for socket.makefile, needs blocking mode
        self.sock.settimeout(None)
        self.file = self.sock.makefile('rb')