python

JSON. Вы человек или машина?

  • среда, 12 мая 2021 г. в 00:38:55
https://habr.com/ru/company/huawei/blog/556792/
  • Блог компании Huawei
  • Python
  • XML
  • Visual Studio


JSON, YAML, XML

Недавно я переехал в Москву в квартиру без письменного стола. 

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

Через пару дней мебель доставили. Я распаковал первую коробку, из нее вывалилась инструкция и у меня опустились руки: в ней наверняка должно быть пятьдесят разных языков, все мелким шрифтом, как книга заклинаний из Гарри Поттера. Но приглянувшись я увидел, что в ней были только рисунки, а именно: два смешных чувачочка показывали, как обращаться с деталями, как их вертеть, собирать и так далее. Уф, счастье! Я подумал о JSON и XML. IKEA молодцы они использовали универсальный язык жестов и картинов, понятный всем на свете.

Если я напишу какой-то код в JAVA и если мне взбредет в голову обменяться этим кодом с другим приложением, которое написано на Python, то, скорей всего, ничего не получится. Это все равно что подсунуть японцу инструкцию по сборке письменного стола на монгольском языке. Для этой точки коммуникации мне нужно найти общий язык или data serialization language, таких красавец как JSON или XML, например.

XML (Extensible Markup Language) в основном используется в сайтах и он пытается быть удобным для восприятия человеком. Я сказал “пытается” потому что он делает это хорошо, но не отлично. Его название включает понятие markup (разметка), потому что в коде он включает дополнительные детали как форматировать текст, шрифт, его цвет и размер.

Другое дело JSON (JavaScriptObject Notation). Как и указано в названии, он в основном используется с JavaScript. Но мы часто видим его в мире автоматизации сети, в частности в APIs. Причина почему именно он в APIs, а не XML, потому что он более понятен для нас. Мы можем читать его как стихотворение.

Оппозиционер XML это YAML, он не использует разметку (markup) и это делает его более простым. Он фаворит среди языков-сценариев, таких как Python и Perl. Мы часто используем его в Ansible. Ansible это популярный инструмент автоматизации сети. Некоторые ради шутки называют его Yansible. И он безумно-безумно удобен для восприятия человеком.

Интерпретация JSON

Вы человек или машина? Причина, по которой мы натыкаемся на эти ловушки в том, что машины не умеют распознавать неформатированные данные. Если данные не понятны, машина не сможет их распознать и интерпретировать, доказав, что она не человек.

Мы, люди, можем легко читать данные как на этой картинке. Например, если мы введем команду display version на коммутаторе серии CE, то он может немного отличаться от вывода такой же команды на роутере серии NE и для нас в этом не будет особой проблемы:

Для нас людей такая разница не существенна, потому что она все равно понятна для нас, но для машин даже незначительная разница может стать критической для обработки. Например, если я подключаюсь к коммутатору через SSH используя Python и отправляю команду display version или display ip int brief, но при этом не буду использовать JSON формат данных, или любой другой формат, как XML или YAML, то, во-первых, будет сложно написать код, чтобы он был верно интерпретирован машиной, во-вторых, разобраться с ситуацией, когда вывод изменится. Для примера, если вы обновите ваш роутер и вывод конфигурации будет изменен, то ваш Python-код вряд ли сможет быть применен. Для машина-машина коммуникации важно, чтобы вывод был стандартизирован. В некоторых особенно продвинутых (на мой взгляд) компаниях при устройстве на работу могут попросить представить рассказ о себе в виде JSON.

Мы тут не будет рассказывать о себе, вместо этого попробуем рассказать о Живописном Мосте в Москве:

Зададимся типовыми вопросами, например:

Кто конструктор моста? 

Конструктор: Шумаков.Н.И

Какой тип конструкции этого моста?

Конструкция: Вантово-балочной с арочным пилоном

Обратите внимание как я записал эту информацию жирным шрифтом! Первое значение известно как “ключ” (key), второе - “значение” (value). Между ними двоеточие (colon).

Какова высота моста?

Высота: 105м

Из чего сделан мост?

Материал: железобетон

Какова дата открытия моста?

Открытие: 27 декабря 2007 года

Я просто взял эту информацию из Википедии. Надеюсь, она верна. Главное здесь не информация, главное - формат. Каждая пара состоит из key и value, при этом key отделен от value с помощью двоеточия. В мире компьютеров подобная информация будет выглядеть так:

“height”: “105m”

Каждое значение помещается в двойные кавычки.

Есть два вида данных в JSON формате: objects и arrays.

Вот пример объекта: 

{“height”: “105m”, “color”: “red”}

Вот что свойственно объектам:

Группы пар key:value не требуют упорядоченности. То есть их порядок не имеет значения, он может быть любым.

Данные замыкаются в изогнутные скобки {} curly braces

Key и value отделяются друг от друга с помощью двоетония : a colon

Каждая пара key:value отделяется друг от друга запятой , a comma (кроме последней пары!)

Используеются только двойные кавычки, не единичные () double quotes

Взглянем на другой пример в более удобной форме:

Объект (object)

{

    “height” : “105m”,

    “color” : “red”

}    

После последней пары не должно стоять запятой:

Если поставить там запятую, то будет проблема.

Давайте я покажу вам на реальном примере с помощью Ansible. Я отправлю запрос на коммутатор CloudEngine6800 из playbook файла команду display int GE1/0/1:

При этом к стартовой команде добавлю значение -vvv, чтобы увидеть логи запроса и вывод команды. Вывод будет в формате JSON:

ansible-playbook -vvv display_int_1.yml

Первое, что мы увидем - это лог успешного применения запроса:

Где здесь объект? Вот объект:

При этом внутри этого объекта есть другой объект, вот он:

Где здесь key и value? Вот они:

За последней парой нет запятой! 

Причина, по которой одни value находятся в двойных кавычках, а другие нет в том, что если числовое значение value поместить в кавычки, то оно перестанет быть числовым значением, а станет именем. Null - значит пустое значение. В данном примере только числовые значения не находятся в кавычках.

Здесь также есть квадратные скобки (square brackets):

Они здесь указывают на существование второго вида данных arrays.

Array используется для того, чтобы упорядочить список value.

Например, если мы добавим вторую команду в список заданий в файле playbook, например display version:

И запустим команду снова, то увидим, что вывод каждой из команд будет замкнут в квадратные скобки:

Здесь мы имеем несколько команд и вывод нескольких команд, и квадратные скобки как синтаксическую единицу, чтобы отделить одно от другого в рамках одного объекта - commands.

Array может содержать широкий перечень типов данных JSON, такие как строка (string), в нашем примере это "Huawei Versatile Routing Platform Software", а также числа, другой объект, пустое значени (null) или другой array.

Итак, еще раз. Все что находится внутри { }curly braces -  это JSON object. Это почти то же самое, что словарь в Pythone - dictionary:

Другой игрок - array. Он замыкает группу данных в квадратных скобках [ ] square brackets. Это очень похоже на list:

Если вы назовете array листом или object словарем - не краснейте, люди делают это постоянно. Это взаимозаменяемые определения.

Записать перечень имен получится так:

Взглянем с помощью Postman взглянем на реальные данные от роутера, а именно его интерфейсы. Полученные данный вставим в Visual Studio Code:

Первое, на что мы должны обратить тут внимание это открытый { curly braces и следом за ним первую пару key: value. Key всегда выделяется двойными кавычками!

Дальше мы видим открытую квадратную скобку, следом за которой сразу изогнутая скобка. Это значит, что value здесь - это лист JSON объектов:

Опустимся ниже, посмотрим сколько всего у нас объектов… Мы уже видим, что у нас есть loopback 4 и loopback 5, и это два объекта. Далее у нас есть GigabitEthernet1:

И loopback 2 и loopback 3. Итого 5 интерфейсов. Обратите внимание, что каждый объект отделен от другого запятой:

Мы понимаем, что loopback 5 это последний интерфейс, потому что после закрывающей изогнутой скобки нет запятой. И мы также понимаем что это конец и для array или листа, потому что у нас есть закрывающая квадратная скобка:

После следует еще одна пара key:value, который закрывает этот большой объект. Здесь нет запятой, но есть закрывающая изогнутая скобка на конечной линии:

Прелесть Visual Studio code в том, что он позволяет свернуть объекты внутри объекта.

Мы можем нажать на эту стрелочку вверху...

И Voila! У нас теперь всего один большой объект:

В этом большом объекте есть только две пары key:value. Первая пара: items + array, вторая - kind + collections#interface

То, что мы увидели - это красивый или pretty JSON. Вот как на этой схеме ниже: тут есть и пустые поля и отступы, все, что нужно для лучшего понимания.

Чаще всего JSON предстает в другом виде. Например, если в Python мы попросим вывести нам аналогичный файл с перечнем интерфейсов, то увидим примерно следующее:

Недавно я сдавал экзамен ENCOR 350-401 и мне попалось пара вопросов, где требовалось разобрать такой JSON output, и это было очень непросто.

Чтобы в Python увидеть pretty JSON, нужно ввести команду pretty print (pprint):

И вот совсем другой результат, именно так, как мы и хотим видеть JSON:

Вы можете узнать немного больше об Ansible и его применении на коммутаторах CloudEngine от Huawei, в статьях: "Немного пинг-понга на Windows с Ansible. Автоматизируем нашу сеть прямо сейчас!” и "Пинг-понг с Ansible на CloudEngine коммутаторах"