Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes issue 235 by completing CLI deploy command #257

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/maestro_run-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ jobs:
- name: Run unit tests
run: |
cd maestro
poetry run pytest
poetry run pytest --ignore=tests/integration/deploys
45 changes: 35 additions & 10 deletions maestro/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from openai import OpenAI
from jsonschema.exceptions import ValidationError, SchemaError

from src.deploy import Deploy
from src.workflow import Workflow, create_agents
from cli.common import Console, parse_yaml

Expand All @@ -32,13 +33,13 @@ def __init__(self, args):

def command(self):
if self.args.get('validate') and self.args['validate']:
return Validate(self.args)
return ValidateCmd(self.args)
elif self.args.get('create') and self.args['create']:
return Create(self.args)
return CreateCmd(self.args)
elif self.args.get('run') and self.args['run']:
return Run(self.args)
return RunCmd(self.args)
elif self.args.get('deploy') and self.args['deploy']:
return Deploy(self.args)
return DeployCmd(self.args)
else:
raise Exception("Invalid command")

Expand Down Expand Up @@ -97,7 +98,7 @@ def dispatch(self):

# validate command group
# maestro validate SCHEMA_FILE YAML_FILE [options]
class Validate(Command):
class ValidateCmd(Command):
def __init__(self, args):
self.args = args
super().__init__(self.args)
Expand Down Expand Up @@ -134,7 +135,7 @@ def validate(self):

# Create command group
# maestro create AGENTS_FILE [options]
class Create(Command):
class CreateCmd(Command):
def __init__(self, args):
self.args = args
super().__init__(self.args)
Expand Down Expand Up @@ -163,7 +164,7 @@ def create(self):

# Run command group
# maestro run AGENTS_FILE WORKFLOW_FILE [options]
class Run(Command):
class RunCmd(Command):
def __init__(self, args):
self.args = args
super().__init__(self.args)
Expand Down Expand Up @@ -201,14 +202,38 @@ def run(self):

# Deploy command group
# maestro deploy AGENTS_FILE WORKFLOW_FILE [options]
class Deploy(Command):
class DeployCmd(Command):
def __init__(self, args):
self.args = args
super().__init__(self.args)

def __deploy_agents_workflow(self, agents_yaml, workflow_yaml):
# TODO: complete this
pass
bee_api_key = os.getenv("BEE_API_KEY")
bee_api = os.getenv("BEE_API_KEY", "http://192.168.86.45:4000")

try:
if self.docker():
deploy = Deploy(agents_yaml, workflow_yaml, bee_api_key, bee_api, self.url())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding "DRY_RUN=1" here enables the dry run.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Deploy constructor is expecting like this:

deploy = Deploy("../tests/examples/condition_agents.yaml", "../tests/examples/condition_workflow.yaml", "BEE_API_KEY=sk-proj-testkey BEE_API=http://192.168.86.45:4000")

The format of the environment variables is like "key1=value1 key2=value2"

deploy.deploy_to_docker()
elif self.k8s():
deploy = Deploy(agents_yaml, workflow_yaml, )
deploy.deploy_to_kubernetes()
else:
Console.error("Need to specify --docker or --k8s | --kubernetes")
Console,ok(f"Workflow deployed: {self.url}")
except Exception as e:
self._check_verbose()
raise RuntimeError(f"Unable to run workflow: {str(e)}") from e
return 0

def url(self):
return self.args['--url'] | "127.0.0.1:5000"

def k8s(self):
return self.args['--k8s'] | self.args['--kubernetes']

def docker(self):
return self.args['--docker']

def AGENTS_FILE(self):
return self.args['AGENTS_FILE']
Expand Down
6 changes: 5 additions & 1 deletion maestro/cli/maestro.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
--verbose Show all output.
--dry-run Mocks agents and other parts of workflow execution.

--url The deployment URL, default: 127.0.0.1:5000
--k8s | --kubernetes Deploys to Kubernetes
--docker Deploys to Docker

-h --help Show this screen.
-v --version Show version.

Expand All @@ -52,7 +56,7 @@ def __execute(command):
return 1

def __run_cli():
args = docopt(__doc__, version='Maestro CLI v0.0.2')
args = docopt(__doc__, version='Maestro CLI v0.0.3')
command = CLI(args).command()
rc = __execute(command)
sys.exit(rc)
Expand Down
1 change: 1 addition & 0 deletions maestro/src/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def create_or_restore_agents(self, agent_defs, workflow):
for agent in workflow["spec"]["template"]["agents"]:
self.agents[agent] = restore_agent(agent)

#TODO: why is this public? It should be private by naming: _find_index(...) @aki
def find_index(self, steps, name):
for step in steps:
if step.get("name") == name:
Expand Down
29 changes: 26 additions & 3 deletions maestro/tests/cli/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ def setUp(self):
'--help': False,
'--verbose': False,
'--version': False,
'--url': "127.0.0.1:5000",
'--k8s': False,
'--kubernetes': False,
'--docker': False,
'AGENTS_FILE': self.get_fixture('yamls/agents/simple_agent.yaml'),
'SCHEMA_FILE': None,
'WORKFLOW_FILE': self.get_fixture('yamls/workflows/simple_workflow.yaml'),
Expand All @@ -53,10 +57,29 @@ def tearDown(self):
self.args = {}
self.command = None

def test_deploy__dry_run(self):
def test_deploy__dry_run_k8s(self):
self.assertTrue(self.command.name() == 'deploy')
#TODO: complete test for deploy and check deployment server
self.assertTrue(self.command.execute() == 0)
self.args["--k8s"] = True
try:
self.assertTrue(self.command.execute() == 0)
except Exception as e:
self.fail("Exception running command: {message}".format(message=str(e)))

def test_deploy__dry_run_kubernetes(self):
self.assertTrue(self.command.name() == 'deploy')
self.args["--kubernetes"] = True
try:
self.assertTrue(self.command.execute() == 0)
except Exception as e:
self.fail("Exception running command: {message}".format(message=str(e)))

def test_deploy__dry_run_docker(self):
self.assertTrue(self.command.name() == 'deploy')
self.args["--docker"] = True
try:
self.assertTrue(self.command.execute() == 0)
except Exception as e:
self.fail("Exception running command: {message}".format(message=str(e)))

# `run` commmand tests
class RunCommand(TestCommand):
Expand Down
Loading