feat: allow to install a Tool from pypi

This commit is contained in:
Lucas Gomide
2025-05-24 13:34:34 -03:00
parent 6f73bd80f4
commit 1c29a289d2
2 changed files with 39 additions and 4 deletions

View File

@@ -3,6 +3,7 @@ import os
import subprocess import subprocess
import tempfile import tempfile
from pathlib import Path from pathlib import Path
from typing import Any
import click import click
from rich.console import Console from rich.console import Console
@@ -178,7 +179,8 @@ class ToolCommand(BaseCommand, PlusAPIMixin):
"Successfully authenticated to the tool repository.", style="bold green" "Successfully authenticated to the tool repository.", style="bold green"
) )
def _add_package(self, tool_details): def _add_package(self, tool_details: dict[str, Any]):
is_from_pypi = tool_details.get("source", None) == "pypi"
tool_handle = tool_details["handle"] tool_handle = tool_details["handle"]
repository_handle = tool_details["repository"]["handle"] repository_handle = tool_details["repository"]["handle"]
repository_url = tool_details["repository"]["url"] repository_url = tool_details["repository"]["url"]
@@ -187,10 +189,13 @@ class ToolCommand(BaseCommand, PlusAPIMixin):
add_package_command = [ add_package_command = [
"uv", "uv",
"add", "add",
"--index",
index,
tool_handle,
] ]
if is_from_pypi:
add_package_command.append(tool_handle)
else:
add_package_command.extend(["--index", index, tool_handle])
add_package_result = subprocess.run( add_package_result = subprocess.run(
add_package_command, add_package_command,
capture_output=False, capture_output=False,

View File

@@ -85,6 +85,36 @@ def test_install_success(mock_get, mock_subprocess_run, capsys, tool_command):
env=unittest.mock.ANY, env=unittest.mock.ANY,
) )
@patch("crewai.cli.tools.main.subprocess.run")
@patch("crewai.cli.plus_api.PlusAPI.get_tool")
def test_install_success_from_pypi(mock_get, mock_subprocess_run, capsys, tool_command):
mock_get_response = MagicMock()
mock_get_response.status_code = 200
mock_get_response.json.return_value = {
"handle": "sample-tool",
"repository": {"handle": "sample-repo", "url": "https://example.com/repo"},
"source": "pypi",
}
mock_get.return_value = mock_get_response
mock_subprocess_run.return_value = MagicMock(stderr=None)
tool_command.install("sample-tool")
output = capsys.readouterr().out
assert "Successfully installed sample-tool" in output
mock_get.assert_has_calls([mock.call("sample-tool"), mock.call().json()])
mock_subprocess_run.assert_any_call(
[
"uv",
"add",
"sample-tool",
],
capture_output=False,
text=True,
check=True,
env=unittest.mock.ANY,
)
@patch("crewai.cli.plus_api.PlusAPI.get_tool") @patch("crewai.cli.plus_api.PlusAPI.get_tool")
def test_install_tool_not_found(mock_get, capsys, tool_command): def test_install_tool_not_found(mock_get, capsys, tool_command):