mirror of
https://github.com/MinaSaad1/pbi-cli
synced 2026-04-21 13:37:19 +00:00
feat: auto-discover Power BI Desktop port, making -d optional on connect
This commit is contained in:
parent
62b2305909
commit
6f0f1afa61
3 changed files with 84 additions and 6 deletions
|
|
@ -41,11 +41,13 @@ Install and set up pbi-cli from https://github.com/MinaSaad1/pbi-cli.git
|
|||
**Or install manually (two commands):**
|
||||
|
||||
```bash
|
||||
pipx install pbi-cli-tool # 1. Install (handles PATH automatically)
|
||||
pbi connect -d localhost:54321 # 2. Connect (auto-downloads binary + installs skills)
|
||||
pipx install pbi-cli-tool # 1. Install (handles PATH automatically)
|
||||
pbi connect # 2. Auto-detects Power BI Desktop, downloads binary, installs skills
|
||||
```
|
||||
|
||||
That's it. The first `connect` automatically downloads the MCP binary and installs Claude Code skills. Open Claude Code and start asking.
|
||||
That's it. Open Power BI Desktop with a `.pbix` file, run `pbi connect`, and everything is set up automatically. Open Claude Code and start asking.
|
||||
|
||||
You can also specify the port manually: `pbi connect -d localhost:54321`
|
||||
|
||||
> **Requires:** Python 3.10+ and Power BI Desktop (local) or a Fabric workspace (cloud).
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,12 @@ from pbi_cli.main import PbiContext, pass_context
|
|||
|
||||
|
||||
@click.command()
|
||||
@click.option("--data-source", "-d", required=True, help="Data source (e.g., localhost:54321).")
|
||||
@click.option(
|
||||
"--data-source",
|
||||
"-d",
|
||||
default=None,
|
||||
help="Data source (e.g., localhost:54321). Auto-detected if omitted.",
|
||||
)
|
||||
@click.option("--catalog", "-C", default="", help="Initial catalog / dataset name.")
|
||||
@click.option(
|
||||
"--name", "-n", default=None, help="Name for this connection (auto-generated if omitted)."
|
||||
|
|
@ -33,11 +38,21 @@ from pbi_cli.main import PbiContext, pass_context
|
|||
)
|
||||
@pass_context
|
||||
def connect(
|
||||
ctx: PbiContext, data_source: str, catalog: str, name: str | None, connection_string: str
|
||||
ctx: PbiContext,
|
||||
data_source: str | None,
|
||||
catalog: str,
|
||||
name: str | None,
|
||||
connection_string: str,
|
||||
) -> None:
|
||||
"""Connect to a Power BI instance via data source."""
|
||||
"""Connect to a Power BI instance via data source.
|
||||
|
||||
If --data-source is omitted, auto-detects a running Power BI Desktop instance.
|
||||
"""
|
||||
_ensure_ready()
|
||||
|
||||
if data_source is None:
|
||||
data_source = _auto_discover_data_source()
|
||||
|
||||
conn_name = name or _auto_name(data_source)
|
||||
|
||||
request: dict[str, object] = {
|
||||
|
|
@ -233,6 +248,27 @@ def connections_last(ctx: PbiContext) -> None:
|
|||
)
|
||||
|
||||
|
||||
def _auto_discover_data_source() -> str:
|
||||
"""Auto-detect a running Power BI Desktop instance.
|
||||
|
||||
Raises click.ClickException if no instance is found.
|
||||
"""
|
||||
from pbi_cli.core.output import print_info
|
||||
from pbi_cli.utils.platform import discover_pbi_port
|
||||
|
||||
port = discover_pbi_port()
|
||||
if port is None:
|
||||
raise click.ClickException(
|
||||
"No running Power BI Desktop instance found.\n"
|
||||
" 1. Open Power BI Desktop and load a .pbix file\n"
|
||||
" 2. Run 'pbi connect' again, or specify manually: pbi connect -d localhost:<port>"
|
||||
)
|
||||
|
||||
data_source = f"localhost:{port}"
|
||||
print_info(f"Auto-detected Power BI Desktop on {data_source}")
|
||||
return data_source
|
||||
|
||||
|
||||
def _ensure_ready() -> None:
|
||||
"""Auto-setup binary and skills if not already done.
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,46 @@ def ensure_executable(path: Path) -> None:
|
|||
path.chmod(current | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||
|
||||
|
||||
def discover_pbi_port() -> int | None:
|
||||
"""Find the port of a running Power BI Desktop instance.
|
||||
|
||||
Power BI Desktop writes its XMLA port to a file at:
|
||||
%LOCALAPPDATA%/Microsoft/Power BI Desktop/AnalysisServicesWorkspaces/
|
||||
AnalysisServicesWorkspace_*/Data/msmdsrv.port.txt
|
||||
|
||||
Returns the port number, or None if Power BI Desktop is not running.
|
||||
"""
|
||||
if platform.system() != "Windows":
|
||||
return None
|
||||
|
||||
import os
|
||||
|
||||
local_app_data = os.environ.get("LOCALAPPDATA", "")
|
||||
if not local_app_data:
|
||||
return None
|
||||
|
||||
workspaces_dir = (
|
||||
Path(local_app_data) / "Microsoft" / "Power BI Desktop" / "AnalysisServicesWorkspaces"
|
||||
)
|
||||
if not workspaces_dir.exists():
|
||||
return None
|
||||
|
||||
# Find all port files, pick the most recently modified (latest instance)
|
||||
port_files = sorted(
|
||||
workspaces_dir.glob("*/Data/msmdsrv.port.txt"),
|
||||
key=lambda p: p.stat().st_mtime,
|
||||
reverse=True,
|
||||
)
|
||||
if not port_files:
|
||||
return None
|
||||
|
||||
try:
|
||||
port_text = port_files[0].read_text(encoding="utf-8").strip()
|
||||
return int(port_text)
|
||||
except (ValueError, OSError):
|
||||
return None
|
||||
|
||||
|
||||
def find_vscode_extension_binary() -> Path | None:
|
||||
"""Look for the binary in the VS Code extension install directory.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue