rss2db
Что
API, отправив запрос в который, пользователь оформляет подписку на выбранный RSS-канал. Новые публикации в канале регулярно пополняют автоматически создаваемую таблицу в базе данных на сервере postgres. Возможна обработка публикаций с помощью LLM.
Почему
- Многие интересные источники информации либо не имеют публичного API, либо имеют, но платный, а RSS-каналы имеют
всеочень многие. Это сотни тысяч, миллионы источников, как в России, так и за рубежом.
- Обновления в канале распространяются в XML-документах — легковесных, структурированных, в которых нет ничего лишнего. Это способ сбора информации, который прослужит долго, потому что структура обновления стабильна и не зависит от верстки сайта. Структура регламентирована версией спецификации RSS. Это гарантирует разработчику единообразие обработки данных: один стабильный парсер для сотен тысяч источников на годы вперед.
- Идея универсальна (инвариантна относительно предметной области источника) и способствует накоплению в УВА аналитических материалов и фактуры для использования в проверках. “Утром — в газете, вечером — в базе данных”.
Примеры
- Ahead of AI, by Sebastian Raschka: https://magazine.sebastianraschka.com/
- Berkeley Artificial Intelligence Research (BAIR): https://bair.berkeley.edu/blog/
- MIT Machine Learning News: https://news.mit.edu/topic/machine-learning
Описание
- API работает на машине ОАИТ в Облаке УВА Advanced.
Swagger: 10.0.4.62:1707/docs. GitHub.
- Чтобы подписаться на RSS-канал, пользователь отправляет запрос, содержащий ссылку на канал, например:
{ "link": "https://bair.berkeley.edu/blog/feed.xml" }Пример ответа:
{ "link": "https://bair.berkeley.edu/blog/feed.xml", "table_name": "bair_berkeley_edu_blog_feed_xml", "message": "Subscription created" }
- Подписка в данном контексте означает, что:
- На сервере postgres в Облаке УВА Advanced создана база данных со следуюшими полями: id (первичный ключ), атрибуты источника sourceTitle, sourceSubtitle, sourceLink, атрибуты обновления entryTitle, entryDescription, entryLink, entryPublished, entryLanguage и entryContent.
- При создании подписки база данных наполняется данными постов, которые присутствуют в канале в данный момент.
- Создается ежесуточное задание (джоб) на парсинг и пуш в базу новых постов. Время для задания выбирается случайным образом, чтобы распределить нагрузку на машину равномерно. Задания хранятся в отдельной служебной базе данных, резервная копия которой обновляется в бакете объектного хранилища. Предусмотрен механизм, который возобновляет задания в случае перезагрузки машины и исполняет пропущенные очереди в случае простоя оффлайн.
- Есть эндпоинт, который вернет пользователю все активные задания с временем их ближайших исполнений, именами и описаниями соответствующих таблиц на postgres. Пример ответа:
[ { "table_name": "technologyreview_com_feed", "trigger": "cron[hour='19', minute='1', second='8']", "next_run_time": "2025-10-21 19:01:08+03:00", "description": "MIT Technology Review" }, { "table_name": "aiacceleratorinstitute_com_rss", "trigger": "cron[hour='2', minute='0', second='44']", "next_run_time": "2025-10-22 02:00:44+03:00", "description": "The future of machine intelligence" }, { "table_name": "bair_berkeley_edu_blog_feed_xml", "trigger": "cron[hour='5', minute='5', second='25']", "next_run_time": "2025-10-22 05:05:25+03:00", "description": "The BAIR Blog" } ]
- Есть непубличный (защищенный токеном доступа) эндпоинт, который позволяет удалить задание (прекратить исполнение и удалить его из служебной базы данных заданий).
- В API предусмотрена валидация входных данных и обработка различных ошибок.
- Есть эндпоинт, который позволяет получить из таблицы все тела постов (столбец entryContent) в двух режимах: оригинальный html и очищенный текст. Пример запроса:
{ "table_name": "bair_berkeley_edu_blog_feed_xml", "clean": true }Схематичный пример ответа:
{ "table_name": "bair_berkeley_edu_blog_feed_xml", "clean": true, "content": [ "<1st post cleaned>", "<2nd post cleaned>", ..., "<last post cleaned>" ] }
- Есть непубличный (защищенный токеном доступа) эндпоинт, который позволяет работать с фидами (по умолчанию суммаризировать) с помощью любого OpenAI-совместимого провайдера.