|
| 1 | +import os |
1 | 2 | import argparse
|
2 | 3 |
|
3 |
| -from polyapi.utils import print_green |
| 4 | +from polyapi.utils import print_green, print_red |
4 | 5 |
|
5 |
| -from .config import clear_config, set_api_key_and_url |
| 6 | +from .config import initialize_config, set_api_key_and_url |
6 | 7 | from .generate import generate, clear
|
7 | 8 | from .function_cli import function_add_or_update, function_execute
|
8 | 9 | from .rendered_spec import get_and_update_rendered_spec
|
| 10 | +from .prepare import prepare_deployables |
| 11 | +from .sync import sync_deployables |
9 | 12 |
|
10 | 13 |
|
11 | 14 | CLI_COMMANDS = ["setup", "generate", "function", "clear", "help", "update_rendered_spec"]
|
12 | 15 |
|
13 |
| -CLIENT_DESC = """Commands |
14 |
| - python -m polyapi setup Setup your Poly connection |
15 |
| - python -m polyapi generate Generates Poly library |
16 |
| - python -m polyapi function <command> Manages functions |
17 |
| - python -m polyapi clear Clear current generated Poly library |
18 |
| -""" |
19 |
| - |
20 |
| - |
21 |
| -def execute_from_cli() -> None: |
| 16 | +def execute_from_cli(): |
| 17 | + # First we setup all our argument parsing logic |
| 18 | + # Then we parse the arguments (waaay at the bottom) |
22 | 19 | parser = argparse.ArgumentParser(
|
23 |
| - prog="python -m polyapi", description=CLIENT_DESC, formatter_class=argparse.RawTextHelpFormatter |
| 20 | + prog="python -m polyapi", |
| 21 | + description="Manage your Poly API configurations and functions", |
| 22 | + formatter_class=argparse.RawTextHelpFormatter |
24 | 23 | )
|
25 |
| - parser.add_argument("--context", required=False, default="") |
26 |
| - parser.add_argument("--description", required=False, default="") |
27 |
| - parser.add_argument("--client", action="store_true", help="Pass --client when adding function to add a client function.") |
28 |
| - parser.add_argument("--server", action="store_true", help="Pass --server when adding function to add a server function.") |
29 |
| - parser.add_argument("--logs", action="store_true", help="Pass --logs when adding function if you want to store and see the function logs.") |
30 |
| - parser.add_argument("--skip-generate", action="store_true", help="Pass --skip-generate to skip generating the library after adding a function.") |
31 |
| - parser.add_argument("command", choices=CLI_COMMANDS) |
32 |
| - parser.add_argument("subcommands", nargs="*") |
33 |
| - args = parser.parse_args() |
34 |
| - command = args.command |
35 |
| - |
36 |
| - if command == "help": |
37 |
| - parser.print_help() |
38 |
| - elif command == "generate": |
| 24 | + |
| 25 | + subparsers = parser.add_subparsers(help="Available commands") |
| 26 | + |
| 27 | + ########################################################################### |
| 28 | + # Setup command |
| 29 | + setup_parser = subparsers.add_parser("setup", help="Setup your Poly connection") |
| 30 | + setup_parser.add_argument("api_key", nargs="?", help="API key for Poly API") |
| 31 | + setup_parser.add_argument("url", nargs="?", help="URL for the Poly API") |
| 32 | + |
| 33 | + def setup(args): |
| 34 | + if args.api_key and args.url: |
| 35 | + set_api_key_and_url(args.url, args.api_key) |
| 36 | + else: |
| 37 | + initialize_config(force=True) |
| 38 | + generate() |
| 39 | + |
| 40 | + setup_parser.set_defaults(command=setup) |
| 41 | + |
| 42 | + |
| 43 | + ########################################################################### |
| 44 | + # Generate command |
| 45 | + generate_parser = subparsers.add_parser("generate", help="Generates Poly library") |
| 46 | + |
| 47 | + def generate_command(args): |
| 48 | + initialize_config() |
39 | 49 | print("Generating Poly functions...", end="")
|
40 | 50 | generate()
|
41 | 51 | print_green("DONE")
|
42 |
| - elif command == "setup" and len(args.subcommands) == 2: |
43 |
| - set_api_key_and_url(args.subcommands[1], args.subcommands[0]) |
44 |
| - elif command == "setup": |
45 |
| - clear_config() |
46 |
| - generate() |
47 |
| - elif command == "update_rendered_spec": |
48 |
| - assert len(args.subcommands) == 1 |
49 |
| - updated = get_and_update_rendered_spec(args.subcommands[0]) |
| 52 | + |
| 53 | + generate_parser.set_defaults(command=generate_command) |
| 54 | + |
| 55 | + |
| 56 | + ########################################################################### |
| 57 | + # Function commands |
| 58 | + fn_parser = subparsers.add_parser("function", help="Manage and execute functions") |
| 59 | + fn_subparsers = fn_parser.add_subparsers(help="Available commands") |
| 60 | + |
| 61 | + # Function - Add command |
| 62 | + fn_add_parser = fn_subparsers.add_parser("add", help="Add or update the function") |
| 63 | + fn_add_parser.add_argument("name", help="Name of the function") |
| 64 | + fn_add_parser.add_argument("file", help="Path to the function file") |
| 65 | + fn_add_parser.add_argument("--context", required=False, default="", help="Context of the function") |
| 66 | + fn_add_parser.add_argument("--description", required=False, default="", help="Description of the function") |
| 67 | + fn_add_parser.add_argument("--server", action="store_true", help="Marks the function as a server function") |
| 68 | + fn_add_parser.add_argument("--client", action="store_true", help="Marks the function as a client function") |
| 69 | + fn_add_parser.add_argument("--logs", choices=["enabled", "disabled"], default="disabled", help="Enable or disable logs for the function.") |
| 70 | + fn_add_parser.add_argument("--execution-api-key", required=False, default="", help="API key for execution (for server functions only).") |
| 71 | + fn_add_parser.add_argument("--disable-ai", "--skip-generate", action="store_true", help="Pass --disable-ai skip AI generation of missing descriptions") |
| 72 | + |
| 73 | + def add_function(args): |
| 74 | + initialize_config() |
| 75 | + logs_enabled = args.logs == "enabled" |
| 76 | + err = "" |
| 77 | + if args.server and args.client: |
| 78 | + err = "Specify either `--server` or `--client`. Found both." |
| 79 | + elif not args.server and not args.client: |
| 80 | + err = "You must specify `--server` or `--client`." |
| 81 | + elif logs_enabled and not args.server: |
| 82 | + err = "Option `logs` is only for server functions (--server)." |
| 83 | + |
| 84 | + if err: |
| 85 | + print_red("ERROR") |
| 86 | + print(err) |
| 87 | + exit(1) |
| 88 | + |
| 89 | + function_add_or_update( |
| 90 | + name=args.name, |
| 91 | + file=args.file, |
| 92 | + context=args.context, |
| 93 | + description=args.description, |
| 94 | + client=args.client, |
| 95 | + server=args.server, |
| 96 | + logs_enabled=logs_enabled, |
| 97 | + generate=not args.disable_ai, |
| 98 | + execution_api_key=args.execution_api_key |
| 99 | + ) |
| 100 | + |
| 101 | + fn_add_parser.set_defaults(command=add_function) |
| 102 | + |
| 103 | + |
| 104 | + # Function - Execute command |
| 105 | + fn_exec_parser = fn_subparsers.add_parser("execute", help="Execute a function with the provided arguments") |
| 106 | + fn_exec_parser.add_argument("name", help="Name of the function") |
| 107 | + fn_exec_parser.add_argument("args", nargs="*", help="Arguments for the function") |
| 108 | + fn_exec_parser.add_argument("--context", required=False, default="", help="Context of the function") |
| 109 | + |
| 110 | + def execute_function(args): |
| 111 | + initialize_config() |
| 112 | + print(function_execute(args.context, args.name, args.args)) |
| 113 | + |
| 114 | + fn_exec_parser.set_defaults(command=execute_function) |
| 115 | + |
| 116 | + |
| 117 | + ########################################################################### |
| 118 | + # Clear command |
| 119 | + clear_parser = subparsers.add_parser("clear", help="Clear current generated Poly library") |
| 120 | + |
| 121 | + def clear_command(_): |
| 122 | + print("Clearing the generated library...") |
| 123 | + clear() |
| 124 | + |
| 125 | + clear_parser.set_defaults(command=clear_command) |
| 126 | + |
| 127 | + |
| 128 | + ########################################################################### |
| 129 | + # Update rendered spec command |
| 130 | + update_spec_parser = subparsers.add_parser("update_rendered_spec", help="Update the rendered spec file") |
| 131 | + update_spec_parser.add_argument("spec", help="Specification file to update") |
| 132 | + |
| 133 | + def update_rendered_spec(args): |
| 134 | + updated = get_and_update_rendered_spec(args.spec) |
50 | 135 | if updated:
|
51 | 136 | print("Updated rendered spec!")
|
52 | 137 | else:
|
53 | 138 | print("Failed to update rendered spec!")
|
54 | 139 | exit(1)
|
55 |
| - elif command == "clear": |
56 |
| - print("Clearing the generated library...") |
57 |
| - clear() |
58 |
| - elif command == "function": |
59 |
| - if args.subcommands[0] == "execute": |
60 |
| - print(function_execute(args.context, args.subcommands)) |
61 |
| - else: |
62 |
| - function_add_or_update(args.context, args.description, args.client, args.server, args.logs, args.subcommands, not args.skip_generate) |
| 140 | + |
| 141 | + update_spec_parser.set_defaults(command=update_rendered_spec) |
| 142 | + |
| 143 | + |
| 144 | + ########################################################################### |
| 145 | + # Prepare command |
| 146 | + prepare_parser = subparsers.add_parser('prepare', help="Find and prepare all Poly deployables") |
| 147 | + prepare_parser.add_argument("--lazy", action="store_true", help="Skip prepare work if the cache is up to date. (Relies on `git`)") |
| 148 | + prepare_parser.add_argument("--disable-docs", action="store_true", help="Don't write any docstrings into the deployable files.") |
| 149 | + prepare_parser.add_argument("--disable-ai", action="store_true", help="Don't use AI to fill in any missing descriptions.") |
| 150 | + |
| 151 | + def prepare(args): |
| 152 | + initialize_config() |
| 153 | + disable_ai = args.disable_ai or bool(os.getenv("DISABLE_AI")) |
| 154 | + prepare_deployables(lazy=args.lazy, disable_docs=args.disable_docs, disable_ai=disable_ai) |
| 155 | + |
| 156 | + prepare_parser.set_defaults(command=prepare) |
| 157 | + |
| 158 | + |
| 159 | + ########################################################################### |
| 160 | + # Sync command |
| 161 | + sync_parser = subparsers.add_parser("sync", help="Find and sync all Poly deployables") |
| 162 | + sync_parser.add_argument("--dry-run", action="store_true", help="Run through sync steps with logging but don't make any changes.") |
| 163 | + |
| 164 | + def sync(args): |
| 165 | + initialize_config() |
| 166 | + prepare_deployables(lazy=True, disable_docs=True, disable_ai=True) |
| 167 | + if args.dry_run: |
| 168 | + print("Running dry-run of sync...") |
| 169 | + sync_deployables(dry_run=args.dry_run) |
| 170 | + print("Poly deployments synced.") |
| 171 | + |
| 172 | + sync_parser.set_defaults(command=sync) |
| 173 | + |
| 174 | + ########################################################################### |
| 175 | + # _------. # |
| 176 | + # / , \_ __ __ _ ________ # |
| 177 | + # / / /{}\ |o\_ / / ___ / /( )_____ / ____/ /_ __ # |
| 178 | + # / \ `--' /-' \ / / / _ \/ __/// ___/ / /_ / / / / / # |
| 179 | + # | \ \ | / /___/ __/ /_ (__ ) / __/ / / /_/ / # |
| 180 | + # | |`-, | /_____/\___/\__/ /____/ /_/ /_/\__, / # |
| 181 | + # / /__/)/ /____/ # |
| 182 | + # / | # |
| 183 | + ########################################################################### |
| 184 | + parsed_args = parser.parse_args() |
| 185 | + if hasattr(parsed_args, "command"): |
| 186 | + parsed_args.command(parsed_args) |
| 187 | + else: |
| 188 | + parser.print_help() |
0 commit comments