nntp ==== .. py:module:: nntp Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/nntp/fifo/index /autoapi/nntp/headerdict/index /autoapi/nntp/nntp/index /autoapi/nntp/types/index /autoapi/nntp/utils/index /autoapi/nntp/yenc/index Exceptions ---------- .. autoapisummary:: nntp.NNTPDataError nntp.NNTPError nntp.NNTPPermanentError nntp.NNTPProtocolError nntp.NNTPReplyError nntp.NNTPTemporaryError Classes ------- .. autoapisummary:: nntp.BaseNNTPClient nntp.NNTPClient Package Contents ---------------- .. py:class:: BaseNNTPClient(host: str, port: int = 119, username: str = '', password: str = '', *, timeout: int = 30, use_ssl: bool = False, ssl_mode: nntp.types.SSLMode = SSLMode.IMPLICIT) NNTP BaseNNTPClient. Base class for NNTP clients implements the basic command interface and transparently handles compressed replies. .. py:attribute:: encoding :value: 'utf-8' .. py:attribute:: errors :value: 'surrogateescape' .. py:attribute:: _buffer .. py:attribute:: _generating :value: False .. py:attribute:: username :value: '' .. py:attribute:: password :value: '' .. py:attribute:: socket .. py:method:: _enable_tls(host: str) -> None .. py:method:: _recv(size: int = 4096) -> None Reads data from the socket. Raises: NNTPError: When connection times out or read from socket fails. .. py:method:: _line() -> collections.abc.Iterator[bytes] Generator that reads a line of data from the server. It first attempts to read from the internal buffer. If there is not enough data to read a line it then requests more data from the server and adds it to the buffer. This process repeats until a line of data can be read from the internal buffer. Yields: A line of data when it becomes available. .. py:method:: _buf(length: int = 0) -> collections.abc.Iterator[bytes] Generator that reads a block of data from the server. It first attempts to read from the internal buffer. If there is not enough data in the internal buffer it then requests more data from the server and adds it to the buffer. Args: length: An optional amount of data to retrieve. A length of 0 (the default) will retrieve a least one buffer of data. Yields: A block of data when enough data becomes available. Note: If a length of 0 is supplied then the size of the yielded buffer can vary. If there is data in the internal buffer it will yield all of that data otherwise it will yield the the data returned by a recv on the socket. .. py:method:: status() -> tuple[int, str] Reads a command response status. If there is no response message then the returned status message will be an empty string. Raises: NNTPError: If data is required to be read from the socket and fails. NNTPProtocolError: If the status line can't be parsed. NNTPTemporaryError: For status code 400-499 NNTPPermanentError: For status code 500-599 Returns: A tuple of status code and status message. .. py:method:: _info_plain() -> collections.abc.Iterator[bytes] Generator for the lines of an info (textual) response. When a terminating line (line containing single period) is received the generator exits. If there is a line beginning with an 'escaped' period then the extra period is trimmed. Yields: A line of the info response. Raises: NNTPError: If data is required to be read from the socket and fails. .. py:method:: _info_gzip() -> collections.abc.Iterator[bytes] Generator for the lines of a compressed info (textual) response. Compressed responses are an extension to the NNTP protocol supported by some usenet servers to reduce the bandwidth of heavily used range style commands that can return large amounts of textual data. This function handles gzip compressed responses that have the terminating line inside or outside the compressed data. From experience if the 'XFEATURE COMPRESS GZIP' command causes the terminating '.\r\n' to follow the compressed data and 'XFEATURE COMPRESS GZIP TERMINATOR' causes the terminator to be the last part of the compressed data (i.e the reply the gzipped version of the original reply - terminating line included) This function will produce that same output as the _info_plain() function. In other words it takes care of decompression. Yields: A line of the info response. Raises: NNTPError: If data is required to be read from the socket and fails. NNTPDataError: If decompression fails. .. py:method:: _info_yenczlib() -> collections.abc.Iterator[bytes] Generator for the lines of a compressed info (textual) response. Compressed responses are an extension to the NNTP protocol supported by some usenet servers to reduce the bandwidth of heavily used range style commands that can return large amounts of textual data. The server returns that same data as it would for the uncompressed versions of the command the difference being that the data is zlib deflated and then yEnc encoded. This function will produce that same output as the info() function. In other words it takes care of decoding and decompression. Yields: A line of the info response. Raises: NNTPError: If data is required to be read from the socket and fails. NNTPDataError: When there is an error parsing the yEnc header or trailer, if the CRC check fails or decompressing data fails. .. py:method:: _info(code: int, message: str, yz: bool = False) -> collections.abc.Iterator[bytes] Dispatcher for the info generators. Determines which _info_*() generator should be used based on the supplied parameters. Args: code: The status code for the command response. message: The status message for the command response. yz: Use yenzlib decompression. Useful for xz* commands. Yields: A lines of the info response as bytes. .. py:method:: info(code: int, message: str, yz: bool = False) -> collections.abc.Iterator[str] Dispatcher for the info generators. Determines which _info_*() generator should be used based on the supplied parameters. Args: code: The status code for the command response. message: The status message for the command response. yz: Use yenzlib decompression. Useful for xz* commands. Yields: A line of the info response as a string. .. py:method:: command(verb: str, args: str | None = None) -> tuple[int, str] Call a command on the server. If the user has not authenticated then authentication will be done as part of calling the command on the server. For commands that don't return a status message the status message will default to an empty string. Args: verb: The verb of the command to call. args: The arguments of the command as a string (default None). Returns: A tuple of status code (as an integer) and status message. Note: You can run raw commands by supplying the full command (including args) in the verb. Note: Although it is possible you shouldn't issue more than one command at a time by adding newlines to the verb as it will most likely lead to undesirable results. .. py:method:: close() -> None Closes the connection at the client. Once this method has been called, no other methods of the NNTPClient object should be called. .. py:class:: NNTPClient(host: str, port: int = 119, username: str = '', password: str = '', *, timeout: int = 30, use_ssl: bool = False, ssl_mode: nntp.types.SSLMode = SSLMode.IMPLICIT, reader: bool = True) Bases: :py:obj:`BaseNNTPClient` NNTP NNTPClient. Implements many of the commands that are commonly used by current usenet servers. Including handling commands that use compressed responses. Implements generators for commands for which generators are likely to yield (bad pun warning) performance gains. These gains will be in the form of lower memory consumption and the added ability to process and receive data in parallel. If you are using commands that can take a range as an argument or can return large amounts of data there should be a _gen() version of the command and it should be used in preference to the standard version. Note: All commands can raise the following exceptions: NNTPError NNTPProtocolError NNTPPermanentError NNTPReplyError IOError (socket.error) Note: All commands that use compressed responses can also raise an NNTPDataError. .. py:method:: __enter__() -> typing_extensions.Self Support for the 'with' context manager statement. .. py:method:: __exit__(exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None) -> Literal[False] Support for the 'with' context manager statement. .. py:method:: capabilities(keyword: str | None = None) -> collections.abc.Iterator[str] CAPABILITIES command. Determines the capabilities of the server. Although RFC3977 states that this is a required command for servers to implement not all servers do, so expect that NNTPPermanentError may be raised when this command is issued. See Args: keyword: Passed directly to the server, however, this is unused by the server according to RFC3977. Yields: Each of the capabilities supported by the server. The VERSION capability is the first capability to be yielded. .. py:method:: mode_reader() -> bool MODE READER command. Instructs a mode-switching server to switch modes. See Returns: Boolean value indicating whether posting is allowed or not. .. py:method:: quit() -> None QUIT command. Tells the server to close the connection. After the server acknowledges the request to quit the connection is closed both at the server and client. Only useful for graceful shutdown. If you are in a generator use close() instead. Once this method has been called, no other methods of the NNTPClient object should be called. See .. py:method:: date() -> datetime.datetime DATE command. Coordinated Universal time from the perspective of the usenet server. It can be used to provide information that might be useful when using the NEWNEWS command. See Returns: The UTC time according to the server as a datetime object. Raises: NNTPDataError: If the timestamp can't be parsed. .. py:method:: help() -> str HELP command. Provides a short summary of commands that are understood by the usenet server. See Returns: The help text from the server. .. py:method:: newgroups(timestamp: datetime.datetime) -> collections.abc.Iterator[nntp.types.Newsgroup] NEWGROUPS command. Retrieves a list of newsgroups created on the server since the specified timestamp. See Args: timestamp: Datetime object giving 'created since' Yields: A 4-tuple containing the name, low water mark, high water mark, and status for the newsgroup, for each newsgroup. Note: If the datetime object supplied as the timestamp is naive (tzinfo is None) then it is assumed to be given as GMT. .. py:method:: newnews(pattern: str, timestamp: datetime.datetime) -> collections.abc.Iterator[str] NEWNEWS command. Retrieves a list of message-ids for articles created since the specified timestamp for newsgroups with names that match the given pattern. See Args: pattern: Glob matching newsgroups of interest. timestamp: Datetime object giving 'created since' Yields: A message-id as string, for each article. Note: If the datetime object supplied as the timestamp is naive (tzinfo is None) then it is assumed to be given as GMT. If tzinfo is set then it will be converted to GMT by this function. .. py:method:: list(keyword: str | None = None, args: str | None = None, *, success: collections.abc.Iterable[int] = (215, )) -> collections.abc.Iterator[str] LIST command. General purpose list command. allows the server to provide blocks of information to the client. The keyword specifies the type of list, if no keyword is provided, it defaults to ACTIVE. See Args: keyword: Information requested. args: Keyword specific arguments. Yields: A line of the list response. .. py:method:: list_active(pattern: str | None = None) -> collections.abc.Iterator[nntp.types.Newsgroup] LIST ACTIVE command. Retrieves a list of active newsgroups that match the specified pattern. See Args: pattern: Glob matching newsgroups of interest. Yields: A 4-tuple containing the name, low water mark, high water mark, and status for the newsgroup, for each newsgroup. .. py:method:: list_active_times() -> collections.abc.Iterator[tuple[str, datetime.datetime, str]] LIST ACTIVE TIMES command. Retrieves a list of newsgroups including the creation time and who created them. See Yields: A 3-tuple containing the name, creation date as a datetime object and creator as a string for the newsgroup for each newsgroup. .. py:method:: list_headers(variant: Literal['MSGID', 'RANGE', None] = None) -> collections.abc.Iterator[str] LIST HEADERS command. Returns a list of fields that may be retrieved using the HDR command. See Args: variant: The string 'MSGID' or 'RANGE' or None (the default). Different variants of the HDR request may return a different fields. Yields: The field name for each of the fields. .. py:method:: list_newsgroups(pattern: str | None = None) -> collections.abc.Iterator[tuple[str, str]] LIST NEWSGROUPS command. Retrieves a list of newsgroups including the name and a short description. See Args: pattern: Glob matching newsgroups of interest. Yields: A tuple containing the name, and description for the newsgroup, for each newsgroup that matches the pattern. .. py:method:: list_overview_fmt() -> collections.abc.Iterator[tuple[str, bool]] LIST OVERVIEW.FMT command. Returns a description of the fields in the database for which it is consistent. See Yields: A 2-tuple of the name of the field and a boolean indicating whether the the field name is included in the field data, for each field in the database which is consistent, fields are yielded in order. .. py:method:: list_extensions() -> collections.abc.Iterator[str] LIST EXTENSIONS command. Allows a client to determine which extensions are supported by the server at any given time. See Yields: The name of the extension of each of the available extensions. .. py:method:: group(name: str) -> tuple[int, int, int, str] GROUP command. Selects a newsgroup as the currently selected newsgroup and returns summary information about it. See Args: name: The group name. Returns: A 4-tuple of the estimated total articles in the group, the articles numbers of the first and last article and the group name. Raises: NNTPReplyError: If no such newsgroup exists. .. py:method:: next() -> tuple[int, str] NEXT command. Sets the current article number to the next article in the current newsgroup. See Returns: A 2-tuple of the article number and message id. Raises: NNTPReplyError: If no such article exists or the currently selected newsgroup is invalid. .. py:method:: last() -> tuple[int, str] LAST command. Sets the current article number to the previous article in the current newsgroup. See Returns: A 2-tuple of the article number and message id. Raises: NNTPReplyError: If no such article exists or the currently selected newsgroup is invalid. .. py:method:: _body(code: int, message: str, decode: bool | None = None) -> bytes .. py:method:: article(msgid_article: str | int | None = None, decode: bool | None = None) -> tuple[int, nntp.headerdict.HeaderDict, bytes] ARTICLE command. Selects an article according to the arguments and presents the entire article (that is, the headers, an empty line, and the body, in that order) to the client. See Args: msgid_article: A message-id as a string, or an article number as an integer. A msgid_article of None (the default) uses the current article. decode: Force yenc decoding to be enabled or disabled. A value of None (the default) attempts to determine this automatically. Returns: A 3-tuple of the article number, the article headers, and the article body. The headers are decoded to unicode, where as the body is returned as bytes. Raises: NNTPReplyError: If no such article exists. .. py:method:: head(msgid_article: str | int | None = None) -> nntp.headerdict.HeaderDict HEAD command. Identical to the ARTICLE command except that only the headers are presented. See Args: msgid_article: A message-id as a string, or an article number as an integer. A msgid_article of None (the default) uses the current article. Returns: The article headers. Raises: NNTPReplyError: If no such article exists. .. py:method:: body(msgid_article: str | int | None = None, decode: bool | None = None) -> bytes BODY command. Identical to the ARTICLE command except that only the body is presented. See Args: msgid_article: A message-id as a string, or an article number as an integer. A msgid_article of None (the default) uses the current article. decode: Force yenc decoding to be enabled or disabled. A value of None (the default) attempts to determine this automatically. Returns: The article body. Raises: NNTPReplyError: If no such article exists. .. py:method:: _hdr(header: str, msgid_range: str | nntp.types.Range | None = None, verb: str = 'HDR') -> collections.abc.Iterator[tuple[int, str]] .. py:method:: hdr(header: str, msgid_range: str | nntp.types.Range | None = None) -> collections.abc.Iterator[tuple[int, str]] HDR command. Provides access to specific fields from an article specified by message-id, or from a specified article or range of articles in the currently selected newsgroup. See Args: header: The header field to retrieve. msgid_range: A message-id as a string, or an article number as an integer, or a tuple of specifying a range of article numbers in the form (first, [last]) - if last is omitted then all articles after first are included. A msgid_range of None (the default) uses the current article. Yields: A 2-tuple giving the article number and value for the provided header field for each article in the given range. Raises: NNTPDataError: If the response from the server is malformed. NNTPReplyError: If no such article exists. .. py:method:: xhdr(header: str, msgid_range: str | nntp.types.Range | None = None) -> collections.abc.Iterator[tuple[int, str]] Generator for the XHDR command. See hdr_gen() .. py:method:: xzhdr(header: str, msgid_range: str | nntp.types.Range | None = None) -> collections.abc.Iterator[tuple[int, str]] Generator for the XZHDR command. The compressed version of XHDR. See xhdr(). .. py:property:: overview_fmt :type: tuple[str, Ellipsis] .. py:method:: _xover(range: nntp.types.Range | None = None, verb: str = 'XOVER') -> collections.abc.Iterator[tuple[int, nntp.headerdict.HeaderDict]] .. py:method:: xover(range: nntp.types.Range | None = None) -> collections.abc.Iterator[tuple[int, nntp.headerdict.HeaderDict]] XOVER command. The XOVER command returns information from the overview database for the article(s) specified. Args: range: An article number as an integer, or a tuple of specifying a range of article numbers in the form (first, [last]). If last is omitted then all articles after first are included. A range of None (the default) uses the current article. Yields: A 2-tuple of the article number and a dictionary of the fields as given by the overview database for each available article in the specified range. The names of the fields that are returned are determined using the LIST OVERVIEW.FMT command if the server supports it, otherwise a fallback set of 'required' headers is used. Raises: NNTPReplyError: If no such article exists or the currently selected newsgroup is invalid. .. py:method:: xzver(range: nntp.types.Range | None = None) -> collections.abc.Iterator[tuple[int, nntp.headerdict.HeaderDict]] XZVER command. The compressed version of XHDR. See xover(). .. py:method:: xpat(header: str, msgid_range: str | nntp.types.Range, *pattern: str) -> collections.abc.Iterator[str] XPAT command. Used to retrieve specific headers from specific articles, based on pattern matching on the contents of the header. See Args: header: The header field to match against. msgid_range: An article number as an integer, or a tuple of specifying a range of article numbers in the form (first, [last]). If last is omitted then all articles after first are included. Yields: Not sure of the format but the value of the header will be part of it. Raises: NNTPReplyError: If no such article exists. .. py:method:: xfeature_compress_gzip(terminator: bool = False) -> bool XFEATURE COMPRESS GZIP command. .. py:method:: post(headers: collections.abc.Mapping[str, str] | None = None, body: str | bytes | collections.abc.Iterable[bytes] = b'') -> str | bool POST command. Args: headers: A dictionary of headers. body: A string, bytes or binary file-like object containing the post content. Raises: NNTPDataError: If binary characters are detected in the message body. Returns: A value that evaluates to true if posting the message succeeded. (See note for further details) Note: '\n' line terminators are converted to '\r\n' Note: Though not part of any specification it is common for usenet servers to return the message-id for a successfully posted message. If a message-id is identified in the response from the server then that message-id will be returned by the function, otherwise True will be returned. Note: Due to protocol issues if illegal characters are found in the body the message will still be posted but will be truncated as soon as an illegal character is detected. No illegal characters will be sent to the server. For information illegal characters include embedded carriage returns '\r' and null characters '\0' (because this function converts line feeds to CRLF, embedded line feeds are not an issue) .. py:exception:: NNTPDataError Bases: :py:obj:`NNTPError` NNTP data error. Data errors are raised when the content of a response cannot be parsed. .. py:exception:: NNTPError Bases: :py:obj:`Exception` Base class for all NNTP errors. .. py:exception:: NNTPPermanentError(code: int, message: str) Bases: :py:obj:`NNTPReplyError` NNTP permanent errors. Permanent errors have response codes from 500 to 599. .. py:exception:: NNTPProtocolError Bases: :py:obj:`NNTPError` NNTP protocol error. Protocol errors are raised when the response status is invalid. .. py:exception:: NNTPReplyError(code: int, message: str) Bases: :py:obj:`NNTPError` NNTP response status errors. .. py:attribute:: code .. py:attribute:: message .. py:method:: __str__() -> str Return str(self). .. py:exception:: NNTPTemporaryError(code: int, message: str) Bases: :py:obj:`NNTPReplyError` NNTP temporary errors. Temporary errors have response codes from 400 to 499.