1:mod:`nntplib` --- NNTP protocol client
2=======================================
3
4.. module:: nntplib
5   :synopsis: NNTP protocol client (requires sockets).
6   :deprecated:
7
8**Source code:** :source:`Lib/nntplib.py`
9
10.. index::
11   pair: NNTP; protocol
12   single: Network News Transfer Protocol
13
14.. deprecated:: 3.11
15   The :mod:`nntplib` module is deprecated (see :pep:`594` for details).
16
17--------------
18
19This module defines the class :class:`NNTP` which implements the client side of
20the Network News Transfer Protocol.  It can be used to implement a news reader
21or poster, or automated news processors.  It is compatible with :rfc:`3977`
22as well as the older :rfc:`977` and :rfc:`2980`.
23
24.. include:: ../includes/wasm-notavail.rst
25
26Here are two small examples of how it can be used.  To list some statistics
27about a newsgroup and print the subjects of the last 10 articles::
28
29   >>> s = nntplib.NNTP('news.gmane.io')
30   >>> resp, count, first, last, name = s.group('gmane.comp.python.committers')
31   >>> print('Group', name, 'has', count, 'articles, range', first, 'to', last)
32   Group gmane.comp.python.committers has 1096 articles, range 1 to 1096
33   >>> resp, overviews = s.over((last - 9, last))
34   >>> for id, over in overviews:
35   ...     print(id, nntplib.decode_header(over['subject']))
36   ...
37   1087 Re: Commit privileges for Łukasz Langa
38   1088 Re: 3.2 alpha 2 freeze
39   1089 Re: 3.2 alpha 2 freeze
40   1090 Re: Commit privileges for Łukasz Langa
41   1091 Re: Commit privileges for Łukasz Langa
42   1092 Updated ssh key
43   1093 Re: Updated ssh key
44   1094 Re: Updated ssh key
45   1095 Hello fellow committers!
46   1096 Re: Hello fellow committers!
47   >>> s.quit()
48   '205 Bye!'
49
50To post an article from a binary file (this assumes that the article has valid
51headers, and that you have right to post on the particular newsgroup)::
52
53   >>> s = nntplib.NNTP('news.gmane.io')
54   >>> f = open('article.txt', 'rb')
55   >>> s.post(f)
56   '240 Article posted successfully.'
57   >>> s.quit()
58   '205 Bye!'
59
60The module itself defines the following classes:
61
62
63.. class:: NNTP(host, port=119, user=None, password=None, readermode=None, usenetrc=False, [timeout])
64
65   Return a new :class:`NNTP` object, representing a connection
66   to the NNTP server running on host *host*, listening at port *port*.
67   An optional *timeout* can be specified for the socket connection.
68   If the optional *user* and *password* are provided, or if suitable
69   credentials are present in :file:`/.netrc` and the optional flag *usenetrc*
70   is true, the ``AUTHINFO USER`` and ``AUTHINFO PASS`` commands are used
71   to identify and authenticate the user to the server.  If the optional
72   flag *readermode* is true, then a ``mode reader`` command is sent before
73   authentication is performed.  Reader mode is sometimes necessary if you are
74   connecting to an NNTP server on the local machine and intend to call
75   reader-specific commands, such as ``group``.  If you get unexpected
76   :exc:`NNTPPermanentError`\ s, you might need to set *readermode*.
77   The :class:`NNTP` class supports the :keyword:`with` statement to
78   unconditionally consume :exc:`OSError` exceptions and to close the NNTP
79   connection when done, e.g.:
80
81    >>> from nntplib import NNTP
82    >>> with NNTP('news.gmane.io') as n:
83    ...     n.group('gmane.comp.python.committers')
84    ... # doctest: +SKIP
85    ('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers')
86    >>>
87
88   .. audit-event:: nntplib.connect self,host,port nntplib.NNTP
89
90   .. audit-event:: nntplib.putline self,line nntplib.NNTP
91
92      All commands will raise an :ref:`auditing event <auditing>`
93      ``nntplib.putline`` with arguments ``self`` and ``line``,
94      where ``line`` is the bytes about to be sent to the remote host.
95
96   .. versionchanged:: 3.2
97      *usenetrc* is now ``False`` by default.
98
99   .. versionchanged:: 3.3
100      Support for the :keyword:`with` statement was added.
101
102   .. versionchanged:: 3.9
103      If the *timeout* parameter is set to be zero, it will raise a
104      :class:`ValueError` to prevent the creation of a non-blocking socket.
105
106.. class:: NNTP_SSL(host, port=563, user=None, password=None, ssl_context=None, readermode=None, usenetrc=False, [timeout])
107
108   Return a new :class:`NNTP_SSL` object, representing an encrypted
109   connection to the NNTP server running on host *host*, listening at
110   port *port*.  :class:`NNTP_SSL` objects have the same methods as
111   :class:`NNTP` objects.  If *port* is omitted, port 563 (NNTPS) is used.
112   *ssl_context* is also optional, and is a :class:`~ssl.SSLContext` object.
113   Please read :ref:`ssl-security` for best practices.
114   All other parameters behave the same as for :class:`NNTP`.
115
116   Note that SSL-on-563 is discouraged per :rfc:`4642`, in favor of
117   STARTTLS as described below.  However, some servers only support the
118   former.
119
120   .. audit-event:: nntplib.connect self,host,port nntplib.NNTP_SSL
121
122   .. audit-event:: nntplib.putline self,line nntplib.NNTP_SSL
123
124      All commands will raise an :ref:`auditing event <auditing>`
125      ``nntplib.putline`` with arguments ``self`` and ``line``,
126      where ``line`` is the bytes about to be sent to the remote host.
127
128   .. versionadded:: 3.2
129
130   .. versionchanged:: 3.4
131      The class now supports hostname check with
132      :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see
133      :data:`ssl.HAS_SNI`).
134
135   .. versionchanged:: 3.9
136      If the *timeout* parameter is set to be zero, it will raise a
137      :class:`ValueError` to prevent the creation of a non-blocking socket.
138
139.. exception:: NNTPError
140
141   Derived from the standard exception :exc:`Exception`, this is the base
142   class for all exceptions raised by the :mod:`nntplib` module.  Instances
143   of this class have the following attribute:
144
145   .. attribute:: response
146
147      The response of the server if available, as a :class:`str` object.
148
149
150.. exception:: NNTPReplyError
151
152   Exception raised when an unexpected reply is received from the server.
153
154
155.. exception:: NNTPTemporaryError
156
157   Exception raised when a response code in the range 400--499 is received.
158
159
160.. exception:: NNTPPermanentError
161
162   Exception raised when a response code in the range 500--599 is received.
163
164
165.. exception:: NNTPProtocolError
166
167   Exception raised when a reply is received from the server that does not begin
168   with a digit in the range 1--5.
169
170
171.. exception:: NNTPDataError
172
173   Exception raised when there is some error in the response data.
174
175
176.. _nntp-objects:
177
178NNTP Objects
179------------
180
181When connected, :class:`NNTP` and :class:`NNTP_SSL` objects support the
182following methods and attributes.
183
184Attributes
185^^^^^^^^^^
186
187.. attribute:: NNTP.nntp_version
188
189   An integer representing the version of the NNTP protocol supported by the
190   server.  In practice, this should be ``2`` for servers advertising
191   :rfc:`3977` compliance and ``1`` for others.
192
193   .. versionadded:: 3.2
194
195.. attribute:: NNTP.nntp_implementation
196
197   A string describing the software name and version of the NNTP server,
198   or :const:`None` if not advertised by the server.
199
200   .. versionadded:: 3.2
201
202Methods
203^^^^^^^
204
205The *response* that is returned as the first item in the return tuple of almost
206all methods is the server's response: a string beginning with a three-digit
207code.  If the server's response indicates an error, the method raises one of
208the above exceptions.
209
210Many of the following methods take an optional keyword-only argument *file*.
211When the *file* argument is supplied, it must be either a :term:`file object`
212opened for binary writing, or the name of an on-disk file to be written to.
213The method will then write any data returned by the server (except for the
214response line and the terminating dot) to the file; any list of lines,
215tuples or objects that the method normally returns will be empty.
216
217.. versionchanged:: 3.2
218   Many of the following methods have been reworked and fixed, which makes
219   them incompatible with their 3.1 counterparts.
220
221
222.. method:: NNTP.quit()
223
224   Send a ``QUIT`` command and close the connection.  Once this method has been
225   called, no other methods of the NNTP object should be called.
226
227
228.. method:: NNTP.getwelcome()
229
230   Return the welcome message sent by the server in reply to the initial
231   connection.  (This message sometimes contains disclaimers or help information
232   that may be relevant to the user.)
233
234
235.. method:: NNTP.getcapabilities()
236
237   Return the :rfc:`3977` capabilities advertised by the server, as a
238   :class:`dict` instance mapping capability names to (possibly empty) lists
239   of values. On legacy servers which don't understand the ``CAPABILITIES``
240   command, an empty dictionary is returned instead.
241
242      >>> s = NNTP('news.gmane.io')
243      >>> 'POST' in s.getcapabilities()
244      True
245
246   .. versionadded:: 3.2
247
248
249.. method:: NNTP.login(user=None, password=None, usenetrc=True)
250
251   Send ``AUTHINFO`` commands with the user name and password.  If *user*
252   and *password* are ``None`` and *usenetrc* is true, credentials from
253   ``~/.netrc`` will be used if possible.
254
255   Unless intentionally delayed, login is normally performed during the
256   :class:`NNTP` object initialization and separately calling this function
257   is unnecessary.  To force authentication to be delayed, you must not set
258   *user* or *password* when creating the object, and must set *usenetrc* to
259   False.
260
261   .. versionadded:: 3.2
262
263
264.. method:: NNTP.starttls(context=None)
265
266   Send a ``STARTTLS`` command.  This will enable encryption on the NNTP
267   connection.  The *context* argument is optional and should be a
268   :class:`ssl.SSLContext` object.  Please read :ref:`ssl-security` for best
269   practices.
270
271   Note that this may not be done after authentication information has
272   been transmitted, and authentication occurs by default if possible during a
273   :class:`NNTP` object initialization.  See :meth:`NNTP.login` for information
274   on suppressing this behavior.
275
276   .. versionadded:: 3.2
277
278   .. versionchanged:: 3.4
279      The method now supports hostname check with
280      :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see
281      :data:`ssl.HAS_SNI`).
282
283.. method:: NNTP.newgroups(date, *, file=None)
284
285   Send a ``NEWGROUPS`` command.  The *date* argument should be a
286   :class:`datetime.date` or :class:`datetime.datetime` object.
287   Return a pair ``(response, groups)`` where *groups* is a list representing
288   the groups that are new since the given *date*. If *file* is supplied,
289   though, then *groups* will be empty.
290
291      >>> from datetime import date, timedelta
292      >>> resp, groups = s.newgroups(date.today() - timedelta(days=3))
293      >>> len(groups) # doctest: +SKIP
294      85
295      >>> groups[0] # doctest: +SKIP
296      GroupInfo(group='gmane.network.tor.devel', last='4', first='1', flag='m')
297
298
299.. method:: NNTP.newnews(group, date, *, file=None)
300
301   Send a ``NEWNEWS`` command.  Here, *group* is a group name or ``'*'``, and
302   *date* has the same meaning as for :meth:`newgroups`.  Return a pair
303   ``(response, articles)`` where *articles* is a list of message ids.
304
305   This command is frequently disabled by NNTP server administrators.
306
307
308.. method:: NNTP.list(group_pattern=None, *, file=None)
309
310   Send a ``LIST`` or ``LIST ACTIVE`` command.  Return a pair
311   ``(response, list)`` where *list* is a list of tuples representing all
312   the groups available from this NNTP server, optionally matching the
313   pattern string *group_pattern*.  Each tuple has the form
314   ``(group, last, first, flag)``, where *group* is a group name, *last*
315   and *first* are the last and first article numbers, and *flag* usually
316   takes one of these values:
317
318   * ``y``: Local postings and articles from peers are allowed.
319   * ``m``: The group is moderated and all postings must be approved.
320   * ``n``: No local postings are allowed, only articles from peers.
321   * ``j``: Articles from peers are filed in the junk group instead.
322   * ``x``: No local postings, and articles from peers are ignored.
323   * ``=foo.bar``: Articles are filed in the ``foo.bar`` group instead.
324
325   If *flag* has another value, then the status of the newsgroup should be
326   considered unknown.
327
328   This command can return very large results, especially if *group_pattern*
329   is not specified.  It is best to cache the results offline unless you
330   really need to refresh them.
331
332   .. versionchanged:: 3.2
333      *group_pattern* was added.
334
335
336.. method:: NNTP.descriptions(grouppattern)
337
338   Send a ``LIST NEWSGROUPS`` command, where *grouppattern* is a wildmat string as
339   specified in :rfc:`3977` (it's essentially the same as DOS or UNIX shell wildcard
340   strings).  Return a pair ``(response, descriptions)``, where *descriptions*
341   is a dictionary mapping group names to textual descriptions.
342
343      >>> resp, descs = s.descriptions('gmane.comp.python.*')
344      >>> len(descs) # doctest: +SKIP
345      295
346      >>> descs.popitem() # doctest: +SKIP
347      ('gmane.comp.python.bio.general', 'BioPython discussion list (Moderated)')
348
349
350.. method:: NNTP.description(group)
351
352   Get a description for a single group *group*.  If more than one group matches
353   (if 'group' is a real wildmat string), return the first match.   If no group
354   matches, return an empty string.
355
356   This elides the response code from the server.  If the response code is needed,
357   use :meth:`descriptions`.
358
359
360.. method:: NNTP.group(name)
361
362   Send a ``GROUP`` command, where *name* is the group name.  The group is
363   selected as the current group, if it exists.  Return a tuple
364   ``(response, count, first, last, name)`` where *count* is the (estimated)
365   number of articles in the group, *first* is the first article number in
366   the group, *last* is the last article number in the group, and *name*
367   is the group name.
368
369
370.. method:: NNTP.over(message_spec, *, file=None)
371
372   Send an ``OVER`` command, or an ``XOVER`` command on legacy servers.
373   *message_spec* can be either a string representing a message id, or
374   a ``(first, last)`` tuple of numbers indicating a range of articles in
375   the current group, or a ``(first, None)`` tuple indicating a range of
376   articles starting from *first* to the last article in the current group,
377   or :const:`None` to select the current article in the current group.
378
379   Return a pair ``(response, overviews)``.  *overviews* is a list of
380   ``(article_number, overview)`` tuples, one for each article selected
381   by *message_spec*.  Each *overview* is a dictionary with the same number
382   of items, but this number depends on the server.  These items are either
383   message headers (the key is then the lower-cased header name) or metadata
384   items (the key is then the metadata name prepended with ``":"``).  The
385   following items are guaranteed to be present by the NNTP specification:
386
387   * the ``subject``, ``from``, ``date``, ``message-id`` and ``references``
388     headers
389   * the ``:bytes`` metadata: the number of bytes in the entire raw article
390     (including headers and body)
391   * the ``:lines`` metadata: the number of lines in the article body
392
393   The value of each item is either a string, or :const:`None` if not present.
394
395   It is advisable to use the :func:`decode_header` function on header
396   values when they may contain non-ASCII characters::
397
398      >>> _, _, first, last, _ = s.group('gmane.comp.python.devel')
399      >>> resp, overviews = s.over((last, last))
400      >>> art_num, over = overviews[0]
401      >>> art_num
402      117216
403      >>> list(over.keys())
404      ['xref', 'from', ':lines', ':bytes', 'references', 'date', 'message-id', 'subject']
405      >>> over['from']
406      '=?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?= <[email protected]>'
407      >>> nntplib.decode_header(over['from'])
408      '"Martin v. Löwis" <[email protected]>'
409
410   .. versionadded:: 3.2
411
412
413.. method:: NNTP.help(*, file=None)
414
415   Send a ``HELP`` command.  Return a pair ``(response, list)`` where *list* is a
416   list of help strings.
417
418
419.. method:: NNTP.stat(message_spec=None)
420
421   Send a ``STAT`` command, where *message_spec* is either a message id
422   (enclosed in ``'<'`` and ``'>'``) or an article number in the current group.
423   If *message_spec* is omitted or :const:`None`, the current article in the
424   current group is considered.  Return a triple ``(response, number, id)``
425   where *number* is the article number and *id* is the message id.
426
427      >>> _, _, first, last, _ = s.group('gmane.comp.python.devel')
428      >>> resp, number, message_id = s.stat(first)
429      >>> number, message_id
430      (9099, '<[email protected]>')
431
432
433.. method:: NNTP.next()
434
435   Send a ``NEXT`` command.  Return as for :meth:`.stat`.
436
437
438.. method:: NNTP.last()
439
440   Send a ``LAST`` command.  Return as for :meth:`.stat`.
441
442
443.. method:: NNTP.article(message_spec=None, *, file=None)
444
445   Send an ``ARTICLE`` command, where *message_spec* has the same meaning as
446   for :meth:`.stat`.  Return a tuple ``(response, info)`` where *info*
447   is a :class:`~collections.namedtuple` with three attributes *number*,
448   *message_id* and *lines* (in that order).  *number* is the article number
449   in the group (or 0 if the information is not available), *message_id* the
450   message id as a string, and *lines* a list of lines (without terminating
451   newlines) comprising the raw message including headers and body.
452
453      >>> resp, info = s.article('<[email protected]>')
454      >>> info.number
455      0
456      >>> info.message_id
457      '<[email protected]>'
458      >>> len(info.lines)
459      65
460      >>> info.lines[0]
461      b'Path: main.gmane.org!not-for-mail'
462      >>> info.lines[1]
463      b'From: Neal Norwitz <[email protected]>'
464      >>> info.lines[-3:]
465      [b'There is a patch for 2.3 as well as 2.2.', b'', b'Neal']
466
467
468.. method:: NNTP.head(message_spec=None, *, file=None)
469
470   Same as :meth:`article()`, but sends a ``HEAD`` command.  The *lines*
471   returned (or written to *file*) will only contain the message headers, not
472   the body.
473
474
475.. method:: NNTP.body(message_spec=None, *, file=None)
476
477   Same as :meth:`article()`, but sends a ``BODY`` command.  The *lines*
478   returned (or written to *file*) will only contain the message body, not the
479   headers.
480
481
482.. method:: NNTP.post(data)
483
484   Post an article using the ``POST`` command.  The *data* argument is either
485   a :term:`file object` opened for binary reading, or any iterable of bytes
486   objects (representing raw lines of the article to be posted).  It should
487   represent a well-formed news article, including the required headers.  The
488   :meth:`post` method automatically escapes lines beginning with ``.`` and
489   appends the termination line.
490
491   If the method succeeds, the server's response is returned.  If the server
492   refuses posting, a :class:`NNTPReplyError` is raised.
493
494
495.. method:: NNTP.ihave(message_id, data)
496
497   Send an ``IHAVE`` command. *message_id* is the id of the message to send
498   to the server (enclosed in  ``'<'`` and ``'>'``).  The *data* parameter
499   and the return value are the same as for :meth:`post()`.
500
501
502.. method:: NNTP.date()
503
504   Return a pair ``(response, date)``.  *date* is a :class:`~datetime.datetime`
505   object containing the current date and time of the server.
506
507
508.. method:: NNTP.slave()
509
510   Send a ``SLAVE`` command.  Return the server's *response*.
511
512
513.. method:: NNTP.set_debuglevel(level)
514
515   Set the instance's debugging level.  This controls the amount of debugging
516   output printed.  The default, ``0``, produces no debugging output.  A value of
517   ``1`` produces a moderate amount of debugging output, generally a single line
518   per request or response.  A value of ``2`` or higher produces the maximum amount
519   of debugging output, logging each line sent and received on the connection
520   (including message text).
521
522
523The following are optional NNTP extensions defined in :rfc:`2980`.  Some of
524them have been superseded by newer commands in :rfc:`3977`.
525
526
527.. method:: NNTP.xhdr(hdr, str, *, file=None)
528
529   Send an ``XHDR`` command.  The *hdr* argument is a header keyword, e.g.
530   ``'subject'``.  The *str* argument should have the form ``'first-last'``
531   where *first* and *last* are the first and last article numbers to search.
532   Return a pair ``(response, list)``, where *list* is a list of pairs ``(id,
533   text)``, where *id* is an article number (as a string) and *text* is the text of
534   the requested header for that article. If the *file* parameter is supplied, then
535   the output of the  ``XHDR`` command is stored in a file.  If *file* is a string,
536   then the method will open a file with that name, write to it  then close it.
537   If *file* is a :term:`file object`, then it will start calling :meth:`write` on
538   it to store the lines of the command output. If *file* is supplied, then the
539   returned *list* is an empty list.
540
541
542.. method:: NNTP.xover(start, end, *, file=None)
543
544   Send an ``XOVER`` command.  *start* and *end* are article numbers
545   delimiting the range of articles to select.  The return value is the
546   same of for :meth:`over()`.  It is recommended to use :meth:`over()`
547   instead, since it will automatically use the newer ``OVER`` command
548   if available.
549
550
551Utility functions
552-----------------
553
554The module also defines the following utility function:
555
556
557.. function:: decode_header(header_str)
558
559   Decode a header value, un-escaping any escaped non-ASCII characters.
560   *header_str* must be a :class:`str` object.  The unescaped value is
561   returned.  Using this function is recommended to display some headers
562   in a human readable form::
563
564      >>> decode_header("Some subject")
565      'Some subject'
566      >>> decode_header("=?ISO-8859-15?Q?D=E9buter_en_Python?=")
567      'Débuter en Python'
568      >>> decode_header("Re: =?UTF-8?B?cHJvYmzDqG1lIGRlIG1hdHJpY2U=?=")
569      'Re: problème de matrice'
570