llamactl 0.3.0a16__py3-none-any.whl → 0.3.0a18__py3-none-any.whl
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.
- llama_deploy/cli/commands/auth.py +4 -5
- llama_deploy/cli/commands/serve.py +111 -0
- llama_deploy/cli/config/_config.py +32 -3
- llama_deploy/cli/config/auth_service.py +1 -1
- llama_deploy/cli/config/env_service.py +2 -0
- {llamactl-0.3.0a16.dist-info → llamactl-0.3.0a18.dist-info}/METADATA +4 -4
- {llamactl-0.3.0a16.dist-info → llamactl-0.3.0a18.dist-info}/RECORD +9 -9
- {llamactl-0.3.0a16.dist-info → llamactl-0.3.0a18.dist-info}/WHEEL +0 -0
- {llamactl-0.3.0a16.dist-info → llamactl-0.3.0a18.dist-info}/entry_points.txt +0 -0
|
@@ -276,11 +276,10 @@ def validate_authenticated_profile(interactive: bool) -> Auth:
|
|
|
276
276
|
|
|
277
277
|
|
|
278
278
|
def _prompt_for_api_key() -> str:
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
rprint("[yellow]API key is required[/yellow]")
|
|
279
|
+
entered = questionary.password("Enter API key token").ask()
|
|
280
|
+
if entered:
|
|
281
|
+
return entered.strip()
|
|
282
|
+
raise click.ClickException("No API key entered")
|
|
284
283
|
|
|
285
284
|
|
|
286
285
|
def _validate_token_and_list_projects(
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
import os
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
import click
|
|
5
|
+
import questionary
|
|
4
6
|
from llama_deploy.appserver.app import (
|
|
5
7
|
prepare_server,
|
|
6
8
|
start_server_in_target_venv,
|
|
7
9
|
)
|
|
10
|
+
from llama_deploy.appserver.workflow_loader import parse_environment_variables
|
|
11
|
+
from llama_deploy.cli.commands.auth import validate_authenticated_profile
|
|
12
|
+
from llama_deploy.cli.config.env_service import service
|
|
13
|
+
from llama_deploy.cli.config.schema import Auth
|
|
14
|
+
from llama_deploy.cli.options import interactive_option
|
|
8
15
|
from llama_deploy.core.config import DEFAULT_DEPLOYMENT_FILE_PATH
|
|
16
|
+
from llama_deploy.core.deployment_config import (
|
|
17
|
+
read_deployment_config_from_git_root_or_cwd,
|
|
18
|
+
)
|
|
9
19
|
from rich import print as rprint
|
|
10
20
|
|
|
11
21
|
from ..app import app
|
|
@@ -47,6 +57,7 @@ from ..app import app
|
|
|
47
57
|
type=click.Choice(["console", "json"], case_sensitive=False),
|
|
48
58
|
help="The format to use for logging",
|
|
49
59
|
)
|
|
60
|
+
@interactive_option
|
|
50
61
|
def serve(
|
|
51
62
|
deployment_file: Path,
|
|
52
63
|
no_install: bool,
|
|
@@ -57,6 +68,7 @@ def serve(
|
|
|
57
68
|
ui_port: int | None = None,
|
|
58
69
|
log_level: str | None = None,
|
|
59
70
|
log_format: str | None = None,
|
|
71
|
+
interactive: bool = False,
|
|
60
72
|
) -> None:
|
|
61
73
|
"""Run llama_deploy API Server in the foreground. Reads the deployment configuration from the current directory. Can optionally specify a deployment file path."""
|
|
62
74
|
if not deployment_file.exists():
|
|
@@ -64,7 +76,11 @@ def serve(
|
|
|
64
76
|
raise click.Abort()
|
|
65
77
|
|
|
66
78
|
try:
|
|
79
|
+
# Pre-check: if the template requires llama cloud access, ensure credentials
|
|
80
|
+
_maybe_inject_llama_cloud_credentials(deployment_file, interactive)
|
|
81
|
+
|
|
67
82
|
prepare_server(
|
|
83
|
+
deployment_file=deployment_file,
|
|
68
84
|
install=not no_install,
|
|
69
85
|
build=preview,
|
|
70
86
|
)
|
|
@@ -86,3 +102,98 @@ def serve(
|
|
|
86
102
|
except Exception as e:
|
|
87
103
|
rprint(f"[red]Error: {e}[/red]")
|
|
88
104
|
raise click.Abort()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _set_env_vars_from_profile(profile: Auth):
|
|
108
|
+
if profile.api_key:
|
|
109
|
+
_set_env_vars(profile.api_key, profile.api_url)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _set_env_vars_from_env(env_vars: dict[str, str]):
|
|
113
|
+
key = env_vars.get("LLAMA_CLOUD_API_KEY")
|
|
114
|
+
url = env_vars.get("LLAMA_CLOUD_BASE_URL", "https://api.cloud.llamaindex.ai")
|
|
115
|
+
if key:
|
|
116
|
+
_set_env_vars(key, url)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _set_env_vars(key: str, url: str):
|
|
120
|
+
print(f"Setting env vars: {key}, {url}")
|
|
121
|
+
os.environ["LLAMA_CLOUD_API_KEY"] = key
|
|
122
|
+
os.environ["LLAMA_CLOUD_BASE_URL"] = url
|
|
123
|
+
# kludge for common web servers to inject local auth key
|
|
124
|
+
for prefix in ["VITE_", "NEXT_PUBLIC_"]:
|
|
125
|
+
os.environ[f"{prefix}LLAMA_CLOUD_API_KEY"] = key
|
|
126
|
+
os.environ[f"{prefix}LLAMA_CLOUD_BASE_URL"] = url
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _maybe_inject_llama_cloud_credentials(
|
|
130
|
+
deployment_file: Path, interactive: bool
|
|
131
|
+
) -> None:
|
|
132
|
+
"""If the deployment config indicates Llama Cloud usage, ensure LLAMA_CLOUD_API_KEY is set.
|
|
133
|
+
|
|
134
|
+
Behavior:
|
|
135
|
+
- If LLAMA_CLOUD_API_KEY is already set, do nothing.
|
|
136
|
+
- Else, try to read current profile's api_key and inject.
|
|
137
|
+
- If no profile/api_key and session is interactive, prompt to log in and inject afterward.
|
|
138
|
+
- If user declines or session is non-interactive, warn that deployment may not work.
|
|
139
|
+
"""
|
|
140
|
+
# Read config directly to avoid cached global settings
|
|
141
|
+
try:
|
|
142
|
+
config = read_deployment_config_from_git_root_or_cwd(
|
|
143
|
+
Path.cwd(), deployment_file
|
|
144
|
+
)
|
|
145
|
+
except Exception:
|
|
146
|
+
rprint(
|
|
147
|
+
"[red]Error: Could not read a deployment config. This doesn't appear to be a valid llama-deploy project.[/red]"
|
|
148
|
+
)
|
|
149
|
+
raise click.Abort()
|
|
150
|
+
|
|
151
|
+
if not config.llama_cloud:
|
|
152
|
+
return
|
|
153
|
+
|
|
154
|
+
vars = parse_environment_variables(
|
|
155
|
+
config, deployment_file.parent if deployment_file.is_file() else deployment_file
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
existing = os.environ.get("LLAMA_CLOUD_API_KEY") or vars.get("LLAMA_CLOUD_API_KEY")
|
|
159
|
+
if existing:
|
|
160
|
+
_set_env_vars_from_env({**os.environ, **vars})
|
|
161
|
+
return
|
|
162
|
+
|
|
163
|
+
env = service.get_current_environment()
|
|
164
|
+
if not env.requires_auth:
|
|
165
|
+
rprint(
|
|
166
|
+
"[yellow]Warning: This app requires Llama Cloud authentication, and no LLAMA_CLOUD_API_KEY is present. The app may not work.[/yellow]"
|
|
167
|
+
)
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
auth_svc = service.current_auth_service()
|
|
171
|
+
profile = auth_svc.get_current_profile()
|
|
172
|
+
if profile and profile.api_key:
|
|
173
|
+
_set_env_vars_from_profile(profile)
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
# No key available; consider prompting if interactive
|
|
177
|
+
if interactive:
|
|
178
|
+
should_login = questionary.confirm(
|
|
179
|
+
"This deployment requires Llama Cloud. Login now to inject credentials?",
|
|
180
|
+
default=True,
|
|
181
|
+
).ask()
|
|
182
|
+
if should_login:
|
|
183
|
+
try:
|
|
184
|
+
authed = validate_authenticated_profile(True)
|
|
185
|
+
if authed.api_key:
|
|
186
|
+
_set_env_vars_from_profile(authed)
|
|
187
|
+
return
|
|
188
|
+
except Exception:
|
|
189
|
+
# fall through to warning
|
|
190
|
+
pass
|
|
191
|
+
rprint(
|
|
192
|
+
"[yellow]Warning: No Llama Cloud credentials configured. The app may not work.[/yellow]"
|
|
193
|
+
)
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
# Non-interactive session
|
|
197
|
+
rprint(
|
|
198
|
+
"[yellow]Warning: LLAMA_CLOUD_API_KEY is not set and no logged-in profile was found. The deployment may not work.[/yellow]"
|
|
199
|
+
)
|
|
@@ -79,13 +79,40 @@ class ConfigManager:
|
|
|
79
79
|
if "api_key" not in mig_columns:
|
|
80
80
|
conn.execute("ALTER TABLE profiles ADD COLUMN api_key TEXT")
|
|
81
81
|
|
|
82
|
+
# Migration: change profiles primary key from name to composite (name, api_url)
|
|
83
|
+
# Only perform if the table exists with single-column PK on name
|
|
84
|
+
pk_info_cur = conn.execute("PRAGMA table_info(profiles)")
|
|
85
|
+
pk_info_rows = pk_info_cur.fetchall()
|
|
86
|
+
pk_columns = [row[1] for row in pk_info_rows if len(row) > 5 and row[5] > 0]
|
|
87
|
+
if pk_columns == ["name"] and "api_url" in columns:
|
|
88
|
+
conn.execute("ALTER TABLE profiles RENAME TO profiles_old")
|
|
89
|
+
conn.execute(
|
|
90
|
+
"""
|
|
91
|
+
CREATE TABLE profiles (
|
|
92
|
+
name TEXT NOT NULL,
|
|
93
|
+
api_url TEXT NOT NULL,
|
|
94
|
+
project_id TEXT NOT NULL,
|
|
95
|
+
api_key TEXT,
|
|
96
|
+
PRIMARY KEY (name, api_url)
|
|
97
|
+
)
|
|
98
|
+
"""
|
|
99
|
+
)
|
|
100
|
+
conn.execute(
|
|
101
|
+
"""
|
|
102
|
+
INSERT INTO profiles (name, api_url, project_id, api_key)
|
|
103
|
+
SELECT name, api_url, project_id, api_key FROM profiles_old
|
|
104
|
+
"""
|
|
105
|
+
)
|
|
106
|
+
conn.execute("DROP TABLE profiles_old")
|
|
107
|
+
|
|
82
108
|
# Create tables with new schema (this will only create if they don't exist)
|
|
83
109
|
conn.execute("""
|
|
84
110
|
CREATE TABLE IF NOT EXISTS profiles (
|
|
85
|
-
name TEXT
|
|
111
|
+
name TEXT NOT NULL,
|
|
86
112
|
api_url TEXT NOT NULL,
|
|
87
113
|
project_id TEXT NOT NULL,
|
|
88
|
-
api_key TEXT
|
|
114
|
+
api_key TEXT,
|
|
115
|
+
PRIMARY KEY (name, api_url)
|
|
89
116
|
)
|
|
90
117
|
""")
|
|
91
118
|
|
|
@@ -177,7 +204,9 @@ class ConfigManager:
|
|
|
177
204
|
)
|
|
178
205
|
conn.commit()
|
|
179
206
|
except sqlite3.IntegrityError:
|
|
180
|
-
raise ValueError(
|
|
207
|
+
raise ValueError(
|
|
208
|
+
f"Profile '{name}' already exists for environment '{api_url}'"
|
|
209
|
+
)
|
|
181
210
|
|
|
182
211
|
return profile
|
|
183
212
|
|
|
@@ -30,6 +30,8 @@ class EnvService:
|
|
|
30
30
|
self.config_manager.create_or_update_environment(
|
|
31
31
|
env.api_url, env.requires_auth, env.min_llamactl_version
|
|
32
32
|
)
|
|
33
|
+
self.config_manager.set_settings_current_environment(env.api_url)
|
|
34
|
+
self.config_manager.set_settings_current_profile(None)
|
|
33
35
|
|
|
34
36
|
def delete_environment(self, api_url: str) -> bool:
|
|
35
37
|
return self.config_manager.delete_environment(api_url)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: llamactl
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.0a18
|
|
4
4
|
Summary: A command-line interface for managing LlamaDeploy projects and deployments
|
|
5
5
|
Author: Adrian Lyjak
|
|
6
6
|
Author-email: Adrian Lyjak <adrianlyjak@gmail.com>
|
|
7
7
|
License: MIT
|
|
8
|
-
Requires-Dist: llama-deploy-core[client]>=0.3.
|
|
9
|
-
Requires-Dist: llama-deploy-appserver>=0.3.
|
|
10
|
-
Requires-Dist: httpx>=0.24.0
|
|
8
|
+
Requires-Dist: llama-deploy-core[client]>=0.3.0a18,<0.4.0
|
|
9
|
+
Requires-Dist: llama-deploy-appserver>=0.3.0a18,<0.4.0
|
|
10
|
+
Requires-Dist: httpx>=0.24.0,<1.0.0
|
|
11
11
|
Requires-Dist: rich>=13.0.0
|
|
12
12
|
Requires-Dist: questionary>=2.0.0
|
|
13
13
|
Requires-Dist: click>=8.2.1
|
|
@@ -2,14 +2,14 @@ llama_deploy/cli/__init__.py,sha256=df028686233c4d5a3e244bb50c1c7b84cf2399ae03ab
|
|
|
2
2
|
llama_deploy/cli/app.py,sha256=9170e4f506c482522bd745eb1cdb700a198cfcfd7204c168c94e5ee2b6b43ffa,2199
|
|
3
3
|
llama_deploy/cli/client.py,sha256=f0f72c90cddfbc9198e154883f3b8f05fb47dbe7ec1f5755106dbb8009d2bb54,1459
|
|
4
4
|
llama_deploy/cli/commands/aliased_group.py,sha256=bc41007c97b7b93981217dbd4d4591df2b6c9412a2d9ed045b0ec5655ed285f2,1066
|
|
5
|
-
llama_deploy/cli/commands/auth.py,sha256=
|
|
5
|
+
llama_deploy/cli/commands/auth.py,sha256=da8ad888a199955b8c970e84e6933c92211a1c823e77ec6d746ed994e09c7adf,12610
|
|
6
6
|
llama_deploy/cli/commands/deployment.py,sha256=ae6e20c216edf51df94cd66397743076bb97ee2b64bccd14e602e9642fe6befd,9980
|
|
7
7
|
llama_deploy/cli/commands/env.py,sha256=e0b96b9f4e7921b4370ad5f8bc0a2bfb19b705e73004f72c37c9bed28a208e0d,6702
|
|
8
8
|
llama_deploy/cli/commands/init.py,sha256=51b2de1e35ff34bc15c9dfec72fbad08aaf528c334df168896d36458a4e9401c,6307
|
|
9
|
-
llama_deploy/cli/commands/serve.py,sha256=
|
|
10
|
-
llama_deploy/cli/config/_config.py,sha256=
|
|
11
|
-
llama_deploy/cli/config/auth_service.py,sha256=
|
|
12
|
-
llama_deploy/cli/config/env_service.py,sha256=
|
|
9
|
+
llama_deploy/cli/commands/serve.py,sha256=1841c9c63fdd6616b28f36ab899582bfd5b513ed77f3d176e99ccaa8bdd7944a,6775
|
|
10
|
+
llama_deploy/cli/config/_config.py,sha256=91caae934d27f2b956156a4e9f5df151692786e139e7e13611961df0dd67a3b5,16287
|
|
11
|
+
llama_deploy/cli/config/auth_service.py,sha256=d1c978e1249276285db7aa7b490ca3f6d06e892c0cb171bdbe08799fe55d1d40,2664
|
|
12
|
+
llama_deploy/cli/config/env_service.py,sha256=d8583b1632aec33c74bfe62fa5f3489161dbc00edbfb317f24907a0bc8ac671b,2582
|
|
13
13
|
llama_deploy/cli/config/schema.py,sha256=086b6161b238c2037068a2b510f5d4bbda917494df764818ff9692e9735a8953,608
|
|
14
14
|
llama_deploy/cli/debug.py,sha256=e85a72d473bbe1645eb31772f7349bde703d45704166f767385895c440afc762,496
|
|
15
15
|
llama_deploy/cli/env.py,sha256=6ebc24579815b3787829c81fd5bb9f31698a06e62c0128a788559f962b33a7af,1016
|
|
@@ -26,7 +26,7 @@ llama_deploy/cli/textual/github_callback_server.py,sha256=dc74c510f8a98ef6ffaab0
|
|
|
26
26
|
llama_deploy/cli/textual/llama_loader.py,sha256=33cb32a46dd40bcf889c553e44f2672c410e26bd1d4b17aa6cca6d0a5d59c2c4,1468
|
|
27
27
|
llama_deploy/cli/textual/secrets_form.py,sha256=a43fbd81aad034d0d60906bfd917c107f9ace414648b0f63ac0b29eeba4050db,7061
|
|
28
28
|
llama_deploy/cli/textual/styles.tcss,sha256=b1a54dc5fb0e0aa12cbf48807e9e6a94b9926838b8058dae1336a134f02e92b0,3327
|
|
29
|
-
llamactl-0.3.
|
|
30
|
-
llamactl-0.3.
|
|
31
|
-
llamactl-0.3.
|
|
32
|
-
llamactl-0.3.
|
|
29
|
+
llamactl-0.3.0a18.dist-info/WHEEL,sha256=66530aef82d5020ef5af27ae0123c71abb9261377c5bc519376c671346b12918,79
|
|
30
|
+
llamactl-0.3.0a18.dist-info/entry_points.txt,sha256=b67e1eb64305058751a651a80f2d2268b5f7046732268421e796f64d4697f83c,52
|
|
31
|
+
llamactl-0.3.0a18.dist-info/METADATA,sha256=a7089a1d4aac69fdc32c230ea89700ec038b320d8a8e297c908bf01b3c7ede2a,3184
|
|
32
|
+
llamactl-0.3.0a18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|