jvcli 2.0.18__py3-none-any.whl → 2.0.20__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.
- jvcli/__init__.py +1 -1
- jvcli/auth.py +23 -0
- jvcli/cli.py +4 -0
- jvcli/commands/clean.py +29 -0
- jvcli/commands/server.py +260 -0
- jvcli/commands/startproject.py +0 -1
- jvcli/templates/2.0.0/project/README.md +509 -16
- jvcli/templates/2.0.0/project/env.example +4 -3
- jvcli/utils.py +26 -0
- jvcli-2.0.20.dist-info/METADATA +644 -0
- {jvcli-2.0.18.dist-info → jvcli-2.0.20.dist-info}/RECORD +15 -20
- {jvcli-2.0.18.dist-info → jvcli-2.0.20.dist-info}/WHEEL +1 -1
- jvcli/templates/2.0.0/project/sh/exportenv.sh +0 -12
- jvcli/templates/2.0.0/project/sh/importagent.sh +0 -47
- jvcli/templates/2.0.0/project/sh/initagents.sh +0 -37
- jvcli/templates/2.0.0/project/sh/inituser.sh +0 -50
- jvcli/templates/2.0.0/project/sh/jacclean.sh +0 -11
- jvcli/templates/2.0.0/project/sh/serve.sh +0 -7
- jvcli/templates/2.0.0/project/sh/startclient.sh +0 -7
- jvcli-2.0.18.dist-info/METADATA +0 -128
- {jvcli-2.0.18.dist-info → jvcli-2.0.20.dist-info}/entry_points.txt +0 -0
- {jvcli-2.0.18.dist-info → jvcli-2.0.20.dist-info}/licenses/LICENSE +0 -0
- {jvcli-2.0.18.dist-info → jvcli-2.0.20.dist-info}/top_level.txt +0 -0
jvcli/__init__.py
CHANGED
jvcli/auth.py
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
import json
|
4
4
|
import os
|
5
5
|
|
6
|
+
import requests
|
7
|
+
|
6
8
|
TOKEN_FILE = os.path.expanduser("~/.jvcli_token")
|
7
9
|
|
8
10
|
|
@@ -43,3 +45,24 @@ def load_namespaces() -> str:
|
|
43
45
|
"""Load the namespaces from the token."""
|
44
46
|
token = load_token()
|
45
47
|
return token.get("namespaces", {}).get("default", "anonymous")
|
48
|
+
|
49
|
+
|
50
|
+
def login_jivas() -> str:
|
51
|
+
"""Login to Jivas and return the token."""
|
52
|
+
email = os.environ.get("JIVAS_USER")
|
53
|
+
password = os.environ.get("JIVAS_PASSWORD")
|
54
|
+
if not email or not password:
|
55
|
+
raise ValueError(
|
56
|
+
"JIVAS_USER and JIVAS_PASSWORD environment variables are required."
|
57
|
+
)
|
58
|
+
|
59
|
+
login_url = (
|
60
|
+
f"{os.environ.get('JIVAS_BASE_URL', 'http://localhost:8000')}/user/login"
|
61
|
+
)
|
62
|
+
response = requests.post(login_url, json={"email": email, "password": password})
|
63
|
+
if response.status_code == 200:
|
64
|
+
data = response.json()
|
65
|
+
os.environ["JIVAS_TOKEN"] = data["token"]
|
66
|
+
return data["token"]
|
67
|
+
else:
|
68
|
+
raise ValueError(f"Login failed: {response.text}")
|
jvcli/cli.py
CHANGED
@@ -4,11 +4,13 @@ import click
|
|
4
4
|
|
5
5
|
from jvcli import __version__
|
6
6
|
from jvcli.commands.auth import login, logout, signup
|
7
|
+
from jvcli.commands.clean import clean
|
7
8
|
from jvcli.commands.client import client
|
8
9
|
from jvcli.commands.create import create
|
9
10
|
from jvcli.commands.download import download
|
10
11
|
from jvcli.commands.info import info
|
11
12
|
from jvcli.commands.publish import publish
|
13
|
+
from jvcli.commands.server import server
|
12
14
|
from jvcli.commands.startproject import startproject
|
13
15
|
from jvcli.commands.studio import studio
|
14
16
|
from jvcli.commands.update import update
|
@@ -30,6 +32,8 @@ jvcli.add_command(info)
|
|
30
32
|
jvcli.add_command(studio)
|
31
33
|
jvcli.add_command(client)
|
32
34
|
jvcli.add_command(startproject)
|
35
|
+
jvcli.add_command(clean)
|
36
|
+
jvcli.add_command(server)
|
33
37
|
|
34
38
|
# Register standalone commands
|
35
39
|
jvcli.add_command(signup)
|
jvcli/commands/clean.py
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
"""Runs the jac clean command"""
|
2
|
+
|
3
|
+
import subprocess
|
4
|
+
|
5
|
+
import click
|
6
|
+
|
7
|
+
|
8
|
+
@click.command(
|
9
|
+
help="Clean the Jac files in the current directory and subdirectories. This command executes 'jac clean', which removes compiled Jac artifacts and temporary files. "
|
10
|
+
"Use this command to ensure a clean state before rebuilding your Jac project."
|
11
|
+
)
|
12
|
+
@click.pass_context
|
13
|
+
def clean(ctx: click.Context) -> None:
|
14
|
+
"""Clean the Jac files in directory."""
|
15
|
+
try:
|
16
|
+
click.echo("Running jac clean in actions directory...")
|
17
|
+
result = subprocess.run(["jac", "clean"], check=True)
|
18
|
+
if result.returncode == 0:
|
19
|
+
click.echo("Successfully cleaned directory.")
|
20
|
+
|
21
|
+
else:
|
22
|
+
click.secho("Failed to clean directory.", fg="red")
|
23
|
+
ctx.exit(1)
|
24
|
+
except subprocess.CalledProcessError as e:
|
25
|
+
click.secho(f"Error running jac clean: {e}", fg="red")
|
26
|
+
ctx.exit(1)
|
27
|
+
except Exception as e:
|
28
|
+
click.secho(f"Unexpected error: {e}", fg="red")
|
29
|
+
ctx.exit(1)
|
jvcli/commands/server.py
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
"""Server command group for interfacing with the Jivas Server."""
|
2
|
+
|
3
|
+
import json
|
4
|
+
import os
|
5
|
+
import subprocess
|
6
|
+
import sys
|
7
|
+
from typing import Optional
|
8
|
+
|
9
|
+
import click
|
10
|
+
import requests
|
11
|
+
|
12
|
+
from jvcli.auth import login_jivas
|
13
|
+
from jvcli.commands.clean import clean
|
14
|
+
from jvcli.utils import is_server_running, load_env_if_present
|
15
|
+
|
16
|
+
load_env_if_present()
|
17
|
+
|
18
|
+
|
19
|
+
@click.group()
|
20
|
+
def server() -> None:
|
21
|
+
"""Group for interfacing with the Jivas Server."""
|
22
|
+
pass # pragma: no cover
|
23
|
+
|
24
|
+
|
25
|
+
@server.command()
|
26
|
+
@click.option(
|
27
|
+
"--jac-file",
|
28
|
+
default="main.jac",
|
29
|
+
help="Path to the JAC file to run. Defaults to main.jac in the current directory.",
|
30
|
+
)
|
31
|
+
def launch(jac_file: str) -> None:
|
32
|
+
"""Launch the Jivas Server by running the specified JAC file."""
|
33
|
+
click.echo(f"Launching Jivas Server with JAC file: {jac_file}...")
|
34
|
+
subprocess.call(["jac", "jvserve", jac_file])
|
35
|
+
|
36
|
+
|
37
|
+
@server.command()
|
38
|
+
@click.option(
|
39
|
+
"--email",
|
40
|
+
required=False,
|
41
|
+
help="Email address for Jivas login.",
|
42
|
+
)
|
43
|
+
@click.option(
|
44
|
+
"--password",
|
45
|
+
required=False,
|
46
|
+
hide_input=True,
|
47
|
+
help="Password for Jivas login.",
|
48
|
+
)
|
49
|
+
def login(email: Optional[str] = None, password: Optional[str] = None) -> Optional[str]:
|
50
|
+
"""Login to Jivas Server and get an authentication token."""
|
51
|
+
email = os.environ.get("JIVAS_USER") or email
|
52
|
+
password = os.environ.get("JIVAS_PASSWORD") or password
|
53
|
+
|
54
|
+
if email is None:
|
55
|
+
email = click.prompt("Email")
|
56
|
+
if password is None:
|
57
|
+
password = click.prompt("Password", hide_input=True)
|
58
|
+
|
59
|
+
click.echo(f"Logging in to Jivas Server as {email}...")
|
60
|
+
|
61
|
+
login_url = (
|
62
|
+
f"{os.environ.get('JIVAS_BASE_URL', 'http://localhost:8000')}/user/login"
|
63
|
+
)
|
64
|
+
|
65
|
+
try:
|
66
|
+
response = requests.post(login_url, json={"email": email, "password": password})
|
67
|
+
if response.status_code == 200:
|
68
|
+
data = response.json()
|
69
|
+
token = data["token"]
|
70
|
+
os.environ["JIVAS_TOKEN"] = token
|
71
|
+
click.secho("Login successful!", fg="green", bold=True)
|
72
|
+
click.echo(f"Token: {token}")
|
73
|
+
return token
|
74
|
+
else:
|
75
|
+
click.secho(f"Login failed: {response.text}", fg="red", bold=True)
|
76
|
+
return None
|
77
|
+
except Exception as e:
|
78
|
+
click.secho(f"Error connecting to Jivas Server: {str(e)}", fg="red", bold=True)
|
79
|
+
return None
|
80
|
+
|
81
|
+
|
82
|
+
@server.command()
|
83
|
+
@click.option(
|
84
|
+
"--email",
|
85
|
+
required=False,
|
86
|
+
help="Email address for the system admin.",
|
87
|
+
)
|
88
|
+
@click.option(
|
89
|
+
"--password",
|
90
|
+
required=False,
|
91
|
+
hide_input=True,
|
92
|
+
help="Password for the system admin.",
|
93
|
+
)
|
94
|
+
def createadmin(email: Optional[str] = None, password: Optional[str] = None) -> None:
|
95
|
+
"""Create a system administrator account."""
|
96
|
+
email = os.environ.get("JIVAS_USER") or email
|
97
|
+
password = os.environ.get("JIVAS_PASSWORD") or password
|
98
|
+
|
99
|
+
if email is None:
|
100
|
+
email = click.prompt("Email")
|
101
|
+
if password is None:
|
102
|
+
password = click.prompt("Password", hide_input=True)
|
103
|
+
|
104
|
+
database_host = os.environ.get("DATABASE_HOST")
|
105
|
+
|
106
|
+
if not database_host:
|
107
|
+
click.echo("Database host is not set. Using signup endpoint...")
|
108
|
+
signup_url = (
|
109
|
+
f"{os.environ.get('JIVAS_BASE_URL', 'http://localhost:8000')}/user/register"
|
110
|
+
)
|
111
|
+
|
112
|
+
try:
|
113
|
+
response = requests.post(
|
114
|
+
signup_url, json={"email": email, "password": password}
|
115
|
+
)
|
116
|
+
if response.status_code in (200, 201):
|
117
|
+
click.secho("Admin user created successfully!", fg="green", bold=True)
|
118
|
+
return response.json()
|
119
|
+
else:
|
120
|
+
click.secho(
|
121
|
+
f"Failed to create admin: {response.text}", fg="red", bold=True
|
122
|
+
)
|
123
|
+
except Exception as e:
|
124
|
+
click.secho(
|
125
|
+
f"Error connecting to Jivas Server: {str(e)}", fg="red", bold=True
|
126
|
+
)
|
127
|
+
else:
|
128
|
+
click.echo("Creating system admin...")
|
129
|
+
try:
|
130
|
+
result = subprocess.call(
|
131
|
+
[
|
132
|
+
"jac",
|
133
|
+
"create_system_admin",
|
134
|
+
"main.jac",
|
135
|
+
"--email",
|
136
|
+
email,
|
137
|
+
"--password",
|
138
|
+
password,
|
139
|
+
]
|
140
|
+
)
|
141
|
+
if result == 0:
|
142
|
+
click.secho("Admin user created successfully!", fg="green", bold=True)
|
143
|
+
else:
|
144
|
+
click.secho("Failed to create admin user", fg="red", bold=True)
|
145
|
+
except Exception as e:
|
146
|
+
click.secho(f"Error running jac command: {str(e)}", fg="red", bold=True)
|
147
|
+
|
148
|
+
|
149
|
+
@server.command()
|
150
|
+
def initagents() -> None:
|
151
|
+
"""
|
152
|
+
Initialize agents in the Jivas system.
|
153
|
+
|
154
|
+
Usage:
|
155
|
+
jvcli initagents
|
156
|
+
"""
|
157
|
+
|
158
|
+
# Check if server is running
|
159
|
+
if not is_server_running():
|
160
|
+
click.secho("Server is not running. Please start the server first.", fg="red")
|
161
|
+
sys.exit(1)
|
162
|
+
|
163
|
+
# Login to Jivas
|
164
|
+
token = login_jivas()
|
165
|
+
if not token:
|
166
|
+
click.secho("Failed to login to Jivas.", fg="red")
|
167
|
+
sys.exit(1)
|
168
|
+
click.secho("Logged in to Jivas successfully.", fg="green")
|
169
|
+
|
170
|
+
# Run jvcli clean command
|
171
|
+
click.secho("Cleaning Jac files before initializing agents...", fg="blue")
|
172
|
+
ctx = click.Context(clean, info_name="clean")
|
173
|
+
clean.invoke(ctx)
|
174
|
+
|
175
|
+
# Initialize agents
|
176
|
+
try:
|
177
|
+
response = requests.post(
|
178
|
+
f"{os.environ['JIVAS_BASE_URL']}/walker/init_agents",
|
179
|
+
headers={
|
180
|
+
"Content-Type": "application/json",
|
181
|
+
"Accept": "application/json",
|
182
|
+
"Authorization": f"Bearer {token}",
|
183
|
+
},
|
184
|
+
json={}, # Add empty JSON object as request data
|
185
|
+
)
|
186
|
+
|
187
|
+
if response.status_code == 200:
|
188
|
+
data = response.json()
|
189
|
+
click.secho(f"Successfully initialized agents: {data}", fg="green")
|
190
|
+
else:
|
191
|
+
click.secho("Failed to initialize agents", fg="red")
|
192
|
+
sys.exit(1)
|
193
|
+
except requests.RequestException as e:
|
194
|
+
click.secho(f"Error during request: {e}", fg="red")
|
195
|
+
sys.exit(1)
|
196
|
+
|
197
|
+
|
198
|
+
@server.command()
|
199
|
+
@click.argument("agent_name")
|
200
|
+
@click.argument("version", required=False)
|
201
|
+
def importagent(agent_name: str, version: str) -> None:
|
202
|
+
"""
|
203
|
+
Import an agent from a DAF package.
|
204
|
+
|
205
|
+
Usage:
|
206
|
+
jvcli importagent <agent_name> [--version <jivas_version>]
|
207
|
+
"""
|
208
|
+
|
209
|
+
# Check if server is running
|
210
|
+
if not is_server_running():
|
211
|
+
click.secho("Server is not running. Please start the server first.", fg="red")
|
212
|
+
sys.exit(1)
|
213
|
+
|
214
|
+
# Login to Jivas
|
215
|
+
token = login_jivas()
|
216
|
+
if not token:
|
217
|
+
click.secho("Failed to login to Jivas.", fg="red")
|
218
|
+
sys.exit(1)
|
219
|
+
click.secho("Logged in to Jivas successfully.", fg="green")
|
220
|
+
|
221
|
+
# Check if version is provided
|
222
|
+
if not version:
|
223
|
+
version = "latest"
|
224
|
+
|
225
|
+
try:
|
226
|
+
response = requests.post(
|
227
|
+
f"{os.environ.get('JIVAS_BASE_URL', 'http://localhost:8000')}/walker/import_agent",
|
228
|
+
json={"daf_name": agent_name, "daf_version": version},
|
229
|
+
headers={
|
230
|
+
"Content-Type": "application/json",
|
231
|
+
"Accept": "application/json",
|
232
|
+
"Authorization": f"Bearer {token}",
|
233
|
+
},
|
234
|
+
)
|
235
|
+
|
236
|
+
if response.status_code == 200:
|
237
|
+
try:
|
238
|
+
data = response.json()
|
239
|
+
agent_id = data.get("id")
|
240
|
+
if agent_id:
|
241
|
+
click.secho(
|
242
|
+
f"Successfully imported agent. Agent ID: {agent_id}", fg="green"
|
243
|
+
)
|
244
|
+
else:
|
245
|
+
click.secho(
|
246
|
+
"Agent imported but no ID was returned in the response",
|
247
|
+
fg="yellow",
|
248
|
+
)
|
249
|
+
except json.JSONDecodeError:
|
250
|
+
click.secho("Invalid JSON response from server", fg="red")
|
251
|
+
sys.exit(1)
|
252
|
+
else:
|
253
|
+
click.secho(
|
254
|
+
f"Failed to import agent. Status: {response.status_code}", fg="red"
|
255
|
+
)
|
256
|
+
click.echo(response.text)
|
257
|
+
sys.exit(1)
|
258
|
+
except requests.RequestException as e:
|
259
|
+
click.secho(f"Request failed: {e}", fg="red")
|
260
|
+
sys.exit(1)
|