Skip to main content
Цей посібник — наскрізний приклад читання /v1 у Power BI. Він охоплює шаблон підключення в Power Query (M), семантичну модель за схемою «зірка», побудовану на /v1/activities, інкрементальне оновлення, а також випадки, коли слід використовувати reporting preview-набори даних для результатів фішингу по кожній особі. У прикладах використовується виробничий хост для США (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.

Для чого призначений цей приклад

Використовуйте його, якщо вам потрібно:
  • Завантажити списочні endpoint-и /v1 у набір даних Power BI з коректною курсорною пагінацією та повторною спробою у разі перевищення ліміту запитів.
  • Побудувати семантичну модель, у якій міри («активні сутності», «активності на одну активну сутність») є вимірними, а не підраховуються з пласкої таблиці.
  • Перевести заплановане оновлення Power BI від повного обходу історії до невеликого щоденного вікна за допомогою інкрементального оновлення.
  • Обрати правильну деталізацію фішингових даних: підсумки кампаній (операційні) або результати по кожній особі та типізовані події (reporting preview).

Передумови

  • Ключ 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 preview-сімейству, описаному нижче. Ключ, якому надано лише 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 як low, 3 як medium, а 4–5 як high.
Не створюйте нових BI-інтеграцій на основі недокументованих мережевих викликів Dashboard або застарілого курованого огляду Public API /api/v1. Автентифікуйтеся на регіональному хості /v1 вашої організації за допомогою ключа API з Developer Hub. Див. Regions.

Шаблон підключення (Power Query)

В основі кожного запиту в цьому прикладі лежать чотири правила. Кожне з них вимагається службою Power BI, а не є стильовим уподобанням.
Усе динамічне розміщуйте в 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.
Коли Power BI запитує облікові дані для джерела даних /v1, виберіть Basic і вставте ключ API як username. У поле password введіть заповнювач, наприклад x. Служба Power BI відхиляє порожній пароль, хоча API це поле ігнорує. Ключ як пароль із заповнювачем замість імені користувача також працює.Не додавайте заголовок Authorization у M. Він працює на вашому комп’ютері, але вбудовує ключ у файл запиту та конфліктує із запланованим оновленням.
GET /v1 вимагає автентифікації: він повертає 200 з дійсним ключем і 401 без нього. Вкажіть …/v1 як джерело даних і не пропускайте перевірку — дійсний ключ зберігається, а відкликаний або некоректний одразу викликає помилку.У старіших прикладах як джерело даних використовувався голий хост і пропонувалося пропустити перевірку, оскільки GET / завжди повертає 404. Переналаштуйте ці моделі на …/v1.
Розмір сторінки за замовчуванням для кожного списочного endpoint-а /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 навмисно не повторюється — помилка сервера має бути помітною, а не непомітно створювати частковий набір даних.
  • 60-секундний Timeout. Сторінки зазвичай відповідають значно швидше ніж за секунду, тому хвилина тиші означає, що запит «мертвий».
  • Binary.Buffer перед Json.Document. Без буферизації рушій mashup може повторно запитувати потік відповіді, якщо зчитує його більше одного разу.
  • baseQuery передається без змін на кожній ітерації. Токени сторінок — це непрозорі підписані курсори, прив’язані до організації, облікових даних, версії контракту та відбитка фільтрів і сортування. Зміна фільтра під час обходу відхиляється як недійсний токен, а не перезапускається з першої сторінки.
Fn_FetchAll.pq — base and call shape

Типізовані запити для кожного endpoint-а

Кожен споживач Fn_FetchAll дотримується однакової структури: викликає endpoint, проєктує фіксований перелік стовпців, видаляє дискримінатор object і типізує часові мітки як datetimezone, щоб міри дат непомітно не зсувалися через часовий пояс ємності оновлення.
Явний перелік стовпців у Table.FromRecords забезпечує стабільність схеми, коли endpoint повертає нуль рядків. Порожній Table.FromRecords({}) створює таблицю без стовпців, і всі наступні кроки завершуються помилкою через відсутні поля.

Excel

Той самий Power Query (M) працює в Get & Transform в Excel — це той самий рушій, що й у Power BI Desktop. Використовуйте це, коли вам потрібна таблиця на аркуші замість семантичної моделі. В Excel для Windows (Microsoft 365, Excel 2024, 2021, 2019 або 2016):
  1. Data → Get Data → From Other Sources → Blank Query.
  2. У редакторі Power Query виберіть Home → Advanced Editor. Спочатку вставте Fn_FetchAll, потім перейменуйте цей запит на Fn_FetchAll (Query Settings → Name або клацніть правою кнопкою миші в панелі Queries → Rename).
  3. Повторіть для Fn_GetJson, а потім для кожного запиту звіту.
  4. Home → Close & Load → Close & Load To… відкриває діалог Import Data. Виберіть Only Create Connection для Fn_FetchAll та Fn_GetJson (це функції, а не таблиці). Виберіть Table для кожного запиту звіту, який потрібен на аркуші.
  5. Під час першого оновлення виберіть Basic: ключ API як User name, заповнювач, наприклад x, як Password. Excel зберігає одні облікові дані на кожну URL-адресу джерела даних; наступні запити до того самого хоста /v1 використовують їх повторно.
Close & Load To… може бути неактивним, коли ви вперше створюєте запит у книзі. Скористайтеся Close & Load, потім в Excel виберіть Data → Queries & Connections, клацніть запит правою кнопкою миші та виберіть Load To. Корпорація Microsoft документує цей шлях саме для такого випадку.
Ви не можете надсилати 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 preview-набори даних (фішинг по кожній особі)

Reporting preview-сімейство надає набори даних для фішингу по кожній особі. Воно потребує reporting:read та доступу до звітності для вашої організації. Скористайтеся наведеним нижче каталогом наборів даних, щоб переглянути їхні схеми та політики даних. Отримайте актуальний каталог:
Кожен набір даних оголошує деталізацію, первинний ключ, приєднання, водяний знак, політику виправлень і видалення.

simulation_results

  • Шлях: GET /v1/reporting/simulation_results
  • Деталізація: сутність × симуляція
  • Фільтри: simulation, entity, updated_after, а також limit / page_token
  • Об’єкт wire: 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
  • Об’єкт wire: reporting.simulation_event
  • Типи подій: закриті публічні токени, такі як simulation.delivered, simulation.opened, simulation.link_clicked, simulation.credentials_submitted, simulation.reported — не сирі типи активностей ClickHouse phishing.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
  • Об’єкт wire: 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 для версій сутностей і час спостереження запиту для членств у Cohort. Закриті історичні інтервали не вигадуються.
  • 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 — це останнє оновлення Cohort, тож інкрементальне оновлення залишається коректним. 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 повторно прив’язує до кожної партиції під час оновлення. Кожен запит фактів підставляє ці параметри у фільтри start_date і end_date API, тож кількість запитів на рівні партиції пропорційна партиції, а не всій історії. Запит розширює вікно API на хвилину з кожного боку та повторно застосовує точну напіввідкриту межу [RangeStart, RangeEnd) локально, тож коректність партицій не залежить від того, чи сервер трактує свої межі як включні, чи як виключні.
Activities.pq — the fold that makes incremental refresh work
Перше оновлення після розгортання застосовує політику: повне завантаження історії, повільне. Кожне наступне оновлення зачіпає лише інкрементальне вікно. Виміряно на наборі даних із ~158 000 активностей і ~2 300 сутностей:
Класичний REST endpoint оновлення Power BI (POST .../refreshes лише з notifyOption) непомітно ігнорує політики оновлення й щоразу виконує повний обхід. Щоб застосувати політику через REST API, використовуйте розширене оновлення: надішліть type, commitMode і applyRefreshPolicy у тілі запиту. Оновлення, ініційовані планувальником служби Power BI, завжди застосовують політики — ця особливість стосується лише REST-виклику.
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 не може надіслати цей заголовок, коли джерело даних використовує збережені облікові дані — власні заголовки дозволяють лише анонімні джерела даних. Додавання заголовка призводить до помилки оновлення:
Зберігайте ключ у збережених облікових даних Power BI й не додавайте власний заголовок. Якщо версію в запиті явно не вказано, API використовує закріплену 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 auth.

Pagination

Конверт списку, токени курсора та стабільність фільтрів під час обходу.

Rate limits

Бюджети на ключ і на IP, контракт 429 та рекомендації щодо повторних спроб.