[Из песочницы] Data Science блог с помощью fastpages

Как запустить свой DS/ML/AI/Tech блог с минимумом сложностей связанных с хостингом и деплойем этого блога.

В конце февраля 2020 года ребята из fast.ai представили миру fastpages — платформу для ведения блога. Отмечу, что fastpages основан на Jekyll, о котором на Хабре есть множество постов.

Примером блога на движке fastpages является данный блог.

Главное отличительная черта и преимущество fastpages состоит в поддерживаемых из коробки форматах постов:


  • Jupyter ноутбуки (расширение .ipynb);
  • Markdown файлы (расширение .md);
  • Word файлы (расширение .docx)

Таким образом, автору блога необходимо сохранить пост в любом из перечисленных выше форматах в соответствующей директории:


  • './_notebooks/' для .ipynb;
  • './_posts/' для .md;
  • './_word/' для .docx.

А все остальное сделает fastpages, как утверждают его авторы.

fastpages использует Github Pages для хостинга и Github Actions для автоматизации публикации постов.

Как я понимаю, fastpages является доработкой связки Github Pages + Jekyll, где можно сразу же из Jupyter ноутбука получить опубликованный пост.

Если хотите самостоятельно разобраться, то вот официальная инструкция по настройке в репозитории fastpages.

Процесс настройки fastpages:


  1. Создать собственную копию репозитория из шаблона fastpages по ссылке

    image

  2. Далее автоматически откроется pull request (через ~ 30 секунд), который отвечает за настройку вашего блога, чтобы он мог начать работать.

    image

  3. Вам нужно выполнить инструкции из полученного pull request’a и вы получите свою собственную уже работающую платформу для блога.


Видео туториал


Есть возможность для персонализированной конфигурации вашего блога. Параметры конфигурации находятся в файле ./_config.yml, некоторые из них приведены ниже:


  • title — название вашего блога, которое отображается в верхнем левом углу на каждой странице;


  • description — описание, которое будет отображаться в разных местах при предварительном просмотре вашего сайта (например, в социальных сетях);


  • github_username — позволяет вашему сайту отображать ссылку на вашу страницу GitHub в нижнем колонтитуле;


  • github_repo — позволяет вашему сайту отображать ссылки на ваш репозиторий для различных функций, таких как ссылки на GitHub, Google Colab и Binder для Jupyter ноутбуков;


  • default_badges — по умолчанию ссылки GitHub, Google Colab и Binder будут отображаться в постах созданных из Jupyter ноутбуков. Вы можете задать, какие из них будут отображаться по умолчанию, установив для соответствующего значения в default_badges значение true или false. Например, если вы хотите отключить ссылки на Binder, вы должны поправить default_badges:

    default_badges:
    github: true
    binder: false
    colab: true

  • url — это не нужно менять, если у вас нет собственного домена;


  • baseurl — см. комментарии в /_config.yml для получения инструкций («Special Instructions for baseurl»). Если у вас нет настраиваемого домена, вы можете игнорировать эту опцию;


  • twitter_username — создает ссылку в нижнем колонтитуле на страницу Twitter;


  • use_math — установите значение true, чтобы получить поддержку математических формул LaTeX;


  • show_description — отображает на домашней странице описание под заголовком ваших постов в блоге. По умолчанию установлено значение true;


  • google_analytics — опционально можно использовать идентификатор Google Analytics;


  • pagination — максимальное количество постов, отображаемых на каждой странице вашей домашней страницы. Значение по умолчанию равно 15. Когда число постов превысит заданное значение, тогда произойдет разбивка на страницы, которая выглядит так:
    image


  • show_tags — включает отображение тегов внутри постов, которые выглядят следующим образом:

    image


  • show_image — при значении true включается возможность добавления изображений к постам на домашней странице. Выглядит следующим образом (первые 2 поста сопровождаются изображениями):

    image



  1. Сохраните исходный файл вашего поста (в одном из форматов: .ipynb, .md или .docx) в соответствующей папке репозитория (./_notebooks, ./_posts или ./_word). Пример имени для поста 2020-05-26-DS-fastpages-blog.ipynb. Такое наименование является необходимым для отображения поста движком Jekyll (больше деталей).
    Важные аспекты наименования постов:
    • Вначале имени поста указывается дата в формате YYYY-MM-DD-;
    • Символ, следующий сразу за тире, должен быть буквой алфавита.
  2. Сделайте commit и push ваших файлов на удаленный репозиторий GitHub в ветку master.
  3. GitHub автоматически конвертирует ваши файлы в посты блога. Процесс конвертации займет ~5 минут. Можно перейти на вкладку «Actions» в репозитории на GitHub. Вы увидите три workflow, которые запускаются при каждом push в ветку master:
    • Check Configurations — процесс проверки ваших файлов (например, ссылок на изображения), перед обновлением контента в блоге;
    • CI — процесс непрерывного деплоя вашего блога;
    • GH Pages Status — процесс проверки доступа к блогу.
      Если эти процессы завершаются зеленой галочкой для последнего коммита, то сайт блога успешно обновился.
  4. Для предварительного локального просмотра того, как ваш блог будет выглядеть, см. этот раздел.
    Ниже представлены различные возможности форматирования, которые fastpages поддерживает из коробки.


Возможности форматирования постов

Хочу заранее предупредить, что ряд вещей не могут быть отображены в посте на Хабре, поэтому я добавил их как изображения и гифки. Для того чтобы полностью оценить то, как выглядят эти элементы, советую посмотреть пост в моем блоге, созданном на движке fastpages.

Первая ячейка в вашем Jupyter ноутбуке (а также первые строки в Markdown файлах) содержит метаданные, которые могут включать/выключать опции связанные с постом.

# "Title"
> "Awesome summary"

- toc: true
- branch: master
- badges: true
- comments: true
- author: Hamel Husain & Jeremy Howard
- categories: [fastpages, jupyter]

Для указания таких в Markdown файлах необходимо в начале файла задать опции как и в ноутбуке, только поместив эти метаданные между строк содержащих по три минуса, т.е. ---.

Выглядит это так:

---
title: "Title"
description: "Awesome description"
toc: true
layout: post
categories: [markdown]
---

Все, что определено в начале поста, должно соответствовать YAML разметке. Поэтому если вы хотите использовать двоеточие в заголовке, вы должны экранировать его двойными кавычками: - title: "Deep learning: A tutorial"

Для большего понимания советую ознакомиться с туториалом по YAML.

Перечень управляющих конструкций для форматирования поста (взято отсюда):


  • toc — при значении true автоматически будет сгенерировано оглавление поста из заголовков, обозначенных Markdown разметкой;
  • badges [notebooks only] — при значении true отображаются ссылки Google Colab, Binder и GitHub, не работает при приватном репозитории;
  • hide_github_badge [notebooks only] — при значении true скроет ссылку на GitHub;
  • hide_colab_badge [notebooks only] — при значении true скроет ссылку на Google Colab;
  • hide_binder_badge [notebooks only] — при значении true скроет ссылку на Binder;
  • branch [notebooks only] — используется для дополнительной ссылки на ваш Jupyter ноутбук на Colab и GitHub. Значение по умолчанию: master;
  • comments — при значении true будут включены комментарии (больше деталей);
  • author — при значении true отображаются имена авторов;
  • categories — позволяют группировать посты по тегам (на странице «Tags»).
  • image — задает изображение для поста, которое будет отображаться на главной странице блога и в соц. сетях (Twitter) вместе с ссылкой на пост:
    • пример задания изображения к посту — images/figure.png;
    • изображение обязательно должно находиться внутри папке /images вашего репозитория;
  • search_exclude — позволяет скрывать пост в поиске блога (страница Search), стоит заменить, поиск работает только с латиницей;
  • hide — при значении true пост будет скрыт на главной странице блога, но будет доступен по прямой ссылке:
    • рекомендуется использовать permalinks для создания предсказуемых ссылок на сам пост;
    • если search_exclude будет иметь значение true, то пост можно будет найти через поиск блога (страница Search);
  • sticky_rank — позволяет закрепить пост на конкретной позиции, задав ему порядковый номер. Если двум постам задать одинаковый номер, то между собой они будут отсортированы по дате.


Скрытие и сворачивание кода

Приятной функциональностью этого движка для блога является возможность скрывать код и/или результаты его выполнения. Это позволяет не нагружать посты отображением простыни кода или огромного количество принтов (что бывает при обучении нейросетей по эпохам), скрывая эти большие по размеру элементы, но не выкидывая их из поста на совсем.

Ниже приведены управляющие конструкции, которые задаются в первой строке ячейки в Jupyter ноутбука. Как это выглядит, можно посмотреть в моем посте.


  • #hide — скрывает как ввод, так и вывод текущей ячейки;
  • #hide_input — скрывает только ввод текущей ячейки;
  • #collapse-hide — скрывает код этой ячейки внутри поста, но добавляет кнопку, позволяющую показать эту ячейку;
  • #collapse-show — добавляет кнопку, позволяющую показать эту ячейку.


Интерактивные графики с помощью Altair

Графики построенные с помощью библиотеки Altair внутри поста остаются интерактивными как в ноутбуке. Для проверки интерактивности опять же см. мой пост.

altair.gif


Отображение таблиц

Таблицы в опубликованных постах отображаются примерно как и в Jupyter ноутбуках.
image


Вставка изображений

Вы можете добавлять изображения с подписями следующим образом:

![](https://www.fast.ai/images/fastai_paper/show_batch.png "Credit: https://www.fast.ai/2020/02/13/fastai-A-Layered-API-for-Deep-Learning/")

Результат выглядит так:
image

Напомню, что подписи опциональны, и что изображения можно указывать как локально (в рамках репозитория блога), так и находящиеся в открытом доступе (имею в виду интернет).


Анимированные гифки

Гифки вставляются как изображения и полноценно отображаются в постах.

ChessPawnSpecialMoves.gif


Видео Youtube

Чтобы красиво вставить видео с Youtube достаточно использовать конструкцию:

> youtube: https://youtu.be/L0boq3zqazI


Посты из Twitter

Есть возможность отображать посты из Twitter.

Например, ссылка на этот пост

> twitter: https://twitter.com/jakevdp/status/1204765621767901185?s=20

отобразит следующее:
image


LaTeX формулы

Jupyter ноутбуки поддерживают синтаксис LaTeX формул. Чтобы формулы отображались в постах, нужно убедиться, что опция use_math включена внутри _config.yml (см. Настройка блога).

Следующий LaTeX код:

> $$L(\theta) = \frac{1}{N} \sum_i^N{(y_i - \hat{y_i})^2} \rightarrow \min_{\theta}$$

будет отображен таким образом:

$$display$$L (\theta) = \frac{1}{N} \sum_i^N{(y_i — \hat{y_i})^2} \rightarrow \min_{\theta}$$display$$


Примечания

Есть возможность отображать примечания различных типов.

Предупреждение: > Warning: There will be no second warning!

image
Важно: > Important: Pay attention! It's important.

image
Подсказка: > Tip: This is my tip.

image
Заметка: > Note: Take note of this.

image

Если вставить в любое из примечаний ссылку, то она будет работать.
Например,

> Note: A doc link to [an example website: fast.ai](https://www.fast.ai/) should also work fine.

отобразится так:
image


Отображение Emoji

Если написать

Сейчас будет эмоджи :robot:.

то получится:
Сейчас будет эмоджи : robot:.

Шпаргалка по Emoji.


Сноски

В jupyter ноутбуках можно использовать сноски, однако синтаксис отличается от Markdown разметки. Это руководство содержит более подробную информацию об этом синтаксисе, который выглядит следующим образом:

{% raw %}For example, here is a footnote {% fn 1 %}.
And another {% fn 2 %}
{{ 'This is the footnote.' | fndetail: 1 }}
{{ 'This is the other footnote. You can even have a [link](https://fastpages.fast.ai/jupyter/2020/02/20/test.html#Footnotes)' | fndetail: 2 }}{% endraw %}

image

Для этого fastpages использует nbdev для преобразования jupyter ноутбуков, word и .md файлов в посты блога. После того, как вы сохраните исходные файлы своих постов в папках /_notebooks, /_word или /_posts, то GitHub Actions c помощью nbdev автоматически преобразует их в конечный вид, в котором посты отображаются на сайте вашего блога.

Стоит упомянуть, что ранее fast.ai выпустили аналогичный проект под названием fast_template, который еще проще в настройке, но не поддерживает автоматическое создание постов из Word и Jupyter файлов, а также многие другие функции перечисленные выше. Поскольку fastpages более гибок и расширяем, его авторы рекомендуют использовать его там, где это возможно.

Авторы предполагают, что fast_template может быть лучшим вариантом для тех, кто ведет не технические блоги. В этом случае посты можно создавать только с помощью встроенного онлайн-редактора Github, не заморачиваясь с использованием git.


Что понравилось


  • простота создания и размещения блога и публикации контента;
  • возможность публиковать Jupyter ноутбуки в качестве постов + удобства оформления:
    • поддержка отображения интерактивных графиков;
    • скрытие/сворачивание кода;
    • поддержка отображения GIF-анимации;
    • интеграция видео с youtube и тд.
  • нет зависимости от сторонней платформы по типу Medium;
  • возможность разместить блог по собственному url;
  • параметр badges в метаинформации к посту позволяет прикрепить ссылки на GitHub, Binder, Google Colab, что позволяет сразу перейти от поста к коду и его исполнению;
  • комментарии для блога из коробки;
  • возможность прикрепить пост на конкретную позицию на общей странице с помощью sticky_rank, смотреть тут;
  • отсутствие сторонней рекламы;


Что не понравилось или вызывало вопросы


  • непонятно, как сделать структурированный блог с вложенностью:
    • возможное решение permalinks;
    • структура нужна для объединения нескольких постов общей темой;
    • хочется структуру, чтобы в одной директорий хранить все, что связанно с постом (данные, изображения для ноутбуков) в одной папке, а не искать их в куче общих файлов и не городить какую-то структуру в этих общих для всех постов папках.
  • нет WYSIWYG (What You See Is What You Get):
  • в Jekyll в заголовке и описании поста не поддерживаются обратные кавычки, квадратные скобки и тд.
  • Jekyll подразумевает использование git для публикации постов;
  • целесообразность хранения Jupyter ноутбуков в репозитории под вопросом;
  • непонятно, как привязать spell checker для Jupyter ноутбуков.

Команда fast.ai предложили DS сообществу интересный и достаточно функциональный инструмент для ведения блога, автору которого остается думать только о том, какой контент публиковать.

Сложность использования практически минимальная, нужны базовые знания git, разметки Markdown и Jupyter Notebook. И никаких проблем с тем, как и где хостить и деплоить сам блог.

Конечно, есть определенные пожелания по поводу функционала этого движка, для этого можно участвовать в развитии проекта, находя баги или предлагая те или иные улучшения. В последнем случае даже pull request не обязателен, порой хватает текстового описание тех или иных желаний пользователей.

В заключение хочу сказать, что сам пользуюсь и всем советую.


Блоги компаний


© Habrahabr.ru