agenta 0.1.17__py3-none-any.whl → 0.1.19__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.
Potentially problematic release.
This version of agenta might be problematic. Click here for more details.
- agenta/cli/main.py +7 -1
- agenta/cli/variant_commands.py +21 -1
- agenta/client/client.py +59 -24
- agenta/docker/docker_utils.py +28 -6
- {agenta-0.1.17.dist-info → agenta-0.1.19.dist-info}/METADATA +1 -1
- {agenta-0.1.17.dist-info → agenta-0.1.19.dist-info}/RECORD +8 -8
- {agenta-0.1.17.dist-info → agenta-0.1.19.dist-info}/WHEEL +0 -0
- {agenta-0.1.17.dist-info → agenta-0.1.19.dist-info}/entry_points.txt +0 -0
agenta/cli/main.py
CHANGED
|
@@ -37,7 +37,7 @@ def init(app_name: str):
|
|
|
37
37
|
if not app_name:
|
|
38
38
|
while True:
|
|
39
39
|
app_name = questionary.text('Please enter the app name').ask()
|
|
40
|
-
if app_name and re.match('^[a-zA-Z0-9_]+$', app_name):
|
|
40
|
+
if app_name and re.match('^[a-zA-Z0-9_-]+$', app_name):
|
|
41
41
|
break
|
|
42
42
|
else:
|
|
43
43
|
if app_name is None: # User pressed Ctrl+C
|
|
@@ -93,6 +93,12 @@ def init(app_name: str):
|
|
|
93
93
|
shutil.copy(file, current_dir / file.name)
|
|
94
94
|
elif init_option is None: # User pressed Ctrl+C
|
|
95
95
|
sys.exit(0)
|
|
96
|
+
|
|
97
|
+
# Create a .gitignore file and add some default environment folder names to it
|
|
98
|
+
gitignore_content = "# Environments \nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/"
|
|
99
|
+
with open('.gitignore', 'w') as gitignore_file:
|
|
100
|
+
gitignore_file.write(gitignore_content)
|
|
101
|
+
|
|
96
102
|
click.echo("App initialized successfully")
|
|
97
103
|
if init_option == 'Start from template':
|
|
98
104
|
click.echo("Please check the README.md for further instructions to setup the template.")
|
agenta/cli/variant_commands.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
import sys
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import List
|
|
@@ -41,6 +42,7 @@ def add_variant(variant_name: str, app_folder: str, file_name: str, host: str) -
|
|
|
41
42
|
if not app_file.exists():
|
|
42
43
|
click.echo(click.style(f"No {file_name} exists! Please make sure you are in the right directory", fg='red'))
|
|
43
44
|
return None
|
|
45
|
+
|
|
44
46
|
env_file = app_path / '.env'
|
|
45
47
|
if not env_file.exists():
|
|
46
48
|
continue_without_env = questionary.confirm(
|
|
@@ -48,9 +50,27 @@ def add_variant(variant_name: str, app_folder: str, file_name: str, host: str) -
|
|
|
48
50
|
if not continue_without_env:
|
|
49
51
|
click.echo("Operation cancelled.")
|
|
50
52
|
sys.exit(0)
|
|
53
|
+
|
|
54
|
+
requirements_file = app_path / 'requirements.txt'
|
|
55
|
+
if not requirements_file.exists():
|
|
56
|
+
continue_without_requirements = questionary.confirm(
|
|
57
|
+
'No requirements.txt file found! Are you sure you do not need it in your application?\n Do you want to continue without it?').ask()
|
|
58
|
+
if not continue_without_requirements:
|
|
59
|
+
click.echo("Operation cancelled.")
|
|
60
|
+
sys.exit(0)
|
|
51
61
|
|
|
62
|
+
# Ask for variant name and validate.
|
|
52
63
|
if not variant_name:
|
|
53
|
-
|
|
64
|
+
while True:
|
|
65
|
+
variant_name = questionary.text('Please enter the variant name').ask()
|
|
66
|
+
if variant_name and re.match('^[a-zA-Z0-9_]+$', variant_name):
|
|
67
|
+
break
|
|
68
|
+
else:
|
|
69
|
+
if variant_name is None: # User pressed Ctrl+C
|
|
70
|
+
sys.exit(0)
|
|
71
|
+
else:
|
|
72
|
+
print("Invalid input. Please use only alphanumeric characters without spaces.")
|
|
73
|
+
|
|
54
74
|
# update the config file with the variant names from the backend
|
|
55
75
|
overwrite = False
|
|
56
76
|
if variant_name in config['variants']:
|
agenta/client/client.py
CHANGED
|
@@ -14,7 +14,9 @@ class APIRequestError(Exception):
|
|
|
14
14
|
"""Exception to be raised when an API request fails."""
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def add_variant_to_server(
|
|
17
|
+
def add_variant_to_server(
|
|
18
|
+
app_name: str, variant_name: str, image: Image, host: str
|
|
19
|
+
):
|
|
18
20
|
"""Adds a variant to the server.
|
|
19
21
|
|
|
20
22
|
Arguments:
|
|
@@ -23,32 +25,41 @@ def add_variant_to_server(app_name: str, variant_name: str, image: Image, host:
|
|
|
23
25
|
image_name -- Name of the image
|
|
24
26
|
"""
|
|
25
27
|
app_variant: AppVariant = AppVariant(
|
|
26
|
-
app_name=app_name, variant_name=variant_name
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
app_name=app_name, variant_name=variant_name
|
|
29
|
+
)
|
|
30
|
+
response = requests.post(
|
|
31
|
+
f"{host}/{BACKEND_URL_SUFFIX}/app_variant/add/from_image/",
|
|
32
|
+
json={"app_variant": app_variant.dict(), "image": image.dict()},
|
|
33
|
+
timeout=600,
|
|
34
|
+
)
|
|
29
35
|
if response.status_code != 200:
|
|
30
36
|
error_message = response.text
|
|
31
37
|
raise APIRequestError(
|
|
32
|
-
f"Request to app_variant endpoint failed with status code {response.status_code} and error message: {error_message}."
|
|
38
|
+
f"Request to app_variant endpoint failed with status code {response.status_code} and error message: {error_message}."
|
|
39
|
+
)
|
|
33
40
|
|
|
34
41
|
|
|
35
42
|
def start_variant(app_name: str, variant_name: str, host: str) -> str:
|
|
36
43
|
"""Starts a container with the variant an expose its endpoint
|
|
37
44
|
|
|
38
45
|
Arguments:
|
|
39
|
-
app_name --
|
|
46
|
+
app_name --
|
|
40
47
|
variant_name -- _description_
|
|
41
48
|
|
|
42
49
|
Returns:
|
|
43
50
|
The endpoint of the container
|
|
44
51
|
"""
|
|
45
|
-
response = requests.post(
|
|
46
|
-
|
|
52
|
+
response = requests.post(
|
|
53
|
+
f"{host}/{BACKEND_URL_SUFFIX}/app_variant/start/",
|
|
54
|
+
json={"app_name": app_name, "variant_name": variant_name},
|
|
55
|
+
timeout=600,
|
|
56
|
+
)
|
|
47
57
|
if response.status_code != 200:
|
|
48
58
|
error_message = response.text
|
|
49
59
|
raise APIRequestError(
|
|
50
|
-
f"Request to start variant endpoint failed with status code {response.status_code} and error message: {error_message}."
|
|
51
|
-
|
|
60
|
+
f"Request to start variant endpoint failed with status code {response.status_code} and error message: {error_message}."
|
|
61
|
+
)
|
|
62
|
+
return response.json()["uri"]
|
|
52
63
|
|
|
53
64
|
|
|
54
65
|
def list_variants(app_name: str, host: str) -> List[AppVariant]:
|
|
@@ -60,13 +71,17 @@ def list_variants(app_name: str, host: str) -> List[AppVariant]:
|
|
|
60
71
|
Returns:
|
|
61
72
|
a list of the variants using the pydantic model
|
|
62
73
|
"""
|
|
63
|
-
response = requests.get(
|
|
74
|
+
response = requests.get(
|
|
75
|
+
f"{host}/{BACKEND_URL_SUFFIX}/app_variant/list_variants/?app_name={app_name}",
|
|
76
|
+
timeout=600,
|
|
77
|
+
)
|
|
64
78
|
|
|
65
79
|
# Check for successful request
|
|
66
80
|
if response.status_code != 200:
|
|
67
81
|
error_message = response.text
|
|
68
82
|
raise APIRequestError(
|
|
69
|
-
f"Request to list_variants endpoint failed with status code {response.status_code} and error message: {error_message}."
|
|
83
|
+
f"Request to list_variants endpoint failed with status code {response.status_code} and error message: {error_message}."
|
|
84
|
+
)
|
|
70
85
|
app_variants = response.json()
|
|
71
86
|
return [AppVariant(**variant) for variant in app_variants]
|
|
72
87
|
|
|
@@ -80,17 +95,24 @@ def remove_variant(app_name: str, variant_name: str, host: str):
|
|
|
80
95
|
"""
|
|
81
96
|
app_variant = AppVariant(app_name=app_name, variant_name=variant_name)
|
|
82
97
|
app_variant_json = app_variant.json()
|
|
83
|
-
response = requests.delete(
|
|
84
|
-
|
|
98
|
+
response = requests.delete(
|
|
99
|
+
f"{host}/{BACKEND_URL_SUFFIX}/app_variant/remove_variant/",
|
|
100
|
+
data=app_variant_json,
|
|
101
|
+
headers={"Content-Type": "application/json"},
|
|
102
|
+
timeout=600,
|
|
103
|
+
)
|
|
85
104
|
|
|
86
105
|
# Check for successful request
|
|
87
106
|
if response.status_code != 200:
|
|
88
107
|
error_message = response.text
|
|
89
108
|
raise APIRequestError(
|
|
90
|
-
f"Request to remove_variant endpoint failed with status code {response.status_code} and error message: {error_message}"
|
|
109
|
+
f"Request to remove_variant endpoint failed with status code {response.status_code} and error message: {error_message}"
|
|
110
|
+
)
|
|
91
111
|
|
|
92
112
|
|
|
93
|
-
def update_variant_image(
|
|
113
|
+
def update_variant_image(
|
|
114
|
+
app_name: str, variant_name: str, image: Image, host: str
|
|
115
|
+
):
|
|
94
116
|
"""Adds a variant to the server.
|
|
95
117
|
|
|
96
118
|
Arguments:
|
|
@@ -99,25 +121,38 @@ def update_variant_image(app_name: str, variant_name: str, image: Image, host: s
|
|
|
99
121
|
image_name -- Name of the image
|
|
100
122
|
"""
|
|
101
123
|
app_variant: AppVariant = AppVariant(
|
|
102
|
-
app_name=app_name, variant_name=variant_name
|
|
103
|
-
|
|
104
|
-
|
|
124
|
+
app_name=app_name, variant_name=variant_name
|
|
125
|
+
)
|
|
126
|
+
response = requests.put(
|
|
127
|
+
f"{host}/{BACKEND_URL_SUFFIX}/app_variant/update_variant_image/",
|
|
128
|
+
json={"app_variant": app_variant.dict(), "image": image.dict()},
|
|
129
|
+
timeout=600,
|
|
130
|
+
)
|
|
105
131
|
if response.status_code != 200:
|
|
106
132
|
error_message = response.text
|
|
107
133
|
raise APIRequestError(
|
|
108
|
-
f"Request to update app_variant failed with status code {response.status_code} and error message: {error_message}."
|
|
134
|
+
f"Request to update app_variant failed with status code {response.status_code} and error message: {error_message}."
|
|
135
|
+
)
|
|
109
136
|
|
|
110
137
|
|
|
111
|
-
def send_docker_tar(
|
|
112
|
-
|
|
138
|
+
def send_docker_tar(
|
|
139
|
+
app_name: str, variant_name: str, tar_path: Path, host: str
|
|
140
|
+
) -> Image:
|
|
141
|
+
with tar_path.open("rb") as tar_file:
|
|
113
142
|
response = requests.post(
|
|
114
143
|
f"{host}/{BACKEND_URL_SUFFIX}/containers/build_image/?app_name={app_name}&variant_name={variant_name}",
|
|
115
144
|
files={
|
|
116
|
-
|
|
145
|
+
"tar_file": tar_file,
|
|
117
146
|
},
|
|
118
|
-
timeout=1200
|
|
147
|
+
timeout=1200,
|
|
119
148
|
)
|
|
120
149
|
|
|
150
|
+
if response.status_code == 500:
|
|
151
|
+
error_msg = "Serving the variant failed. Here's how you can solve the issue:\n"
|
|
152
|
+
error_msg += "- First, make sure that the requirements.txt file has all the dependencies that you need.\n"
|
|
153
|
+
error_msg += "- Second, check the Docker logs for the backend image to see the error when running the Docker container."
|
|
154
|
+
raise Exception(error_msg)
|
|
155
|
+
|
|
121
156
|
response.raise_for_status()
|
|
122
157
|
image = Image.parse_obj(response.json())
|
|
123
158
|
return image
|
agenta/docker/docker_utils.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
import os
|
|
3
2
|
import shutil
|
|
4
3
|
import tarfile
|
|
5
4
|
import tempfile
|
|
@@ -40,22 +39,45 @@ def build_tar_docker_container(folder: Path, file_name: Path) -> Path:
|
|
|
40
39
|
tarfile_path = folder / "docker.tar.gz" # output file
|
|
41
40
|
if tarfile_path.exists():
|
|
42
41
|
tarfile_path.unlink()
|
|
42
|
+
|
|
43
43
|
dockerfile_path = create_dockerfile(folder)
|
|
44
44
|
shutil.copytree(Path(__file__).parent.parent / "sdk", folder / "agenta", dirs_exist_ok=True)
|
|
45
45
|
shutil.copy(Path(__file__).parent /
|
|
46
46
|
"docker-assets" / "main.py", folder)
|
|
47
47
|
shutil.copy(Path(__file__).parent /
|
|
48
48
|
"docker-assets" / "entrypoint.sh", folder)
|
|
49
|
-
|
|
49
|
+
|
|
50
|
+
# Read the contents of .gitignore file
|
|
51
|
+
gitignore_content = ""
|
|
52
|
+
gitignore_file_path = folder / ".gitignore"
|
|
53
|
+
if gitignore_file_path.exists():
|
|
54
|
+
with open(gitignore_file_path, 'r') as gitignore_file:
|
|
55
|
+
gitignore_content = gitignore_file.read()
|
|
56
|
+
|
|
57
|
+
# Create a temporary directory
|
|
50
58
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
51
59
|
temp_path = Path(temp_dir)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
|
|
61
|
+
# Clean - remove '/' from every files and folders in the gitignore contents
|
|
62
|
+
sanitized_patterns = [
|
|
63
|
+
pattern.replace("/", "")
|
|
64
|
+
for pattern in gitignore_content.splitlines()
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
# Function to ignore files based on the patterns
|
|
68
|
+
def ignore_patterns(path, names):
|
|
69
|
+
return set(sanitized_patterns)
|
|
70
|
+
|
|
71
|
+
# Use a single copytree call with ignore_patterns
|
|
72
|
+
shutil.copytree(folder, temp_path, ignore=ignore_patterns, dirs_exist_ok=True)
|
|
73
|
+
|
|
74
|
+
# Rename the specified file to _app.py in the temporary directory
|
|
56
75
|
shutil.copy(temp_path / file_name, temp_path / "_app.py")
|
|
76
|
+
|
|
77
|
+
# Create the tar.gz file
|
|
57
78
|
with tarfile.open(tarfile_path, "w:gz") as tar:
|
|
58
79
|
tar.add(temp_path, arcname=folder.name)
|
|
80
|
+
|
|
59
81
|
# dockerfile_path.unlink()
|
|
60
82
|
return tarfile_path
|
|
61
83
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
agenta/__init__.py,sha256=TqCcA0MJb_SwAH7oX2NZUDAFmAMnpopR5wQZ-NCdaAc,167
|
|
2
2
|
agenta/cli/helper.py,sha256=w5bVUN6N0JoiDHTC2yzbOAG8d_V8FKYZpgwlV5OeV1s,2445
|
|
3
|
-
agenta/cli/main.py,sha256=
|
|
4
|
-
agenta/cli/variant_commands.py,sha256=
|
|
3
|
+
agenta/cli/main.py,sha256=G1uVxX1xezwqJaJpXa8DgMI4TQGNR7laRjnnDAgLQ4o,4034
|
|
4
|
+
agenta/cli/variant_commands.py,sha256=BU5uI7uMYT3uSb0TsiZD5AXZrPLfR3vRgrw-i9xQUkg,10416
|
|
5
5
|
agenta/client/Readme.md,sha256=umhMce1Gq_der9pH4M_pP4NQ8rHa3MENJLM9OrdUZ50,131
|
|
6
6
|
agenta/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
agenta/client/api_models.py,sha256=gqIIZay_A7kg2d451gO9QTgaKxGuAk3YKtWtArIzMNw,325
|
|
8
|
-
agenta/client/client.py,sha256
|
|
8
|
+
agenta/client/client.py,sha256=-Pw1pkvVFp9X2PmLR7cf30dTrtneLlQ4JCzo6xZefeA,5273
|
|
9
9
|
agenta/config.py,sha256=9FSS-5-UHSxPL3L36txI7nWs_pmgSdLeoS2cAKJmX0M,629
|
|
10
10
|
agenta/config.toml,sha256=un4IS3NUcJczZS2LrjPCOShx8W9aw0XIoabZKfqZAWw,198
|
|
11
11
|
agenta/docker/docker-assets/Dockerfile.template,sha256=WrFCL5Sy23trqBi8keaw_EE8U3SHf04hTZRQnS45pdk,416
|
|
12
12
|
agenta/docker/docker-assets/README.md,sha256=XHxwh2ks_ozrtAU7SLbL3J14SB2holG6buoTxwmMiZM,102
|
|
13
13
|
agenta/docker/docker-assets/entrypoint.sh,sha256=609un15YyEIKZ2k06hXAQs1DpZAJ2LkU0jS9UShR90c,43
|
|
14
14
|
agenta/docker/docker-assets/main.py,sha256=6wFpQOgw_SrztJGc8uesnvYh-gjnFSWq1xK7hqGY5vw,326
|
|
15
|
-
agenta/docker/docker_utils.py,sha256=
|
|
15
|
+
agenta/docker/docker_utils.py,sha256=AHjPz4seXSSPxqTJCWYjQcQFg24nqFCOT3Vnj_1Homw,5037
|
|
16
16
|
agenta/sdk/__init__.py,sha256=HSa94-ynZoEbH3dDn-owMkSmvk_AwjQwK9wKVJX1ZUM,241
|
|
17
17
|
agenta/sdk/agenta.py,sha256=HSRoPAGmCtrJDwZsUz68ytBHsfYx4wNJRJFloPZqmvs,7090
|
|
18
18
|
agenta/sdk/context.py,sha256=EI6g8mNdG26JoWTSeg6t5t9ThegoIZ3_rB5Qj-JQYEI,864
|
|
@@ -24,7 +24,7 @@ agenta/templates/simple_prompt/app.py,sha256=uNRiM6vaI2yXPFmPP4Yd5iepZwuS3__Mw9b
|
|
|
24
24
|
agenta/templates/simple_prompt/env.example,sha256=g9AE5bYcGPpxawXMJ96gh8oenEPCHTabsiOnfQo3c5k,70
|
|
25
25
|
agenta/templates/simple_prompt/requirements.txt,sha256=ywRglRy7pPkw8bljmMEJJ4aOOQKrt9FGKULZ-DGkoBU,23
|
|
26
26
|
agenta/templates/simple_prompt/template.toml,sha256=DQBtRrF4GU8LBEXOZ-GGuINXMQDKGTEG5y37tnvIUIE,60
|
|
27
|
-
agenta-0.1.
|
|
28
|
-
agenta-0.1.
|
|
29
|
-
agenta-0.1.
|
|
30
|
-
agenta-0.1.
|
|
27
|
+
agenta-0.1.19.dist-info/METADATA,sha256=mT12vmR1m08g_CP9d8nFTCmpXfalpwf4itFlSWCVYw4,1027
|
|
28
|
+
agenta-0.1.19.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
|
29
|
+
agenta-0.1.19.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
|
|
30
|
+
agenta-0.1.19.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|