🗞️

rss2db

Что

API, отправив запрос в который, пользователь оформляет подписку на выбранный RSS-канал. Новые публикации в канале регулярно пополняют автоматически создаваемую таблицу в базе данных на сервере postgres. Возможна обработка публикаций с помощью LLM.

Почему

  • Многие интересные источники информации либо не имеют публичного API, либо имеют, но платный, а RSS-каналы имеют все очень многие. Это сотни тысяч, миллионы источников, как в России, так и за рубежом.
  • Обновления в канале распространяются в XML-документах — легковесных, структурированных, в которых нет ничего лишнего. Это способ сбора информации, который прослужит долго, потому что структура обновления стабильна и не зависит от верстки сайта. Структура регламентирована версией спецификации RSS. Это гарантирует разработчику единообразие обработки данных: один стабильный парсер для сотен тысяч источников на годы вперед.
  • Идея универсальна (инвариантна относительно предметной области источника) и способствует накоплению в УВА аналитических материалов и фактуры для использования в проверках. “Утром — в газете, вечером — в базе данных”.

Примеры

Описание

  1. API работает на машине ОАИТ в Облаке УВА Advanced.
    Swagger: 10.0.4.62:1707/docs. GitHub.
  1. Чтобы подписаться на 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"
    }
  1. Подписка в данном контексте означает, что:
    • На сервере postgres в Облаке УВА Advanced создана база данных со следуюшими полями: id (первичный ключ), атрибуты источника sourceTitle, sourceSubtitle, sourceLink, атрибуты обновления entryTitle, entryDescription, entryLink, entryPublished, entryLanguage и entryContent.
    • При создании подписки база данных наполняется данными постов, которые присутствуют в канале в данный момент.
    • Создается ежесуточное задание (джоб) на парсинг и пуш в базу новых постов. Время для задания выбирается случайным образом, чтобы распределить нагрузку на машину равномерно. Задания хранятся в отдельной служебной базе данных, резервная копия которой обновляется в бакете объектного хранилища. Предусмотрен механизм, который возобновляет задания в случае перезагрузки машины и исполняет пропущенные очереди в случае простоя оффлайн.
  1. Есть эндпоинт, который вернет пользователю все активные задания с временем их ближайших исполнений, именами и описаниями соответствующих таблиц на 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"
      }
    ]
  1. Есть непубличный (защищенный токеном доступа) эндпоинт, который позволяет удалить задание (прекратить исполнение и удалить его из служебной базы данных заданий).
  1. В API предусмотрена валидация входных данных и обработка различных ошибок.
  1. Есть эндпоинт, который позволяет получить из таблицы все тела постов (столбец 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>"   
      ]
    }
  1. Есть непубличный (защищенный токеном доступа) эндпоинт, который позволяет работать с фидами (по умолчанию суммаризировать) с помощью любого OpenAI-совместимого провайдера.