-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.py
More file actions
96 lines (73 loc) · 3.1 KB
/
main.py
File metadata and controls
96 lines (73 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import json
import os
import re
from pathlib import Path
import click
from dotenv import load_dotenv
from datapilot import __version__
from datapilot.core.knowledge.cli import cli as knowledge
from datapilot.core.mcp_utils.mcp import mcp
from datapilot.core.platforms.dbt.cli.cli import dbt
def load_config_from_file():
"""Load configuration from ~/.altimate/altimate.json if it exists."""
config_path = Path.home() / ".altimate" / "altimate.json"
if not config_path.exists():
return {}
try:
with config_path.open() as f:
config = json.load(f)
return config
except (OSError, json.JSONDecodeError) as e:
click.echo(f"Warning: Failed to load config from {config_path}: {e}", err=True)
return {}
def substitute_env_vars(value):
"""Replace ${env:ENV_VARIABLE} patterns with actual environment variable values."""
if not isinstance(value, str):
return value
# Pattern to match ${env:VARIABLE_NAME}
pattern = r"\$\{env:([^}]+)\}"
def replacer(match):
env_var = match.group(1)
return os.environ.get(env_var, match.group(0))
return re.sub(pattern, replacer, value)
def process_config(config):
"""Process configuration dictionary to substitute environment variables."""
processed = {}
for key, value in config.items():
processed[key] = substitute_env_vars(value)
return processed
@click.group()
@click.version_option(version=__version__, prog_name="datapilot")
@click.option("--token", required=False, help="Your API token for authentication.", hide_input=True)
@click.option("--instance-name", required=False, help="Your tenant ID.")
@click.option("--backend-url", required=False, help="Altimate's Backend URL", default="https://api.myaltimate.com")
@click.pass_context
def datapilot(ctx, token, instance_name, backend_url):
"""Altimate CLI for DBT project management."""
# Load .env file from current directory if it exists
load_dotenv()
# Load configuration from file
file_config = load_config_from_file()
file_config = process_config(file_config)
# Map config file keys to CLI option names
config_mapping = {"altimateApiKey": "token", "altimateInstanceName": "instance_name", "altimateUrl": "backend_url"}
# Store common options in context, with CLI args taking precedence
ctx.ensure_object(dict)
# Apply file config first
for file_key, cli_key in config_mapping.items():
if file_key in file_config:
ctx.obj[cli_key] = file_config[file_key]
# Override with CLI arguments if provided
if token is not None:
ctx.obj["token"] = token
if instance_name is not None:
ctx.obj["instance_name"] = instance_name
if backend_url != "https://api.myaltimate.com": # Only override if not default
ctx.obj["backend_url"] = backend_url
# Set defaults if nothing was provided
ctx.obj.setdefault("token", None)
ctx.obj.setdefault("instance_name", None)
ctx.obj.setdefault("backend_url", "https://api.myaltimate.com")
datapilot.add_command(dbt)
datapilot.add_command(mcp)
datapilot.add_command(knowledge)