Skip to content

Commit

Permalink
feat(agent): Working agent deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
RezaRahemtola committed Dec 10, 2024
1 parent 8e20f5c commit 09f6a79
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 20 deletions.
59 changes: 44 additions & 15 deletions libertai_client/commands/agent.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import zipfile
from enum import Enum
from typing import Annotated

import aiohttp
Expand All @@ -23,54 +24,82 @@

def create_agent_zip(src_dir: str, zip_name: str):
# Read and parse the .gitignore file
with open(get_full_path(src_dir, ".gitignore"), 'r') as gitignore_file:
with open(get_full_path(src_dir, ".gitignore"), "r") as gitignore_file:
gitignore_patterns = gitignore_file.read()
spec = pathspec.PathSpec.from_lines('gitwildmatch', gitignore_patterns.splitlines() + AGENT_ZIP_BLACKLIST)
spec = pathspec.PathSpec.from_lines(
"gitwildmatch", gitignore_patterns.splitlines() + AGENT_ZIP_BLACKLIST
)

with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
with zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED) as zipf:
for root, _, files in os.walk(src_dir):
for file in files:
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, src_dir)

# Check if the file matches any .gitignore pattern
if not spec.match_file(relative_path) or relative_path in AGENT_ZIP_WHITELIST:
if (
not spec.match_file(relative_path)
or relative_path in AGENT_ZIP_WHITELIST
):
zipf.write(file_path, arcname=relative_path)


class AgentPythonPackageManager(str, Enum):
poetry = "poetry"
pip = "pip"


@app.command()
async def deploy(path: Annotated[str, typer.Option(help="Path to the root of your repository", prompt=True)] = ".",
python_version: Annotated[str, typer.Option(help="Version to deploy with", prompt=True)] = "3.11"):
async def deploy(
path: Annotated[
str, typer.Option(help="Path to the root of your repository", prompt=True)
] = ".",
python_version: Annotated[
str, typer.Option(help="Version to deploy with", prompt=True)
] = "3.11",
package_manager: Annotated[
AgentPythonPackageManager, typer.Option(case_sensitive=False, prompt=True)
] = AgentPythonPackageManager.pip.value, # type: ignore
):
"""
Deploy or redeploy an agent
"""

# TODO: try to detect package manager, show detected value and ask user for the confirmation or change
# Same for python version

# TODO: allow user to give a custom deployment script URL

try:
libertai_env_path = get_full_path(path, ".env.libertai")
libertai_config = parse_agent_config_env(dotenv_values(libertai_env_path))
except (FileNotFoundError, EnvironmentError) as error:
err_console.print(f"[red]{error}")
raise typer.Exit(1)

create_agent_zip(path, "/tmp/libertai-agent.zip")
agent_zip_path = "/tmp/libertai-agent.zip"

create_agent_zip(path, agent_zip_path)

data = aiohttp.FormData()
data.add_field('secret', libertai_config.secret)
data.add_field('python_version', python_version)
data.add_field('package_manager', "poetry") # TODO: detect/ask user
data.add_field('code', open('/tmp/libertai-agent.zip', 'rb'), filename='libertai-agent.zip')
data.add_field("secret", libertai_config.secret)
data.add_field("python_version", python_version)
data.add_field("package_manager", package_manager.value)
data.add_field("code", open(agent_zip_path, "rb"), filename="libertai-agent.zip")

async with aiohttp.ClientSession() as session:
async with session.put(f"{config.AGENTS_BACKEND_URL}/agent/{libertai_config.id}",
headers={'accept': 'application/json'},
data=data) as response:
async with session.put(
f"{config.AGENTS_BACKEND_URL}/agent/{libertai_config.id}",
headers={"accept": "application/json"},
data=data,
) as response:
if response.status == 200:
print("Request succeeded:", await response.text())
else:
print(f"Request failed: {response.status}")
print(await response.text())

os.remove("/tmp/libertai-agent.zip")
os.remove(agent_zip_path)

# with Progress(TextColumn(TEXT_PROGRESS_FORMAT),
# SpinnerColumn(finished_text="✔ ")) as progress:
Expand Down
5 changes: 3 additions & 2 deletions libertai_client/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ class _Config:
AGENTS_BACKEND_URL: str

def __init__(self):
self.AGENTS_BACKEND_URL = os.getenv("LIBERTAI_CLIENT_AGENTS_BACKEND_URL",
"https://agent.api.libertai.io")
self.AGENTS_BACKEND_URL = os.getenv(
"LIBERTAI_CLIENT_AGENTS_BACKEND_URL", "https://agent.api.libertai.io"
)


config = _Config()
3 changes: 2 additions & 1 deletion libertai_client/utils/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def parse_agent_config_env(env: dict[str, str | None]) -> AgentConfig:

if agent_id is None or agent_secret is None:
raise EnvironmentError(
f"Missing {'LIBERTAI_AGENT_ID' if agent_id is None else 'LIBERTAI_AGENT_SECRET'} variable in your project's .env.libertai")
f"Missing {'LIBERTAI_AGENT_ID' if agent_id is None else 'LIBERTAI_AGENT_SECRET'} variable in your project's .env.libertai"
)

return AgentConfig(id=agent_id, secret=agent_secret)
6 changes: 4 additions & 2 deletions libertai_client/utils/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ def __validate_path(path: str, with_file: bool = False) -> str:
is_valid_path = os.path.exists(path)

if not is_valid_path:
raise FileNotFoundError(f"{'File' if with_file else 'Folder'} '{path}' doesn't exist.")
raise FileNotFoundError(
f"{'File' if with_file else 'Folder'} '{path}' doesn't exist."
)

return path

Expand All @@ -15,5 +17,5 @@ def get_full_path(folder_path: str, file: str | None = None) -> str:
path = os.path.abspath(folder_path)
return __validate_path(path, with_file=False)

path = os.path.abspath(f'{folder_path}/{file}')
path = os.path.abspath(f"{folder_path}/{file}")
return __validate_path(path, with_file=True)

0 comments on commit 09f6a79

Please sign in to comment.