Skip to content

Commit

Permalink
Implement expansion deploy command
Browse files Browse the repository at this point in the history
  • Loading branch information
cartermak committed Jan 30, 2024
1 parent 025feaa commit 353ffbf
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 1 deletion.
106 changes: 105 additions & 1 deletion src/aerie_cli/commands/expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
from pathlib import Path
import fnmatch

import arrow

from rich.console import Console
from rich.table import Table

from aerie_cli.commands.command_context import CommandContext
from aerie_cli.utils.prompts import select_from_list
from aerie_cli.schemas.client import ExpansionRun
from aerie_cli.schemas.client import ExpansionRun, ExpansionDeployConfiguration

app = typer.Typer()
sequences_app = typer.Typer()
Expand All @@ -19,6 +21,108 @@
app.add_typer(runs_app, name='runs', help='Commands for expansion runs')
app.add_typer(sets_app, name='sets', help='Commands for expansion sets')

# === Bulk Deploy Command ===

@app.command('deploy')
def bulk_deploy(
model_id: int = typer.Option(
..., '--model-id', '-m', prompt='Mission Model ID',
help='Mission Model ID'
),
command_dictionary_id: int = typer.Option(
..., '--command-dict-id', '-d', prompt='Command Dictionary ID',
help='Command Dictionary ID'
),
config_file: str = typer.Option(
..., "--config-file", "-c", prompt="Configuration file",
help="Deploy configuration JSON file"
),
rules_path: Path = typer.Option(
Path.cwd(), help="Path to folder containing expansion rule files"
),
time_tag: bool = typer.Option(False, help="Append time tags to create unique expansion rule/set names")
):
"""
Bulk deploy command expansion rules and sets to an Aerie instance according to a JSON configuration file.
The configuration file contains a list of rules and a list of sets:
```
{
"rules": [...],
"sets": [...]
}
```
Each rule must provide a unique rule name, the activity type name, and the name of the file with expansion logic:
```
{
"name": "Expansion Rule Name",
"activity_type": "Activity Type Name",
"file_name": "my_file.ts"
}
```
Each set must provide a unique set name and a list of rule names to add:
```
{
"name": "Expansion Set Name",
"rules": ["Expansion Rule Name", ...]
}
```
"""

client = CommandContext.get_client()

with open(Path(config_file), "r") as fid:
configuration: ExpansionDeployConfiguration = ExpansionDeployConfiguration.from_dict(json.load(fid))

name_suffix = arrow.utcnow().format("_YYYY-MM-DDTHH-mm-ss") if time_tag else ""

# Loop and upload all expansion rules
uploaded_rules = {}
for rule in configuration.rules:
try:
with open(rules_path.joinpath(rule.file_name), "r") as fid:
expansion_logic = fid.read()

rule_id = client.create_expansion_rule(
expansion_logic=expansion_logic,
activity_name=rule.activity_type,
model_id=model_id,
command_dictionary_id=command_dictionary_id,
name=rule.name + name_suffix
)
typer.echo(f"Created expansion rule {rule.name + name_suffix}: {rule_id}")
uploaded_rules[rule.name] = rule_id
except:
typer.echo(f"Failed to create expansion rule {rule.name}")

for set in configuration.sets:
try:
rule_ids = []
for rule_name in set.rules:
if rule_name in uploaded_rules.keys():
rule_ids.append(uploaded_rules[rule_name])
else:
typer.echo(f"No uploaded rule {rule_name} for set {set.name}")

assert len(rule_ids)

set_id = client.create_expansion_set(
command_dictionary_id=command_dictionary_id,
model_id=model_id,
expansion_ids=rule_ids,
name=set.name + name_suffix
)

typer.echo(f"Created expansion set {set.name + name_suffix}: {set_id}")
except:
typer.echo(f"Failed to create expansion set {set.name}")


# === Commands for expansion runs ===


Expand Down
25 changes: 25 additions & 0 deletions src/aerie_cli/schemas/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,28 @@ class ExpansionRule(ClientSerialize):
class ResourceType(ClientSerialize):
name: str
schema: Dict


@define
class ExpansionDeployRule(ClientSerialize):
name: str
activity_type: str
file_name: str


@define
class ExpansionDeploySet(ClientSerialize):
name: str
rules: List[str]


@define
class ExpansionDeployConfiguration(ClientSerialize):
rules: List[ExpansionDeployRule] = field(
converter=converters.optional(
lambda x: [ExpansionDeployRule.from_dict(d) if isinstance(d, dict) else d for d in x])
)
sets: List[ExpansionDeploySet] = field(
converter=converters.optional(
lambda x: [ExpansionDeploySet.from_dict(d) if isinstance(d, dict) else d for d in x])
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default function MyExpansion(props: {
activityInstance: ActivityType
}): ExpansionReturn {
const { activityInstance } = props
return []
}
6 changes: 6 additions & 0 deletions tests/integration_tests/files/expansion/BiteBanana_exp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default function MyExpansion(props: {
activityInstance: ActivityType
}): ExpansionReturn {
const { activityInstance } = props
return []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"rules": [
{
"name": "integration_test_BakeBananaBread",
"activity_type": "BakeBananaBread",
"file_name": "BakeBananaBread_exp.ts"
},
{
"name": "integration_test_BiteBanana",
"activity_type": "BiteBanana",
"file_name": "BiteBanana_exp.ts"
},
{
"name": "integration_test_bad",
"activity_type": "Fake",
"file_name": "this path no exist"
}
],
"sets": [
{
"name": "integration_test_set",
"rules": [
"integration_test_BakeBananaBread",
"integration_test_BiteBanana"
]
}
]
}
29 changes: 29 additions & 0 deletions tests/integration_tests/test_expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
# Expansion Variables
expansion_set_id = -1
expansion_sequence_id = 1
EXPANSION_FILES_PATH = os.path.join(FILES_PATH, "expansion")
EXPANSION_DEPLOY_CONFIG_PATH = os.path.join(EXPANSION_FILES_PATH, "expansion_deploy_config.json")

@pytest.fixture(scope="module", autouse=True)
def set_up_environment(request):
Expand Down Expand Up @@ -127,6 +129,33 @@ def test_expansion_sequence_delete():
# Uses model, command dictionary, and activity types
#######################


def test_expansion_deploy():
result = runner.invoke(
app,
[
"expansion",
"deploy",
"-m",
str(model_id),
"-d",
str(command_dictionary_id),
"-c",
EXPANSION_DEPLOY_CONFIG_PATH,
"--rules-path",
EXPANSION_FILES_PATH,
"--time-tag"
],
catch_exceptions=False
)
assert result.exit_code == 0, \
f"{result.stdout}"\
f"{result.stderr}"
assert "Created expansion rule integration_test_BakeBananaBread" in result.stdout
assert "Created expansion rule integration_test_BiteBanana" in result.stdout
assert "Failed to create expansion rule integration_test_bad" in result.stdout
assert "Created expansion set integration_test_set" in result.stdout

def test_expansion_set_create():
client.create_expansion_rule(
expansion_logic="""
Expand Down

0 comments on commit 353ffbf

Please sign in to comment.