pbi-enterprise-cli 0.1.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pbi_enterprise_cli-0.1.0.dev0/LICENSE +21 -0
- pbi_enterprise_cli-0.1.0.dev0/PKG-INFO +103 -0
- pbi_enterprise_cli-0.1.0.dev0/README.md +309 -0
- pbi_enterprise_cli-0.1.0.dev0/README.pypi.md +47 -0
- pbi_enterprise_cli-0.1.0.dev0/pyproject.toml +81 -0
- pbi_enterprise_cli-0.1.0.dev0/setup.cfg +4 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/__init__.py +3 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/_audit.py +57 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/_snapshot.py +95 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/backends/__init__.py +1 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/backends/mock_backend.py +323 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/backends/pbir_backend.py +813 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/backends/protocol.py +52 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/backends/tom_backend.py +650 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/backends/xmla_backend.py +627 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/cli.py +332 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/__init__.py +1 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/_doctor.py +84 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/_shared.py +88 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/calendar_cmd.py +186 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/connections.py +153 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/custom_visual.py +325 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/database.py +76 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/dax.py +174 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/deploy.py +193 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/docs.py +57 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/filter_cmd.py +235 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/govern.py +124 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/layout.py +104 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/measure.py +185 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/model.py +499 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/partition.py +89 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/repl.py +209 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/report.py +561 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/security.py +90 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/server_cmd.py +30 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/skills_cmd.py +168 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/source.py +581 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/theme.py +60 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/trace.py +142 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/visual.py +507 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/commands/watch.py +145 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/docs_gen/__init__.py +1 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/docs_gen/confluence.py +24 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/docs_gen/markdown.py +36 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/__init__.py +1 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/engine.py +70 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/rules/__init__.py +85 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/rules/measure_brackets.py +27 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/rules/measure_description.py +41 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/rules/measure_format.py +38 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/rules/measure_naming.py +93 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/governance/rules/table_pascal_case.py +44 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/intelligence/__init__.py +1 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/intelligence/layout_engine.py +192 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/intelligence/measure_generator.py +40 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/intelligence/theme_generator.py +193 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/intelligence/visual_builder.py +429 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/intelligence/visual_recommender.py +42 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/server/__init__.py +1 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_cli/server/api.py +185 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_enterprise_cli.egg-info/PKG-INFO +103 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_enterprise_cli.egg-info/SOURCES.txt +65 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_enterprise_cli.egg-info/dependency_links.txt +1 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_enterprise_cli.egg-info/entry_points.txt +2 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_enterprise_cli.egg-info/requires.txt +35 -0
- pbi_enterprise_cli-0.1.0.dev0/src/pbi_enterprise_cli.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mudassir
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pbi-enterprise-cli
|
|
3
|
+
Version: 0.1.0.dev0
|
|
4
|
+
Summary: Power BI enterprise CLI — AI-driven model management, governance, PBIR authoring, XMLA, and DAX testing
|
|
5
|
+
Author-email: Mudassir <mir.mudassir1@gmail.com>
|
|
6
|
+
License: MIT AND LicenseRef-Microsoft-AS-Client-Libraries
|
|
7
|
+
Project-URL: Homepage, https://github.com/mudassir09/pbi-enterprise-cli
|
|
8
|
+
Project-URL: Repository, https://github.com/mudassir09/pbi-enterprise-cli
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/mudassir09/pbi-enterprise-cli/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/mudassir09/pbi-enterprise-cli/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: power-bi,cli,dax,tmdl,pbir,powerbi,microsoft,governance
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Information Technology
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Topic :: Office/Business
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: click>=8.1
|
|
28
|
+
Requires-Dist: rich>=13.0
|
|
29
|
+
Requires-Dist: pythonnet>=3.0
|
|
30
|
+
Requires-Dist: pydantic>=2.0
|
|
31
|
+
Requires-Dist: python-dotenv>=1.0
|
|
32
|
+
Requires-Dist: PyYAML>=6.0
|
|
33
|
+
Provides-Extra: ai
|
|
34
|
+
Requires-Dist: anthropic>=0.25; extra == "ai"
|
|
35
|
+
Provides-Extra: viz
|
|
36
|
+
Requires-Dist: Pillow>=10.0; extra == "viz"
|
|
37
|
+
Requires-Dist: python-wcag-contrast-ratio>=1.0; extra == "viz"
|
|
38
|
+
Requires-Dist: playwright>=1.44; extra == "viz"
|
|
39
|
+
Provides-Extra: xmla
|
|
40
|
+
Requires-Dist: msal>=1.28; extra == "xmla"
|
|
41
|
+
Provides-Extra: server
|
|
42
|
+
Requires-Dist: fastapi>=0.110; extra == "server"
|
|
43
|
+
Requires-Dist: uvicorn>=0.29; extra == "server"
|
|
44
|
+
Provides-Extra: sources
|
|
45
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "sources"
|
|
46
|
+
Requires-Dist: openpyxl>=3.1; extra == "sources"
|
|
47
|
+
Requires-Dist: httpx>=0.27; extra == "sources"
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
50
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
51
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
52
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
53
|
+
Provides-Extra: all
|
|
54
|
+
Requires-Dist: pbi-enterprise-cli[ai,dev,server,sources,viz,xmla]; extra == "all"
|
|
55
|
+
Dynamic: license-file
|
|
56
|
+
|
|
57
|
+
# pbi-enterprise-cli
|
|
58
|
+
|
|
59
|
+
**Full-stack Power BI enterprise automation from the command line.**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install pbi-enterprise-cli
|
|
63
|
+
pbi doctor # verify setup
|
|
64
|
+
pbi model tables # list tables in the connected model
|
|
65
|
+
pbi govern check # run governance rules
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Feature highlights
|
|
69
|
+
|
|
70
|
+
- **25 command groups** covering every layer of Power BI development
|
|
71
|
+
- **32 visual types** — from cards to decomposition trees
|
|
72
|
+
- **3 backends** — Desktop (TOM via pythonnet), XMLA (Premium/Fabric), Mock (CI)
|
|
73
|
+
- **PBIR GA format** — read and write `.pbip` project files directly
|
|
74
|
+
- **Governance engine** — 5 built-in rules + custom plugin system
|
|
75
|
+
- **REST source profiling** — Bearer/API-key auth, OData pagination, star-schema scaffold
|
|
76
|
+
- **REPL mode** — interactive session with tab completion and persistent history
|
|
77
|
+
- **Custom visual SDK** — scaffold, build, package, import `.pbiviz`
|
|
78
|
+
- **AI measure generation** — Claude API integration (requires `[ai]` extra)
|
|
79
|
+
- **24 AI skills** — install Claude Code skills (`pbi skills install --all`)
|
|
80
|
+
- **547 unit tests** passing on Python 3.10–3.12
|
|
81
|
+
|
|
82
|
+
## Install options
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install pbi-enterprise-cli # base
|
|
86
|
+
pip install "pbi-enterprise-cli[ai]" # + Claude AI
|
|
87
|
+
pip install "pbi-enterprise-cli[xmla]" # + MSAL auth for XMLA
|
|
88
|
+
pip install "pbi-enterprise-cli[sources]" # + SQL/Excel/REST profiling
|
|
89
|
+
pip install "pbi-enterprise-cli[all]" # everything
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Requirements
|
|
93
|
+
|
|
94
|
+
- Python 3.10+
|
|
95
|
+
- Windows (for Desktop/XMLA backends using .NET AMO)
|
|
96
|
+
- Power BI Desktop (for the `desktop` backend)
|
|
97
|
+
|
|
98
|
+
## Links
|
|
99
|
+
|
|
100
|
+
- [GitHub Repository](https://github.com/mudassir09/pbi-enterprise-cli)
|
|
101
|
+
- [Full Documentation](https://github.com/mudassir09/pbi-enterprise-cli#readme)
|
|
102
|
+
- [Changelog](https://github.com/mudassir09/pbi-enterprise-cli/blob/main/CHANGELOG.md)
|
|
103
|
+
- [Security Policy](https://github.com/mudassir09/pbi-enterprise-cli/blob/main/SECURITY.md)
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# pbi-enterprise-cli
|
|
2
|
+
|
|
3
|
+
> Full-stack Power BI enterprise automation from the command line — semantic model management, report authoring, governance enforcement, DAX testing, REST source profiling, and AI-powered measure generation.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
`pbi-enterprise-cli` gives you a single `pbi` command that covers every layer of Power BI development — no clicking through the Desktop UI, no manual file editing, no proprietary tooling dependencies.
|
|
16
|
+
|
|
17
|
+
| Area | Commands |
|
|
18
|
+
|---|---|
|
|
19
|
+
| **Semantic model** | `pbi model` — tables, columns, relationships, lint, lineage |
|
|
20
|
+
| **DAX measures** | `pbi measure` — add, update, delete, AI-generate |
|
|
21
|
+
| **DAX testing** | `pbi dax` — query, validate, YAML unit-test suites |
|
|
22
|
+
| **Source profiling** | `pbi source` — SQL, Excel, CSV, REST APIs → star-schema scaffold |
|
|
23
|
+
| **Report authoring** | `pbi report` — pages, bookmarks (PBIR GA format) |
|
|
24
|
+
| **Visuals** | `pbi visual` — 32 visual types, colour-scale & data-bar formatting |
|
|
25
|
+
| **Layout** | `pbi layout` — shelf-packing auto-layout, named templates |
|
|
26
|
+
| **Themes** | `pbi theme` — generate WCAG-compliant themes from a brand colour |
|
|
27
|
+
| **Filters** | `pbi filter` — relative-date, TopN, basic value filters |
|
|
28
|
+
| **Governance** | `pbi govern` — 5 built-in rules + custom plugin system, auto-fix |
|
|
29
|
+
| **Security (RLS)** | `pbi security` — role add/delete/test |
|
|
30
|
+
| **Partitions** | `pbi partition` — add, refresh, delete |
|
|
31
|
+
| **Deployment** | `pbi deploy` — snapshot, diff, push via XMLA |
|
|
32
|
+
| **TMDL** | `pbi database` — export / import TMDL snapshots |
|
|
33
|
+
| **Docs** | `pbi docs` — markdown/Confluence data dictionary, audit log |
|
|
34
|
+
| **Tracing** | `pbi trace` — query performance tracing and benchmarking |
|
|
35
|
+
| **Connections** | `pbi connections` — list and manage data source connections |
|
|
36
|
+
| **Skills** | `pbi skills` — 24 Power BI AI skill definitions |
|
|
37
|
+
| **Calendar** | `pbi calendar` — generate date/calendar tables |
|
|
38
|
+
| **Culture** | `pbi culture` — locale and culture settings |
|
|
39
|
+
| **Custom Visuals** | `pbi custom-visual` — manage custom visual imports |
|
|
40
|
+
| **REPL** | `pbi repl` — interactive Power BI shell |
|
|
41
|
+
| **Diagnostics** | `pbi doctor` — check pythonnet, optional deps, platform (works on Linux/macOS too) |
|
|
42
|
+
| **Watch mode** | `pbi watch` — re-run governance + DAX tests on file change |
|
|
43
|
+
| **REST API** | `pbi server` — FastAPI server for pipeline integration |
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Backends
|
|
48
|
+
|
|
49
|
+
The same CLI works against three backends — swap with `--backend`:
|
|
50
|
+
|
|
51
|
+
| Backend | When to use |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `desktop` (default) | Local Power BI Desktop open with a `.pbip` project |
|
|
54
|
+
| `xmla` | Power BI Premium or Microsoft Fabric — no Desktop required |
|
|
55
|
+
| `mock` | CI pipelines, unit tests, demos — zero infrastructure |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
**Base install** (semantic model, governance, DAX, report authoring):
|
|
62
|
+
```bash
|
|
63
|
+
pip install pbi-enterprise-cli
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The base install includes **PyYAML**, so YAML-based DAX unit-test suites (`pbi dax test --suite`) work out of the box with no extra packages.
|
|
67
|
+
|
|
68
|
+
**Optional feature groups:**
|
|
69
|
+
```bash
|
|
70
|
+
pip install "pbi-enterprise-cli[ai]" # Claude AI measure generation
|
|
71
|
+
pip install "pbi-enterprise-cli[xmla]" # XMLA auth (MSAL)
|
|
72
|
+
pip install "pbi-enterprise-cli[sources]" # SQL / Excel / REST profiling
|
|
73
|
+
pip install "pbi-enterprise-cli[viz]" # WCAG theme validation, screenshots
|
|
74
|
+
pip install "pbi-enterprise-cli[server]" # FastAPI REST server
|
|
75
|
+
pip install "pbi-enterprise-cli[all]" # Everything
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> **Requirements:** Python 3.10+. The `desktop` and `xmla` backends require Windows and the AMO .NET assemblies (installed with Power BI Desktop).
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Quick Start
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Check your setup
|
|
86
|
+
pbi doctor
|
|
87
|
+
|
|
88
|
+
# Connect to open Power BI Desktop and inspect the model
|
|
89
|
+
pbi model tables
|
|
90
|
+
pbi model relationships
|
|
91
|
+
pbi measure list
|
|
92
|
+
|
|
93
|
+
# Run governance checks
|
|
94
|
+
pbi govern check
|
|
95
|
+
|
|
96
|
+
# Auto-fix safe violations (PascalCase, missing format strings, etc.)
|
|
97
|
+
pbi govern fix --auto
|
|
98
|
+
|
|
99
|
+
# Add a measure
|
|
100
|
+
pbi measure add \
|
|
101
|
+
--table Sales \
|
|
102
|
+
--name "Total Revenue" \
|
|
103
|
+
--expression "SUM(Sales[Revenue])" \
|
|
104
|
+
--format-string "#,0.00" \
|
|
105
|
+
--description "Net revenue after discounts"
|
|
106
|
+
|
|
107
|
+
# Run DAX unit tests
|
|
108
|
+
pbi dax test --suite tests/fixtures/measures/sales_suite.yaml
|
|
109
|
+
|
|
110
|
+
# Profile a REST API and scaffold a star-schema model
|
|
111
|
+
pbi source profile --type rest \
|
|
112
|
+
--url https://api.example.com/v1/orders \
|
|
113
|
+
--bearer-token $MY_TOKEN \
|
|
114
|
+
--output profile.json
|
|
115
|
+
|
|
116
|
+
pbi source scaffold --profile profile.json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Report Authoring (PBIP / PBIR)
|
|
122
|
+
|
|
123
|
+
Write directly to the `.pbip` project files — no running Desktop required. Open Desktop after to see the changes.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Pages
|
|
127
|
+
pbi report pages --pbip ./Sales.Report
|
|
128
|
+
pbi report page-add --pbip ./Sales.Report --name "Executive Summary"
|
|
129
|
+
|
|
130
|
+
# Visuals (32 types: card, bar, column, line, table, slicer, matrix, scatter, pie, map, ...)
|
|
131
|
+
pbi visual add --pbip ./Sales.Report \
|
|
132
|
+
--page "Executive Summary" \
|
|
133
|
+
--type card \
|
|
134
|
+
--table Sales --value "Total Revenue" --measure
|
|
135
|
+
|
|
136
|
+
# Bookmarks
|
|
137
|
+
pbi report bookmark-add --pbip ./Sales.Report --name "Q4 2024 View"
|
|
138
|
+
|
|
139
|
+
# Conditional formatting
|
|
140
|
+
pbi visual format-color-scale --pbip ./Sales.Report \
|
|
141
|
+
--page "Executive Summary" \
|
|
142
|
+
--visual-title "Sales by Product" \
|
|
143
|
+
--table Sales --field Revenue \
|
|
144
|
+
--min "#FF6B6B" --mid "#FFD93D" --max "#6BCB77"
|
|
145
|
+
|
|
146
|
+
# Auto-layout (shelf-packing)
|
|
147
|
+
pbi layout auto --pbip ./Sales.Report --page "Executive Summary"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Governance
|
|
153
|
+
|
|
154
|
+
Five built-in rules run out of the box. Drop a `.py` file in `~/.pbi-cli/rules/` to add your own:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
# ~/.pbi-cli/rules/no_spaces_in_columns.py
|
|
158
|
+
RULE_ID = "custom.no_spaces_in_columns"
|
|
159
|
+
|
|
160
|
+
def check(backend):
|
|
161
|
+
violations = []
|
|
162
|
+
for table in backend.table_list():
|
|
163
|
+
for col in backend.column_list(table["name"]):
|
|
164
|
+
if " " in col["name"]:
|
|
165
|
+
violations.append({
|
|
166
|
+
"rule": RULE_ID,
|
|
167
|
+
"object": f"{table['name']}.{col['name']}",
|
|
168
|
+
"message": "Column name contains a space.",
|
|
169
|
+
"severity": "warning",
|
|
170
|
+
"autoFixable": False,
|
|
171
|
+
})
|
|
172
|
+
return violations
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
pbi govern rules # lists all built-in + plugin rules
|
|
177
|
+
pbi govern check # exit code 1 on errors — use as a CI gate
|
|
178
|
+
pbi govern fix --auto
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## XMLA Backend
|
|
184
|
+
|
|
185
|
+
Connect to Power BI Premium or Fabric — no Desktop required:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from pbi_cli.backends.xmla_backend import XmlaBackend
|
|
189
|
+
|
|
190
|
+
b = XmlaBackend()
|
|
191
|
+
b.connect(
|
|
192
|
+
"powerbi://api.powerbi.com/v1.0/myorg/MySalesWorkspace",
|
|
193
|
+
catalog="MySalesDataset",
|
|
194
|
+
auth_mode="service_principal", # or "device_flow" / "token"
|
|
195
|
+
client_id=..., client_secret=..., tenant_id=...,
|
|
196
|
+
)
|
|
197
|
+
print(b.table_list())
|
|
198
|
+
print(b.dax_query("EVALUATE TOPN(5, Sales)"))
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Connection pooling is automatic — same `(endpoint, catalog)` pair reuses the live AMO Server object.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Skills
|
|
206
|
+
|
|
207
|
+
`pbi-enterprise-cli` ships **24 AI skill definitions** under `skills/` for use with Claude and other AI agents. Each skill encapsulates domain expertise for a specific Power BI area:
|
|
208
|
+
|
|
209
|
+
| Skill | Purpose |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `power-bi-dax` | Write, optimise, and test DAX expressions |
|
|
212
|
+
| `power-bi-modeling` | Design star schemas, relationships, and calculated columns |
|
|
213
|
+
| `power-bi-visuals` | Choose and configure the right visual for any scenario |
|
|
214
|
+
| `power-bi-report` | Page layout, bookmarks, and report UX patterns |
|
|
215
|
+
| `power-bi-governance` | Apply and enforce governance rules across a dataset |
|
|
216
|
+
| `power-bi-themes` | Generate and validate WCAG-compliant colour themes |
|
|
217
|
+
| `power-bi-sources` | Profile and scaffold data sources into star-schema models |
|
|
218
|
+
| `power-bi-security` | Define and validate RLS roles and row-level security |
|
|
219
|
+
| `power-bi-deployment` | Snapshot, diff, and deploy semantic models via XMLA |
|
|
220
|
+
| `power-bi-deployment-pipeline` | Orchestrate multi-stage deployment pipelines |
|
|
221
|
+
| `power-bi-filters` | Build and troubleshoot filter context |
|
|
222
|
+
| `power-bi-layout` | Auto-layout and spacing for report pages |
|
|
223
|
+
| `power-bi-partitions` | Manage incremental refresh and partition strategies |
|
|
224
|
+
| `power-bi-performance` | Diagnose and optimise query and refresh performance |
|
|
225
|
+
| `power-bi-testing` | Author and run DAX unit-test suites |
|
|
226
|
+
| `power-bi-diagnostics` | Interpret Doctor output and resolve environment issues |
|
|
227
|
+
| `power-bi-docs` | Generate and maintain data dictionaries |
|
|
228
|
+
| `power-bi-pages` | Add, rename, and reorder report pages |
|
|
229
|
+
| `power-bi-patterns` | Apply common Power BI design patterns |
|
|
230
|
+
| `power-bi-design-system` | Enforce colour, typography, and UX consistency |
|
|
231
|
+
| `power-bi-custom-visuals` | Import and configure custom visual packages |
|
|
232
|
+
| `power-bi-page-designer` | Interactive page composition and alignment |
|
|
233
|
+
| `power-bi-project-orchestrator` | Coordinate multi-skill Power BI projects end-to-end |
|
|
234
|
+
| `power-bi-troubleshooter` | Diagnose and fix common Power BI errors |
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## CI / CD
|
|
239
|
+
|
|
240
|
+
```yaml
|
|
241
|
+
# .github/workflows/pbi-governance.yml
|
|
242
|
+
name: PBI Governance
|
|
243
|
+
on: [push, pull_request]
|
|
244
|
+
jobs:
|
|
245
|
+
govern:
|
|
246
|
+
runs-on: ubuntu-latest
|
|
247
|
+
steps:
|
|
248
|
+
- uses: actions/checkout@v4
|
|
249
|
+
- uses: actions/setup-python@v5
|
|
250
|
+
with: { python-version: '3.12' }
|
|
251
|
+
- run: pip install "pbi-enterprise-cli[dev]"
|
|
252
|
+
- run: pbi --backend mock govern check
|
|
253
|
+
- run: pbi --backend mock dax test --suite tests/fixtures/
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Global Flags
|
|
259
|
+
|
|
260
|
+
These work with every command:
|
|
261
|
+
|
|
262
|
+
| Flag | Purpose |
|
|
263
|
+
|---|---|
|
|
264
|
+
| `--backend desktop\|xmla\|mock` | Select backend (default: `desktop`) |
|
|
265
|
+
| `--dry-run` | Preview changes without applying them |
|
|
266
|
+
| `--json` | Machine-readable JSON output |
|
|
267
|
+
| `--port 5000` | Desktop local server port |
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Environment Variables
|
|
272
|
+
|
|
273
|
+
| Variable | Purpose |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `ANTHROPIC_API_KEY` | Claude AI for `pbi measure generate` |
|
|
276
|
+
| `PBI_REST_BEARER` | Default Bearer token for REST source profiling |
|
|
277
|
+
| `PBI_CLIENT_ID` | AAD app client ID for XMLA service principal auth |
|
|
278
|
+
| `PBI_CLIENT_SECRET` | AAD app client secret |
|
|
279
|
+
| `PBI_TENANT_ID` | AAD tenant ID |
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Development
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
git clone https://github.com/mudassir09/pbi-enterprise-cli.git
|
|
287
|
+
cd pbi-enterprise-cli
|
|
288
|
+
pip install -e ".[all]"
|
|
289
|
+
|
|
290
|
+
# Run the full test suite (547 tests, ~4 s)
|
|
291
|
+
python -m pytest
|
|
292
|
+
|
|
293
|
+
# Lint
|
|
294
|
+
ruff check src/ tests/
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### CI notes
|
|
298
|
+
|
|
299
|
+
- All tests run on **Python 3.10, 3.11, and 3.12** via GitHub Actions on `ubuntu-latest`.
|
|
300
|
+
- `pbi doctor` works cross-platform — on Linux/macOS it gracefully reports pythonnet as unavailable instead of crashing.
|
|
301
|
+
- Coverage is measured on testable code only; `tom_backend.py` (requires Windows/.NET) and `server/api.py` (requires a live server) are excluded from the coverage gate. The enforced minimum is **65%**.
|
|
302
|
+
|
|
303
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for branch strategy and coding standards.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## License
|
|
308
|
+
|
|
309
|
+
[MIT](LICENSE) — © 2026 Mudassir
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# pbi-enterprise-cli
|
|
2
|
+
|
|
3
|
+
**Full-stack Power BI enterprise automation from the command line.**
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install pbi-enterprise-cli
|
|
7
|
+
pbi doctor # verify setup
|
|
8
|
+
pbi model tables # list tables in the connected model
|
|
9
|
+
pbi govern check # run governance rules
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Feature highlights
|
|
13
|
+
|
|
14
|
+
- **25 command groups** covering every layer of Power BI development
|
|
15
|
+
- **32 visual types** — from cards to decomposition trees
|
|
16
|
+
- **3 backends** — Desktop (TOM via pythonnet), XMLA (Premium/Fabric), Mock (CI)
|
|
17
|
+
- **PBIR GA format** — read and write `.pbip` project files directly
|
|
18
|
+
- **Governance engine** — 5 built-in rules + custom plugin system
|
|
19
|
+
- **REST source profiling** — Bearer/API-key auth, OData pagination, star-schema scaffold
|
|
20
|
+
- **REPL mode** — interactive session with tab completion and persistent history
|
|
21
|
+
- **Custom visual SDK** — scaffold, build, package, import `.pbiviz`
|
|
22
|
+
- **AI measure generation** — Claude API integration (requires `[ai]` extra)
|
|
23
|
+
- **24 AI skills** — install Claude Code skills (`pbi skills install --all`)
|
|
24
|
+
- **547 unit tests** passing on Python 3.10–3.12
|
|
25
|
+
|
|
26
|
+
## Install options
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install pbi-enterprise-cli # base
|
|
30
|
+
pip install "pbi-enterprise-cli[ai]" # + Claude AI
|
|
31
|
+
pip install "pbi-enterprise-cli[xmla]" # + MSAL auth for XMLA
|
|
32
|
+
pip install "pbi-enterprise-cli[sources]" # + SQL/Excel/REST profiling
|
|
33
|
+
pip install "pbi-enterprise-cli[all]" # everything
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Requirements
|
|
37
|
+
|
|
38
|
+
- Python 3.10+
|
|
39
|
+
- Windows (for Desktop/XMLA backends using .NET AMO)
|
|
40
|
+
- Power BI Desktop (for the `desktop` backend)
|
|
41
|
+
|
|
42
|
+
## Links
|
|
43
|
+
|
|
44
|
+
- [GitHub Repository](https://github.com/mudassir09/pbi-enterprise-cli)
|
|
45
|
+
- [Full Documentation](https://github.com/mudassir09/pbi-enterprise-cli#readme)
|
|
46
|
+
- [Changelog](https://github.com/mudassir09/pbi-enterprise-cli/blob/main/CHANGELOG.md)
|
|
47
|
+
- [Security Policy](https://github.com/mudassir09/pbi-enterprise-cli/blob/main/SECURITY.md)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pbi-enterprise-cli"
|
|
7
|
+
version = "0.1.0.dev0"
|
|
8
|
+
description = "Power BI enterprise CLI — AI-driven model management, governance, PBIR authoring, XMLA, and DAX testing"
|
|
9
|
+
readme = "README.pypi.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT AND LicenseRef-Microsoft-AS-Client-Libraries" }
|
|
12
|
+
keywords = ["power-bi", "cli", "dax", "tmdl", "pbir", "powerbi", "microsoft", "governance"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Mudassir", email = "mir.mudassir1@gmail.com" },
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Intended Audience :: Information Technology",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
"Topic :: Office/Business",
|
|
29
|
+
]
|
|
30
|
+
dependencies = [
|
|
31
|
+
"click>=8.1",
|
|
32
|
+
"rich>=13.0",
|
|
33
|
+
"pythonnet>=3.0",
|
|
34
|
+
"pydantic>=2.0",
|
|
35
|
+
"python-dotenv>=1.0",
|
|
36
|
+
"PyYAML>=6.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/mudassir09/pbi-enterprise-cli"
|
|
41
|
+
Repository = "https://github.com/mudassir09/pbi-enterprise-cli"
|
|
42
|
+
"Bug Tracker" = "https://github.com/mudassir09/pbi-enterprise-cli/issues"
|
|
43
|
+
Changelog = "https://github.com/mudassir09/pbi-enterprise-cli/blob/main/CHANGELOG.md"
|
|
44
|
+
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
ai = ["anthropic>=0.25"]
|
|
47
|
+
viz = ["Pillow>=10.0", "python-wcag-contrast-ratio>=1.0", "playwright>=1.44"]
|
|
48
|
+
xmla = ["msal>=1.28"]
|
|
49
|
+
server = ["fastapi>=0.110", "uvicorn>=0.29"]
|
|
50
|
+
sources = ["sqlalchemy>=2.0", "openpyxl>=3.1", "httpx>=0.27"]
|
|
51
|
+
dev = ["pytest>=7.0", "pytest-cov>=4.0", "ruff>=0.4.0", "mypy>=1.10"]
|
|
52
|
+
all = ["pbi-enterprise-cli[ai,viz,xmla,server,sources,dev]"]
|
|
53
|
+
|
|
54
|
+
[project.scripts]
|
|
55
|
+
pbi = "pbi_cli.cli:cli"
|
|
56
|
+
|
|
57
|
+
[tool.setuptools.packages.find]
|
|
58
|
+
where = ["src"]
|
|
59
|
+
|
|
60
|
+
[tool.ruff]
|
|
61
|
+
line-length = 100
|
|
62
|
+
target-version = "py310"
|
|
63
|
+
|
|
64
|
+
[tool.ruff.lint]
|
|
65
|
+
select = ["E", "F", "I", "UP"]
|
|
66
|
+
|
|
67
|
+
[tool.mypy]
|
|
68
|
+
python_version = "3.10"
|
|
69
|
+
ignore_missing_imports = true
|
|
70
|
+
warn_unused_ignores = false
|
|
71
|
+
# strict mode is disabled: backends use pythonnet/AMO dynamic dispatch (Any is intentional)
|
|
72
|
+
|
|
73
|
+
[tool.coverage.run]
|
|
74
|
+
omit = [
|
|
75
|
+
"src/pbi_cli/backends/tom_backend.py",
|
|
76
|
+
"src/pbi_cli/server/api.py",
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[tool.pytest.ini_options]
|
|
80
|
+
testpaths = ["tests"]
|
|
81
|
+
markers = ["e2e: requires live Power BI Desktop or XMLA endpoint"]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Append-only audit log for all pbi-cli write operations (Epic D6)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import datetime
|
|
6
|
+
import getpass
|
|
7
|
+
import json
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
_AUDIT_FILE = Path.home() / ".pbi-cli" / "audit.jsonl"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def write_audit_entry(
|
|
15
|
+
command: str,
|
|
16
|
+
before: Any = None,
|
|
17
|
+
after: Any = None,
|
|
18
|
+
extra: dict[str, Any] | None = None,
|
|
19
|
+
) -> None:
|
|
20
|
+
"""Append one JSON line to ~/.pbi-cli/audit.jsonl."""
|
|
21
|
+
_AUDIT_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
22
|
+
entry: dict[str, Any] = {
|
|
23
|
+
"timestamp": datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
|
24
|
+
"user": _get_user(),
|
|
25
|
+
"command": command,
|
|
26
|
+
}
|
|
27
|
+
if before is not None:
|
|
28
|
+
entry["before"] = before
|
|
29
|
+
if after is not None:
|
|
30
|
+
entry["after"] = after
|
|
31
|
+
if extra:
|
|
32
|
+
entry.update(extra)
|
|
33
|
+
with _AUDIT_FILE.open("a", encoding="utf-8") as f:
|
|
34
|
+
f.write(json.dumps(entry, default=str) + "\n")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def read_audit_log(limit: int = 50) -> list[dict[str, Any]]:
|
|
38
|
+
"""Return the last *limit* audit entries (most-recent last)."""
|
|
39
|
+
if not _AUDIT_FILE.exists():
|
|
40
|
+
return []
|
|
41
|
+
lines = _AUDIT_FILE.read_text(encoding="utf-8").splitlines()
|
|
42
|
+
entries = []
|
|
43
|
+
for line in lines:
|
|
44
|
+
line = line.strip()
|
|
45
|
+
if line:
|
|
46
|
+
try:
|
|
47
|
+
entries.append(json.loads(line))
|
|
48
|
+
except json.JSONDecodeError:
|
|
49
|
+
pass
|
|
50
|
+
return entries[-limit:]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _get_user() -> str:
|
|
54
|
+
try:
|
|
55
|
+
return getpass.getuser()
|
|
56
|
+
except Exception:
|
|
57
|
+
return "unknown"
|