Skip to content

Commit e182af6

Browse files
authored
informative import error messages (#25)
1 parent fcd4291 commit e182af6

File tree

4 files changed

+51
-5
lines changed

4 files changed

+51
-5
lines changed

DEVELOPMENT.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,16 @@ Automated releases are handled by the [release workflow][release-workflow] which
9595
Testing, type checking, and formatting/linting is [checked in CI][ci].
9696

9797
[ci]: .github/workflows/ci.yml
98+
99+
## Style guide
100+
101+
### Adding integrations with external libraries
102+
103+
When adding integrations with external libraries, always use a lazy import. The external dependency should not be required to use the `cleanlab-codex` library. Wrap the lazy import in a `try`/`except` block to catch the `ImportError` and raise a `MissingDependencyError` with a helpful message. See [codex_tool.py](src/cleanlab_codex/codex_tool.py) file for examples one of which is shown below:
104+
105+
```python
106+
try:
107+
from cleanlab_codex.utils.smolagents import CodexTool as SmolagentsCodexTool
108+
except ImportError as e:
109+
raise MissingDependencyError("smolagents", "https://github.com/huggingface/smolagents") from e
110+
```

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,4 @@ html = "coverage html"
101101
xml = "coverage xml"
102102

103103
[tool.ruff.lint]
104-
ignore = ["FA100", "UP007", "UP006"]
104+
ignore = ["FA100", "UP007", "UP006", "EM101"]

src/cleanlab_codex/codex_tool.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
from typing_extensions import Annotated
88

99
from cleanlab_codex.project import Project
10-
from cleanlab_codex.utils.function import pydantic_model_from_function, required_properties_from_model
10+
from cleanlab_codex.utils.errors import MissingDependencyError
11+
from cleanlab_codex.utils.function import (
12+
pydantic_model_from_function,
13+
required_properties_from_model,
14+
)
1115

1216

1317
class CodexTool:
@@ -119,7 +123,10 @@ def to_smolagents_tool(self) -> Any:
119123
120124
Note: You must have the [`smolagents` library installed](https://github.com/huggingface/smolagents) to use this method.
121125
"""
122-
from cleanlab_codex.utils.smolagents import CodexTool as SmolagentsCodexTool
126+
try:
127+
from cleanlab_codex.utils.smolagents import CodexTool as SmolagentsCodexTool
128+
except ImportError as e:
129+
raise MissingDependencyError("smolagents", "https://github.com/huggingface/smolagents") from e
123130

124131
return SmolagentsCodexTool(
125132
query=self.query,
@@ -133,7 +140,14 @@ def to_llamaindex_tool(self) -> Any:
133140
134141
Note: You must have the [`llama-index` library installed](https://docs.llamaindex.ai/en/stable/getting_started/installation/) to use this method.
135142
"""
136-
from llama_index.core.tools import FunctionTool
143+
try:
144+
from llama_index.core.tools import FunctionTool
145+
146+
except ImportError as e:
147+
raise MissingDependencyError(
148+
"llama-index-core",
149+
"https://docs.llamaindex.ai/en/stable/getting_started/installation/",
150+
) from e
137151

138152
return FunctionTool.from_defaults(
139153
fn=self.query,
@@ -147,7 +161,11 @@ def to_langchain_tool(self) -> Any:
147161
148162
Note: You must have the [`langchain` library installed](https://python.langchain.com/docs/concepts/architecture/) to use this method.
149163
"""
150-
from langchain_core.tools.structured import StructuredTool
164+
try:
165+
from langchain_core.tools.structured import StructuredTool
166+
167+
except ImportError as e:
168+
raise MissingDependencyError("langchain", "https://pypi.org/project/langchain/") from e
151169

152170
return StructuredTool.from_function(
153171
func=self.query,

src/cleanlab_codex/utils/errors.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from __future__ import annotations
2+
3+
4+
class MissingDependencyError(Exception):
5+
"""Raised when a lazy import is missing."""
6+
7+
def __init__(self, import_name: str, package_url: str | None = None) -> None:
8+
self.import_name = import_name
9+
self.package_url = package_url
10+
11+
def __str__(self) -> str:
12+
message = f"Failed to import {self.import_name}. Please install the package using `pip install {self.import_name}` and try again."
13+
if self.package_url:
14+
message += f" For more information, see {self.package_url}."
15+
return message

0 commit comments

Comments
 (0)