API reference
This part of the documentation covers all the public interfaces of reader.
Reader object
Most of reader’s functionality can be accessed through a Reader
instance.
- reader.make_reader(url, *, feed_root=None, plugins=..., session_timeout=(3.05, 60), reserved_name_scheme=..., search_enabled='auto')
Create a new
Reader
.reader can optionally parse local files, with the feed URL either a bare path or a file URI.
The interpretation of local feed URLs depends on the value of the feed
feed_root
argument. It can be one of the following:None
No local file parsing. Updating local feeds will fail.
''
(the empty string)Full filesystem access. This should be used only if the source of feed URLs is trusted.
Both absolute and relative feed paths are supported. The current working directory is used normally (as if the path was passed to
open()
).Example: Assuming the current working directory is
/feeds
, all of the following feed URLs correspond to/feeds/feed.xml
:feed.xml
,/feeds/feed.xml
,file:feed.xml
, andfile:/feeds/feed.xml
.'/path/to/feed/root'
(any non-empty string)An absolute path; all feed URLs are interpreted as relative to it. This can be used if the source of feed URLs is untrusted.
Feed paths must be relative. The current working directory is ignored.
Example: Assuming the feed root is
/feeds
, feed URLsfeed.xml
andfile:feed.xml
correspond to/feeds/feed.xml
./feed.xml
andfile:/feed.xml
are both errors.Relative paths pointing outside the feed root are errors, to prevent directory traversal attacks. Note that symbolic links inside the feed root can point outside it.
The root and feed paths are joined and normalized with no regard for symbolic links; see
os.path.normpath()
for details.Accessing device files on Windows is an error.
- Parameters:
url (str) – Path to the reader database.
feed_root (str or None) – Directory where to look for local feeds. One of
None
(don’t open local feeds; default),''
(full filesystem access), or'/path/to/feed/root'
(an absolute path that feed paths are relative to).plugins (iterable(str or callable(Reader)) or None) – An iterable of built-in plugin names or plugin(reader) –> None callables. The callables are called with the reader object before it is returned. Exceptions from plugin code will propagate to the caller. Defaults to
DEFAULT_PLUGINS
.session_timeout (float or tuple(float, float) or None) – When retrieving HTTP(S) feeds, how many seconds to wait for the server to send data, as a float, or a (connect timeout, read timeout) tuple. Passed to the underlying Requests session.
reserved_name_scheme (dict(str, str)) – Value for
reserved_name_scheme
. The prefixes default to.reader.
/.plugin.
, and the separator to.
search_enabled (bool or None or
'auto'
) – Whether to enable search. One of'auto'
(enable on the firstupdate_search()
call; default),True
(enable),False
(disable),None
(do nothing).
- Returns:
The reader.
- Return type:
- Raises:
StorageError – An error occurred while connecting to storage.
SearchError – An error occurred while enabling/disabling search.
InvalidPluginError – An invalid plugin name was passed to
plugins
.PluginInitError – A plugin failed to initialize.
PluginError – An ambiguous plugin-related error occurred.
ReaderError – An ambiguous exception occurred while creating the reader.
Changelog
Changed in version 3.0: Wrap exceptions raised during plugin initialization in
PluginInitError
instead of letting them bubble up.New in version 2.4: The
search_enabled
keyword argument.Changed in version 2.4: Enable search on the first
update_search()
call. To get the previous behavior (leave search as-is), usesearch_enabled=None
.Changed in version 2.0:
feed_root
now defaults toNone
(don’t open local feeds) instead of''
(full filesystem access).New in version 1.17: The
reserved_name_scheme
keyword argument.New in version 1.16: The
plugins
keyword argument. Using an invalid plugin name raisesInvalidPluginError
, aValueError
subclass.New in version 1.14: The
session_timeout
keyword argument, with a default of (3.05, 60) seconds; the previous behavior was to never time out.New in version 1.6: The
feed_root
keyword argument.
- class reader.Reader(...)
A feed reader.
Persists feed and entry state, provides operations on them, and stores configuration.
Currently, the following feed types are supported:
Atom (provided by feedparser)
RSS (provided by feedparser)
JSON Feed
Additional sources can be added through plugins.
In order to perform maintenance tasks and release underlying resources in a predictable manner, the Reader object should be used as a context manager from each thread where it is used. For convenience, it is possible to use a Reader object directly; in this case, maintenance tasks may sometimes be performed before arbitrary method calls return.
Important
Reader objects should be created using
make_reader()
; the Reader constructor is not stable yet and may change without any notice.Changelog
Changed in version 2.16: Allow using a Reader object from multiple threads directly (do not require it to be used as a context manager anymore).
Changed in version 2.16: Allow Reader objects to be reused after closing.
Changed in version 2.16: Allow using a Reader object from multiple asyncio tasks.
Changed in version 2.15: Allow using Reader objects as context managers.
Changed in version 2.15: Allow using Reader objects from threads other than the creating thread.
Changed in version 2.10: Allow passing a (feed URL,) 1-tuple anywhere a feed URL can be passed.
New in version 1.13: JSON Feed support.
- close()
Close this
Reader
.Releases any underlying resources associated with the reader.
The reader can be reused after being closed (but you have to call close() again after that).
close() should be called from each thread where the reader is used. Prefer using the reader as a context manager instead.
- Raises:
Changelog
Changed in version 2.16: Allow calling close() from any thread.
- add_feed(feed, /, exist_ok=False, *, allow_invalid_url=False)
Add a new feed.
Feed updates are enabled by default.
- Parameters:
- Raises:
FeedExistsError – If the feed already exists, and exist_ok is false.
InvalidFeedURLError – If
feed
is invalid andallow_invalid_url
is false.
Changelog
Changed in version 3.0: The
feed
argument is now positional-only.New in version 2.8: The
exist_ok
argument.New in version 2.5: The
allow_invalid_url
keyword argument.Changed in version 2.5: Validate the new feed URL. To get the previous behavior (no validation), use
allow_invalid_url=True
.
- delete_feed(feed, /, missing_ok=False)
Delete a feed and all of its entries and tags.
- Parameters:
- Raises:
FeedNotFoundError – If the feed does not exist, and missing_ok is false.
Changelog
Changed in version 3.0: The
feed
argument is now positional-only.New in version 2.8: The
missing_ok
argument.New in version 1.18: Renamed from
remove_feed()
.
- change_feed_url(old, new, /, *, allow_invalid_url=False)
Change the URL of a feed.
User-defined feed attributes are preserved:
added
,user_title
. Feed-defined feed attributes are also preserved, at least until the next update:title
,link
,author
,subtitle
(exceptupdated
andversion
, which get set to None). All other feed attributes are set to their default values.The entries and tags are preserved.
- Parameters:
- Raises:
FeedNotFoundError – If
old
does not exist.FeedExistsError – If
new
already exists.InvalidFeedURLError – If
new
is invalid andallow_invalid_url
is false.
Changelog
Changed in version 3.0: The
old
andnew
arguments are now positional-only.New in version 2.5: The
allow_invalid_url
keyword argument.Changed in version 2.5: Validate the new feed URL. To get the previous behavior (no validation), use
allow_invalid_url=True
.New in version 1.8.
- get_feeds(*, feed=None, tags=None, broken=None, updates_enabled=None, new=None, sort='title', limit=None, starting_after=None)
Get all or some of the feeds.
The
tags
argument can be a list of one or more feed tags. Multiple tags are interpreted as a conjunction (AND). To use a disjunction (OR), use a nested list. To negate a tag, prefix the tag value with a minus sign (-
). Examples:['one']
one
['one', 'two']
[['one'], ['two']]
one AND two
[['one', 'two']]
one OR two
[['one', 'two'], 'three']
(one OR two) AND three
['one', '-two']
one AND NOT two
Special values
True
andFalse
match feeds with any tags and no tags, respectively.True
[True]
any tags
False
[False]
no tags
[True, '-one']
any tags AND NOT one
[[False, 'one']]
no tags OR one
- Parameters:
feed (str or tuple(str) or Feed or None) – Only return the feed with this URL.
tags (None or bool or list(str or bool or list(str or bool))) – Only return feeds matching these tags.
broken (bool or None) – Only return broken / healthy feeds.
updates_enabled (bool or None) – Only return feeds that have updates enabled / disabled.
new (bool or None) – Only return feeds that have never been updated / have been updated before.
sort (str) – How to order feeds; one of
'title'
(byuser_title
ortitle
, case insensitive; default), or'added'
(last added first).limit (int or None) – A limit on the number of feeds to be returned; by default, all feeds are returned.
starting_after (str or tuple(str) or Feed or None) – Return feeds after this feed; a cursor for use in pagination.
- Yields:
Feed
– Sorted according tosort
.- Raises:
FeedNotFoundError – If
starting_after
does not exist.
Changelog
New in version 2.6: The
new
keyword argument.New in version 1.12: The
limit
andstarting_after
keyword arguments.New in version 1.11: The
updates_enabled
keyword argument.New in version 1.7: The
tags
keyword argument.New in version 1.7: The
broken
keyword argument.
- get_feed(feed: str | FeedLike, /) Feed
- get_feed(feed: str | FeedLike, default: _T, /) Feed | _T
Get a feed.
Like
next(iter(reader.get_feeds(feed=feed)))
, but raises a custom exception instead ofStopIteration
.- Parameters:
- Returns:
The feed.
- Return type:
- Raises:
Changelog
Changed in version 3.0: The
feed
anddefault
arguments are now positional-only.
- get_feed_counts(*, feed=None, tags=None, broken=None, updates_enabled=None, new=None)
Count all or some of the feeds.
See
get_feeds()
for details on how filtering works.- Parameters:
feed (str or tuple(str) or Feed or None) – Only count the feed with this URL.
tags (None or bool or list(str or bool or list(str or bool))) – Only count feeds matching these tags.
broken (bool or None) – Only count broken / healthy feeds.
updates_enabled (bool or None) – Only count feeds that have updates enabled / disabled.
new (bool or None) – Only count feeds that have never been updated / have been updated before.
- Return type:
- Raises:
Changelog
New in version 2.6: The
new
keyword argument.New in version 1.11.
- set_feed_user_title(feed, title, /)
Set a user-defined title for a feed.
- Parameters:
- Raises:
Changelog
Changed in version 3.0: The
feed
andtitle
arguments are now positional-only.
- enable_feed_updates(feed, /)
Enable updates for a feed.
See
update_feeds()
for details.- Parameters:
- Raises:
Changelog
Changed in version 3.0: The
feed
argument is now positional-only.New in version 1.11.
- disable_feed_updates(feed, /)
Disable updates for a feed.
See
update_feeds()
for details.- Parameters:
- Raises:
Changelog
Changed in version 3.0: The
feed
argument is now positional-only.New in version 1.11.
- update_feeds(*, feed=None, tags=None, broken=None, updates_enabled=True, new=None, workers=1)
Update all or some of the feeds.
Silently skip feeds that raise
ParseError
.Re-raise
before_feeds_update_hooks
failures immediately. Collect all other update hook failures and re-raise them as anUpdateHookErrorGroup
; currently, only the exceptions for the first 5 feeds with hook failures are collected.By default, update all the feeds that have updates enabled.
Roughly equivalent to
for _ in reader.update_feeds_iter(...): pass
.- Parameters:
feed (str or tuple(str) or Feed or None) – Only update the feed with this URL.
tags (None or bool or list(str or bool or list(str or bool))) – Only update feeds matching these tags.
broken (bool or None) – Only update broken / healthy feeds.
updates_enabled (bool or None) – Only update feeds that have updates enabled / disabled. Defaults to true.
new (bool or None) – Only update feeds that have never been updated / have been updated before. Defaults to None.
workers (int) – Number of threads to use when getting the feeds.
- Raises:
UpdateHookError – For unexpected hook exceptions.
Changelog
Changed in version 3.8: Wrap unexpected update hook exceptions in
UpdateHookError
. Try to update all the feeds, don’t stop after a feed/entry hook fails.Changed in version 3.8: Document this method can raise non-feed-related
UpdateError
s (other thanUpdateHookError
).New in version 2.6: The
feed
,tags
,broken
, andupdates_enabled
keyword arguments.Changed in version 2.0: Removed the
new_only
parameter.Changed in version 2.0: All parameters are keyword-only.
Changed in version 1.15: Update entries whenever their content changes, regardless of their
updated
date.Content-only updates (not due to an
updated
change) are limited to 24 consecutive updates, to prevent spurious updates for entries whose content changes excessively (for example, because it includes the current time).Previously, entries would be updated only if the entry
updated
was newer than the stored one.Changed in version 1.11: Only update the feeds that have updates enabled.
- update_feeds_iter(*, feed=None, tags=None, broken=None, updates_enabled=True, new=None, workers=1, _call_feeds_update_hooks=True)
Update all or some of the feeds.
Yield information about each updated feed.
Re-raise
before_feeds_update_hooks
failures immediately. Yield feed/entry update hook failures. Collectafter_feeds_update_hooks
failures and re-raise them as anUpdateHookErrorGroup
after updating all the feeds.By default, update all the feeds that have updates enabled.
- Parameters:
feed (str or tuple(str) or Feed or None) – Only update the feed with this URL.
tags (None or bool or list(str or bool or list(str or bool))) – Only update feeds matching these tags.
broken (bool or None) – Only update broken / healthy feeds.
updates_enabled (bool or None) – Only update feeds that have updates enabled / disabled. Defaults to true.
new (bool or None) – Only update feeds that have never been updated / have been updated before. Defaults to None.
workers (int) – Number of threads to use when getting the feeds.
- Yields:
UpdateResult
– An (url, value) pair; the value is one of:a summary of the updated feed, if the update was successful
None, if the server indicated the feed has not changed since the last update
an exception instance
Currently, the exception can be:
ParseError
, if retrieving/parsing the feed failedUpdateHookError
, for unexpected hook exceptions raised inbefore_feed_update_hooks
,after_entry_update_hooks
, orafter_feed_update_hooks
…but other
UpdateError
subclasses may be yielded in the future.- Raises:
UpdateHookError – For unexpected hook exceptions raised in
before_feeds_update_hooks
orafter_feeds_update_hooks
.UpdateError – For non-feed-related update exceptions.
Changelog
Changed in version 3.8: Wrap unexpected update hook exceptions in
UpdateHookError
. Try to update all the feeds, don’t stop after a feed/entry hook fails.Changed in version 3.8: Document this method can raise non-feed-related
UpdateError
s (other thanUpdateHookError
).New in version 2.6: The
feed
,tags
,broken
, andupdates_enabled
keyword arguments.Changed in version 2.0: Removed the
new_only
parameter.Changed in version 2.0: All parameters are keyword-only.
Changed in version 1.15: Update entries whenever their content changes. See
update_feeds()
for details.New in version 1.14.
- update_feed(feed, /)
Update a single feed.
The feed will be updated even if updates are disabled for it.
Like
next(iter(reader.update_feeds_iter(feed=feed, updates_enabled=None)))[1]
, but raises theUpdateError
, if any.- Parameters:
- Returns:
A summary of the updated feed or None, if the server indicated the feed has not changed since the last update.
- Return type:
UpdatedFeed or None
- Raises:
UpdateHookError – For unexpected hook exceptions.
Changelog
Changed in version 3.8: Wrap unexpected update hook exceptions in
UpdateHookError
.Changed in version 3.8: Document this method can raise
UpdateError
s (other thanParseError
andUpdateHookError
).Changed in version 3.0: The
feed
argument is now positional-only.Changed in version 1.15: Update entries whenever their content changes. See
update_feeds()
for details.Changed in version 1.14: The method now returns UpdatedFeed or None instead of None.
- get_entries(*, feed=None, entry=None, read=None, important=None, has_enclosures=None, tags=None, feed_tags=None, sort='recent', limit=None, starting_after=None)
Get all or some of the entries.
Entries are sorted according to
sort
. Possible values:'recent'
Most recent first. That is:
by published date for entries imported on the first update (if an entry does not have
published
,updated
is used)by added date for entries imported after that
This is to make sure newly imported entries appear at the top regardless of when the feed says they were published, while not having all the old entries at the top for new feeds.
Note
The algorithm for “recent” is a heuristic and may change over time.
Changelog
Changed in version 3.1: Sort entries by added date most of the time, with the exception of those imported on the first update. Previously, entries would be sorted by added only if they were published less than 7 days ago.
'random'
Random order (shuffled). At at most 256 entries will be returned.
Changelog
New in version 1.2.
- Parameters:
feed (str or tuple(str) or Feed or None) – Only return the entries for this feed.
entry (tuple(str, str) or Entry or None) – Only return the entry with this (feed URL, entry id) tuple.
read (bool or None) – Only return (un)read entries.
important (bool or None or str) – Only return (un)important entries. For more precise filtering, use one of the
TristateFilterInput
string filters.has_enclosures (bool or None) – Only return entries that (don’t) have enclosures.
feed_tags (None or bool or list(str or bool or list(str or bool))) – Only return the entries from feeds matching these tags; works like the
get_feeds()
tags
argument.sort (str) – How to order entries; one of
'recent'
(default) or'random'
.limit (int or None) – A limit on the number of entries to be returned; by default, all entries are returned.
starting_after (tuple(str, str) or Entry or None) – Return entries after this entry; a cursor for use in pagination. Using
starting_after
withsort='random'
is not supported.
- Yields:
Entry
– Sorted according tosort
.- Raises:
EntryNotFoundError – If
starting_after
does not exist.
Changelog
Changed in version 3.5: The
important
argument also accepts string values.New in version 1.12: The
limit
andstarting_after
keyword arguments.New in version 1.7: The
feed_tags
keyword argument.New in version 1.2: The
sort
keyword argument.
- get_entry(entry: tuple[str, str] | EntryLike, /) Entry
- get_entry(entry: tuple[str, str] | EntryLike, default: _T, /) Entry | _T
Get an entry.
Like
next(iter(reader.get_entries(entry=entry)))
, but raises a custom exception instead ofStopIteration
.- Parameters:
- Returns:
The entry.
- Return type:
- Raises:
Changelog
Changed in version 3.0: The
entry
anddefault
arguments are now positional-only.
- get_entry_counts(*, feed=None, entry=None, read=None, important=None, has_enclosures=None, tags=None, feed_tags=None)
Count all or some of the entries.
See
get_entries()
for details on how filtering works.- Parameters:
feed (str or tuple(str) or Feed or None) – Only count the entries for this feed.
entry (tuple(str, str) or Entry or None) – Only count the entry with this (feed URL, entry id) tuple.
read (bool or None) – Only count (un)read entries.
important (bool or None or str) – Only count (un)important entries. For more precise filtering, use one of the
TristateFilterInput
string filters.has_enclosures (bool or None) – Only count entries that (don’t) have enclosures.
feed_tags (None or bool or list(str or bool or list(str or bool))) – Only count the entries from feeds matching these tags.
- Return type:
- Raises:
Changelog
Changed in version 3.5: The
important
argument also accepts string values.New in version 1.11.
- set_entry_read(entry, read, /, modified=no value)
Mark an entry as read or unread, possibly with a custom timestamp.
- Parameters:
entry (tuple(str, str) or Entry) – (feed URL, entry id) tuple.
read (bool) – Mark the entry as read if true, and as unread otherwise.
modified (datetime or None) – Set
read_modified
to this. Naive datetimes are normalized by passing them toastimezone()
. Defaults to the current time.
- Raises:
Changelog
Changed in version 3.5: Do not coerce
read
tobool
anymore, require it to beTrue
orFalse
.Changed in version 3.0: The
entry
andread
arguments are now positional-only.New in version 2.2.
- mark_entry_as_read(entry, /)
Mark an entry as read.
Alias for
set_entry_read(entry, True)
.Changelog
Changed in version 3.0: The
entry
argument is now positional-only.New in version 1.18: Renamed from
mark_as_read()
.
- mark_entry_as_unread(entry, /)
Mark an entry as unread.
Alias for
set_entry_read(entry, False)
.Changelog
Changed in version 3.0: The
entry
argument is now positional-only.New in version 1.18: Renamed from
mark_as_unread()
.
- set_entry_important(entry, important, /, modified=no value)
Mark an entry as important or unimportant, possibly with a custom timestamp.
- Parameters:
entry (tuple(str, str) or Entry) – (feed URL, entry id) tuple.
important (bool or None) – Mark the entry as important if true, as unimportant if false, or as not set if none.
modified (datetime or None) – Set
important_modified
to this. Naive datetimes are normalized by passing them toastimezone()
. Defaults to the current time.
- Raises:
Changelog
Changed in version 3.5:
important
can now beNone
.Changed in version 3.5: Do not coerce
important
tobool
anymore, require it to beTrue
orFalse
orNone
.Changed in version 3.0: The
entry
andimportant
arguments are now positional-only.New in version 2.2.
- mark_entry_as_important(entry, /)
Mark an entry as important.
Alias for
set_entry_important(entry, True)
.Changelog
Changed in version 3.0: The
entry
argument is now positional-only.New in version 1.18: Renamed from
mark_as_important()
.
- mark_entry_as_unimportant(entry, /)
Mark an entry as unimportant.
Alias for
set_entry_important(entry, False)
.Changelog
Changed in version 3.0: The
entry
argument is now positional-only.New in version 1.18: Renamed from
mark_as_unimportant()
.
- add_entry(entry, /)
Add a new entry to an existing feed.
entry
can be anyEntry
-like object, or a mapping of the same shape:>>> from types import SimpleNamespace >>> reader.add_entry(SimpleNamespace( ... feed_url='http://example.com', ... id='one', ... title='title', ... enclosures=[SimpleNamespace(href='enclosure')], ... )) >>> reader.add_entry({ ... 'feed_url': 'http://example.com', ... 'id': 'two', ... 'updated': datetime.now(timezone.utc), ... 'content': [{'value': 'content'}], ... })
The following attributes are used (they must have the same types as on
Entry
):Naive datetimes are normalized by passing them to
astimezone()
.The added entry will be
added_by
'user'
.- Parameters:
entry (Entry or dict) – An entry-like object or equivalent mapping.
- Raises:
EntryExistsError – If an entry with the same id already exists.
Changelog
Changed in version 3.0: The
entry
argument is now positional-only.New in version 2.5.
- delete_entry(entry, /, missing_ok=False)
Delete an entry.
Currently, only entries added by
add_entry()
(added_by
'user'
) can be deleted.- Parameters:
- Raises:
EntryNotFoundError – If the entry does not exist, and missing_ok is false.
EntryError – If the entry was not added by the user.
Changelog
Changed in version 3.0: The
entry
argument is now positional-only.New in version 2.8: The
missing_ok
argument.New in version 2.5.
- enable_search()
Enable full-text search.
Calling this method if search is already enabled is a no-op.
- Raises:
- disable_search()
Disable full-text search.
Calling this method if search is already disabled is a no-op.
- Raises:
- is_search_enabled()
Check if full-text search is enabled.
- Returns:
Whether search is enabled or not.
- Return type:
- Raises:
- update_search()
Update the full-text search index.
Search must be enabled to call this method.
If
make_reader()
was called withsearch_enabled='auto'
and search is disabled, it will be enabled automatically.- Raises:
- search_entries(query, /, *, feed=None, entry=None, read=None, important=None, has_enclosures=None, tags=None, feed_tags=None, sort='relevant', limit=None, starting_after=None)
Get entries matching a full-text search query.
Entries are sorted according to
sort
. Possible values:'relevant'
Most relevant first.
'recent'
Most recent first. See
get_entries()
for details on what recent means.Changelog
Changed in version 3.1: Sort entries by added date most of the time, with the exception of those imported on the first update. Previously, entries would be sorted by added only if they were published less than 7 days ago.
New in version 1.4.
'random'
Random order (shuffled). At at most 256 entries will be returned.
Changelog
New in version 1.10.
Note
The query syntax is dependent on the search provider.
The default (and for now, only) search provider is SQLite FTS5. You can find more details on its query syntax here: https://www.sqlite.org/fts5.html#full_text_query_syntax
The columns available in queries are:
title
: the entry titlefeed
: the feed titlecontent
: the entry main text content; this includes the summary and the value of contents that have text/(x)html, text/plain or missing content types
Query examples:
hello internet
: entries that match “hello” and “internet”hello NOT internet
: entries that match “hello” but do not match “internet”hello feed: cortex
: entries that match “hello” anywhere, and their feed title matches “cortex”hello NOT feed: internet
: entries that match “hello” anywhere, and their feed title does not match “internet”
Search must be enabled to call this method.
- Parameters:
query (str) – The search query.
feed (str or tuple(str) or Feed or None) – Only search the entries for this feed.
entry (tuple(str, str) or Entry or None) – Only search for the entry with this (feed URL, entry id) tuple.
read (bool or None) – Only search (un)read entries.
important (bool or None or str) – Only search (un)important entries. For more precise filtering, use one of the
TristateFilterInput
string filters.has_enclosures (bool or None) – Only search entries that (don’t) have enclosures.
feed_tags (None or bool or list(str or bool or list(str or bool))) – Only return the entries from feeds matching these tags; works like the
get_feeds()
tags
argument.sort (str) – How to order results; one of
'relevant'
(default),'recent'
, or'random'
.limit (int or None) – A limit on the number of results to be returned; by default, all results are returned.
starting_after (tuple(str, str) or EntrySearchResult or None) – Return results after this result; a cursor for use in pagination. Using
starting_after
withsort='random'
is not supported.
- Yields:
EntrySearchResult
– Sorted according tosort
.- Raises:
EntryNotFoundError – If
starting_after
does not exist.
Changelog
Changed in version 3.5: The
important
argument also accepts string values.Changed in version 3.0: The
query
argument is now positional-only.New in version 1.12: The
limit
andstarting_after
keyword arguments.New in version 1.7: The
feed_tags
keyword argument.New in version 1.4: The
sort
keyword argument.
- search_entry_counts(query, /, *, feed=None, entry=None, read=None, important=None, has_enclosures=None, tags=None, feed_tags=None)
Count entries matching a full-text search query.
See
search_entries()
for details on how the query syntax and filtering work.Search must be enabled to call this method.
- Parameters:
query (str) – The search query.
feed (str or tuple(str) or Feed or None) – Only count the entries for this feed.
entry (tuple(str, str) or Entry or None) – Only count the entry with this (feed URL, entry id) tuple.
read (bool or None or str) – Only count (un)read entries. For more precise filtering, use one of the
TristateFilterInput
string filters.important (bool or None) – Only count (un)important entries.
has_enclosures (bool or None) – Only count entries that (don’t) have enclosures.
feed_tags (None or bool or list(str or bool or list(str or bool))) – Only count the entries from feeds matching these tags.
- Return type:
- Raises:
Changelog
Changed in version 3.5: The
important
argument also accepts string values.Changed in version 3.0: The
query
argument is now positional-only.New in version 1.11.
- get_tags(resource, /, *, key=None)
Get all or some tags of a resource as
(key, value)
pairs.resource can have one of the following types:
Feed
orstr
or(str,)
A feed or feed URL (possibly enclosed in a tuple).
Entry
or(str, str)
An entry or a (feed URL, entry id) pair representing an entry.
()
(empty tuple)Special value representing the global tag namespace.
- Parameters:
resource (reader.types.ResourceInput) – The resource to get tags for.
key (str or None) – Only return the value for this key.
- Yields:
tuple(str, JSONType) –
(key, value)
pairs, in undefined order. JSONType is whateverjson.dumps()
accepts.- Raises:
Changelog
Changed in version 3.0: The
resource
argument is now positional-only.Changed in version 2.10: Support entry and global tags.
Changed in version 2.10: Removed support for the
(None,)
(any feed) andNone
(any resource) wildcard resource values.New in version 2.8.
- get_tag_keys(resource=None, /)
Get the keys of all or some resource tags.
Equivalent to
sorted(k for k, _ in reader.get_tags(resource))
.See
get_tags()
for possible resource values. In addition, resource can have one of the following wildcard values:(None,)
Any feed.
(None, None)
Any entry.
None
Any resource (feed, entry, or the global namespace).
- Parameters:
resource (reader.types.AnyResourceInput) – Only return tag keys for this resource.
- Yields:
str – The tag keys, in alphabetical order.
- Raises:
Changelog
Changed in version 3.0: The
resource
argument is now positional-only.Changed in version 2.10: Support entry and global tags.
New in version 2.8.
- get_tag(resource: ResourceInput, key: str, /) JSONType
- get_tag(resource: ResourceInput, key: str, default: _T, /) reader.types.JSONType | _T
Get the value of this resource tag.
Like
next(iter(reader.get_tags(resource, key=key)))[1]
, but raises a custom exception instead ofStopIteration
.See
get_tags()
for possible resource values.- Parameters:
resource – The resource.
key (str) – The key of the tag to retrieve.
default – Returned if given and no tag exists for key.
- Returns:
The tag value. JSONType is whatever
json.dumps()
accepts.- Return type:
JSONType
- Raises:
Changelog
Changed in version 3.0: The
resource
,key
, anddefault
arguments are now positional-only.Changed in version 2.10: Support entry and global tags.
New in version 2.8.
- set_tag(resource: ResourceInput, key: str, /) None
- set_tag(resource: ResourceInput, key: str, value: JSONType, /) None
Set the value of this resource tag.
See
get_tags()
for possible resource values.- Parameters:
resource – The resource.
key (str) – The key of the tag to set.
value (JSONType) – The value of the tag to set. If not provided, and the tag already exists, the value remains unchanged; if the tag does not exist, it is set to
None
. JSONType is whateverjson.dumps()
accepts.
- Raises:
Changelog
Changed in version 3.0: The
resource
,key
, andvalue
arguments are now positional-only.Changed in version 2.10: Support entry and global tags.
New in version 2.8.
- delete_tag(resource, key, /, missing_ok=False)
Delete this resource tag.
See
get_tags()
for possible resource values.- Parameters:
resource (reader.types.ResourceInput) – The resource.
key (str) – The key of the tag to delete.
missing_ok (bool) – If true, don’t raise
TagNotFoundError
if the tag does not exist.
- Raises:
TagNotFoundError – If the tag does not exist, and missing_ok is false.
Changelog
Changed in version 3.0: The
resource
andkey
arguments are now positional-only.Changed in version 2.10: Support entry and global tags.
New in version 2.8.
- make_reader_reserved_name(key, /)
Create a reader-reserved tag name. See Reserved names for details.
Uses
reserved_name_scheme
to build names of the format:{reader_prefix}{key}
Using the default scheme:
>>> reader.make_reader_reserved_name('key') '.reader.key'
Changelog
Changed in version 3.0: The
key
argument is now positional-only.New in version 1.17.
- make_plugin_reserved_name(plugin_name, key=None, /)
Create a plugin-reserved tag name. See Reserved names for details.
Plugins should use this to generate names for plugin-specific tags.
Uses
reserved_name_scheme
to build names of the format:{plugin_prefix}{plugin_name} {plugin_prefix}{plugin_name}{separator}{key}
Using the default scheme:
>>> reader.make_plugin_reserved_name('myplugin') '.plugin.myplugin' >>> reader.make_plugin_reserved_name('myplugin', 'key') '.plugin.myplugin.key'
- Parameters:
- Returns:
The name.
- Return type:
Changelog
Changed in version 3.0: The
plugin_name
andkey
arguments are now positional-only.New in version 1.17.
- property reserved_name_scheme: Mapping[str, str]
Mapping used to build reserved names. See
make_reader_reserved_name()
andmake_plugin_reserved_name()
for details on how this is used.The default scheme (these keys are required):
{'reader_prefix': '.reader.', 'plugin_prefix': '.plugin.', 'separator': '.'}
The returned mapping is immutable; assign a new mapping to change the scheme.
Changelog
New in version 1.17.
- property before_feeds_update_hooks: MutableSequence[Callable[[Reader], None]]
List of functions called once before updating any feeds, at the beginning of
update_feeds()
/update_feeds_iter()
, but notupdate_feed()
.Each function is called with:
reader – the
Reader
instance
Each function should return
None
.The hooks are run in order. Exceptions raised by hooks are wrapped in a
SingleUpdateHookError
and re-raised (hooks after the one that failed are not run).Changelog
Changed in version 3.8: Wrap unexpected exceptions in
UpdateHookError
.New in version 2.12.
- property before_feed_update_hooks: MutableSequence[Callable[[Reader, str], None]]
List of functions called for each updated feed before the feed is updated.
Each function is called with:
Each function should return
None
.The hooks are run in order. Exceptions raised by hooks are wrapped in a
SingleUpdateHookError
and re-raised (hooks after the one that failed are not run).Changelog
Changed in version 3.8: Wrap unexpected exceptions in
UpdateHookError
.New in version 2.7.
- property after_entry_update_hooks: MutableSequence[Callable[[Reader, EntryData, EntryUpdateStatus], None]]
List of functions called for each updated entry after the feed is updated.
Each function is called with:
reader – the
Reader
instanceentry – an
Entry
-like objectstatus – an
EntryUpdateStatus
value
Each function should return
None
.Warning
The only entry attributes guaranteed to be present are
feed_url
,id
, andresource_id
; all other attributes may be missing (accessing them may raiseAttributeError
).The hooks are run in order. Exceptions raised by hooks are wrapped in a
SingleUpdateHookError
, collected, and re-raised as anUpdateHookErrorGroup
after all the hooks are run; currently, only the exceptions for the first 5 entries with hook failures are collected.Changelog
Changed in version 3.8: Wrap unexpected exceptions in
UpdateHookError
. Try to run all hooks, don’t stop after one fails.New in version 1.20.
- property after_feed_update_hooks: MutableSequence[Callable[[Reader, str], None]]
List of functions called for each updated feed after the feed is updated.
Each function is called with:
Each function should return
None
.The hooks are run in order. Exceptions raised by hooks are wrapped in a
SingleUpdateHookError
, collected, and re-raised as anUpdateHookErrorGroup
after all the hooks are run.Changelog
Changed in version 3.8: Wrap unexpected exceptions in
UpdateHookError
. Try to run all hooks, don’t stop after one fails.New in version 2.2.
- property after_feeds_update_hooks: MutableSequence[Callable[[Reader], None]]
List of functions called once after updating all feeds, at the end of
update_feeds()
/update_feeds_iter()
, but notupdate_feed()
.Each function is called with:
reader – the
Reader
instance
Each function should return
None
.The hooks are run in order. Exceptions raised by hooks are wrapped in a
SingleUpdateHookError
, collected, and re-raised as anUpdateHookErrorGroup
after all the hooks are run.Changelog
Changed in version 3.8: Wrap unexpected exceptions in
UpdateHookError
. Try to run all hooks, don’t stop after one fails.New in version 2.12.
Data objects
- class reader.Feed(url, updated=None, title=None, link=None, author=None, subtitle=None, version=None, user_title=None, added=None, last_updated=None, last_exception=None, updates_enabled=True)
Data type representing a feed.
All
datetime
attributes are timezone-aware, with the timezone set toutc
.Changelog
Changed in version 2.0:
datetime
attributes are now timezone-aware; prior to 2.0, they were naive datetimes representing UTC times.- version: str | None = None
The feed type and version.
For Atom and RSS, provided by feedparser (e.g.
atom10
,rss20
); full list.For JSON Feed:
json10
json11
json
JSON Feed (unknown or unrecognized version)
Plugins may add other versions.
Changelog
New in version 2.4.
- last_updated: datetime | None = None
The date when the feed was last retrieved by reader.
Changelog
New in version 1.3.
- last_exception: ExceptionInfo | None = None
If a
UpdateError
happened during the last update, its details.Changelog
Changed in version 3.9: Store the details of any
UpdateError
(except hook errors), not just the__cause__
ofParseError
s.New in version 1.3.
- class reader.ExceptionInfo(type_name, value_str, traceback_str)
Data type representing information about an exception.
Changelog
New in version 1.3.
- class reader.Entry(id, updated=None, title=None, link=None, author=None, published=None, summary=None, content=(), enclosures=(), read=False, read_modified=None, important=None, important_modified=None, added=None, added_by=None, last_updated=None, original_feed_url=None, feed=None)
Data type representing an entry.
All
datetime
attributes are timezone-aware, with the timezone set toutc
.Changelog
Changed in version 2.0:
datetime
attributes are now timezone-aware; prior to 2.0, they were naive datetimes representing UTC times.- updated: datetime | None = None
The date the entry was last updated, according to the feed.
Changelog
Changed in version 2.5: Is now
None
if missing in the feed; useupdated_not_none
for the pre-2.5 behavior.Changed in version 2.0: May be
None
in some cases. In a future version, will beNone
if missing in the feed; useupdated_not_none
for the pre-2.0 behavior.
- enclosures: Sequence[Enclosure] = ()
External files associated with the entry. A sequence of
Enclosure
objects.
- read_modified: datetime | None = None
The date when
read
was last set by the user;None
if that never happened, or the entry predates the date being recorded.Changelog
New in version 2.2.
- important: bool | None = None
Whether the entry is important or not.
None
means not set.False
means “explicitly unimportant”.
- important_modified: datetime | None = None
The date when
important
was last set by the user;None
if that never happened, or the entry predates the date being recorded.Changelog
New in version 2.2.
- added: datetime = None
The date when the entry was added (first updated) to reader.
Changelog
New in version 2.5.
- added_by: Literal['feed', 'user'] = None
The source of the entry. One of
'feed'
,'user'
.Other values may be added in the future.
Changelog
New in version 2.5.
- last_updated: datetime = None
The date when the entry was last updated by reader.
Changelog
New in version 1.3.
- original_feed_url: str = None
The URL of the original feed of the entry.
If the feed URL never changed, the same as
feed_url
.Changelog
New in version 1.8.
- class reader.Content(value, type=None, language=None)
Data type representing a piece of content.
- class reader.Enclosure(href, type=None, length=None)
Data type representing an external file.
- class reader.EntrySearchResult(feed_url, id, metadata=<factory>, content=<factory>)
Data type representing the result of an entry search.
metadata
andcontent
are dicts where the key is the path of an entry attribute, and the value is aHighlightedString
snippet corresponding to that attribute, with HTML stripped.>>> result = next(reader.search_entries('hello internet')) >>> result.metadata['.title'].value 'A Recent Hello Internet' >>> reader.get_entry(result).title 'A Recent Hello Internet'
- metadata: Mapping[str, HighlightedString]
Matching entry metadata, in arbitrary order. Currently entry.title and entry.feed.user_title/.title.
- content: Mapping[str, HighlightedString]
Matching entry content, sorted by relevance. Any of entry.summary and entry.content[].value.
- class reader.HighlightedString(value='', highlights=())
A string that has some of its parts highlighted.
- highlights: Sequence[slice] = ()
The highlights; non-overlapping slices with positive start/stop and None step.
- classmethod extract(text, before, after)
Extract highlights with before/after markers from text.
>>> HighlightedString.extract( '>one< two', '>', '<') HighlightedString(value='one two', highlights=(slice(0, 3, None),))
- Parameters:
- Returns:
A highlighted string.
- Return type:
- split()
Split the highlighted string into parts.
>>> list(HighlightedString('abcd', [slice(1, 3)])) ['a', 'bc', 'd']
- Yields:
str – The parts (always an odd number); parts with odd indexes are highlighted, parts with even indexes are not.
- class reader.FeedCounts(total=None, broken=None, updates_enabled=None)
Count information about feeds.
Changelog
New in version 1.11.
- class reader.EntryCounts(total=None, read=None, important=None, has_enclosures=None, averages=None)
Count information about entries.
Changelog
New in version 1.11.
- class reader.EntrySearchCounts(total=None, read=None, important=None, has_enclosures=None, averages=None)
Count information about entry search results.
Changelog
New in version 1.11.
- class reader.UpdateResult(url, value)
Named tuple representing the result of a feed update.
Changelog
New in version 1.14.
- value: UpdatedFeed | None | UpdateError
One of:
If the update was successful; a summary of the updated feed.
If the server indicated the feed has not changed since the last update without returning any data.
If there was an error while updating the feed.
Changelog
Changed in version 3.8: Narrow down the error type from
ReaderError
toUpdateError
.
- property updated_feed: UpdatedFeed | None
The updated feed, if the update was successful,
None
otherwise.Changelog
New in version 2.1.
- property error: UpdateError | None
The exception, if there was an error,
None
otherwise.Changelog
New in version 2.1.
- class reader.UpdatedFeed(url, new=0, modified=0, unmodified=0)
The result of a successful feed update.
Changelog
Changed in version 1.19: The
updated
argument/attribute was renamed tomodified
.New in version 1.14.
- new: int = 0
The number of new entries (entries that did not previously exist in storage).
Changelog
Changed in version 3.2: This field is now optional, and defaults to 0.
- modified: int = 0
The number of modified entries (entries that existed in storage, but had different data than the corresponding feed file entry.)
Changelog
Changed in version 3.2: This field is now optional, and defaults to 0.
- class reader.EntryUpdateStatus(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Enum representing how an entry was updated.
Changelog
New in version 1.20.
- NEW = 'new'
The entry did not previously exist in storage.
- MODIFIED = 'modified'
The entry existed in storage, but had different data from the one in the feed file.
Exceptions
- exception reader.ReaderError(message='')
Base for all public exceptions.
- exception reader.FeedError(url, /, message='')
Bases:
ReaderError
A feed error occurred.
Changelog
Changed in version 3.0: The
url
argument is now positional-only.
- exception reader.FeedNotFoundError(url, /, message='')
Bases:
FeedError
,ResourceNotFoundError
Feed not found.
- exception reader.InvalidFeedURLError(url, /, message='')
Bases:
FeedError
,ValueError
Invalid feed URL.
Changelog
New in version 2.5.
- exception reader.EntryError(feed_url, id, /, message='')
Bases:
ReaderError
An entry error occurred.
Changelog
Changed in version 3.0: The
feed_url
andid
arguments are now positional-only.Changed in version 1.18: The
url
argument/attribute was renamed tofeed_url
.
- exception reader.EntryExistsError(feed_url, id, /, message='')
Bases:
EntryError
Entry already exists.
Changelog
New in version 2.5.
- exception reader.EntryNotFoundError(feed_url, id, /, message='')
Bases:
EntryError
,ResourceNotFoundError
Entry not found.
- exception reader.UpdateError(message='')
Bases:
ReaderError
An error occurred while updating the feed.
Parent of all update-related exceptions.
Changelog
New in version 3.8.
- exception reader.ParseError(url, /, message='')
Bases:
UpdateError
,FeedError
,ReaderWarning
An error occurred while retrieving/parsing the feed.
The original exception should be chained to this one (e.__cause__).
Changelog
Changed in version 3.8: Inherit from
UpdateError
.
- exception reader.UpdateHookError(message='')
Bases:
UpdateError
One or more update hooks (unexpectedly) failed.
Not raised directly; allows catching any hook errors with a single except clause.
To inspect individual hook failures, use except* with
SingleUpdateHookError
(or, on Python earlier than 3.11, check if the exceptionisinstance()
UpdateHookErrorGroup
and examine itsexceptions
).Changelog
New in version 3.8.
- exception reader.SingleUpdateHookError(when, hook, resource_id=None)
Bases:
UpdateHookError
An update hook (unexpectedly) failed.
The original exception should be chained to this one (e.__cause__).
Changelog
New in version 3.8.
- when
The update phase (the hook type). One of:
'before_feeds_update'
'before_feed_update'
'after_entry_update'
'after_feed_update'
'after_feeds_update'
- hook
The hook.
- resource_id
The resource_id of the resource, if any.
- exception reader.UpdateHookErrorGroup(msg, excs, /)
Bases:
ExceptionGroup
,UpdateHookError
A (possibly nested)
ExceptionGroup
ofUpdateHookError
s.Changelog
New in version 3.8.
- exception reader.StorageError(message='')
Bases:
ReaderError
An exception was raised by the underlying storage.
The original exception should be chained to this one (e.__cause__).
- exception reader.SearchError(message='')
Bases:
ReaderError
A search-related exception.
If caused by an exception raised by the underlying search provider, the original exception should be chained to this one (e.__cause__).
- exception reader.SearchNotEnabledError(message='')
Bases:
SearchError
A search-related method was called when search was not enabled.
- exception reader.InvalidSearchQueryError(message='')
Bases:
SearchError
,ValueError
The search query provided was somehow invalid.
- exception reader.TagError(resource_id, key, /, message='')
Bases:
ReaderError
A tag error occurred.
Changelog
Changed in version 3.0: Signature changed from
TagError(key, resource_id, ...)
toTagError(resource_id, key, ...)
.Changed in version 3.0: The
resource_id
andkey
arguments are now positional-only.Changed in version 2.17: Signature changed from
TagError(key, object_id, ...)
toTagError(key, resource_id, ...)
.New in version 2.8.
- exception reader.TagNotFoundError(resource_id, key, /, message='')
Bases:
TagError
Tag not found.
Changelog
New in version 2.8.
- exception reader.ResourceNotFoundError(message='')
Bases:
ReaderError
Resource (feed, entry) not found.
Changelog
New in version 2.8.
- exception reader.PluginError(message='')
Bases:
ReaderError
A plugin-related exception.
- exception reader.InvalidPluginError(message='')
Bases:
PluginError
,ValueError
An invalid plugin was provided.
Changelog
New in version 1.16.
- exception reader.PluginInitError(message='')
Bases:
PluginError
A plugin failed to initialize.
The original exception should be chained to this one (e.__cause__).
Changelog
New in version 3.0.
- exception reader.ReaderWarning(message='')
Bases:
ReaderError
,UserWarning
Base for all warnings emitted by reader that are not
DeprecationWarning
.
Exception hierarchy
The class hierarchy for reader
exceptions is:
ReaderError
├── ReaderWarning [UserWarning]
├── ResourceNotFoundError
├── FeedError
│ ├── FeedExistsError
│ ├── FeedNotFoundError [ResourceNotFoundError]
│ └── InvalidFeedURLError [ValueError]
├── EntryError
│ ├── EntryExistsError
│ └── EntryNotFoundError [ResourceNotFoundError]
├── UpdateError
│ ├── ParseError [FeedError, ReaderWarning]
│ └── UpdateHookError
│ ├── SingleUpdateHookError
│ └── UpdateHookErrorGroup [ExceptionGroup]
├── StorageError
├── SearchError
│ ├── SearchNotEnabledError
│ └── InvalidSearchQueryError [ValueError]
├── PluginError
│ ├── InvalidPluginError [ValueError]
│ └── PluginInitError
└── TagError
└── TagNotFoundError
Type aliases
- reader.types.TristateFilterInput
Possible values for options that filter items by an optional boolean attribute (one that can be either true, false, or not set).
None
selects all items.True
andFalse
select items based of the attribute’s truth value (aNone
attribute is treated as false).For more precise filtering, use one of the following string filters:
attribute values
string filter
optional bool filter
True
istrue
True
False
isfalse
None
notset
False, None
nottrue
False
True, None
notfalse
True, False
isset
True, False, None
any
None
Changelog
New in version 3.5.
alias of
Literal
[None, True, False, ‘istrue’, ‘isfalse’, ‘notset’, ‘nottrue’, ‘notfalse’, ‘isset’, ‘any’]
Constants
- reader.plugins.DEFAULT_PLUGINS = ['reader.ua_fallback']
The list of plugins
make_reader()
uses by default.