Документация Python неофициальный перевод
Содержание страницы

21.16. nntplib – клиент протокола NNTPnntplib – NNTP protocol client

Исходный код: Lib/nntplib.py


Этот модуль определяет класс NNTP, реализующий клиентскую часть протокола передачи новостей (Network News Transfer Protocol). Его можно использовать для создания программ чтения новостей, публикации сообщений или автоматической обработки новостей. Он совместим с RFC 3977, а также с более старыми RFC 977 и RFC 2980.

Вот два небольших примера использования. Чтобы вывести статистику по группе новостей и напечатать темы последних 10 статей:

>>> s = nntplib.NNTP('news.gmane.org')
>>> resp, count, first, last, name = s.group('gmane.comp.python.committers')
>>> print('Group', name, 'has', count, 'articles, range', first, 'to', last)
Group gmane.comp.python.committers has 1096 articles, range 1 to 1096
>>> resp, overviews = s.over((last - 9, last))
>>> for id, over in overviews:
...     print(id, nntplib.decode_header(over['subject']))
...
1087 Re: Commit privileges for Łukasz Langa
1088 Re: 3.2 alpha 2 freeze
1089 Re: 3.2 alpha 2 freeze
1090 Re: Commit privileges for Łukasz Langa
1091 Re: Commit privileges for Łukasz Langa
1092 Updated ssh key
1093 Re: Updated ssh key
1094 Re: Updated ssh key
1095 Hello fellow committers!
1096 Re: Hello fellow committers!
>>> s.quit()
'205 Bye!'

Чтобы опубликовать статью из двоичного файла (предполагается, что статья содержит корректные заголовки и у вас есть права на публикацию в данной группе новостей):

>>> s = nntplib.NNTP('news.gmane.org')
>>> f = open('article.txt', 'rb')
>>> s.post(f)
'240 Article posted successfully.'
>>> s.quit()
'205 Bye!'

Сам модуль определяет следующие классы:

class nntplib.NNTP(host, port=119, user=None, password=None, readermode=None, usenetrc=False[, timeout])

Возвращает новый объект NNTP, представляющий соединение с NNTP-сервером, работающим на хосте host, прослушивающем порт port. Для сокетного соединения можно указать необязательный timeout. Если указаны необязательные user и password, или если подходящие учётные данные находятся в /.netrc и необязательный флаг usenetrc имеет значение true, для идентификации и аутентификации пользователя на сервере используются команды AUTHINFO USER и AUTHINFO PASS. Если необязательный флаг readermode имеет значение true, то перед выполнением аутентификации отправляется команда mode reader. Режим чтения (reader mode) иногда необходим, если вы подключаетесь к NNTP-серверу на локальной машине и собираетесь вызывать специфичные для чтения команды, например group. Если вы получаете неожиданные NNTPPermanentError, возможно, потребуется установить readermode. Класс NNTP поддерживает оператор with для безусловного перехвата исключений OSError и закрытия NNTP-соединения по завершении, например:

>>> from nntplib import NNTP
>>> with NNTP('news.gmane.org') as n:
...     n.group('gmane.comp.python.committers')
... # doctest: +SKIP
('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers')
>>>

Изменено в версии 3.2: usenetrc теперь по умолчанию равен False.

Изменено в версии 3.3: Добавлена поддержка оператора with.

class nntplib.NNTP_SSL(host, port=563, user=None, password=None, ssl_context=None, readermode=None, usenetrc=False[, timeout])

Возвращает новый объект NNTP_SSL, представляющий зашифрованное соединение с NNTP-сервером, работающим на хосте host, прослушивающем порт port. Объекты NNTP_SSL имеют те же методы, что и объекты NNTP. Если port опущен, используется порт 563 (NNTPS). ssl_context также необязателен и является объектом SSLContext. Пожалуйста, прочитайте Соображения безопасности для ознакомления с лучшими практиками. Все остальные параметры ведут себя так же, как для NNTP.

Обратите внимание, что SSL на порту 563 не рекомендуется согласно RFC 4642, вместо него следует использовать STARTTLS, как описано ниже. Однако некоторые серверы поддерживают только первый вариант.

Новое в версии 3.2.

Изменено в версии 3.4: Теперь класс поддерживает проверку имени хоста с помощью ssl.SSLContext.check_hostname и Server Name Indication (см. ssl.HAS_SNI).

exception nntplib.NNTPError

Производный от стандартного исключения Exception, это базовый класс для всех исключений, возбуждаемых модулем nntplib. Экземпляры этого класса имеют следующий атрибут:

response

Ответ сервера, если доступен, в виде объекта str.

exception nntplib.NNTPReplyError

Исключение, возникающее при получении неожиданного ответа от сервера.

exception nntplib.NNTPTemporaryError

Исключение возбуждается, когда получен код ответа в диапазоне 400–499.

exception nntplib.NNTPPermanentError

Исключение возбуждается, когда получен код ответа в диапазоне 500–599.

exception nntplib.NNTPProtocolError

Исключение возбуждается, когда от сервера получен ответ, который не начинается с цифры в диапазоне 1–5.

exception nntplib.NNTPDataError

Исключение возбуждается при наличии ошибки в данных ответа.

21.16.1. Объекты NNTPNNTP Objects

В подключённом состоянии объекты NNTP и NNTP_SSL поддерживают следующие методы и атрибуты.

21.16.1.1. АтрибутыAttributes

NNTP.nntp_version

Целое число, представляющее версию протокола NNTP, поддерживаемую сервером. На практике должно быть равно 2 для серверов, заявляющих о соответствии RFC 3977, и 1 для остальных.

Новое в версии 3.2.

NNTP.nntp_implementation

Строка с названием и версией программного обеспечения NNTP-сервера или None, если сервер не предоставил эту информацию.

Новое в версии 3.2.

21.16.1.2. МетодыMethods

Ответ, возвращаемый в качестве первого элемента кортежа результатов почти всех методов, – это ответ сервера: строка, начинающаяся с трёхзначного кода. Если ответ сервера указывает на ошибку, метод возбуждает одно из перечисленных выше исключений.

Многие из следующих методов принимают необязательный аргумент, передаваемый только по ключу, file. Когда аргумент file указан, он должен быть либо файловый объект, открытым для бинарной записи, либо именем файла на диске для записи. В этом случае метод будет записывать все данные, возвращаемые сервером (за исключением строки ответа и завершающей точки), в файл; любой список строк, кортежей или объектов, который метод обычно возвращает, будет пуст.

Изменено в версии 3.2: Многие из следующих методов были переработаны и исправлены, что делает их несовместимыми с их аналогами из версии 3.1.

NNTP.quit()

Отправляет команду QUIT и закрывает соединение. После вызова этого метода не следует вызывать другие методы объекта NNTP.

NNTP.getwelcome()

Возвращает приветственное сообщение, отправленное сервером в ответ на начальное подключение. (Это сообщение иногда содержит отказ от ответственности или справочную информацию, которая может быть полезна пользователю.)

NNTP.getcapabilities()

Возвращает RFC 3977 возможности, объявленные сервером, в виде экземпляра dict, отображающего имена возможностей в (возможно пустые) списки значений. На устаревших серверах, которые не понимают команду CAPABILITIES, вместо этого возвращается пустой словарь.

>>> s = NNTP('news.gmane.org')
>>> 'POST' in s.getcapabilities()
True

Новое в версии 3.2.

NNTP.login(user=None, password=None, usenetrc=True)

Отправляет команды AUTHINFO с именем пользователя и паролем. Если user и password равны None, а usenetrc истинно, то по возможности будут использованы учётные данные из ~/.netrc.

Если задержка не задана намеренно, вход обычно выполняется во время инициализации объекта NNTP, и отдельный вызов этой функции не требуется. Чтобы принудительно отложить аутентификацию, при создании объекта не следует задавать user или password, а usenetrc должно быть установлено в False.

Новое в версии 3.2.

NNTP.starttls(ssl_context=None)

Отправляет команду STARTTLS. Это включит шифрование на NNTP соединении. Аргумент ssl_context необязателен и должен быть объектом ssl.SSLContext. Пожалуйста, прочитайте Рекомендации по безопасности для соблюдения лучших практик.

Обратите внимание, что это не может быть выполнено после передачи данных аутентификации, и аутентификация по умолчанию происходит, если это возможно, во время инициализации объекта NNTP. Информацию о подавлении этого поведения см. в NNTP.login().

Новое в версии 3.2.

Изменено в версии 3.4: Теперь метод поддерживает проверку имени хоста с помощью ssl.SSLContext.check_hostname и Server Name Indication (см. ssl.HAS_SNI).

NNTP.newgroups(date, *, file=None)

Отправляет команду NEWGROUPS. Аргумент date должен быть объектом datetime.date или datetime.datetime. Возвращает пару (response, groups), где groups – это список, представляющий группы, появившиеся после указанной даты date. Однако если указан file, то groups будет пуст.

>>> from datetime import date, timedelta
>>> resp, groups = s.newgroups(date.today() - timedelta(days=3))
>>> len(groups) # doctest: +SKIP
85
>>> groups[0] # doctest: +SKIP
GroupInfo(group='gmane.network.tor.devel', last='4', first='1', flag='m')
NNTP.newnews(group, date, *, file=None)

Отправляет команду NEWNEWS. Здесь group – это имя группы или '*', а date имеет то же значение, что и для newgroups(). Возвращает пару (response, articles), где articles – это список идентификаторов сообщений.

Эта команда часто отключается администраторами NNTP-серверов.

NNTP.list(group_pattern=None, *, file=None)

Отправляет команду LIST или LIST ACTIVE. Возвращает пару (response, list), где list – это список кортежей, представляющих все группы, доступные на этом NNTP-сервере, опционально соответствующие строке шаблона group_pattern. Каждый кортеж имеет вид (group, last, first, flag), где group – имя группы, last и first – последний и первый номера статей, а flag обычно принимает одно из следующих значений:

  • y: разрешены локальные сообщения и статьи от внешних серверов.
  • m: группа модерируется, и все сообщения должны быть одобрены.
  • n: локальные сообщения запрещены, допускаются только статьи от внешних серверов.
  • j: статьи от внешних серверов вместо этого помещаются в группу junk.
  • x: локальные сообщения отсутствуют, а статьи от внешних серверов игнорируются.
  • =foo.bar: статьи помещаются в группу foo.bar вместо этого.

Если flag имеет другое значение, статус группы новостей следует считать неизвестным.

Эта команда может возвращать очень большие результаты, особенно если group_pattern не указан. Результаты лучше кэшировать в автономном режиме, если только нет реальной необходимости их обновлять.

Изменено в версии 3.2: был добавлен group_pattern.

NNTP.descriptions(grouppattern)

Отправляет команду LIST NEWSGROUPS, где grouppattern – это строка wildmat, как указано в RFC 3977 (она, по сути, аналогична подстановочным строкам оболочки DOS или UNIX). Возвращает пару (response, descriptions), где descriptions – это словарь, отображающий имена групп на текстовые описания.

>>> resp, descs = s.descriptions('gmane.comp.python.*')
>>> len(descs) # doctest: +SKIP
295
>>> descs.popitem() # doctest: +SKIP
('gmane.comp.python.bio.general', 'BioPython discussion list (Moderated)')
NNTP.description(group)

Получает описание для одной группы group. Если совпадает несколько групп (если ‘group’ – это строка шаблона wildmat), возвращается первое совпадение. Если ни одна группа не совпадает, возвращается пустая строка.

Этот метод скрывает код ответа от сервера. Если код ответа необходим, используйте descriptions().

NNTP.group(name)

Отправляет команду GROUP, где name – это имя группы. Группа выбирается в качестве текущей группы, если она существует. Возвращает кортеж (response, count, first, last, name), где count – это (предположительное) количество статей в группе, first – номер первой статьи в группе, last – номер последней статьи в группе, а name – это имя группы.

NNTP.over(message_spec, *, file=None)

Отправляет команду OVER или команду XOVER на устаревших серверах. message_spec может быть либо строкой, представляющей идентификатор сообщения, либо кортежем (first, last) чисел, указывающим диапазон статей в текущей группе, либо кортежем (first, None), указывающим диапазон статей, начиная с first до последней статьи в текущей группе, либо None для выбора текущей статьи в текущей группе.

Возвращает пару (response, overviews). overviews – это список кортежей (article_number, overview), по одному для каждой статьи, выбранной message_spec. Каждый overview – это словарь с таким же количеством элементов, но это количество зависит от сервера. Эти элементы являются либо заголовками сообщения (тогда ключ – это имя заголовка в нижнем регистре), либо элементами метаданных (тогда ключ – это имя метаданных с префиксом ":"). Следующие элементы гарантированно присутствуют по спецификации NNTP:

  • заголовки subject, from, date, message-id и references
  • метаданные :bytes: количество байтов в полном сыром сообщении (включая заголовки и тело)
  • метаданные :lines: количество строк в теле статьи

Значением каждого элемента является либо строка, либо None, если он отсутствует.

Рекомендуется использовать функцию decode_header() для значений заголовков, если они могут содержать символы не из ASCII:

>>> _, _, first, last, _ = s.group('gmane.comp.python.devel')
>>> resp, overviews = s.over((last, last))
>>> art_num, over = overviews[0]
>>> art_num
117216
>>> list(over.keys())
['xref', 'from', ':lines', ':bytes', 'references', 'date', 'message-id', 'subject']
>>> over['from']
'=?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?= <martin@v.loewis.de>'
>>> nntplib.decode_header(over['from'])
'"Martin v. Löwis" <martin@v.loewis.de>'

Новое в версии 3.2.

NNTP.help(*, file=None)

Отправляет команду HELP. Возвращает пару (response, list), где list – это список строк справки.

NNTP.stat(message_spec=None)

Отправляет команду STAT, где message_spec – это либо идентификатор сообщения (заключённый в '<' и '>'), либо номер статьи в текущей группе. Если message_spec опущен или равен None, рассматривается текущая статья в текущей группе. Возвращает тройку (response, number, id), где number – это номер статьи, а id – идентификатор сообщения.

>>> _, _, first, last, _ = s.group('gmane.comp.python.devel')
>>> resp, number, message_id = s.stat(first)
>>> number, message_id
(9099, '<20030112190404.GE29873@epoch.metaslash.com>')
NNTP.next()

Отправляет команду NEXT. Возвращаемое значение такое же, как для stat().

NNTP.last()

Отправляет команду LAST. Возвращаемое значение такое же, как для stat().

NNTP.article(message_spec=None, *, file=None)

Отправляет команду ARTICLE, где message_spec имеет то же значение, что и для stat(). Возвращает кортеж (response, info), где info – это namedtuple с тремя атрибутами: number, message_id и lines (в этом порядке). number – номер статьи в группе (или 0, если информация недоступна), message_id – идентификатор сообщения в виде строки, а lines – список строк (без завершающих символов новой строки), составляющих сырое сообщение, включая заголовки и тело.

>>> resp, info = s.article('<20030112190404.GE29873@epoch.metaslash.com>')
>>> info.number
0
>>> info.message_id
'<20030112190404.GE29873@epoch.metaslash.com>'
>>> len(info.lines)
65
>>> info.lines[0]
b'Path: main.gmane.org!not-for-mail'
>>> info.lines[1]
b'From: Neal Norwitz <neal@metaslash.com>'
>>> info.lines[-3:]
[b'There is a patch for 2.3 as well as 2.2.', b'', b'Neal']
NNTP.head(message_spec=None, *, file=None)

То же, что и article(), но отправляет команду HEAD. Возвращаемые строки (или записанные в file) будут содержать только заголовки сообщения, а не тело.

NNTP.body(message_spec=None, *, file=None)

То же, что и article(), но отправляет команду BODY. Возвращаемые строки (или записанные в file) будут содержать только тело сообщения, а не заголовки.

NNTP.post(data)

Post an article using the POST command. The data argument is either a file object opened for binary reading, or any iterable of bytes objects (representing raw lines of the article to be posted). It should represent a well-formed news article, including the required headers. The post() method automatically escapes lines beginning with . and appends the termination line.

В случае успеха метода возвращается ответ сервера. Если сервер отклоняет отправку, возбуждается исключение NNTPReplyError.

NNTP.ihave(message_id, data)

Отправляет команду IHAVE. message_id – это идентификатор сообщения, отправляемого серверу (заключённый в '<' и '>'). Параметр data и возвращаемое значение такие же, как для post().

NNTP.date()

Возвращает пару (response, date). date – это объект datetime , содержащий текущие дату и время сервера.

NNTP.slave()

Отправляет команду SLAVE. Возвращает ответ сервера.

NNTP.set_debuglevel(level)

Устанавливает уровень отладки экземпляра. Он управляет объёмом выводимых отладочных сообщений. Значение по умолчанию, 0, не выводит отладочные сообщения. Значение 1 выдаёт умеренное количество отладочной информации, обычно одну строку на запрос или ответ. Значение 2 или больше выводит максимальный объём отладочной информации, регистрируя каждую отправленную и полученную строку соединения (включая текст сообщения).

Ниже перечислены необязательные расширения NNTP, определённые в RFC 2980. Некоторые из них заменены более новыми командами в RFC 3977.

NNTP.xhdr(hdr, str, *, file=None)

Отправляет команду XHDR. Аргумент hdr – это ключевое слово заголовка, например 'subject'. Аргумент str должен иметь вид 'first-last', где first и last – это номера первой и последней статей для поиска. Возвращает пару (response, list), где list – список пар (id, text), где id – номер статьи (в виде строки), а text – текст запрошенного заголовка для этой статьи. Если указан параметр file, то вывод команды XHDR сохраняется в файл. Если file – строка, метод откроет файл с таким именем, запишет в него и затем закроет. Если fileфайловый объект, то для сохранения строк вывода команды будет вызываться write() для него. Если file указан, возвращаемый list будет пустым списком.

NNTP.xover(start, end, *, file=None)

Отправляет команду XOVER. start и end – это номера статей, определяющие диапазон выбираемых статей. Возвращаемое значение такое же, как для over(). Рекомендуется использовать over(), так как она автоматически применит более новую команду OVER, если она доступна.

NNTP.xpath(id)

Возвращает пару (resp, path), где path – путь к каталогу статьи с идентификатором сообщения id. Чаще всего администраторы NNTP-серверов не включают это расширение.

Устарело с версии 3.3: Расширение XPATH активно не используется.

21.16.2. Вспомогательные функцииUtility functions

Модуль также определяет следующую вспомогательную функцию:

nntplib.decode_header(header_str)

Декодирует значение заголовка, снимая экранирование любых экранированных символов, не входящих в ASCII. header_str должен быть объектом str. Возвращается значение без экранирования. Рекомендуется использовать эту функцию для отображения некоторых заголовков в удобочитаемом виде:

>>> decode_header("Some subject")
'Some subject'
>>> decode_header("=?ISO-8859-15?Q?D=E9buter_en_Python?=")
'Débuter en Python'
>>> decode_header("Re: =?UTF-8?B?cHJvYmzDqG1lIGRlIG1hdHJpY2U=?=")
'Re: problème de matrice'