feat: support api_key fallback to EXA_API_KEY env-var (#341)

This commit is contained in:
Lucas Gomide
2025-06-24 15:47:39 -03:00
committed by GitHub
parent 78a062a907
commit e8825d071a
2 changed files with 41 additions and 3 deletions

View File

@@ -1,6 +1,7 @@
from typing import Any, Optional, Type, List from typing import Any, Optional, Type, List
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from crewai.tools import BaseTool from crewai.tools import BaseTool, EnvVar
import os
try: try:
from exa_py import Exa from exa_py import Exa
@@ -36,10 +37,15 @@ class EXASearchTool(BaseTool):
summary: Optional[bool] = False summary: Optional[bool] = False
type: Optional[str] = "auto" type: Optional[str] = "auto"
package_dependencies: List[str] = ["exa_py"] package_dependencies: List[str] = ["exa_py"]
api_key: Optional[str] = Field(
default_factory=lambda: os.getenv("EXA_API_KEY"), description="API key for Exa services", required=False
)
env_vars: List[EnvVar] = [
EnvVar(name="EXA_API_KEY", description="API key for Exa services", required=False),
]
def __init__( def __init__(
self, self,
api_key: str,
content: Optional[bool] = False, content: Optional[bool] = False,
summary: Optional[bool] = False, summary: Optional[bool] = False,
type: Optional[str] = "auto", type: Optional[str] = "auto",
@@ -62,7 +68,7 @@ class EXASearchTool(BaseTool):
raise ImportError( raise ImportError(
"You are missing the 'exa_py' package. Would you like to install it?" "You are missing the 'exa_py' package. Would you like to install it?"
) )
self.client = Exa(api_key=api_key) self.client = Exa(api_key=self.api_key)
self.content = content self.content = content
self.summary = summary self.summary = summary
self.type = type self.type = type

View File

@@ -0,0 +1,32 @@
import os
from unittest.mock import patch
from crewai_tools import EXASearchTool
import pytest
@pytest.fixture
def exa_search_tool():
return EXASearchTool(api_key="test_api_key")
@pytest.fixture(autouse=True)
def mock_exa_api_key():
with patch.dict(os.environ, {"EXA_API_KEY": "test_key_from_env"}):
yield
def test_exa_search_tool_initialization():
with patch("crewai_tools.tools.exa_tools.exa_search_tool.Exa") as mock_exa_class:
api_key = "test_api_key"
tool = EXASearchTool(api_key=api_key)
assert tool.api_key == api_key
assert tool.content is False
assert tool.summary is False
assert tool.type == "auto"
mock_exa_class.assert_called_once_with(api_key=api_key)
def test_exa_search_tool_initialization_with_env(mock_exa_api_key):
with patch("crewai_tools.tools.exa_tools.exa_search_tool.Exa") as mock_exa_class:
EXASearchTool()
mock_exa_class.assert_called_once_with(api_key="test_key_from_env")