Luo ja konfiguroi Fabric-kartta Python- ja REST API:lla

Tässä artikkelissa näytetään, miten Fabric-karttakohde luodaan ja karttamääritelmä voidaan soveltaa Python-menetelmällä. Se esittelee sekä tuetut toimintajärjestysmallit että sisältää perusvirheiden käsittelyn.

Fabric-kartan luominen ohjelmallisesti vaatii kaksi komponenttia:

  • Karttamääritelmä (map.json)
  • karttakohde Fabric työtilassa

Riippuen valitsemastasi kaavasta, voit:

  • Luo ensin karttaalkio ja määritelmä myöhemmin, tai
  • Luo karttaalkio määritelmän rivissä yhdellä pyynnöllä

Tämä artikkeli havainnollistaa molempia lähestymistapoja.

Vinkki

Useimmissa automaatiotilanteissa suositeltava lähestymistapa on luoda kartta sen määritelmän mukaisesti. Tämä varmistaa, että kartta on täysin konfiguroitu luontihetkellä ja välttää lisä-API-kutsut.

Note

Tämä artikkeli keskittyy karttojen luomiseen ja konfigurointiin (ohjaustaso). Kartan viitaama data (kuten GeoJSON-tiedostot tai SVG-kuvakkeet) täytyy jo olla olemassa OneLakessa tai muussa tuetussa tietolähteessä.

Edellytykset

  • Pääsy Fabric-työtilaan
  • Microsoft Entra ID -sovellus tai käyttäjätunnus työtilan käyttöoikeuksilla
  • Python 3.9 tai uudempi
  • OAuth 2.0 -pääsytunnus Fabric REST API:lle

Esimerkkikarttamääritelmä (map.json)

Seuraava esimerkki esittää yksinkertaistetun map.json hyötykuorman, joka:

  • Käyttää oletuspohjakarttaa
  • Lukee GeoJSON-dataa Lakehouse-tietolähteestä
  • Renderöi datan vektorikerroksena

Määritelmä map.json on deklaratiivinen konfiguraatio , joka kuvaa:

  • dataSources (esimerkiksi Lakehouse- tai Eventhouse-resurssit, jotka tarjoavat dataa)
  • layerSources (tiedostot, taulukot tai funktiot, jotka määrittelevät datan kullekin kerrokselle)
  • layerSettings (visualisointiasetukset jokaiselle kerrokselle, kuten värit, kuvakkeet tai tyylit)

Määritelmä kuvaa, mitä kartan tulisi renderöidä, eikä määritellä proseduraalisia vaiheita renderöinnille.

map_json = {
  "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/map/definition/2.0.0/schema.json",
  "basemap": {
    "options": {
      "style": "road"
    }
  },
  "dataSources": [
    {
      "itemType": "Lakehouse",
      "workspaceId": "<workspace-id>",
      "itemId": "<lakehouse-item-id>"
    }
  ],
  "layerSources": [
    {
      "id": "points-source",
      "name": "Points-GeoJSON",
      "type": "geojson",
      "itemId": "<lakehouse-item-id>",
      "relativePath": "Files/data/points.geojson",
      "refreshIntervalMs": 0
    }
  ],
  "layerSettings": [
    {
      "id": "points-layer",
      "name": "Points",
      "sourceId": "points-source",
      "options": {
        "type": "vector",
        "visible": True,
        "color": "#0078D4",
        "pointLayerType": "bubble",
        "bubbleOptions": {
          "color": "#0078D4"
        }
      }
    }
  ]
}

Lisätietoja keskeisistä komponenteista , map.jsonkatso MapDetails.

Malli 1: Luo kartta, sitten määrittele määritelmä

Käytä tätä kaavaa, kun sinun täytyy ensin luoda Fabric-karttakohde ja soveltaa karttamäärittelyä myöhemmin. Tämä lähestymistapa on hyödyllinen, kun karttamääritelmä generoidaan dynaamisesti, lähteistetään useista tiedostoista tai päivitetään vähitellen karttakohteen olemassaolon jälkeen. Tässä mallissa alkuperäinen API-kutsu luo karttaalkion pelkästään metatiedoista, ja seuraava kutsu määrittää skeema-kelvollisen map.json-määritelmän peruskartan, tietolähteiden ja kerrosten konfigurointiin.

Note

Tätä mallia käytetään tyypillisesti edistyneissä tilanteissa, joissa määritelmä kehittyy ajan myötä tai kootaan dynaamisesti.

Vaihe 1: Luo karttakohde (vain metatiedot)

Tämä kutsu ei sisällä karttamääritelmää:

import httpx

BASE_URL = "https://api.fabric.microsoft.com"
TOKEN = "<access-token>"
WORKSPACE_ID = "<workspace-id>"
map_name = "Automated Map (Pattern 1)"

headers = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json"
}

# Metadata only – NOT map.json
create_map_payload = {
    "displayName": map_name
}

response = httpx.post(
    f"{BASE_URL}/workspaces/{WORKSPACE_ID}/items/maps",
    headers=headers,
    json=create_map_payload,
    timeout=30
)

response.raise_for_status()

map_item = response.json()
map_id = map_item["id"]

Tässä vaiheessa karttaalkio on olemassa, mutta sillä ei ole määriteltyä määritelmää.

Vaihe 2: Määrittele kartta (map.json)

Valmistele pätevä map_json hyötykuorma, kuten aiemmin esitetty esimerkki .

Vaihe 3: Määritä määritelmä kartalle

response = httpx.put(
    f"{BASE_URL}/workspaces/{WORKSPACE_ID}/items/maps/{map_id}/definition",
    headers=headers,
    json={
        "definition": {
            "parts": [
                {
                    "path": "map.json",
                    "payload": map_json,
                    "payloadType": "InlineJson"
                }
            ]
        }
    },
    timeout=30
)

response.raise_for_status()

Käytä tätä kuviota kartan luomiseen ja konfigurointiin yhdellä operaatiolla.

Tämä lähestymistapa sopii hyvin deklaratiivisiin käyttöönottoihin, kuten CI/CD-putkistoihin tai infrastruktuuri-koodina -työnkulkuihin.

Base64-vaatimus

Kun määritelmä sisällytetään REST-kutsuihin, hyötykuorman on oltava Base64-koodattu ja toimitettava määrittely osana.

Important

Jos map.json sisältyy johonkin REST-pyyntöön, se on sisällytettävä Base64-koodattuna hyötykuormana definition.parts[] yhdessä payloadType: "InlineBase64".

Base64-avustaja

Käytä tätä apuvälinettä muuttaaksesi map.json Python dictBase64-merkkijonoksi, jota definition.parts[].payload vaatii.

import base64
import json

def to_inline_base64(obj: dict) -> str:
    """
    Serialize a JSON-compatible dict and return a Base64-encoded UTF-8 string.
    Use this for definition.parts[].payload when payloadType is InlineBase64.
    """
    raw = json.dumps(obj, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
    return base64.b64encode(raw).decode("utf-8")

Luo kartta inline-määritteellä

Pyyntöön sisältyy:

  • displayName (karttakohteen metatiedot)
  • definition.parts[] missä map.json on Base64-encoded ja merkitty muodossa InlineBase64
import httpx

BASE_URL = "https://api.fabric.microsoft.com/v1"
TOKEN = "<access-token>"
WORKSPACE_ID = "<workspace-id>"
map_name = "Automated Map (Pattern 2)"

headers = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json",
}

# Schema-valid map.json (example fields abbreviated here)
map_json = {
    "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/map/definition/2.0.0/schema.json",
    "basemap": {"options": {"style": "road"}},
    "dataSources": [
        {
            "itemType": "KqlDatabase",
            "workspaceId": "<workspace-id>",
            "itemId": "<eventhouse-or-kql-db-item-id>"
        }
    ],
    "layerSources": [
        {
            "id": "work-orders-src",
            "name": "Work orders (Eventhouse)",
            "type": "kusto",
            "itemId": "<eventhouse-or-kql-db-item-id>",
            "refreshIntervalMs": 5000
        }
    ],
    "layerSettings": [
        {
            "id": "work-orders-layer",
            "name": "Work orders",
            "sourceId": "work-orders-src",
            "options": {"type": "vector", "visible": True, "color": "#0078D4"}
        }
    ]
}

payload = {
    "displayName": map_name,
    "definition": {
        "parts": [
            {
                "path": "map.json",
                "payload": to_inline_base64(map_json),
                "payloadType": "InlineBase64"
            }
        ]
    }
}
with httpx.Client(timeout=60) as client:

response = client.post(
    f"{BASE_URL}/workspaces/{WORKSPACE_ID}/maps",
    headers=headers,
    json=payload,
    timeout=30
)
response.raise_for_status()
created = response.json()
map_id = created["id"]

Yhteenveto: Kuvio 1 vs Kuvio 2 (Base64-sääntö)

Molemmat karttamallit perustuvat lopulta samaan karttamäärittelysopimukseen, mutta ne eroavat siinä, milloin määritelmä annetaan ja milloin tarvitaan Base64-koodausta. Tässä osiossa tarkastellaan uudelleen Pattern 1:tä ja Pattern 2:ta rinnakkain selventääkseen yleistä sekaannuksen lähdettä: Aina kunmap.json sisältyy REST-kutsuun – olipa kyse luomisesta tai päivityksestä – se on annettava Base64-koodatun määritelmän osana. Tämän eron ymmärtäminen auttaa varmistamaan, että karttaautomaatiotyönkulut soveltavat oikeaa hyötykuormamuotoa jokaisessa vaiheessa ja välttävät hienovaraiset pyyntömuotovirheet.

Malli 1: Luo kartta → määritä sitten määritelmä

  • Luo karttakutsu: vain metatiedot (ei määritelmää, joten ei Base64:ää luomishetkellä).
  • Määritä määritelmä: käytä Update Map Definition with definition.parts[] and payloadType: "InlineBase64" (joten Base64 vaaditaan päivitysvaiheessa).

Malli 2: Luo kartta, jossa määritelmä sisältyy

  • Create Map -kutsu sisältää määritelmän: Sinun täytyy antaa definition.parts[] ja koodata Base64map.json käyttäen payloadType: "InlineBase64".

Nyrkkisääntö: Jos map.json sisältyy johonkin REST-pyyntöön/vastaukseen, se kuljetetaan Base64-hyötykuormana merkinnässä definition.parts[] , jossa payloadType: "InlineBase64"on .

Create helper funktio kartta-ID:n hakemaan

Kun luot kartan Fabric REST API:n avulla, pyyntö voi palauttaa 202 hyväksytty -vastauksen. Tämä tarkoittaa, että karttaa provisioidaan asynkronisesti pitkäaikaisena operaationa (LRO), eikä sitä luotaisiin välittömästi. Tässä tapauksessa vastaus ei sisällä kartta-ID:tä, eikä LRO:n lopputulos välttämättä anna käyttökelpoista tulosta. Lisäksi, vaikka operaatio olisi valmis, uusi kartta ei välttämättä näy heti, kun List Maps API:ta kutsutaan taustan leviämisen vuoksi.

Jotta saat luotettavan kartta-ID:n, sinun täytyy kysyä karttalista ja yrittää uudelleen, kunnes uusi kartta tulee näkyviin. Seuraava aputoiminto toteuttaa tämän uudelleenyrittämismallin ja varmistaa, että automaatioprosessisi kestää asynkronisia provisionointiviiveitä.

# ---------------------------------------------------------
# Get Map ID
# ---------------------------------------------------------

def resolve_map_id(client, list_url, headers, map_name, max_attempts=10, delay=5):
    """
    Resolve the ID of a newly created Fabric map.

    Why this function is needed:
    - Creating a map may return HTTP 202 (Accepted), indicating an asynchronous
      long-running operation (LRO) rather than immediate creation.
    - LRO responses for map creation don't always return a resource ID.
    - Even after the operation completes, the new map may not be immediately
      visible in the List Maps API due to backend propagation delays.

    What this function does:
    - Repeatedly calls the List Maps API.
    - Searches for a map matching the provided display name.
    - Retries for a configurable number of attempts with a delay between calls.

    Parameters:
        client        : Authenticated HTTP client
        list_url      : Maps list endpoint
        headers       : Authorization headers for Fabric API
        map_name      : Display name of the map to locate
        max_attempts  : Maximum number of retry attempts
        delay         : Delay (seconds) between retries

    Returns:
        The map ID (string) once the map becomes visible.

    Raises:
        RuntimeError if the map is not found after all retry attempts.
    """

    for attempt in range(max_attempts):
        print(f"Resolving map (attempt {attempt + 1}/{max_attempts})...")

        resp = client.get(list_url, headers=headers)
        resp.raise_for_status()

        items = resp.json().get("value", [])

        match = next(
            (m for m in items if m.get("displayName") == map_name),
            None
        )

        if match:
            print("✅ Map found!")
            return match["id"]

        print("⏳ Map not visible yet. Retrying...")
        time.sleep(delay)

    raise RuntimeError("Map created but still not visible after retries")

Sitten sen sijaan, että ottaisit kartta-ID:n kuten edellisessä näytteessä (),map_id = created["id"] kokeile:

    if response.status_code == 201:
        map_id = response.json()["id"]
    elif response.status_code == 202:
        print("LRO completed via 202. Resolving map by name...")
        map_id = resolve_map_id(
            client,
            create_map_url,
            _fabric_headers(),
            map_name
        )  

Seuraavat vaiheet

Käsittele virheitä automatisoidessa Fabric Maps REST API