truefoundry 0.1.2__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of truefoundry might be problematic. Click here for more details.
- truefoundry/autodeploy/__init__.py +0 -0
- truefoundry/autodeploy/agents/__init__.py +0 -0
- truefoundry/autodeploy/agents/base.py +181 -0
- truefoundry/autodeploy/agents/developer.py +113 -0
- truefoundry/autodeploy/agents/project_identifier.py +124 -0
- truefoundry/autodeploy/agents/tester.py +75 -0
- truefoundry/autodeploy/cli.py +348 -0
- truefoundry/autodeploy/constants.py +22 -0
- truefoundry/autodeploy/exception.py +2 -0
- truefoundry/autodeploy/logger.py +13 -0
- truefoundry/autodeploy/tools/__init__.py +26 -0
- truefoundry/autodeploy/tools/ask.py +33 -0
- truefoundry/autodeploy/tools/base.py +31 -0
- truefoundry/autodeploy/tools/commit.py +139 -0
- truefoundry/autodeploy/tools/docker_build.py +109 -0
- truefoundry/autodeploy/tools/docker_run.py +150 -0
- truefoundry/autodeploy/tools/file_type_counts.py +79 -0
- truefoundry/autodeploy/tools/list_files.py +82 -0
- truefoundry/autodeploy/tools/read_file.py +66 -0
- truefoundry/autodeploy/tools/send_request.py +54 -0
- truefoundry/autodeploy/tools/write_file.py +101 -0
- truefoundry/autodeploy/utils/diff.py +157 -0
- truefoundry/autodeploy/utils/pydantic_compat.py +19 -0
- truefoundry/cli/__main__.py +11 -5
- truefoundry/deploy/__init__.py +1 -1
- truefoundry/deploy/cli/__init__.py +0 -0
- truefoundry/deploy/cli/cli.py +99 -0
- truefoundry/deploy/cli/deploy.py +184 -0
- truefoundry/langchain/__init__.py +1 -1
- truefoundry/ml/__init__.py +4 -2
- {truefoundry-0.1.2.dist-info → truefoundry-0.2.0.dist-info}/METADATA +12 -4
- truefoundry-0.2.0.dist-info/RECORD +36 -0
- truefoundry-0.1.2.dist-info/RECORD +0 -10
- {truefoundry-0.1.2.dist-info → truefoundry-0.2.0.dist-info}/WHEEL +0 -0
- {truefoundry-0.1.2.dist-info → truefoundry-0.2.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import difflib
|
|
2
|
+
import pprint
|
|
3
|
+
from typing import Iterator, List
|
|
4
|
+
|
|
5
|
+
from rich.console import Console, ConsoleOptions, RenderResult
|
|
6
|
+
from rich.text import Text
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def rewrite_line(line, line_to_rewrite, prev_marker):
|
|
10
|
+
marker_style_map = {
|
|
11
|
+
"+": {
|
|
12
|
+
" ": "green",
|
|
13
|
+
"+": "white on green",
|
|
14
|
+
"^": "white on green",
|
|
15
|
+
},
|
|
16
|
+
"-": {
|
|
17
|
+
" ": "red",
|
|
18
|
+
"-": "white on red",
|
|
19
|
+
"^": "white on red",
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
new_line = Text("")
|
|
23
|
+
current_span = []
|
|
24
|
+
# Differ lines start with a 2 letter code, so skip past that
|
|
25
|
+
prev_char = line[2]
|
|
26
|
+
for idx, char in enumerate(line[2:], start=2):
|
|
27
|
+
if prev_marker in ("+", "-"):
|
|
28
|
+
if char != prev_char:
|
|
29
|
+
style = marker_style_map.get(prev_marker, {}).get(prev_char, None)
|
|
30
|
+
if style is not None:
|
|
31
|
+
new_line.append_text(Text("".join(current_span), style=style))
|
|
32
|
+
current_span = []
|
|
33
|
+
if idx - 2 < len(line_to_rewrite):
|
|
34
|
+
current_span.append(line_to_rewrite[idx - 2])
|
|
35
|
+
prev_char = char
|
|
36
|
+
|
|
37
|
+
# Lines starting with ? aren't guaranteed to be the same length as the lines before them
|
|
38
|
+
# so some characters may be left over. Add any leftover characters to the output.
|
|
39
|
+
# subtract 2 for code at start
|
|
40
|
+
remaining_index = idx - 2
|
|
41
|
+
if prev_marker == "-":
|
|
42
|
+
new_line.append_text(Text(line_to_rewrite[remaining_index:], style="red"))
|
|
43
|
+
elif prev_marker == "+":
|
|
44
|
+
new_line.append_text(Text(line_to_rewrite[remaining_index:], style="green"))
|
|
45
|
+
return new_line
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def build_symbolic_unified_diff(diff: List[str]) -> RenderResult:
|
|
49
|
+
output_lines = []
|
|
50
|
+
style = "grey"
|
|
51
|
+
last_style = style
|
|
52
|
+
for line in diff:
|
|
53
|
+
if line.startswith("+ "):
|
|
54
|
+
style = "green"
|
|
55
|
+
output_line = f"+ {line[2:]}"
|
|
56
|
+
elif line.startswith("- "):
|
|
57
|
+
style = "red"
|
|
58
|
+
output_line = f"- {line[2:]}"
|
|
59
|
+
elif line.startswith("? "):
|
|
60
|
+
if last_style == "red":
|
|
61
|
+
output_line = line[:-1].replace("+", "-")
|
|
62
|
+
elif last_style == "green":
|
|
63
|
+
output_line = line[:-1].replace("-", "+")
|
|
64
|
+
else:
|
|
65
|
+
output_line = line
|
|
66
|
+
style = "gray"
|
|
67
|
+
output_lines.append(Text(output_line, style=style))
|
|
68
|
+
last_style = style if style != "gray" else last_style
|
|
69
|
+
return output_lines
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def build_unified_diff(diff: List[str]) -> RenderResult:
|
|
73
|
+
prev_marker = ""
|
|
74
|
+
output_lines: List[Text] = []
|
|
75
|
+
for line in diff:
|
|
76
|
+
if line.startswith("- "):
|
|
77
|
+
output_lines.append(Text(line[2:], style="red"))
|
|
78
|
+
elif line.startswith("+ "):
|
|
79
|
+
output_lines.append(Text(line[2:], style="green"))
|
|
80
|
+
elif line.startswith("? "):
|
|
81
|
+
line_to_rewrite = output_lines[-1].plain
|
|
82
|
+
output_lines[-1] = rewrite_line(line, line_to_rewrite, prev_marker)
|
|
83
|
+
else:
|
|
84
|
+
output_lines.append(Text(line[2:], style="#949494"))
|
|
85
|
+
prev_marker = line[0]
|
|
86
|
+
return output_lines
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def llm_unified_diff(diff: List[str]) -> RenderResult:
|
|
90
|
+
prev_marker = ""
|
|
91
|
+
output_lines: List[Text] = []
|
|
92
|
+
for line in diff:
|
|
93
|
+
if len(line) < 1:
|
|
94
|
+
continue
|
|
95
|
+
if line.startswith("---"):
|
|
96
|
+
output_lines.append(Text(line, style="dim"))
|
|
97
|
+
elif line.startswith("+++"):
|
|
98
|
+
output_lines.append(Text(line, style="dim"))
|
|
99
|
+
elif line.startswith("@@"):
|
|
100
|
+
output_lines.append(Text(line, style="bright_blue"))
|
|
101
|
+
elif line.startswith("-"):
|
|
102
|
+
output_lines.append(Text(line[1:], style="red"))
|
|
103
|
+
elif line.startswith("+"):
|
|
104
|
+
output_lines.append(Text(line[1:], style="green"))
|
|
105
|
+
elif line.startswith("?"):
|
|
106
|
+
line_to_rewrite = output_lines[-1].plain
|
|
107
|
+
output_lines[-1] = rewrite_line(line, line_to_rewrite, prev_marker)
|
|
108
|
+
else:
|
|
109
|
+
output_lines.append(Text(line[1:], style="#949494"))
|
|
110
|
+
prev_marker = line[0]
|
|
111
|
+
return output_lines
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class LLMDiff:
|
|
115
|
+
def __init__(self, llm_diff: str) -> None:
|
|
116
|
+
self.diff = llm_diff.splitlines()
|
|
117
|
+
|
|
118
|
+
def __rich_console__(
|
|
119
|
+
self, console: Console, options: ConsoleOptions
|
|
120
|
+
) -> RenderResult:
|
|
121
|
+
return llm_unified_diff(diff=self.diff)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class Diff:
|
|
125
|
+
"""Constructs a Diff object to render diff-highlighted code."""
|
|
126
|
+
|
|
127
|
+
def __init__(
|
|
128
|
+
self,
|
|
129
|
+
lhs: object,
|
|
130
|
+
rhs: object,
|
|
131
|
+
width: int,
|
|
132
|
+
show_symbols: bool = False,
|
|
133
|
+
) -> None:
|
|
134
|
+
self.width = width
|
|
135
|
+
self.lhs = lhs if isinstance(lhs, str) else pprint.pformat(lhs, width=width)
|
|
136
|
+
self.rhs = rhs if isinstance(rhs, str) else pprint.pformat(rhs, width=width)
|
|
137
|
+
self.show_symbols = show_symbols
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def sides_are_different(self) -> bool:
|
|
141
|
+
return self.lhs != self.rhs
|
|
142
|
+
|
|
143
|
+
def raw_unified_diff(self) -> Iterator[str]:
|
|
144
|
+
differ = difflib.Differ()
|
|
145
|
+
lines_lhs = self.lhs.splitlines()
|
|
146
|
+
lines_rhs = self.rhs.splitlines()
|
|
147
|
+
return differ.compare(lines_lhs, lines_rhs)
|
|
148
|
+
|
|
149
|
+
def __rich_console__(
|
|
150
|
+
self, console: Console, options: ConsoleOptions
|
|
151
|
+
) -> RenderResult:
|
|
152
|
+
diff = self.raw_unified_diff()
|
|
153
|
+
if self.show_symbols:
|
|
154
|
+
result = build_symbolic_unified_diff(diff)
|
|
155
|
+
else:
|
|
156
|
+
result = build_unified_diff(diff)
|
|
157
|
+
yield from result
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from typing import Any, Dict, Type
|
|
2
|
+
|
|
3
|
+
import pydantic
|
|
4
|
+
|
|
5
|
+
PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def model_dump(
|
|
9
|
+
model: pydantic.BaseModel,
|
|
10
|
+
) -> Dict[str, Any]:
|
|
11
|
+
if PYDANTIC_V2:
|
|
12
|
+
return model.model_dump()
|
|
13
|
+
return model.dict()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def model_json_schema(model: Type[pydantic.BaseModel]) -> Dict[str, Any]:
|
|
17
|
+
if PYDANTIC_V2:
|
|
18
|
+
return model.model_json_schema()
|
|
19
|
+
return model.schema()
|
truefoundry/cli/__main__.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
from truefoundry.deploy.cli.cli import create_truefoundry_cli
|
|
5
6
|
|
|
6
7
|
MLFOUNDRY_INSTALLED = True
|
|
8
|
+
|
|
9
|
+
|
|
7
10
|
try:
|
|
8
11
|
from mlfoundry.cli.commands import download
|
|
9
12
|
except ImportError:
|
|
@@ -20,10 +23,13 @@ def main():
|
|
|
20
23
|
# If the status is omitted or None, it defaults to zero (i.e., success).
|
|
21
24
|
# If the status is an integer, it will be used as the system exit status.
|
|
22
25
|
# If it is another kind of object, it will be printed and the system exit status will be one (i.e., failure).
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
try:
|
|
27
|
+
cli = create_truefoundry_cli()
|
|
28
|
+
if MLFOUNDRY_INSTALLED:
|
|
29
|
+
ml.add_command(download)
|
|
30
|
+
cli.add_command(ml)
|
|
31
|
+
except Exception as e:
|
|
32
|
+
raise click.exceptions.UsageError(message=str(e)) from e
|
|
27
33
|
sys.exit(cli())
|
|
28
34
|
|
|
29
35
|
|
truefoundry/deploy/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
from servicefoundry import *
|
|
1
|
+
from servicefoundry import * # noqa: F403
|
|
File without changes
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import rich_click as click
|
|
5
|
+
from servicefoundry import logger
|
|
6
|
+
from servicefoundry.cli.commands import (
|
|
7
|
+
deploy_patch_v2_command,
|
|
8
|
+
get_login_command,
|
|
9
|
+
get_logout_command,
|
|
10
|
+
get_patch_command,
|
|
11
|
+
)
|
|
12
|
+
from servicefoundry.cli.config import CliConfig
|
|
13
|
+
from servicefoundry.cli.const import GROUP_CLS
|
|
14
|
+
from servicefoundry.cli.util import setup_rich_click
|
|
15
|
+
from servicefoundry.lib.util import is_debug_env_set, is_experimental_env_set
|
|
16
|
+
from servicefoundry.version import __version__
|
|
17
|
+
|
|
18
|
+
from truefoundry.deploy.cli.deploy import deploy_v2_command
|
|
19
|
+
|
|
20
|
+
click.rich_click.USE_RICH_MARKUP = True
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _add_experimental_commands(cli):
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_truefoundry_cli():
|
|
28
|
+
"""Generates CLI by combining all subcommands into a main CLI and returns in
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
function: main CLI functions will all added sub-commands
|
|
32
|
+
"""
|
|
33
|
+
cli = truefoundry_cli
|
|
34
|
+
cli.add_command(get_login_command())
|
|
35
|
+
# cli.add_command(get_get_command())
|
|
36
|
+
# cli.add_command(get_list_command())
|
|
37
|
+
# cli.add_command(get_delete_command())
|
|
38
|
+
# cli.add_command(get_create_command())
|
|
39
|
+
# cli.add_command(get_redeploy_command())
|
|
40
|
+
cli.add_command(get_logout_command())
|
|
41
|
+
# cli.add_command(get_build_command())
|
|
42
|
+
cli.add_command(deploy_v2_command)
|
|
43
|
+
cli.add_command(deploy_patch_v2_command)
|
|
44
|
+
# cli.add_command(get_build_logs_command())
|
|
45
|
+
# cli.add_command(get_logs_command())
|
|
46
|
+
# cli.add_command(get_trigger_command())
|
|
47
|
+
# cli.add_command(get_terminate_command())
|
|
48
|
+
|
|
49
|
+
if not (sys.platform.startswith("win32") or sys.platform.startswith("cygwin")):
|
|
50
|
+
cli.add_command(get_patch_command())
|
|
51
|
+
|
|
52
|
+
if is_experimental_env_set():
|
|
53
|
+
_add_experimental_commands(cli)
|
|
54
|
+
return cli
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) # noqa: C408
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@click.group(
|
|
61
|
+
cls=GROUP_CLS, context_settings=CONTEXT_SETTINGS, invoke_without_command=True
|
|
62
|
+
)
|
|
63
|
+
@click.option(
|
|
64
|
+
"--json",
|
|
65
|
+
is_flag=True,
|
|
66
|
+
help="Output entities in json format instead of formatted tables",
|
|
67
|
+
)
|
|
68
|
+
@click.option(
|
|
69
|
+
"--debug",
|
|
70
|
+
is_flag=True,
|
|
71
|
+
default=is_debug_env_set,
|
|
72
|
+
help="Set logging level to Debug. Can also be set using environment variable. E.g. SFY_DEBUG=1",
|
|
73
|
+
)
|
|
74
|
+
@click.version_option(__version__)
|
|
75
|
+
@click.pass_context
|
|
76
|
+
def truefoundry_cli(ctx, json, debug):
|
|
77
|
+
"""
|
|
78
|
+
Truefoundry provides an easy way to deploy your services, jobs and models.
|
|
79
|
+
\b
|
|
80
|
+
|
|
81
|
+
To start, login to your Truefoundry account with [i]tfy login[/]
|
|
82
|
+
|
|
83
|
+
Then start deploying with [i]tfy deploy[/]
|
|
84
|
+
|
|
85
|
+
And more: [link=https://docs.truefoundry.com/docs]https://docs.truefoundry.com/docs[/]
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
setup_rich_click()
|
|
89
|
+
# TODO (chiragjn): Change this to -o json|yaml|table|pager
|
|
90
|
+
CliConfig.set("json", json)
|
|
91
|
+
if ctx.invoked_subcommand is None:
|
|
92
|
+
click.echo(ctx.get_help())
|
|
93
|
+
log_level = logging.INFO
|
|
94
|
+
# no info logs while outputting json
|
|
95
|
+
if json:
|
|
96
|
+
log_level = logging.ERROR
|
|
97
|
+
if debug:
|
|
98
|
+
log_level = logging.DEBUG
|
|
99
|
+
logger.add_cli_handler(level=log_level)
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import rich_click as click
|
|
6
|
+
import yaml
|
|
7
|
+
from click import UsageError
|
|
8
|
+
from click.exceptions import ClickException
|
|
9
|
+
from servicefoundry.cli.const import GROUP_CLS
|
|
10
|
+
from servicefoundry.lib.dao import application as application_lib
|
|
11
|
+
|
|
12
|
+
from truefoundry.autodeploy.exception import GitBinaryNotFoundException
|
|
13
|
+
|
|
14
|
+
GIT_BINARY = True
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from truefoundry.autodeploy.cli import cli as autodeploy_cli
|
|
18
|
+
except GitBinaryNotFoundException:
|
|
19
|
+
GIT_BINARY = False
|
|
20
|
+
|
|
21
|
+
default_file = "default"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _get_yaml_file():
|
|
25
|
+
files = ["truefoundry.yaml", "servicefoundry.yaml"]
|
|
26
|
+
for file in files:
|
|
27
|
+
if os.path.exists(file):
|
|
28
|
+
return file
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@click.group(
|
|
33
|
+
name="deploy",
|
|
34
|
+
cls=GROUP_CLS,
|
|
35
|
+
invoke_without_command=True,
|
|
36
|
+
help="Deploy application to Truefoundry",
|
|
37
|
+
)
|
|
38
|
+
@click.option(
|
|
39
|
+
"-f",
|
|
40
|
+
"--file",
|
|
41
|
+
type=click.STRING,
|
|
42
|
+
default=default_file,
|
|
43
|
+
help="Path to truefoundry.yaml file",
|
|
44
|
+
show_default=False,
|
|
45
|
+
)
|
|
46
|
+
@click.option(
|
|
47
|
+
"-w",
|
|
48
|
+
"--workspace-fqn",
|
|
49
|
+
"--workspace_fqn",
|
|
50
|
+
required=True,
|
|
51
|
+
help="FQN of the Workspace to deploy to",
|
|
52
|
+
)
|
|
53
|
+
@click.option(
|
|
54
|
+
"--wait/--no-wait",
|
|
55
|
+
"--wait/--no_wait",
|
|
56
|
+
is_flag=True,
|
|
57
|
+
show_default=True,
|
|
58
|
+
default=True,
|
|
59
|
+
help="Wait and tail the deployment progress",
|
|
60
|
+
)
|
|
61
|
+
def deploy_v2_command(file: str, workspace_fqn: str, wait: bool):
|
|
62
|
+
from servicefoundry.lib.auth.servicefoundry_session import ServiceFoundrySession
|
|
63
|
+
from servicefoundry.v2.lib.deployable_patched_models import Application
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
_ = ServiceFoundrySession()
|
|
67
|
+
except Exception as e:
|
|
68
|
+
raise ClickException(message=str(e)) from e
|
|
69
|
+
|
|
70
|
+
if file != default_file and not os.path.exists(file):
|
|
71
|
+
raise UsageError(
|
|
72
|
+
f"The file {file} does not exist. Please check the file path and try again."
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
file = _get_yaml_file()
|
|
76
|
+
|
|
77
|
+
if file is None:
|
|
78
|
+
click.echo(
|
|
79
|
+
click.style(
|
|
80
|
+
"We did not find any truefoundry.yaml or servicefoundry.yaml at the root path.",
|
|
81
|
+
fg="red",
|
|
82
|
+
),
|
|
83
|
+
color=True,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
if not sys.stdout.isatty():
|
|
87
|
+
click.echo(
|
|
88
|
+
click.style(
|
|
89
|
+
'Please create a truefoundry.yaml or pass the file name with "--file file_name"',
|
|
90
|
+
fg="yellow",
|
|
91
|
+
),
|
|
92
|
+
color=True,
|
|
93
|
+
)
|
|
94
|
+
sys.exit(1)
|
|
95
|
+
|
|
96
|
+
click.echo(
|
|
97
|
+
click.style(
|
|
98
|
+
'We will be using TrueFoundry AI to build your project.\nIf you wish to proceed without TrueFoundry AI,\nyou need to either have a truefoundry.yaml file in your project root or\npass the path to a yaml file using the "--file file_name" option.',
|
|
99
|
+
fg="yellow",
|
|
100
|
+
),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
if GIT_BINARY:
|
|
104
|
+
autodeploy_cli(
|
|
105
|
+
project_root_path=".", deploy=True, workspace_fqn=workspace_fqn
|
|
106
|
+
)
|
|
107
|
+
else:
|
|
108
|
+
raise UsageError(
|
|
109
|
+
"We cannot find the 'git' command. We use Git to track changes made while automatically building your project. Please install Git to use this feature or manually create a 'truefoundry.yaml' file."
|
|
110
|
+
)
|
|
111
|
+
else:
|
|
112
|
+
with open(file, "r") as f:
|
|
113
|
+
application_definition = yaml.safe_load(f)
|
|
114
|
+
|
|
115
|
+
application = Application.parse_obj(application_definition)
|
|
116
|
+
application.deploy(workspace_fqn=workspace_fqn, wait=wait)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@click.group(
|
|
120
|
+
name="patch-application",
|
|
121
|
+
cls=GROUP_CLS,
|
|
122
|
+
invoke_without_command=True,
|
|
123
|
+
help="Deploy application with patches to Truefoundry",
|
|
124
|
+
)
|
|
125
|
+
@click.option(
|
|
126
|
+
"-f",
|
|
127
|
+
"--patch-file",
|
|
128
|
+
"--patch_file",
|
|
129
|
+
type=click.Path(exists=True, dir_okay=False, resolve_path=True),
|
|
130
|
+
help="Path to yaml patch file",
|
|
131
|
+
show_default=True,
|
|
132
|
+
)
|
|
133
|
+
@click.option(
|
|
134
|
+
"-p",
|
|
135
|
+
"--patch",
|
|
136
|
+
type=click.STRING,
|
|
137
|
+
help="Patch in JSON format provided as a string.",
|
|
138
|
+
show_default=True,
|
|
139
|
+
)
|
|
140
|
+
@click.option(
|
|
141
|
+
"-a",
|
|
142
|
+
"--application_fqn",
|
|
143
|
+
"--application-fqn",
|
|
144
|
+
type=click.STRING,
|
|
145
|
+
required=True,
|
|
146
|
+
help="FQN of the Application to patch and deploy",
|
|
147
|
+
)
|
|
148
|
+
@click.option(
|
|
149
|
+
"--wait/--no-wait",
|
|
150
|
+
"--wait/--no_wait",
|
|
151
|
+
is_flag=True,
|
|
152
|
+
show_default=True,
|
|
153
|
+
default=True,
|
|
154
|
+
help="Wait and tail the deployment progress",
|
|
155
|
+
)
|
|
156
|
+
def deploy_patch_v2_command(
|
|
157
|
+
patch_file: str, application_fqn: str, patch: str, wait: bool
|
|
158
|
+
):
|
|
159
|
+
from servicefoundry.v2.lib.deployable_patched_models import Application
|
|
160
|
+
|
|
161
|
+
manifest_patch_obj = None
|
|
162
|
+
if not patch_file and not patch:
|
|
163
|
+
raise Exception("You need to either provide --file or --patch.")
|
|
164
|
+
elif patch and patch_file:
|
|
165
|
+
raise Exception("You can only provide one of --file and --patch")
|
|
166
|
+
elif patch:
|
|
167
|
+
try:
|
|
168
|
+
manifest_patch_obj = json.loads(patch)
|
|
169
|
+
except json.decoder.JSONDecodeError as e:
|
|
170
|
+
raise Exception("Invalid JSON provided as --patch") from e
|
|
171
|
+
elif patch_file:
|
|
172
|
+
with open(patch_file, "r") as f:
|
|
173
|
+
manifest_patch_obj = yaml.safe_load(f)
|
|
174
|
+
|
|
175
|
+
if not manifest_patch_obj or not isinstance(manifest_patch_obj, dict):
|
|
176
|
+
raise Exception("Invalid patch, aborting deployment.")
|
|
177
|
+
|
|
178
|
+
tfy_application = application_lib.get_application(application_fqn=application_fqn)
|
|
179
|
+
patched_application_obj = application_lib.get_patched_application_definition(
|
|
180
|
+
application=tfy_application, manifest_patch=manifest_patch_obj
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
application = Application.parse_obj(patched_application_obj)
|
|
184
|
+
application.deploy(workspace_fqn=tfy_application.workspace.fqn, wait=wait)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
from servicefoundry.langchain import *
|
|
1
|
+
from servicefoundry.langchain import * # noqa: F403
|
truefoundry/ml/__init__.py
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
try:
|
|
2
|
-
from mlfoundry import *
|
|
2
|
+
from mlfoundry import * # noqa: F403
|
|
3
3
|
except ImportError:
|
|
4
|
-
print(
|
|
4
|
+
print(
|
|
5
|
+
"To use metadata/artifact logging features, please run 'pip install truefoundry[ml]'."
|
|
6
|
+
)
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: truefoundry
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Truefoundry CLI
|
|
5
5
|
Author: Abhishek Choudhary
|
|
6
6
|
Author-email: abhichoudhary06@gmail.com
|
|
7
|
-
Requires-Python: >=3.8,<3.13
|
|
7
|
+
Requires-Python: >=3.8.1,<3.13
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.9
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
13
|
Provides-Extra: ml
|
|
14
|
+
Requires-Dist: docker (>=7.0.0,<8.0.0)
|
|
15
|
+
Requires-Dist: gitignorefile (>=1.1.2,<2.0.0)
|
|
16
|
+
Requires-Dist: gitpython (>=3.1.43,<4.0.0)
|
|
17
|
+
Requires-Dist: inquirer (>=3.2.4,<4.0.0)
|
|
15
18
|
Requires-Dist: mlfoundry (==0.10.9) ; extra == "ml"
|
|
16
|
-
Requires-Dist:
|
|
19
|
+
Requires-Dist: openai (>=1.16.2,<2.0.0)
|
|
20
|
+
Requires-Dist: pydantic (>=1.10.0,<3)
|
|
21
|
+
Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
|
|
22
|
+
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
23
|
+
Requires-Dist: rich (>=13.7.1,<14.0.0)
|
|
24
|
+
Requires-Dist: servicefoundry (==0.10.10)
|
|
17
25
|
Description-Content-Type: text/markdown
|
|
18
26
|
|
|
19
27
|
# Truefoundry
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
truefoundry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
truefoundry/autodeploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
truefoundry/autodeploy/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
truefoundry/autodeploy/agents/base.py,sha256=woCry229x7WX0IZmBopW_e_NB76aCLQRLXZBs2QBklk,6405
|
|
5
|
+
truefoundry/autodeploy/agents/developer.py,sha256=u1BfjaMDX6Ad32vWYOEFZPWFK33ux0Ro8JztrRAFviY,4126
|
|
6
|
+
truefoundry/autodeploy/agents/project_identifier.py,sha256=wOFCUIbN-3mVQEToJ2svKm8XvxZ_IxIvUF2P3VqQu94,4438
|
|
7
|
+
truefoundry/autodeploy/agents/tester.py,sha256=Ci-382r3R8M1NCpbnmcBBHZa4UBCVjyrrt5bwufHDm4,2352
|
|
8
|
+
truefoundry/autodeploy/cli.py,sha256=hUY9MbxOJ31k2uOjKaQuHCmJILHECF6Q55i3rhlNRGE,12317
|
|
9
|
+
truefoundry/autodeploy/constants.py,sha256=iloavf3CQk9WiMdOBnSkdYRM_mr_aWeBGpj3I4Zluso,1111
|
|
10
|
+
truefoundry/autodeploy/exception.py,sha256=BHqbkN-RdEsrfqPHQhWwSHiWnwQ6eaBc7PGGEXjJ3RY,54
|
|
11
|
+
truefoundry/autodeploy/logger.py,sha256=tkV2UKcOTFl5nz0cn4eRbzxF-2CZd8b7MK9vnhaflYw,325
|
|
12
|
+
truefoundry/autodeploy/tools/__init__.py,sha256=9zJiC1d4bv9EL-p5XTCa9fAQ6ZKV--AbgeLz9bBBkyQ,875
|
|
13
|
+
truefoundry/autodeploy/tools/ask.py,sha256=MxUFLP7rjpdJ85gCc3El0wUqTZDjpjAw7WOTdV4LLWE,856
|
|
14
|
+
truefoundry/autodeploy/tools/base.py,sha256=X7bBhJ2-mkc1_uo9dLtIoZOgKsvoCsmvCzdh_j0rdys,665
|
|
15
|
+
truefoundry/autodeploy/tools/commit.py,sha256=s-hdFcaFc-rA37XFP9jdxqjN2n3_lDo6z81aSd3X6k8,5892
|
|
16
|
+
truefoundry/autodeploy/tools/docker_build.py,sha256=6LfWLJYh3Y3kCIVOC8lFcZjWHIk3iWEuw_qoAxx642k,3931
|
|
17
|
+
truefoundry/autodeploy/tools/docker_run.py,sha256=6KPLzKtvTj8skN_Acr-0DaS0B-NgV8iDoWAh5gvWV44,5078
|
|
18
|
+
truefoundry/autodeploy/tools/file_type_counts.py,sha256=4p6IHp-j1vBzELpepFhNwfmB88cUUAFdVDQdzv4lGtM,2288
|
|
19
|
+
truefoundry/autodeploy/tools/list_files.py,sha256=9z_Nih_N8v7qe14znl7_-3MKZjw5RylVyy7L8qvU1es,2577
|
|
20
|
+
truefoundry/autodeploy/tools/read_file.py,sha256=h1xdwRMxuRTLX4ZprzSgfkpuu52FbYNrQUJDBW3Ck4A,1751
|
|
21
|
+
truefoundry/autodeploy/tools/send_request.py,sha256=5q_fAo0tXRiHg9M3XpdwhCzUtDUWVh17239oU4LkZfI,1614
|
|
22
|
+
truefoundry/autodeploy/tools/write_file.py,sha256=EcYetnJ4X-NWsd_CdYUKfOnAdz2XXiRukTzJfb_GzFs,3130
|
|
23
|
+
truefoundry/autodeploy/utils/diff.py,sha256=Ef8Y-VffDKel_-q-GxRam6gqiv8qTLMcqVg6iifXfcA,5358
|
|
24
|
+
truefoundry/autodeploy/utils/pydantic_compat.py,sha256=hEAUy5kLjhPdzw7yGZ2iXGMXbbMVXVlGzIofmyHafXQ,412
|
|
25
|
+
truefoundry/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
truefoundry/cli/__main__.py,sha256=Jap_IddZ9zNyMIyIkCw75xHQCN0WtV2dPZJ_pzdLsVc,916
|
|
27
|
+
truefoundry/deploy/__init__.py,sha256=wDQq3y-t9zOEOVA61t15fRpAVQSpBtiWTyW5hVn1iz4,43
|
|
28
|
+
truefoundry/deploy/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
truefoundry/deploy/cli/cli.py,sha256=R4SmXyEUqPwkzKNAHMs2vcWW5-qE64DldPisLDGNVdo,2994
|
|
30
|
+
truefoundry/deploy/cli/deploy.py,sha256=ZOvEa9QNlgjHiVxitmQSL88cBSK2tZ1DTuGs3Iu9Gf4,5524
|
|
31
|
+
truefoundry/langchain/__init__.py,sha256=kQrM0qr2EoB-EFaPkVVVcmSBSJ8KsQzv0nx-LGzmCRo,53
|
|
32
|
+
truefoundry/ml/__init__.py,sha256=yFjvF-e1RW488vLHgn5M7TXoajqww6grkKHb3mhqDEw,179
|
|
33
|
+
truefoundry-0.2.0.dist-info/METADATA,sha256=X7-7LDmtHCyIaVMfD6CF61MSktD_9pAw3PSgyt59Yts,1829
|
|
34
|
+
truefoundry-0.2.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
35
|
+
truefoundry-0.2.0.dist-info/entry_points.txt,sha256=TXvUxQkI6zmqJuycPsyxEIMr3oqfDjgrWj0m_9X12x4,95
|
|
36
|
+
truefoundry-0.2.0.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
truefoundry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
truefoundry/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
truefoundry/cli/__main__.py,sha256=AOayL_PxcWZ8Qn2fGX_JMvlyd2bhKImFYolxJZh2WI4,794
|
|
4
|
-
truefoundry/deploy/__init__.py,sha256=rY-AcjgSmu0r072rdUNpRkMmDFC7hH9drF5_pIN5jnw,29
|
|
5
|
-
truefoundry/langchain/__init__.py,sha256=R1h2DkLLsVLPh3xVVzU2H_kpN4LNgzx3mPCcGVr2u5g,39
|
|
6
|
-
truefoundry/ml/__init__.py,sha256=SJiI5QimXJETfME2x0iXz8gPn6C22YNiLiEdHIV1g7c,151
|
|
7
|
-
truefoundry-0.1.2.dist-info/METADATA,sha256=UjIwn98qoC0Jwd1wVbKiREJKF4RkLbjFACMe-N5Gy2c,1502
|
|
8
|
-
truefoundry-0.1.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
9
|
-
truefoundry-0.1.2.dist-info/entry_points.txt,sha256=TXvUxQkI6zmqJuycPsyxEIMr3oqfDjgrWj0m_9X12x4,95
|
|
10
|
-
truefoundry-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|