Forum Discussion

viswaaa's avatar
viswaaa
Helper IV
8 months ago
Solved

Feature Usage and Adoption symantic model report

Hi All,   I need to created a report with Feature Usage and Adoption symantic model where I need to show workspaces and reports in my org and it should be dynamic. I connected with Adoption symant...
  • tayloramy's avatar
    tayloramy
    8 months ago

    Hi viswaaa

     

    I can't build a full solution for you, but here's something to get you started. 

     

    from sempy.fabric import FabricRestClient
    from urllib.parse import urlencode
    import pandas as pd
    
    client = FabricRestClient()  # Auth tokens are acquired from the Fabric execution context. 
    
    def paged_get(path: str, params: dict | None = None) -> list[dict]:
        """
        Calls a Fabric REST API GET endpoint that returns:
          { "value": [...], "continuationToken": "...", "continuationUri": "..." }
        and keeps fetching until all pages are retrieved.
        """
        all_rows = []
        continuation = None
        params = dict(params or {})
    
        while True:
            q = dict(params)
            if continuation:
                q["continuationToken"] = continuation
    
            url = path + (("?" + urlencode(q)) if q else "")
            resp = client.get(url)
            resp.raise_for_status()
    
            payload = resp.json()
            all_rows.extend(payload.get("value", []))
    
            continuation = payload.get("continuationToken")
            if not continuation:
                break
    
        return all_rows
    
    def list_workspaces(roles: list[str] | None = None) -> list[dict]:
        # roles example: ["Admin","Member","Contributor","Viewer"] 
        params = {}
        if roles:
            params["roles"] = ",".join(roles)
        return paged_get("/v1/workspaces", params=params)
    
    def list_reports_in_workspace(workspace_id: str, recursive: bool = True) -> list[dict]:
        # List Items supports filtering by item type; "Report" is a valid type. 
        params = {
            "type": "Report",
            "recursive": str(recursive)  # API expects boolean; sending "True"/"False" works well in practice
        }
        items = paged_get(f"/v1/workspaces/{workspace_id}/items", params=params)
    
        # Defensive filter in case anything unexpected slips through
        return [i for i in items if i.get("type") == "Report"]
    
    # --- Main ---
    workspaces = list_workspaces()
    rows = []
    
    for ws in workspaces:
        ws_id = ws["id"]
        ws_name = ws.get("displayName")
    
        try:
            reports = list_reports_in_workspace(ws_id, recursive=True)
            for r in reports:
                rows.append({
                    "workspaceId": ws_id,
                    "workspaceName": ws_name,
                    "reportId": r["id"],
                    "reportName": r.get("displayName"),
                    "folderId": r.get("folderId"),
                })
        except Exception as ex:
            # If you ever hit a permissions edge-case, keep going and log it
            rows.append({
                "workspaceId": ws_id,
                "workspaceName": ws_name,
                "reportId": None,
                "reportName": f"ERROR listing reports: {ex}",
                "folderId": None,
            })
    
    df_reports = pd.DataFrame(rows)
    df_reports

    If you found this helpful, consider giving some Kudos. If I answered your question or solved your problem, mark this post as the solution.