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