Skip to content

Commit

Permalink
[AIC-py] cli rage (#870)
Browse files Browse the repository at this point in the history
[AIC-py] cli rage

This just tells the user how to open an issue. I don't want to do
anything automatically
because (a) user trust, and (b) it's much harder to implement without
additional bugs.

This is mostly bedside manner. If the user is raging, they are angry.
Troll them a little bit to lighten the mood first.


https://github.com/lastmile-ai/aiconfig/assets/148090348/2369306f-3af7-49f5-96bb-0ac9be323b51

---
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with
[ReviewStack](https://reviewstack.dev/lastmile-ai/aiconfig/pull/870).
* #903
* __->__ #870
* #869
  • Loading branch information
jonathanlastmileai authored Jan 12, 2024
2 parents 79bbc69 + 0f0182a commit 3b91a53
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 4 deletions.
19 changes: 15 additions & 4 deletions python/src/aiconfig/scripts/aiconfig_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from aiconfig.editor.server.server_utils import DEFAULT_AICONFIGRC, EditServerConfig, ServerMode
from result import Err, Ok, Result

import aiconfig.scripts.rage.rage as rage


class AIConfigCLIConfig(core_utils.Record):
log_level: str | int = "WARNING"
Expand All @@ -36,7 +38,7 @@ async def main_with_args(argv: list[str]) -> int:

def run_subcommand(argv: list[str]) -> Result[str, str]:
LOGGER.info("Running subcommand")
subparser_record_types = {"edit": EditServerConfig}
subparser_record_types = {"edit": EditServerConfig, "rage": rage.RageConfig}
main_parser = core_utils.argparsify(AIConfigCLIConfig, subparser_record_types=subparser_record_types)

# Try to parse the CLI args into a config.
Expand All @@ -57,6 +59,14 @@ def run_subcommand(argv: list[str]) -> Result[str, str]:
LOGGER.debug(f"{edit_config.is_ok()=}")
out = _run_editor_servers_with_configs(edit_config, cli_config)
return out
elif subparser_name == "rage":
res_rage_config = core_utils.parse_args(main_parser, argv[1:], rage.RageConfig)
res_rage = res_rage_config.and_then(rage.rage)
match res_rage:
case Ok(msg):
return Ok(f"Rage complete: {msg}")
case Err(e):
return Err(e)
else:
return Err(f"Unknown subparser: {subparser_name}")

Expand Down Expand Up @@ -143,6 +153,8 @@ def _set_log_level_and_create_default_yaml(cli_config: AIConfigCLIConfig) -> Res
try:
with open(aiconfigrc_path, "x") as f:
YAML().dump(DEFAULT_AICONFIGRC, f)

return Ok(True)
except FileExistsError:
try:

Expand All @@ -159,14 +171,13 @@ def _read() -> str:
if k not in contents:
contents[k] = v

YAML().dump(contents, f)
YAML().dump(contents, f) # type: ignore[yaml library untyped]
return Ok(True)
except Exception as e:
return core_utils.ErrWithTraceback(e)
except Exception as e:
return core_utils.ErrWithTraceback(e)

return Ok(True)


def _run_frontend_server_background() -> Result[list[subprocess.Popen[bytes]], str]:
LOGGER.info("Running frontend server in background")
Expand Down
75 changes: 75 additions & 0 deletions python/src/aiconfig/scripts/rage/rage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import os
import lastmile_utils.lib.core.api as core_utils
import sys
import time
import itertools
import numpy as np
from result import Ok, Result

logger = core_utils.get_logger(__name__)


class RageConfig(core_utils.Record):
log_level: str | int = "WARNING"


def rage(config: RageConfig) -> Result[None, str]:
logger.setLevel(config.log_level)
print("Raging...")
spin(2)
print("Please hold. Your call is important to us.\nA representative will be with you shortly.")
spin(3, type="music")
print("Looking for your server logs...")
spin(4, type="music")
print("Turning up the heat...")
spin(2)
print("If I had a dollar for every time I've seen this error...")
spin(5)
print("I'm glad we're finally spending time together.")
spin(4, type="music")
print("Please continue holding. We appreciate your continued support, or whatever.")
spin(3, type="music")

print("\n\n\n\n............\n\n")
print("Please open an issue! :) Here are some tips on how to do that:")
for logfile in ["editor_flask_server.log", "aiconfig.log"]:
print()
if os.path.exists(logfile):
print(f"Found {logfile}! Please include its contents in your bug report.")
print(f"Full path: {os.path.abspath(logfile)}")
else:
print(f"No {logfile} found. This might be another bug :)")
print("For now, please include your terminal output in your bug report.")

print("\nPlease run the following commands and also include their output:")
print("\nwhich pip; which pip3; which python; which python3; pip3 list | grep aiconfig; python --version; python3 --version")

print("\nPlease open an issue here: https://github.com/lastmile-ai/aiconfig/issues/new")
print("Our sincerest apologies and gratitude. We will comment on the issue as soon as possible.")
print("\n\n")
print("Done raging! :)")
print("\n\n")

return Ok(None)


def spin(seconds: int, type: str = "spinner"):
"""This is just for fun."""

assert type in ["spinner", "music"]

spinning = itertools.cycle(["-", "/", "|", "\\"])

def get_animation():
if type == "spinner":
return next(spinning)
else:
return "".join(np.random.choice(["♩", "♫", "♬", "♪"]) for _ in range(5))

end_time = time.time() + seconds

while time.time() < end_time:
sys.stdout.write(get_animation())
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write("\b" * 5)

0 comments on commit 3b91a53

Please sign in to comment.