Coretex
ui.py
1 # Copyright (C) 2023 Coretex LLC
2 
3 # This file is part of Coretex.ai
4 
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
14 
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
17 
18 from typing import Any, List, Optional, Union
19 
20 from tabulate import tabulate
21 
22 import click
23 import inquirer
24 
25 from ...node import NodeMode
26 from ...configuration import NodeConfiguration
27 
28 
29 def clickPrompt(
30  text: str,
31  default: Any = None,
32  type: Optional[Union[type, click.ParamType]] = None,
33  **kwargs: Any
34 ) -> Any:
35 
36  return click.prompt(click.style(f"\n\U00002754 {text}", fg = "cyan"), default = default, type = type, **kwargs)
37 
38 
39 def arrowPrompt(choices: List[Any], message: str) -> Any:
40  click.echo("\n")
41  answers = inquirer.prompt([
42  inquirer.List(
43  "option",
44  message = message,
45  choices = choices,
46  )
47  ])
48 
49  return answers["option"]
50 
51 
52 def previewNodeConfig(nodeConfig: NodeConfiguration) -> None:
53  allowDocker = "Yes" if nodeConfig.allowDocker else "No"
54 
55  if nodeConfig.secret is None or nodeConfig.secret == "":
56  nodeSecret = ""
57  else:
58  nodeSecret = "********"
59 
60  table = [
61  ["Node name", nodeConfig.name],
62  ["Node image", nodeConfig.image],
63  ["Storage path", nodeConfig.storagePath],
64  ["RAM", f"{nodeConfig.ram}GB"],
65  ["SWAP memory", f"{nodeConfig.swap}GB"],
66  ["POSIX shared memory", f"{nodeConfig.sharedMemory}GB"],
67  ["CPU cores allocated", f"{nodeConfig.cpuCount}"],
68  ["Node mode", f"{NodeMode(nodeConfig.mode).name}"],
69  ["Docker access", allowDocker],
70  ["Node secret", nodeSecret],
71  ["Node init script", nodeConfig.initScript if nodeConfig.initScript is not None else ""],
72  ["Node heartbeat interval", f"{nodeConfig.heartbeatInterval // 1000}s"]
73  ]
74  if nodeConfig.modelId is not None:
75  table.append(["Coretex Model ID", f"{nodeConfig.modelId}"])
76 
77  if nodeConfig.nearWalletId is not None:
78  table.append(["NEAR wallet id", nodeConfig.nearWalletId])
79 
80  if nodeConfig.endpointInvocationPrice is not None:
81  table.append(["Endpoint invocation price", f"{nodeConfig.endpointInvocationPrice}"])
82 
83  stdEcho(tabulate(table))
84 
85 
86 def outputUrl(baseUrl: str, entityUrl: str) -> str:
87  return ("\033[4m" + f"{baseUrl}/{entityUrl}" + "\033[0m")
88 
89 
90 def stdEcho(text: str) -> None:
91  click.echo(click.style(f"\n{text}", fg = "cyan"))
92 
93 
94 def warningEcho(text: str) -> None:
95  click.echo(click.style(f"\nWARNING: {text}", fg = "yellow"))
96 
97 
98 def successEcho(text: str) -> None:
99  click.echo(click.style(f"\n\U0001F680 {text} \U0001F680", fg = "green"))
100 
101 
102 def progressEcho(text: str) -> None:
103  click.echo(click.style(f"\n\U00002699 {text} \U00002699", fg = "yellow"))
104 
105 
106 def errorEcho(text: str) -> None:
107  click.echo(click.style(f"\n\U0000274C {text} \U0000274C", fg = "red"))
108 
109 
110 def highlightEcho(text: str) -> None:
111  click.echo(click.style(f"\n\U00002755 {text} \U00002755"))