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 CHANGED
@@ -4,5 +4,5 @@ jvcli package initialization.
4
4
  This package provides the CLI tool for Jivas Package Repository.
5
5
  """
6
6
 
7
- __version__ = "2.0.18"
7
+ __version__ = "2.0.20"
8
8
  __supported__jivas__versions__ = ["2.0.0"]
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)
@@ -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)
@@ -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)
@@ -40,7 +40,6 @@ def startproject(project_name: str, version: str, no_env: bool) -> None:
40
40
  "tests": [],
41
41
  "actions": [],
42
42
  "daf": [],
43
- "sh": [],
44
43
  }
45
44
 
46
45
  try: