/v1 в Power BI. Оно охватывает
шаблон подключения на Power Query (M), семантическую модель по схеме «звезда»,
построенную на /v1/activities, инкрементальное обновление, а также случаи, когда следует использовать
предварительные наборы данных reporting для получения результатов фишинга по отдельным сотрудникам.
В примерах используется производственный хост для США
(https://api.us-east-1.livingsecurity.ai/v1). Для организации из ЕС используйте
https://api.eu-west-1.livingsecurity.ai/v1 в Fn_FetchAll и
Fn_GetJson, а затем привяжите учётные данные источника данных к этому хосту. См.
Regions.
В этом руководстве используются сохранённые учётные данные Basic с ключом API. Клиент
OAuth не требуется. Варианты учётных данных описаны в разделе Authentication,
а сведения о доступе и настройке — в Developer Hub.
Для чего предназначен этот пример
Используйте его, когда необходимо:- Загрузить списочные конечные точки
/v1в набор данных Power BI с корректной постраничной навигацией на основе курсора и повторными попытками при превышении лимита запросов. - Построить семантическую модель, в которой меры («активные сущности», «действия на одну активную сущность») являются многомерными, а не подсчитываются по плоской таблице.
- Перевести плановое обновление Power BI с полного прохода по всей истории на небольшое ежедневное окно с помощью инкрементального обновления.
- Выбрать подходящую детализацию данных о фишинге: итоги по кампаниям (операционные) или результаты по отдельным сотрудникам и типизированные события (предварительная версия reporting).
Предварительные требования
- Ключ API с разрешениями, необходимыми для ваших запросов:
- Операционный пример:
activity:read,entity:readиsimulation:read. - Данные о фишинге по отдельным сотрудникам через наборы данных reporting:
reporting:read. См. API keys.
- Операционный пример:
- Power BI Desktop или рабочая область Power BI / Fabric, в которой можно создать семантическую модель и настроить расписание обновления.
Выбор подходящей детализации
/v1 предоставляет две связанные области данных о фишинге. Они не взаимозаменяемы.
Приведённые ниже примеры запросов Power BI обращаются к операционным маршрутам
(
/v1/simulations, /v1/simulations/{id}/results, /v1/activities,
/v1/entities). Для отчётности по фишингу на уровне отдельных сотрудников предпочтительно использовать
семейство предварительных маршрутов reporting, описанное ниже. Ключ, которому предоставлено только reporting:read, не может
вызывать операционный /v1/simulation_results (API возвращает 403).
Шкала сложности
Сложность симуляции — целое число от 1 до 5 в свойствах/v1/simulations (difficulty_level),
/v1/simulation_results (difficulty_level), /v1/activities
(difficulty_tier) и /v1/reporting/simulation_events (difficulty_tier).
1 — самый лёгкий уровень, 5 — самый сложный. У адаптивных и прогрессивных симуляций нет
единого значения на уровне кампании, поэтому /v1/simulations.difficulty_level равно null,
при этом difficulty_level для отдельного получателя в результатах всё равно может быть задано. Для сопоставления с
прежними экспортами low/medium/high считайте 1–2 низким, 3 средним, а 4–5 —
высоким.
Шаблон подключения (Power Query)
В основе каждого запроса в примере лежат четыре правила. Каждое из них продиктовано службой Power BI, а не стилистическими предпочтениями.Сохраняйте базовый URL Web.Contents статическим и завершайте его на /v1
Сохраняйте базовый URL Web.Contents статическим и завершайте его на /v1
Всё динамическое поместите в
RelativePath и Query. Первый аргумент
Web.Contents должен быть строковым литералом, заканчивающимся на корне
регионального /v1 вашей организации:- США:
https://api.us-east-1.livingsecurity.ai/v1 - ЕС:
https://api.eu-west-1.livingsecurity.ai/v1
"simulations", а не
"v1/simulations"). Не вставляйте хост для США для организации из ЕС.Если первый аргумент формируется конкатенацией строк, служба Power BI
не может статически определить источник данных, и плановое обновление завершается
ошибкой «dynamic data source», хотя в Power BI Desktop запрос работает.Передавайте ключ API как сохранённые учётные данные Basic, а не в тексте запроса
Передавайте ключ API как сохранённые учётные данные Basic, а не в тексте запроса
Когда Power BI запрашивает учётные данные для источника данных
/v1, выберите
Basic и вставьте ключ API в поле username. В поле Пароль введите заполнитель,
например x. Служба Power BI отклоняет пустой
пароль, хотя API это поле игнорирует. Вариант с ключом в качестве пароля и заполнителем в качестве имени пользователя также работает.Не добавляйте заголовок Authorization в M. Он работает на вашем компьютере, но затем
встраивает ключ в файл запроса и конфликтует с плановым обновлением.Позвольте проверке подключения в диалоговом окне учётных данных выполниться
Позвольте проверке подключения в диалоговом окне учётных данных выполниться
GET /v1 требует аутентификации: он возвращает 200 при действительном ключе и 401
без него. Укажите в качестве источника данных …/v1 и не пропускайте проверку —
корректный ключ сохраняется, а отозванный или неверно сформированный сразу вызывает ошибку.В прежних примерах в качестве источника данных использовался голый хост, а проверку предлагалось пропустить,
так как GET / всегда возвращает 404. Перенастройте такие модели на …/v1.Явно задавайте limit=500 в каждом списочном запросе
Явно задавайте limit=500 в каждом списочном запросе
Размер страницы по умолчанию для каждой списочной конечной точки
/v1 равен 25. Если оставить значение по умолчанию,
число запросов для тех же данных многократно возрастёт. Значения запроса должны быть текстовыми —
limit = "500" в M, а не limit = 500.Общая функция постраничной навигации
Каждый запрос в примере вызывает единую функциюFn_FetchAll, которая проходит
по next_page_token, пока оно не станет null (см.
pagination). Её основные свойства:
- Статический базовый URL
/v1, динамическиеRelativePathиQuery. Необходимо для планового обновления и для проверки учётных данных. ManualStatusHandling = {429}с ограниченным числом повторных попыток. Функция считываетRetry-After, если Power Query его предоставляет, в противном случае ждёт 30 секунд и после 5 подряд полученных ответов429завершается с явной ошибкой, а не зацикливается до истечения времени обновления. Для5xxповторные попытки намеренно не выполняются — ошибка сервера должна быть видна, а не приводить к тихому формированию неполного набора данных.Timeout60 секунд. Страницы обычно отвечают значительно быстрее чем за секунду, поэтому минута молчания означает, что запрос не выполняется.Binary.BufferпередJson.Document. Без буферизации механизм mashup может повторно запросить поток ответа, если прочитает его более одного раза.baseQueryпередаётся без изменений на каждой итерации. Токены страниц — непрозрачные подписанные курсоры, привязанные к организации, учётным данным, версии контракта и отпечатку фильтров и сортировки. Изменение фильтра в ходе прохода отклоняется как недействительный токен, а не перезапускается с первой страницы.
Fn_FetchAll.pq — base and call shape
Типизированные запросы для каждой конечной точки
Каждый потребительFn_FetchAll следует одной схеме: вызвать конечную точку,
спроецировать фиксированный список столбцов, удалить дискриминатор object и
привести временные метки к типу datetimezone, чтобы значения дат в мерах не смещались
незаметно из-за часового пояса ёмкости обновления.
Excel
Тот же Power Query (M) работает в Get & Transform в Excel — это тот же механизм, что и в Power BI Desktop. Используйте этот вариант, когда вам нужна таблица на листе вместо семантической модели. В Excel для Windows (Microsoft 365, Excel 2024, 2021, 2019 или 2016):- Data → Get Data → From Other Sources → Blank Query.
- В Power Query Editor выберите Главная страница → Расширенный редактор. Сначала вставьте
Fn_FetchAll, затем переименуйте этот запрос вFn_FetchAll(Query Settings → Name или щёлкните правой кнопкой мыши в области Queries и выберите Rename). - Повторите для
Fn_GetJson, а затем для каждого запроса отчёта. - Главная страница → Close & Load → Close & Load To… открывает диалоговое окно Import Data.
Выберите Only Create Connection для
Fn_FetchAllиFn_GetJson(это функции, а не таблицы). Выберите Table для каждого запроса отчёта, который нужно разместить на листе. - При первом обновлении выберите Basic: ключ API в поле User name, а
заполнитель, например
x, в поле Пароль. Excel хранит одни учётные данные на URL источника данных; последующие запросы к тому же хосту/v1используют их повторно.
Close & Load To… может быть недоступна (затемнена) при первом создании запроса в
книге. Используйте Close & Load, затем в Excel выберите Data →
Queries & Connections, щёлкните запрос правой кнопкой мыши и выберите Load To.
Корпорация Майкрософт документирует этот путь именно для такого случая.
Living-Security-Version из Power Query для
источника с аутентификацией невозможно — это то же ограничение, что и в Power BI. Закрепите версию за
сервисной учётной записью или передайте api_version в записи запроса. См.
Contract versions and stored credentials.
Готовые запросы отчётов (сопоставление столбцов и отличия от экспорта
предыдущего поставщика):
Per-person compliance
Зачисления на обучение с детализацией «сотрудник × назначение».
Email phishing log
Фишинговые взаимодействия на уровне событий за последние 12 месяцев.
Most susceptible users
Сводка по каждому сотруднику за 12 месяцев: переходы по ссылкам, ввод учётных данных и сообщения о фишинге.
Предварительные наборы данных reporting (фишинг по отдельным сотрудникам)
Семейство предварительных наборов данных reporting предоставляет наборы данных о фишинге по отдельным сотрудникам. Для него требуетсяreporting:read и доступ к отчётности для вашей организации.
Используйте приведённый ниже каталог наборов данных, чтобы изучить их схемы и политики данных.
Получите актуальный каталог:
simulation_results
- Путь:
GET /v1/reporting/simulation_results - Детализация: сущность × симуляция
- Фильтры:
simulation,entity,updated_after, а такжеlimit/page_token - Объект передачи:
reporting.simulation_result - Ключи соединения:
entity_id,simulation_id
ReportingSimulationResults.pq (sketch)
updated_after как включающий нижний водяной знак при обновлении последних
партиций. Изменяемые измерения результатов пересчитываются на месте под тем же id.
simulation_events
- Путь:
GET /v1/reporting/simulation_events - Детализация: один типизированный факт на каждое зафиксированное взаимодействие
- Фильтры:
simulation,entity,event_type,occurred_after, а такжеlimit/page_token - Объект передачи:
reporting.simulation_event - Типы событий: закрытый набор публичных токенов, например
simulation.delivered,simulation.opened,simulation.link_clicked,simulation.credentials_submitted,simulation.reported— а не необработанные типы активности ClickHousephishing.simulation.* - Устройство:
device_type— производный класс (среди наблюдаемых токенов —desktop,mobile,tablet,unknown). Необработанныйuser_agentотсутствует в/v1. Необработанный IP-адрес никогда не попадает в/v1(не сохраняется; толькоip_hashс солью).
ReportingSimulationEvents.pq (sketch)
occurred_after для инкрементальной загрузки событий. Факты только добавляются;
поздно поступившие данные становятся новыми строками.
entities
- Путь:
GET /v1/reporting/entities - Детализация: одна текущая строка на сущность
- Фильтры:
type,updated_after, а такжеlimit/page_token - Объект передачи:
reporting.entity - Ключ соединения:
id/entity_id(одно и то же значение)
reporting.simulation_results.entity_id = reporting.entities.id.
Операционный GET /v1/entities остаётся на entity:read и требует другого
разрешения.
ReportingEntities.pq
entity_versions и cohort_memberships
Эти два набора данных имеют именованное исключение «только текущие данные»:Авторитетной таблицы истории версий или членства не существует. Этот набор данных отображает текущую строку как один открытый интервал (valid_toравно null,is_currentравно true).valid_from— этоcreated_at, а при его отсутствииupdated_atдля версий сущностей и время наблюдения запроса для членства в когортах. Закрытые исторические интервалы не создаются искусственно.
- entity_versions:
GET /v1/reporting/entity_versions. Те же фильтры, что и у entities.valid_from— этоcreated_at, а при его отсутствииupdated_at. Сущность, у которой обе временные метки равны null, пропускается. - cohort_memberships:
GET /v1/reporting/cohort_memberships. Фильтры:cohort,entity,updated_after.updated_at— время последнего обновления когорты, благодаря чему инкрементальное обновление остаётся корректным.valid_from— время наблюдения запроса. Соединитеentity_idсreporting.entities.id.
ReportingEntityVersions.pq
ReportingCohortMemberships.pq
Семантическая модель «звезда» на /v1/activities
/v1/activities — это поток событий организации с временными метками. В нём нет
числовых мер — каждая величина в отчёте представляет собой количество строк, — что делает схему
«звезда» естественным выбором.
Activities— таблица фактов событий с истинной детализацией. Одна строка на активность. Участники здесь отбрасываются и воссоздаются в виде отдельной таблицы.ActivityParticipantsсуществует потому, что участники на самом деле связаны отношением «один ко многим» и имеют роли, такие какactorиtarget. Разворачивание в плоскую структуру наActivitiesпривело бы либо к дублированию строк активности (завышению каждого подсчёта), либо к потере дополнительных участников. Связь сActivities— единственная двунаправленная связь в модели, поэтому срез по сущности доходит до таблицы фактов.Entities— измерение, которое называет участников. Строки участников в активности содержатentity_idи роль, но не отображаемое имя.Datesсоздаётся в M (без обращений к API) и помечается как таблица дат модели. Именно это делает допустимой аналитику времени в DAX (DATESINPERIOD,DATEADD). Столбцы с названиями месяцев и дней недели объявляютsortByColumnна своих числовых двойниках, чтобы визуальные элементы не сортировали месяцы по алфавиту.
discourageImplicitMeasures): общее число
активностей, активные сущности, активности на одну активную сущность, дни с активностью
и 7-дневное скользящее среднее за день.
Структура таблицы-моста
ActivityParticipants проходит по /v1/activities и разворачивает массив participants
в одну строку на участника:
ActivityParticipants.pq
ActivityParticipants проходит по /v1/activities независимо, а не
ссылается на запрос Activities. В Power BI два запроса, загруженные как две
таблицы, при обновлении получают данные независимо. Их независимость
позволяет службе обновлять партиции обеих таблиц параллельно.
Инкрементальное обновление
Обе таблицы с детализацией фактов (Activities и ActivityParticipants) объявляют
политику инкрементального обновления Power BI: хранить 5 лет годовых партиций и
повторно импортировать последние 14 дней при каждом обновлении.
Механизм основан на паре параметров DateTime, RangeStart и RangeEnd,
которые служба Power BI переопределяет для каждой партиции во время обновления. Каждый запрос фактов
подставляет эти параметры в фильтры API start_date и end_date,
поэтому объём запросов на уровне партиции пропорционален партиции,
а не всей истории. Запрос расширяет окно API на минуту
с каждой стороны и локально повторно применяет точную полуоткрытую границу [RangeStart, RangeEnd),
поэтому корректность партиции не зависит от того, считает ли сервер
свои границы включающими или исключающими.
Activities.pq — the fold that makes incremental refresh work
14-дневное окно намеренно выбрано с запасом. Приём данных об активности не ограничивается
добавлением только текущих событий: при заполнении истории коннекторами поступают события с прошлыми временными метками.
Окно в 1–2 дня безвозвратно пропустило бы их.
Расширение окна обновления на стороне API
GET /v1/activities принимает фильтры start_date и end_date, в которые
подставляются параметры Power BI, фильтруя event_ts между границами.
Entities является измерением, поэтому в этом примере оно обновляется полностью каждый раз,
а не инкрементально.
Наборы данных reporting используют собственные водяные знаки (updated_after,
occurred_after) вместо окна дат активностей.
Ограничения частоты запросов во время обновления
/v1 применяет отдельные лимиты для каждого ключа и каждого IP-адреса (см.
rate limits). Учитывайте 429 + Retry-After; не
закладывайте в модель жёстко заданный лимит запросов. Важны два свойства
обновлений Power BI:
- Проход по одной таблице выполняется последовательно. Для каждого запроса страницы нужен токен предыдущей страницы, поэтому скорость обработки одной таблицы ограничена задержкой независимо от размера страницы.
- Параллельные обновления таблиц накладываются друг на друга. Именно одновременное обновление нескольких больших таблиц
приводит к достижению предела, поэтому важен путь повторных попыток при ответе 429
в
Fn_FetchAll. Лучше уменьшить число параллельных таблиц, чем рассчитывать на неограниченный параллелизм.
Версии контракта и сохранённые учётные данные
/v1 принимает заголовок запроса Living-Security-Version, чтобы закрепить опубликованную
версию контракта (см. API quickstart). Power
Query не может отправлять этот заголовок, если источник данных использует сохранённые учётные данные, —
пользовательские заголовки допускают только анонимные источники данных. Его добавление приводит к сбою обновления
со следующей ошибкой:
contract_version или последнюю опубликованную версию, если закрепления нет.
Прежде чем публиковать обновление, уточните версию контракта учётной записи у администратора API. Поддерживаемые версии
см. в API changelog.
Если обновление начинает вести себя неожиданно, проверьте заголовок ответа API
Living-Security-Version, чтобы узнать, какой контракт
фактически обработал запрос.
Обновление и проверка модели
Опубликуйте семантическую модель в рабочей области Power BI, привяжите её сохранённые учётные данные к региональному источнику/v1 и выполните обновление, прежде чем включать
расписание. Проверьте историю обновлений на наличие сбоев или неполного чтения.
Сверьте количества строк с независимым чтением через API с теми же фильтрами.
В руководстве по постраничной навигации приведены примеры на Python и cURL
для чтения полного набора результатов. Обновление, читающее только
первую страницу, может выглядеть успешным на небольшом наборе данных; сравните количества,
прежде чем полагаться на отчёт.
Проектные решения модели
- Итоги кампаний и результаты по отдельным сотрудникам имеют разную детализацию.
SimulationResultsвызываетGET /v1/simulations/{id}/results(один GET на запуск). Для данных о фишинге по отдельным сотрудникам добавьте запросы дляGET /v1/reporting/simulation_resultsиGET /v1/reporting/simulation_events(или операционногоGET /v1/simulation_results, если у вас уже естьsimulation:read). vectorsв/v1/simulationsпреобразуется в строку, соединённую запятыми. Столбец типа «список» нельзя использовать в срезе как настоящее измерение. Если странице отчёта нужна фильтрация по вектору, добавьте таблицу-мост «симуляция — вектор».
Дальнейшие шаги
Developer Hub
Создайте сервисную учётную запись и ключ API для Power BI.
API quickstart
Аутентификация запросов
/v1 с помощью Basic.Pagination
Конверт списка, токены курсора и стабильность фильтров при проходе.
Rate limits
Лимиты для каждого ключа и каждого IP-адреса, контракт ответа 429 и рекомендации по повторным попыткам.

