truefoundry 0.3.0rc9__tar.gz → 0.3.0rc11__tar.gz
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-0.3.0rc9 → truefoundry-0.3.0rc11}/PKG-INFO +2 -2
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/pyproject.toml +2 -2
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/__init__.py +1 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/cli.py +2 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/trigger_command.py +58 -0
- truefoundry-0.3.0rc11/truefoundry/deploy/lib/auth/auth_service_client.py +181 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/auth/credential_provider.py +2 -2
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/clients/servicefoundry_client.py +36 -11
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/dao/application.py +20 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/model/entity.py +17 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/session.py +20 -8
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/util.py +20 -0
- truefoundry-0.3.0rc9/truefoundry/deploy/lib/auth/auth_service_client.py +0 -81
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/README.md +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/agents/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/agents/base.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/agents/developer.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/agents/project_identifier.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/agents/tester.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/cli.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/constants.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/exception.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/logger.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/ask.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/base.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/commit.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/docker_build.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/docker_run.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/file_type_counts.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/list_files.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/read_file.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/send_request.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/write_file.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/utils/client.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/utils/diff.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/utils/pydantic_compat.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/cli/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/cli/__main__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/auto_gen/models.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/dockerfile.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/docker_service.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/apply_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/build_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/build_logs_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/create_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/delete_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/deploy_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/get_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/list_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/login_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/logout_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/logs_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/patch_application_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/patch_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/redeploy_command.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/terminate_comand.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/config.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/console.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/const.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/display_util.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/util.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/core/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/core/login.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/core/logout.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/__main__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/app.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/build.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/remote/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/remote/context.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/remote/method.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/remote/remote.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/route.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/service.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/utils.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/io/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/io/output_callback.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/io/rich_output_callback.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/json_util.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/auth/credential_file_manager.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/auth/servicefoundry_session.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/clients/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/clients/shell_client.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/clients/utils.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/const.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/dao/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/dao/apply.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/dao/version.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/dao/workspace.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/exceptions.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/logs_utils.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/messages.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/model/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/win32.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/lib/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/lib/deploy.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/lib/deploy_workflow.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/lib/deployable_patched_models.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/lib/models.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/lib/patched_models.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/v2/lib/source.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/langchain/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/langchain/deprecated.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/langchain/truefoundry_chat.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/langchain/truefoundry_embeddings.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/langchain/truefoundry_llm.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/langchain/utils.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/logger.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/ml/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/pydantic_v1.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/python_deploy_codegen.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/version.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/__init__.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/container_task.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/example/deploy.sh +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/example/hello_world_package/workflow.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/example/package/test_workflow.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/example/truefoundry.yaml +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/example/workflow.yaml +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/map_task.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/python_task.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/task.py +0 -0
- {truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: truefoundry
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.0rc11
|
|
4
4
|
Summary: Truefoundry CLI
|
|
5
5
|
Author: Abhishek Choudhary
|
|
6
6
|
Author-email: abhishek@truefoundry.com
|
|
@@ -24,7 +24,7 @@ Requires-Dist: flytekit (==1.12.2) ; extra == "workflow"
|
|
|
24
24
|
Requires-Dist: gitignorefile (>=1.1.2,<1.2.0)
|
|
25
25
|
Requires-Dist: importlib-metadata (>=6.0.1,<8.0.0)
|
|
26
26
|
Requires-Dist: importlib-resources (>=5.2.0,<6.0.0)
|
|
27
|
-
Requires-Dist: mlfoundry (==0.11.
|
|
27
|
+
Requires-Dist: mlfoundry (==0.11.4) ; extra == "ml"
|
|
28
28
|
Requires-Dist: openai (>=1.16.2,<2.0.0)
|
|
29
29
|
Requires-Dist: packaging (>=20.0,<25.0)
|
|
30
30
|
Requires-Dist: pydantic (>=1.10.0,<3)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "truefoundry"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.0rc11"
|
|
4
4
|
description = "Truefoundry CLI"
|
|
5
5
|
authors = ["Abhishek Choudhary <abhishek@truefoundry.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -17,7 +17,7 @@ GitPython = ">=3.1.43,<3.2.0"
|
|
|
17
17
|
importlib-metadata = ">=6.0.1,<8.0.0"
|
|
18
18
|
importlib-resources = "^5.2.0"
|
|
19
19
|
Mako = "^1.1.6"
|
|
20
|
-
mlfoundry = { version = "0.11.
|
|
20
|
+
mlfoundry = { version = "0.11.4", optional = true }
|
|
21
21
|
openai = ">=1.16.2,<2.0.0"
|
|
22
22
|
packaging = ">=20.0,<25.0"
|
|
23
23
|
pydantic = ">=1.10.0,<3"
|
|
@@ -13,6 +13,7 @@ from truefoundry.deploy.cli.commands import (
|
|
|
13
13
|
get_logout_command,
|
|
14
14
|
get_patch_application_command,
|
|
15
15
|
get_patch_command,
|
|
16
|
+
get_trigger_command,
|
|
16
17
|
)
|
|
17
18
|
from truefoundry.deploy.cli.config import CliConfig
|
|
18
19
|
from truefoundry.deploy.cli.const import GROUP_CLS
|
|
@@ -36,6 +37,7 @@ def create_truefoundry_cli():
|
|
|
36
37
|
cli.add_command(get_deploy_command())
|
|
37
38
|
cli.add_command(get_patch_application_command())
|
|
38
39
|
cli.add_command(get_delete_command())
|
|
40
|
+
cli.add_command(get_trigger_command())
|
|
39
41
|
|
|
40
42
|
if not (sys.platform.startswith("win32") or sys.platform.startswith("cygwin")):
|
|
41
43
|
cli.add_command(get_patch_command())
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/trigger_command.py
RENAMED
|
@@ -82,6 +82,64 @@ def trigger_job(application_fqn: str, command: Optional[Sequence[str]], params):
|
|
|
82
82
|
)
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
@click.command(
|
|
86
|
+
name="workflow",
|
|
87
|
+
cls=COMMAND_CLS,
|
|
88
|
+
context_settings={"ignore_unknown_options": True, "allow_extra_args": True},
|
|
89
|
+
)
|
|
90
|
+
@click.option(
|
|
91
|
+
"--application-fqn",
|
|
92
|
+
"--application_fqn",
|
|
93
|
+
type=click.STRING,
|
|
94
|
+
required=True,
|
|
95
|
+
help="FQN of the workflow application",
|
|
96
|
+
)
|
|
97
|
+
@click.argument(
|
|
98
|
+
"inputs",
|
|
99
|
+
type=click.STRING,
|
|
100
|
+
nargs=-1,
|
|
101
|
+
required=False,
|
|
102
|
+
)
|
|
103
|
+
@handle_exception_wrapper
|
|
104
|
+
def trigger_workflow(application_fqn: str, inputs):
|
|
105
|
+
"""
|
|
106
|
+
Trigger a Workflow on TrueFoundry
|
|
107
|
+
|
|
108
|
+
[b]tfy trigger workflow --application-fqn "my-cluster:my-workspace:my-workflow"[/]
|
|
109
|
+
|
|
110
|
+
\n
|
|
111
|
+
Additionally, you can pass inputs (if defined in the workflow)\n\n
|
|
112
|
+
|
|
113
|
+
Passing inputs:
|
|
114
|
+
|
|
115
|
+
[b]tfy trigger workflow --application-fqn "my-cluster:my-workspace:my-workflow" -- --input1_name input1_value --input2_name input2_value ...[/]
|
|
116
|
+
"""
|
|
117
|
+
if inputs:
|
|
118
|
+
inputs_dict = {}
|
|
119
|
+
if len(inputs) % 2 != 0:
|
|
120
|
+
raise ClickException(
|
|
121
|
+
f"Found odd number of argument pairs: {inputs}. "
|
|
122
|
+
"Perhaps you forgot to pass a value for one of the inputs? "
|
|
123
|
+
"inputs for workflow should be passed in the "
|
|
124
|
+
"format `--input1_name input1_value --input2_name input2_value ...`"
|
|
125
|
+
)
|
|
126
|
+
for i in range(0, len(inputs), 2):
|
|
127
|
+
key = inputs[i]
|
|
128
|
+
value = inputs[i + 1]
|
|
129
|
+
if not key.startswith("--"):
|
|
130
|
+
raise ClickException(
|
|
131
|
+
f"Got ambiguous argument {key!r} in inputs: {inputs}. "
|
|
132
|
+
f"input names should be prefixed with '--' i.e. "
|
|
133
|
+
"inputs for workflow should be passed in the "
|
|
134
|
+
"format `--input1_name input1_value --input2_name input2_value ...`"
|
|
135
|
+
)
|
|
136
|
+
key = key.lstrip("-")
|
|
137
|
+
inputs_dict[key] = value
|
|
138
|
+
|
|
139
|
+
application.trigger_workflow(application_fqn=application_fqn, inputs=inputs)
|
|
140
|
+
|
|
141
|
+
|
|
85
142
|
def get_trigger_command():
|
|
86
143
|
trigger_command.add_command(trigger_job)
|
|
144
|
+
trigger_command.add_command(trigger_workflow)
|
|
87
145
|
return trigger_command
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from truefoundry.deploy.lib.clients.utils import poll_for_function, request_handling
|
|
7
|
+
from truefoundry.deploy.lib.const import VERSION_PREFIX
|
|
8
|
+
from truefoundry.deploy.lib.exceptions import BadRequestException
|
|
9
|
+
from truefoundry.deploy.lib.model.entity import DeviceCode, Token
|
|
10
|
+
from truefoundry.logger import logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AuthServiceClient(ABC):
|
|
14
|
+
def __init__(self, base_url):
|
|
15
|
+
from truefoundry.deploy.lib.clients.servicefoundry_client import (
|
|
16
|
+
ServiceFoundryServiceClient,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
client = ServiceFoundryServiceClient(init_session=False, base_url=base_url)
|
|
20
|
+
|
|
21
|
+
self._api_server_url = client._api_server_url
|
|
22
|
+
self._auth_server_url = client.tenant_info.auth_server_url
|
|
23
|
+
self._tenant_name = client.tenant_info.tenant_name
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def from_base_url(cls, base_url: str) -> "AuthServiceClient":
|
|
27
|
+
from truefoundry.deploy.lib.clients.servicefoundry_client import (
|
|
28
|
+
ServiceFoundryServiceClient,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
client = ServiceFoundryServiceClient(init_session=False, base_url=base_url)
|
|
32
|
+
if client.python_sdk_config.use_sfy_server_auth_apis:
|
|
33
|
+
return ServiceFoundryServerAuthServiceClient(base_url)
|
|
34
|
+
return AuthServerServiceClient(base_url)
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def refresh_token(self, token: Token, host: str = None) -> Token: ...
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def get_device_code(self) -> DeviceCode: ...
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def get_token_from_device_code(
|
|
44
|
+
self, device_code: str, timeout: float = 60, poll_interval_seconds: int = 1
|
|
45
|
+
) -> Token: ...
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ServiceFoundryServerAuthServiceClient(AuthServiceClient):
|
|
49
|
+
def __init__(self, base_url):
|
|
50
|
+
super().__init__(base_url)
|
|
51
|
+
|
|
52
|
+
def refresh_token(self, token: Token, host: str = None) -> Token:
|
|
53
|
+
host_arg_str = f"--host {host}" if host else "--host HOST"
|
|
54
|
+
if not token.refresh_token:
|
|
55
|
+
# TODO: Add a way to propagate error messages without traceback to the output interface side
|
|
56
|
+
raise Exception(
|
|
57
|
+
f"Unable to resume login session. Please log in again using `tfy login {host_arg_str} --relogin`"
|
|
58
|
+
)
|
|
59
|
+
url = f"{self._api_server_url}/{VERSION_PREFIX}/oauth2/token"
|
|
60
|
+
data = {
|
|
61
|
+
"tenantName": token.tenant_name,
|
|
62
|
+
"refreshToken": token.refresh_token,
|
|
63
|
+
"grantType": "refresh_token",
|
|
64
|
+
"returnJWT": True,
|
|
65
|
+
}
|
|
66
|
+
res = requests.post(url, json=data)
|
|
67
|
+
try:
|
|
68
|
+
res = request_handling(res)
|
|
69
|
+
return Token.parse_obj(res)
|
|
70
|
+
except BadRequestException as ex:
|
|
71
|
+
raise Exception(
|
|
72
|
+
f"Unable to resume login session. Please log in again using `tfy login {host_arg_str} --relogin`"
|
|
73
|
+
) from ex
|
|
74
|
+
|
|
75
|
+
def get_device_code(self) -> DeviceCode:
|
|
76
|
+
url = f"{self._api_server_url}/{VERSION_PREFIX}/oauth2/device-authorize"
|
|
77
|
+
data = {"tenantName": self._tenant_name}
|
|
78
|
+
res = requests.post(url, json=data)
|
|
79
|
+
res = request_handling(res)
|
|
80
|
+
# TODO: temporary cleanup of incorrect attributes
|
|
81
|
+
res = {"userCode": res.get("userCode"), "deviceCode": res.get("deviceCode")}
|
|
82
|
+
return DeviceCode.parse_obj(res)
|
|
83
|
+
|
|
84
|
+
def get_token_from_device_code(
|
|
85
|
+
self, device_code: str, timeout: float = 60, poll_interval_seconds: int = 1
|
|
86
|
+
) -> Token:
|
|
87
|
+
timeout = timeout or 60
|
|
88
|
+
poll_interval_seconds = poll_interval_seconds or 1
|
|
89
|
+
url = f"{self._api_server_url}/{VERSION_PREFIX}/oauth2/token"
|
|
90
|
+
data = {
|
|
91
|
+
"tenantName": self._tenant_name,
|
|
92
|
+
"deviceCode": device_code,
|
|
93
|
+
"grantType": "device_code",
|
|
94
|
+
"returnJWT": True,
|
|
95
|
+
}
|
|
96
|
+
response = requests.post(url=url, json=data)
|
|
97
|
+
start_time = time.monotonic()
|
|
98
|
+
|
|
99
|
+
for response in poll_for_function(
|
|
100
|
+
requests.post, poll_after_secs=poll_interval_seconds, url=url, json=data
|
|
101
|
+
):
|
|
102
|
+
if response.status_code == 201:
|
|
103
|
+
response = response.json()
|
|
104
|
+
return Token.parse_obj(response)
|
|
105
|
+
elif response.status_code == 202:
|
|
106
|
+
logger.debug("User has not authorized yet. Checking again.")
|
|
107
|
+
else:
|
|
108
|
+
raise Exception(
|
|
109
|
+
"Failed to get token using device code. "
|
|
110
|
+
f"status_code {response.status_code},\n {response.text}"
|
|
111
|
+
)
|
|
112
|
+
time_elapsed = time.monotonic() - start_time
|
|
113
|
+
if time_elapsed > timeout:
|
|
114
|
+
logger.warning("Polled server for %s secs.", int(time_elapsed))
|
|
115
|
+
break
|
|
116
|
+
|
|
117
|
+
raise Exception(f"Did not get authorized within {timeout} seconds.")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class AuthServerServiceClient(AuthServiceClient):
|
|
121
|
+
def __init__(self, base_url):
|
|
122
|
+
super().__init__(base_url)
|
|
123
|
+
|
|
124
|
+
def refresh_token(self, token: Token, host: str = None) -> Token:
|
|
125
|
+
host_arg_str = f"--host {host}" if host else "--host HOST"
|
|
126
|
+
if not token.refresh_token:
|
|
127
|
+
# TODO: Add a way to propagate error messages without traceback to the output interface side
|
|
128
|
+
raise Exception(
|
|
129
|
+
f"Unable to resume login session. Please log in again using `tfy login {host_arg_str} --relogin`"
|
|
130
|
+
)
|
|
131
|
+
url = f"{self._auth_server_url}/api/{VERSION_PREFIX}/oauth/token/refresh"
|
|
132
|
+
data = {
|
|
133
|
+
"tenantName": token.tenant_name,
|
|
134
|
+
"refreshToken": token.refresh_token,
|
|
135
|
+
}
|
|
136
|
+
res = requests.post(url, json=data)
|
|
137
|
+
try:
|
|
138
|
+
res = request_handling(res)
|
|
139
|
+
return Token.parse_obj(res)
|
|
140
|
+
except BadRequestException as ex:
|
|
141
|
+
raise Exception(
|
|
142
|
+
f"Unable to resume login session. Please log in again using `tfy login {host_arg_str} --relogin`"
|
|
143
|
+
) from ex
|
|
144
|
+
|
|
145
|
+
def get_device_code(self) -> DeviceCode:
|
|
146
|
+
url = f"{self._auth_server_url}/api/{VERSION_PREFIX}/oauth/device"
|
|
147
|
+
data = {"tenantName": self._tenant_name}
|
|
148
|
+
res = requests.post(url, json=data)
|
|
149
|
+
res = request_handling(res)
|
|
150
|
+
return DeviceCode.parse_obj(res)
|
|
151
|
+
|
|
152
|
+
def get_token_from_device_code(
|
|
153
|
+
self, device_code: str, timeout: float = 60, poll_interval_seconds: int = 1
|
|
154
|
+
) -> Token:
|
|
155
|
+
url = f"{self._auth_server_url}/api/{VERSION_PREFIX}/oauth/device/token"
|
|
156
|
+
data = {
|
|
157
|
+
"tenantName": self._tenant_name,
|
|
158
|
+
"deviceCode": device_code,
|
|
159
|
+
}
|
|
160
|
+
start_time = time.monotonic()
|
|
161
|
+
poll_interval_seconds = 1
|
|
162
|
+
|
|
163
|
+
for response in poll_for_function(
|
|
164
|
+
requests.post, poll_after_secs=poll_interval_seconds, url=url, json=data
|
|
165
|
+
):
|
|
166
|
+
if response.status_code == 201:
|
|
167
|
+
response = response.json()
|
|
168
|
+
return Token.parse_obj(response)
|
|
169
|
+
elif response.status_code == 202:
|
|
170
|
+
logger.debug("User has not authorized yet. Checking again.")
|
|
171
|
+
else:
|
|
172
|
+
raise Exception(
|
|
173
|
+
"Failed to get token using device code. "
|
|
174
|
+
f"status_code {response.status_code},\n {response.text}"
|
|
175
|
+
)
|
|
176
|
+
time_elapsed = time.monotonic() - start_time
|
|
177
|
+
if time_elapsed > timeout:
|
|
178
|
+
logger.warning("Polled server for %s secs.", int(time_elapsed))
|
|
179
|
+
break
|
|
180
|
+
|
|
181
|
+
raise Exception(f"Did not get authorized within {timeout} seconds.")
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/auth/credential_provider.py
RENAMED
|
@@ -44,7 +44,7 @@ class EnvCredentialProvider(CredentialProvider):
|
|
|
44
44
|
# TODO: Read host from cred file as well.
|
|
45
45
|
base_url = resolve_base_url().strip("/")
|
|
46
46
|
self._host = base_url
|
|
47
|
-
self._auth_service = AuthServiceClient(base_url=base_url)
|
|
47
|
+
self._auth_service = AuthServiceClient.from_base_url(base_url=base_url)
|
|
48
48
|
|
|
49
49
|
servicefoundry_client = ServiceFoundryServiceClient(
|
|
50
50
|
init_session=False, base_url=base_url
|
|
@@ -82,7 +82,7 @@ class FileCredentialProvider(CredentialProvider):
|
|
|
82
82
|
self._token = self._last_cred_file_content.to_token()
|
|
83
83
|
self._host = self._last_cred_file_content.host
|
|
84
84
|
|
|
85
|
-
self._auth_service = AuthServiceClient(base_url=self._host)
|
|
85
|
+
self._auth_service = AuthServiceClient.from_base_url(base_url=self._host)
|
|
86
86
|
|
|
87
87
|
@staticmethod
|
|
88
88
|
def can_provide() -> bool:
|
|
@@ -26,12 +26,14 @@ from truefoundry.deploy.lib.model.entity import (
|
|
|
26
26
|
Deployment,
|
|
27
27
|
DockerRegistryCredentials,
|
|
28
28
|
JobRun,
|
|
29
|
+
PythonSDKConfig,
|
|
29
30
|
TenantInfo,
|
|
30
31
|
Token,
|
|
31
32
|
TriggerJobResult,
|
|
32
33
|
Workspace,
|
|
33
34
|
WorkspaceResources,
|
|
34
35
|
)
|
|
36
|
+
from truefoundry.deploy.lib.util import timed_lru_cache
|
|
35
37
|
from truefoundry.deploy.lib.win32 import allow_interrupt
|
|
36
38
|
from truefoundry.deploy.v2.lib.models import (
|
|
37
39
|
AppDeploymentStatusResponse,
|
|
@@ -93,6 +95,24 @@ def check_min_cli_version(fn):
|
|
|
93
95
|
return inner
|
|
94
96
|
|
|
95
97
|
|
|
98
|
+
@timed_lru_cache(seconds=30 * 60)
|
|
99
|
+
def _cached_get_tenant_info(api_server_url: str) -> TenantInfo:
|
|
100
|
+
res = requests.get(
|
|
101
|
+
url=f"{api_server_url}/v1/tenant-id",
|
|
102
|
+
params={"hostName": urlparse(api_server_url).netloc},
|
|
103
|
+
)
|
|
104
|
+
res = request_handling(res)
|
|
105
|
+
return TenantInfo.parse_obj(res)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@timed_lru_cache(seconds=30 * 60)
|
|
109
|
+
def _cached_get_python_sdk_config(api_server_url: str) -> PythonSDKConfig:
|
|
110
|
+
url = f"{api_server_url}/v1/min-cli-version"
|
|
111
|
+
res = requests.get(url)
|
|
112
|
+
res = request_handling(res)
|
|
113
|
+
return PythonSDKConfig.parse_obj(res)
|
|
114
|
+
|
|
115
|
+
|
|
96
116
|
class ServiceFoundryServiceClient:
|
|
97
117
|
def __init__(self, init_session: bool = True, base_url: Optional[str] = None):
|
|
98
118
|
self._session: Optional[ServiceFoundrySession] = None
|
|
@@ -111,20 +131,19 @@ class ServiceFoundryServiceClient:
|
|
|
111
131
|
def base_url(self) -> str:
|
|
112
132
|
return self._base_url
|
|
113
133
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return
|
|
134
|
+
@property
|
|
135
|
+
def tenant_info(self) -> TenantInfo:
|
|
136
|
+
return _cached_get_tenant_info(self._api_server_url)
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def python_sdk_config(self) -> PythonSDKConfig:
|
|
140
|
+
return _cached_get_python_sdk_config(self._api_server_url)
|
|
121
141
|
|
|
122
142
|
@functools.cached_property
|
|
123
143
|
def _min_cli_version_required(self) -> str:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return res["truefoundryCliMinVersion"]
|
|
144
|
+
return _cached_get_python_sdk_config(
|
|
145
|
+
self._api_server_url
|
|
146
|
+
).truefoundry_cli_min_version
|
|
128
147
|
|
|
129
148
|
def _get_header(self):
|
|
130
149
|
if not self._session:
|
|
@@ -616,6 +635,12 @@ class ServiceFoundryServiceClient:
|
|
|
616
635
|
response = request_handling(res)
|
|
617
636
|
return TriggerJobResult.parse_obj(response)
|
|
618
637
|
|
|
638
|
+
def trigger_workflow(self, application_id: str, inputs: Dict[str, Any]):
|
|
639
|
+
url = f"{self._api_server_url}/{VERSION_PREFIX}/workflow/{application_id}/executions"
|
|
640
|
+
res = requests.post(url, json=inputs, headers=self._get_header())
|
|
641
|
+
response = request_handling(res)
|
|
642
|
+
return response
|
|
643
|
+
|
|
619
644
|
@check_min_cli_version
|
|
620
645
|
def get_docker_registry_creds(
|
|
621
646
|
self, docker_registry_fqn: str, cluster_id: str
|
|
@@ -241,3 +241,23 @@ def terminate_job_run(
|
|
|
241
241
|
job_run_name=job_run_name,
|
|
242
242
|
)
|
|
243
243
|
return response
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def trigger_workflow(application_fqn: str, inputs: Optional[Dict[str, Any]] = None):
|
|
247
|
+
inputs = inputs or {}
|
|
248
|
+
client = ServiceFoundryServiceClient()
|
|
249
|
+
_application_info = client.get_application_info_by_fqn(
|
|
250
|
+
application_fqn=application_fqn
|
|
251
|
+
)
|
|
252
|
+
application_info = client.get_application_info(
|
|
253
|
+
application_id=_application_info.applicationId
|
|
254
|
+
)
|
|
255
|
+
client.trigger_workflow(
|
|
256
|
+
application_id=application_info.id,
|
|
257
|
+
inputs=inputs,
|
|
258
|
+
)
|
|
259
|
+
logger.info(f"Started Execution for Workflow: {application_info.name}")
|
|
260
|
+
executions_page = (
|
|
261
|
+
f"{client.base_url.strip('/')}/deployments/{application_info.id}?tab=executions"
|
|
262
|
+
)
|
|
263
|
+
logger.info(f"You can check the executions at {executions_page}")
|
|
@@ -297,6 +297,11 @@ class CredentialsFileContent(BaseModel):
|
|
|
297
297
|
class DeviceCode(BaseModel):
|
|
298
298
|
user_code: str = Field(alias="userCode")
|
|
299
299
|
device_code: str = Field(alias="deviceCode")
|
|
300
|
+
verification_url: Optional[str] = Field(alias="verificationURI")
|
|
301
|
+
complete_verification_url: Optional[str] = Field(alias="verificationURIComplete")
|
|
302
|
+
expires_in_seconds: int = Field(alias="expiresInSeconds", default=60)
|
|
303
|
+
interval_in_seconds: int = Field(alias="intervalInSeconds", default=1)
|
|
304
|
+
message: Optional[str] = Field(alias="message")
|
|
300
305
|
|
|
301
306
|
class Config:
|
|
302
307
|
allow_population_by_field_name = True
|
|
@@ -306,6 +311,18 @@ class DeviceCode(BaseModel):
|
|
|
306
311
|
return f"{auth_host}/authorize/device?userCode={self.user_code}"
|
|
307
312
|
|
|
308
313
|
|
|
314
|
+
class PythonSDKConfig(BaseModel):
|
|
315
|
+
min_version: str = Field(alias="minVersion")
|
|
316
|
+
truefoundry_cli_min_version: str = Field(alias="truefoundryCliMinVersion")
|
|
317
|
+
use_sfy_server_auth_apis: Optional[bool] = Field(
|
|
318
|
+
alias="useSFYServerAuthAPIs", default=False
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
class Config:
|
|
322
|
+
allow_population_by_field_name = True
|
|
323
|
+
allow_mutation = False
|
|
324
|
+
|
|
325
|
+
|
|
309
326
|
class JobRun(Base):
|
|
310
327
|
name: str
|
|
311
328
|
applicationName: str
|
|
@@ -92,7 +92,7 @@ def login(
|
|
|
92
92
|
api_key=api_key, servicefoundry_client=servicefoundry_client
|
|
93
93
|
)
|
|
94
94
|
else:
|
|
95
|
-
auth_service = AuthServiceClient(base_url=host)
|
|
95
|
+
auth_service = AuthServiceClient.from_base_url(base_url=host)
|
|
96
96
|
# interactive login
|
|
97
97
|
token = _login_with_device_code(base_url=host, auth_service=auth_service)
|
|
98
98
|
|
|
@@ -136,11 +136,23 @@ def _login_with_device_code(
|
|
|
136
136
|
) -> Token:
|
|
137
137
|
logger.debug("Logging in with device code")
|
|
138
138
|
device_code = auth_service.get_device_code()
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
139
|
+
auto_open_url = None
|
|
140
|
+
message = "Please click on the above link if it is not automatically opened in a browser window."
|
|
141
|
+
if device_code.complete_verification_url:
|
|
142
|
+
auto_open_url = device_code.complete_verification_url
|
|
143
|
+
elif device_code.verification_url:
|
|
144
|
+
if device_code.message:
|
|
145
|
+
message = device_code.message
|
|
146
|
+
else:
|
|
147
|
+
message = f"Please open the following URL in a browser and enter the code {device_code.user_code} when prompted: {device_code.verification_url}"
|
|
148
|
+
else:
|
|
149
|
+
auto_open_url = device_code.get_user_clickable_url(auth_host=base_url)
|
|
150
|
+
output_hook.print_line(message)
|
|
151
|
+
if auto_open_url:
|
|
152
|
+
output_hook.print_line(f"Opening:- {auto_open_url}")
|
|
153
|
+
click.launch(auto_open_url)
|
|
154
|
+
return auth_service.get_token_from_device_code(
|
|
155
|
+
device_code=device_code.device_code,
|
|
156
|
+
timeout=device_code.expires_in_seconds,
|
|
157
|
+
poll_interval_seconds=device_code.interval_in_seconds,
|
|
144
158
|
)
|
|
145
|
-
click.launch(url_to_go)
|
|
146
|
-
return auth_service.get_token_from_device_code(device_code=device_code.device_code)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
|
+
from functools import lru_cache, wraps
|
|
4
|
+
from time import monotonic_ns
|
|
3
5
|
from typing import Union
|
|
4
6
|
|
|
5
7
|
from truefoundry.deploy.lib.const import (
|
|
@@ -68,3 +70,21 @@ def find_list_paths(data, parent_key="", sep="."):
|
|
|
68
70
|
new_key = f"{parent_key}[{i}]"
|
|
69
71
|
list_paths.extend(find_list_paths(value, new_key, sep))
|
|
70
72
|
return list_paths
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def timed_lru_cache(seconds: int = 300, maxsize: int = None):
|
|
76
|
+
def wrapper_cache(func):
|
|
77
|
+
func = lru_cache(maxsize=maxsize)(func)
|
|
78
|
+
func.delta = seconds * 10**9
|
|
79
|
+
func.expiration = monotonic_ns() + func.delta
|
|
80
|
+
|
|
81
|
+
@wraps(func)
|
|
82
|
+
def wrapped_func(*args, **kwargs):
|
|
83
|
+
if monotonic_ns() >= func.expiration:
|
|
84
|
+
func.cache_clear()
|
|
85
|
+
func.expiration = monotonic_ns() + func.delta
|
|
86
|
+
return func(*args, **kwargs)
|
|
87
|
+
|
|
88
|
+
return wrapped_func
|
|
89
|
+
|
|
90
|
+
return wrapper_cache
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
|
|
3
|
-
import requests
|
|
4
|
-
|
|
5
|
-
from truefoundry.deploy.lib.clients.utils import poll_for_function, request_handling
|
|
6
|
-
from truefoundry.deploy.lib.const import VERSION_PREFIX
|
|
7
|
-
from truefoundry.deploy.lib.exceptions import BadRequestException
|
|
8
|
-
from truefoundry.deploy.lib.model.entity import DeviceCode, Token
|
|
9
|
-
from truefoundry.logger import logger
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class AuthServiceClient:
|
|
13
|
-
def __init__(self, base_url):
|
|
14
|
-
from truefoundry.deploy.lib.clients.servicefoundry_client import (
|
|
15
|
-
ServiceFoundryServiceClient,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
client = ServiceFoundryServiceClient(init_session=False, base_url=base_url)
|
|
19
|
-
tenant_info = client.get_tenant_info()
|
|
20
|
-
|
|
21
|
-
self._auth_server_url = tenant_info.auth_server_url
|
|
22
|
-
self._tenant_name = tenant_info.tenant_name
|
|
23
|
-
|
|
24
|
-
def refresh_token(self, token: Token, host: str = None) -> Token:
|
|
25
|
-
host_arg_str = f"--host {host}" if host else "--host HOST"
|
|
26
|
-
if not token.refresh_token:
|
|
27
|
-
# TODO: Add a way to propagate error messages without traceback to the output interface side
|
|
28
|
-
raise Exception(
|
|
29
|
-
f"Unable to resume login session. Please log in again using `tfy login {host_arg_str} --relogin`"
|
|
30
|
-
)
|
|
31
|
-
url = f"{self._auth_server_url}/api/{VERSION_PREFIX}/oauth/token/refresh"
|
|
32
|
-
data = {
|
|
33
|
-
"tenantName": token.tenant_name,
|
|
34
|
-
"refreshToken": token.refresh_token,
|
|
35
|
-
}
|
|
36
|
-
res = requests.post(url, data=data)
|
|
37
|
-
try:
|
|
38
|
-
res = request_handling(res)
|
|
39
|
-
return Token.parse_obj(res)
|
|
40
|
-
except BadRequestException as ex:
|
|
41
|
-
raise Exception(
|
|
42
|
-
f"Unable to resume login session. Please log in again using `tfy login {host_arg_str} --relogin`"
|
|
43
|
-
) from ex
|
|
44
|
-
|
|
45
|
-
def get_device_code(self) -> DeviceCode:
|
|
46
|
-
url = f"{self._auth_server_url}/api/{VERSION_PREFIX}/oauth/device"
|
|
47
|
-
data = {"tenantName": self._tenant_name}
|
|
48
|
-
res = requests.post(url, data=data)
|
|
49
|
-
res = request_handling(res)
|
|
50
|
-
return DeviceCode.parse_obj(res)
|
|
51
|
-
|
|
52
|
-
def get_token_from_device_code(
|
|
53
|
-
self, device_code: str, timeout: float = 60
|
|
54
|
-
) -> Token:
|
|
55
|
-
url = f"{self._auth_server_url}/api/{VERSION_PREFIX}/oauth/device/token"
|
|
56
|
-
data = {
|
|
57
|
-
"tenantName": self._tenant_name,
|
|
58
|
-
"deviceCode": device_code,
|
|
59
|
-
}
|
|
60
|
-
start_time = time.monotonic()
|
|
61
|
-
poll_interval_seconds = 1
|
|
62
|
-
|
|
63
|
-
for response in poll_for_function(
|
|
64
|
-
requests.post, poll_after_secs=poll_interval_seconds, url=url, data=data
|
|
65
|
-
):
|
|
66
|
-
if response.status_code == 201:
|
|
67
|
-
response = response.json()
|
|
68
|
-
return Token.parse_obj(response)
|
|
69
|
-
elif response.status_code == 202:
|
|
70
|
-
logger.debug("User has not authorized yet. Checking again.")
|
|
71
|
-
else:
|
|
72
|
-
raise Exception(
|
|
73
|
-
"Failed to get token using device code. "
|
|
74
|
-
f"status_code {response.status_code},\n {response.text}"
|
|
75
|
-
)
|
|
76
|
-
time_elapsed = time.monotonic() - start_time
|
|
77
|
-
if time_elapsed > timeout:
|
|
78
|
-
logger.warning("Polled server for %s secs.", int(time_elapsed))
|
|
79
|
-
break
|
|
80
|
-
|
|
81
|
-
raise Exception(f"Did not get authorized within {timeout} seconds.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/agents/project_identifier.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/tools/file_type_counts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/autodeploy/utils/pydantic_compat.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/__init__.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/builder/builders/dockerfile.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/apply_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/build_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/build_logs_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/create_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/delete_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/deploy_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/get_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/list_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/login_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/logout_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/logs_command.py
RENAMED
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/patch_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/redeploy_command.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/cli/commands/terminate_comand.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/__init__.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/remote/context.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/remote/method.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/remote/remote.py
RENAMED
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/function_service/service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/io/rich_output_callback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/auth/servicefoundry_session.py
RENAMED
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/deploy/lib/clients/shell_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/langchain/truefoundry_embeddings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/example/package/test_workflow.py
RENAMED
|
File without changes
|
{truefoundry-0.3.0rc9 → truefoundry-0.3.0rc11}/truefoundry/workflow/example/truefoundry.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|