mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-22 06:18:14 +00:00
feat: implement crewAI lite version with optional dependencies
- Restructure pyproject.toml to move non-essential dependencies to optional extras - Add graceful handling for missing optional dependencies in core modules - Create memory, knowledge, telemetry, visualization, auth, and llm-integrations extras - Implement helpful ImportError messages directing users to install specific extras - Add comprehensive test suite for lite installation scenarios - Maintain backward compatibility with existing installations - Support minimal core installation with Agent/Crew/Task functionality Addresses GitHub issue #3026 for lightweight crewAI installation Co-Authored-By: João <joao@crewai.com>
This commit is contained in:
122
tests/test_optional_dependencies.py
Normal file
122
tests/test_optional_dependencies.py
Normal file
@@ -0,0 +1,122 @@
|
||||
"""Test optional dependency handling for crewAI lite version."""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch, Mock
|
||||
import sys
|
||||
|
||||
|
||||
class TestOptionalDependencies:
|
||||
"""Test that optional dependencies are handled gracefully."""
|
||||
|
||||
def test_chromadb_import_error_memory(self):
|
||||
"""Test that memory functionality raises helpful error without chromadb."""
|
||||
with patch.dict('sys.modules', {'chromadb': None}):
|
||||
with patch('crewai.memory.storage.rag_storage.CHROMADB_AVAILABLE', False):
|
||||
from crewai.memory.storage.rag_storage import RAGStorage
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
RAGStorage("test")
|
||||
|
||||
assert "ChromaDB is required" in str(exc_info.value)
|
||||
assert "crewai[memory]" in str(exc_info.value)
|
||||
|
||||
def test_chromadb_import_error_knowledge(self):
|
||||
"""Test that knowledge functionality raises helpful error without chromadb."""
|
||||
with patch.dict('sys.modules', {'chromadb': None}):
|
||||
with patch('crewai.knowledge.storage.knowledge_storage.CHROMADB_AVAILABLE', False):
|
||||
from crewai.knowledge.storage.knowledge_storage import KnowledgeStorage
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
KnowledgeStorage()
|
||||
|
||||
assert "ChromaDB is required" in str(exc_info.value)
|
||||
assert "crewai[knowledge]" in str(exc_info.value)
|
||||
|
||||
def test_pdfplumber_import_error(self):
|
||||
"""Test that PDF knowledge source raises helpful error without pdfplumber."""
|
||||
with patch.dict('sys.modules', {'pdfplumber': None}):
|
||||
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
|
||||
|
||||
pdf_source = PDFKnowledgeSource(file_paths=["test.pdf"])
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
pdf_source._import_pdfplumber()
|
||||
|
||||
assert "pdfplumber is required" in str(exc_info.value)
|
||||
assert "crewai[knowledge]" in str(exc_info.value)
|
||||
|
||||
def test_pyvis_import_error(self):
|
||||
"""Test that flow visualization raises helpful error without pyvis."""
|
||||
with patch.dict('sys.modules', {'pyvis': None}):
|
||||
with patch('crewai.flow.flow_visualizer.PYVIS_AVAILABLE', False):
|
||||
from crewai.flow.flow_visualizer import plot_flow
|
||||
|
||||
mock_flow = Mock()
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
plot_flow(mock_flow)
|
||||
|
||||
assert "Pyvis is required" in str(exc_info.value)
|
||||
assert "crewai[visualization]" in str(exc_info.value)
|
||||
|
||||
def test_auth0_import_error(self):
|
||||
"""Test that authentication raises helpful error without auth0."""
|
||||
with patch.dict('sys.modules', {'auth0': None}):
|
||||
with patch('crewai.cli.authentication.utils.AUTH0_AVAILABLE', False):
|
||||
from crewai.cli.authentication.utils import validate_token
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
validate_token("fake_token")
|
||||
|
||||
assert "Auth0 is required" in str(exc_info.value)
|
||||
assert "crewai[auth]" in str(exc_info.value)
|
||||
|
||||
def test_aisuite_import_error(self):
|
||||
"""Test that AISuite LLM raises helpful error without aisuite."""
|
||||
with patch.dict('sys.modules', {'aisuite': None}):
|
||||
with patch('crewai.llms.third_party.ai_suite.AISUITE_AVAILABLE', False):
|
||||
from crewai.llms.third_party.ai_suite import AISuiteLLM
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
AISuiteLLM("test-model")
|
||||
|
||||
assert "AISuite is required" in str(exc_info.value)
|
||||
assert "crewai[llm-integrations]" in str(exc_info.value)
|
||||
|
||||
def test_opentelemetry_graceful_degradation(self):
|
||||
"""Test that telemetry degrades gracefully without opentelemetry."""
|
||||
with patch.dict('sys.modules', {'opentelemetry': None}):
|
||||
with patch('crewai.telemetry.telemetry.OPENTELEMETRY_AVAILABLE', False):
|
||||
from crewai.telemetry.telemetry import Telemetry
|
||||
|
||||
telemetry = Telemetry()
|
||||
|
||||
assert not telemetry.ready
|
||||
assert telemetry._is_telemetry_disabled()
|
||||
assert not telemetry._should_execute_telemetry()
|
||||
|
||||
def test_embedding_configurator_import_error(self):
|
||||
"""Test that embedding configurator raises helpful error without chromadb."""
|
||||
with patch.dict('sys.modules', {'chromadb': None}):
|
||||
with patch('crewai.utilities.embedding_configurator.CHROMADB_AVAILABLE', False):
|
||||
from crewai.utilities.embedding_configurator import EmbeddingConfigurator
|
||||
|
||||
configurator = EmbeddingConfigurator()
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
configurator.configure_embedder(None)
|
||||
|
||||
assert "ChromaDB is required" in str(exc_info.value)
|
||||
assert "crewai[memory]" in str(exc_info.value) or "crewai[knowledge]" in str(exc_info.value)
|
||||
|
||||
def test_docling_import_error(self):
|
||||
"""Test that docling knowledge source raises helpful error without docling."""
|
||||
with patch.dict('sys.modules', {'docling': None}):
|
||||
with patch('crewai.knowledge.source.crew_docling_source.DOCLING_AVAILABLE', False):
|
||||
from crewai.knowledge.source.crew_docling_source import CrewDoclingSource
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
CrewDoclingSource()
|
||||
|
||||
assert "docling package is required" in str(exc_info.value)
|
||||
assert "uv add docling" in str(exc_info.value)
|
||||
Reference in New Issue
Block a user