langchain-e2b 0.0.1__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.
@@ -0,0 +1,77 @@
1
+ name: ci
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ name: test (${{ matrix.python-version }})
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
19
+
20
+ steps:
21
+ - name: Checkout
22
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
23
+
24
+ - name: Set up uv
25
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
26
+ with:
27
+ version: "0.11.19"
28
+ python-version: ${{ matrix.python-version }}
29
+ enable-cache: true
30
+ cache-dependency-glob: uv.lock
31
+
32
+ - name: Install dependencies
33
+ run: uv sync --group test --locked
34
+
35
+ - name: Run unit tests
36
+ run: make test
37
+
38
+ lint:
39
+ name: lint
40
+ runs-on: ubuntu-latest
41
+
42
+ steps:
43
+ - name: Checkout
44
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
45
+
46
+ - name: Set up uv
47
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
48
+ with:
49
+ version: "0.11.19"
50
+ python-version: "3.13"
51
+ enable-cache: true
52
+ cache-dependency-glob: uv.lock
53
+
54
+ - name: Install dependencies
55
+ run: uv sync --group test --locked
56
+
57
+ - name: Run lint and type checks
58
+ run: make lint
59
+
60
+ build:
61
+ name: build package
62
+ runs-on: ubuntu-latest
63
+
64
+ steps:
65
+ - name: Checkout
66
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
67
+
68
+ - name: Set up uv
69
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
70
+ with:
71
+ version: "0.11.19"
72
+ python-version: "3.13"
73
+ enable-cache: true
74
+ cache-dependency-glob: uv.lock
75
+
76
+ - name: Build distributions
77
+ run: uv build --no-sources
@@ -0,0 +1,66 @@
1
+ name: release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ build:
12
+ name: build and test distributions
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
18
+
19
+ - name: Set up uv
20
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
21
+ with:
22
+ version: "0.11.19"
23
+ python-version: "3.13"
24
+ enable-cache: true
25
+ cache-dependency-glob: uv.lock
26
+
27
+ - name: Install dependencies
28
+ run: uv sync --group test --locked
29
+
30
+ - name: Run unit tests
31
+ run: make test
32
+
33
+ - name: Run lint and type checks
34
+ run: make lint
35
+
36
+ - name: Build distributions
37
+ run: uv build --no-sources
38
+
39
+ - name: Upload distributions
40
+ uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
41
+ with:
42
+ name: python-package-distributions
43
+ path: dist/*
44
+ if-no-files-found: error
45
+ retention-days: 7
46
+
47
+ publish:
48
+ name: publish to PyPI
49
+ needs: build
50
+ runs-on: ubuntu-latest
51
+ environment:
52
+ name: pypi
53
+ url: https://pypi.org/p/langchain-e2b
54
+ permissions:
55
+ contents: read
56
+ id-token: write
57
+
58
+ steps:
59
+ - name: Download distributions
60
+ uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
61
+ with:
62
+ name: python-package-distributions
63
+ path: dist
64
+
65
+ - name: Publish distributions to PyPI
66
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
@@ -0,0 +1,17 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+
6
+ .coverage
7
+ htmlcov/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .ty/
11
+
12
+ build/
13
+ dist/
14
+
15
+ .env
16
+ .env.*
17
+ .DS_Store
@@ -0,0 +1,7 @@
1
+ <!-- markdownlint-disable MD024 -->
2
+
3
+ # Changelog
4
+
5
+ ## 0.0.1
6
+
7
+ - Initial E2B sandbox integration for Deep Agents.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) LangChain, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,64 @@
1
+ .PHONY: format lint type typecheck test tests integration_test integration_tests test_watch benchmark help lint_package
2
+
3
+ .DEFAULT_GOAL := help
4
+
5
+ .EXPORT_ALL_VARIABLES:
6
+ UV_FROZEN = true
7
+
8
+ ######################
9
+ # TESTING
10
+ ######################
11
+
12
+ TEST_FILE ?= tests/unit_tests/
13
+ PYTEST_EXTRA ?=
14
+
15
+ integration_test integration_tests: TEST_FILE=tests/integration_tests/
16
+
17
+ test: ## Run unit tests
18
+ test tests:
19
+ uv run --group test pytest -vvv $(PYTEST_EXTRA) --disable-socket --allow-unix-socket $(TEST_FILE)
20
+
21
+ integration_test: ## Run integration tests
22
+ integration_test integration_tests:
23
+ uv run --group test pytest -vvv --timeout 30 $(TEST_FILE)
24
+
25
+ test_watch: ## Run tests in watch mode
26
+ uv run --group test ptw --now . -- -vv $(TEST_FILE)
27
+
28
+ benchmark: ## Run benchmark tests
29
+ uv run --group test pytest ./tests -m benchmark
30
+
31
+ ######################
32
+ # LINTING AND FORMATTING
33
+ ######################
34
+
35
+ PYTHON_FILES=.
36
+ lint format: PYTHON_FILES=.
37
+ lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --diff-filter=d main 2>/dev/null | grep -E '\.py$$|\.ipynb$$' || true)
38
+ lint_package: ## Lint only the package
39
+ lint_package: PYTHON_FILES=langchain_e2b
40
+
41
+ lint: ## Run linters and type checker
42
+ lint lint_diff lint_package:
43
+ [ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff check $(PYTHON_FILES)
44
+ [ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff format $(PYTHON_FILES) --diff
45
+ $(MAKE) type
46
+
47
+ type: ## Run type checker
48
+ type typecheck:
49
+ uv run --all-groups ty check langchain_e2b
50
+
51
+ format: ## Run code formatters
52
+ format format_diff:
53
+ [ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff format $(PYTHON_FILES)
54
+ [ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff check --fix $(PYTHON_FILES)
55
+
56
+ ######################
57
+ # HELP
58
+ ######################
59
+
60
+ help: ## Show this help message
61
+ @echo "Usage: make [target] [TEST_FILE=path/to/tests/]"
62
+ @echo ""
63
+ @echo "Targets:"
64
+ @awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*##/ {printf " %-20s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
@@ -0,0 +1,80 @@
1
+ Metadata-Version: 2.4
2
+ Name: langchain-e2b
3
+ Version: 0.0.1
4
+ Summary: E2B sandbox integration for Deep Agents
5
+ Project-URL: Homepage, https://github.com/e2b-dev/langchain-e2b
6
+ Project-URL: Repository, https://github.com/e2b-dev/langchain-e2b
7
+ Project-URL: Documentation, https://github.com/e2b-dev/langchain-e2b#readme
8
+ Project-URL: Issues, https://github.com/e2b-dev/langchain-e2b/issues
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: <4.0,>=3.11
20
+ Requires-Dist: deepagents<0.7.0,>=0.6.0
21
+ Requires-Dist: e2b<3.0.0,>=2.25.1
22
+ Description-Content-Type: text/markdown
23
+
24
+ # langchain-e2b
25
+
26
+ [![PyPI - Version](https://img.shields.io/pypi/v/langchain-e2b?label=%20)](https://pypi.org/project/langchain-e2b/#history)
27
+ [![PyPI - License](https://img.shields.io/pypi/l/langchain-e2b)](https://opensource.org/licenses/MIT)
28
+ [![PyPI - Downloads](https://img.shields.io/pepy/dt/langchain-e2b)](https://pypistats.org/packages/langchain-e2b)
29
+
30
+ ## Quick Install
31
+
32
+ After the package is published:
33
+
34
+ ```bash
35
+ pip install langchain-e2b
36
+ ```
37
+
38
+ ```python
39
+ from e2b import Sandbox
40
+
41
+ from langchain_e2b import E2BSandbox
42
+
43
+ sandbox = Sandbox.create()
44
+ backend = E2BSandbox(sandbox=sandbox)
45
+
46
+ try:
47
+ result = backend.execute("echo hello")
48
+ print(result.output)
49
+ finally:
50
+ sandbox.kill()
51
+ ```
52
+
53
+ ## What is this?
54
+
55
+ `langchain-e2b` adapts an existing E2B sandbox to the Deep Agents sandbox
56
+ protocol. It uses the low-level `e2b` SDK so Deep Agents can run shell commands
57
+ and move files through the standard Deep Agents backend interface.
58
+
59
+ This package intentionally does not hide E2B sandbox lifecycle management. Use
60
+ the E2B SDK to create, connect to, configure, and kill sandboxes, then pass the
61
+ connected sandbox object to `E2BSandbox`.
62
+
63
+ ## Contributing
64
+
65
+ Contributions are welcome. Keep the adapter focused on implementing the Deep
66
+ Agents sandbox backend protocol over the official E2B SDK.
67
+
68
+ ## Development
69
+
70
+ ```bash
71
+ uv sync --group test
72
+ make test
73
+ make lint
74
+ ```
75
+
76
+ Integration tests require `E2B_API_KEY`:
77
+
78
+ ```bash
79
+ E2B_API_KEY=... make integration_tests
80
+ ```
@@ -0,0 +1,57 @@
1
+ # langchain-e2b
2
+
3
+ [![PyPI - Version](https://img.shields.io/pypi/v/langchain-e2b?label=%20)](https://pypi.org/project/langchain-e2b/#history)
4
+ [![PyPI - License](https://img.shields.io/pypi/l/langchain-e2b)](https://opensource.org/licenses/MIT)
5
+ [![PyPI - Downloads](https://img.shields.io/pepy/dt/langchain-e2b)](https://pypistats.org/packages/langchain-e2b)
6
+
7
+ ## Quick Install
8
+
9
+ After the package is published:
10
+
11
+ ```bash
12
+ pip install langchain-e2b
13
+ ```
14
+
15
+ ```python
16
+ from e2b import Sandbox
17
+
18
+ from langchain_e2b import E2BSandbox
19
+
20
+ sandbox = Sandbox.create()
21
+ backend = E2BSandbox(sandbox=sandbox)
22
+
23
+ try:
24
+ result = backend.execute("echo hello")
25
+ print(result.output)
26
+ finally:
27
+ sandbox.kill()
28
+ ```
29
+
30
+ ## What is this?
31
+
32
+ `langchain-e2b` adapts an existing E2B sandbox to the Deep Agents sandbox
33
+ protocol. It uses the low-level `e2b` SDK so Deep Agents can run shell commands
34
+ and move files through the standard Deep Agents backend interface.
35
+
36
+ This package intentionally does not hide E2B sandbox lifecycle management. Use
37
+ the E2B SDK to create, connect to, configure, and kill sandboxes, then pass the
38
+ connected sandbox object to `E2BSandbox`.
39
+
40
+ ## Contributing
41
+
42
+ Contributions are welcome. Keep the adapter focused on implementing the Deep
43
+ Agents sandbox backend protocol over the official E2B SDK.
44
+
45
+ ## Development
46
+
47
+ ```bash
48
+ uv sync --group test
49
+ make test
50
+ make lint
51
+ ```
52
+
53
+ Integration tests require `E2B_API_KEY`:
54
+
55
+ ```bash
56
+ E2B_API_KEY=... make integration_tests
57
+ ```
@@ -0,0 +1,5 @@
1
+ """E2B sandbox integration for Deep Agents."""
2
+
3
+ from langchain_e2b.sandbox import E2BSandbox
4
+
5
+ __all__ = ["E2BSandbox"]
@@ -0,0 +1,5 @@
1
+ """Version information for `langchain-e2b`."""
2
+
3
+ # Keep the `x-release-please-version` annotation — release-please uses it to
4
+ # bump `__version__` in sync with `pyproject.toml` on every release PR.
5
+ __version__ = "0.0.1" # x-release-please-version
@@ -0,0 +1,180 @@
1
+ """E2B sandbox backend implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import e2b
6
+ from deepagents.backends.protocol import (
7
+ ExecuteResponse,
8
+ FileDownloadResponse,
9
+ FileUploadResponse,
10
+ )
11
+ from deepagents.backends.sandbox import BaseSandbox
12
+
13
+ DEFAULT_WORKDIR = "/home/user"
14
+ TIMEOUT_EXIT_CODE = 124
15
+
16
+
17
+ def _combine_output(stdout: str | None, stderr: str | None) -> str:
18
+ output = stdout or ""
19
+ if stderr:
20
+ output += "\n" + stderr if output else stderr
21
+ return output
22
+
23
+
24
+ class E2BSandbox(BaseSandbox):
25
+ """Sandbox backend that operates on an existing E2B sandbox."""
26
+
27
+ def __init__(
28
+ self,
29
+ *,
30
+ sandbox: e2b.Sandbox,
31
+ workdir: str = DEFAULT_WORKDIR,
32
+ timeout: int = 30 * 60,
33
+ ) -> None:
34
+ """Create a backend wrapping an existing E2B sandbox.
35
+
36
+ Args:
37
+ sandbox: Existing E2B sandbox instance to wrap.
38
+ workdir: Working directory for command execution.
39
+ timeout: Default command timeout in seconds when `execute()` is
40
+ called without an explicit `timeout`.
41
+ """
42
+ self._sandbox = sandbox
43
+ self._workdir = workdir
44
+ self._default_timeout = timeout
45
+
46
+ @property
47
+ def id(self) -> str:
48
+ """Return the E2B sandbox id."""
49
+ return self._sandbox.sandbox_id
50
+
51
+ def execute(
52
+ self,
53
+ command: str,
54
+ *,
55
+ timeout: int | None = None,
56
+ ) -> ExecuteResponse:
57
+ """Execute a shell command inside the sandbox.
58
+
59
+ Args:
60
+ command: Shell command string to execute.
61
+ timeout: Maximum time in seconds to wait for this command.
62
+
63
+ If None, uses the backend's default timeout.
64
+
65
+ Returns:
66
+ ExecuteResponse containing output, exit code, and truncation flag.
67
+
68
+ Raises:
69
+ ValueError: If `timeout` is negative.
70
+ """
71
+ effective_timeout = timeout if timeout is not None else self._default_timeout
72
+ if effective_timeout < 0:
73
+ msg = f"timeout must be non-negative, got {effective_timeout}"
74
+ raise ValueError(msg)
75
+
76
+ try:
77
+ result = self._sandbox.commands.run(
78
+ command,
79
+ cwd=self._workdir,
80
+ timeout=effective_timeout,
81
+ )
82
+ except e2b.CommandExitException as exc:
83
+ return ExecuteResponse(
84
+ output=_combine_output(exc.stdout, exc.stderr),
85
+ exit_code=exc.exit_code,
86
+ truncated=False,
87
+ )
88
+ except e2b.TimeoutException:
89
+ return ExecuteResponse(
90
+ output=f"Command timed out after {effective_timeout} seconds",
91
+ exit_code=TIMEOUT_EXIT_CODE,
92
+ truncated=False,
93
+ )
94
+ except e2b.SandboxException as exc:
95
+ return ExecuteResponse(
96
+ output=f"Error executing command ({type(exc).__name__}): {exc}",
97
+ exit_code=1,
98
+ truncated=False,
99
+ )
100
+
101
+ return ExecuteResponse(
102
+ output=_combine_output(result.stdout, result.stderr),
103
+ exit_code=result.exit_code,
104
+ truncated=False,
105
+ )
106
+
107
+ def _read_file(self, path: str) -> FileDownloadResponse:
108
+ if not path.startswith("/"):
109
+ return FileDownloadResponse(path=path, content=None, error="invalid_path")
110
+
111
+ try:
112
+ info = self._sandbox.files.get_info(path)
113
+ if info.type == e2b.FileType.DIR:
114
+ return FileDownloadResponse(
115
+ path=path,
116
+ content=None,
117
+ error="is_directory",
118
+ )
119
+ content = bytes(self._sandbox.files.read(path, format="bytes"))
120
+ return FileDownloadResponse(path=path, content=content, error=None)
121
+ except e2b.FileNotFoundException:
122
+ return FileDownloadResponse(path=path, content=None, error="file_not_found")
123
+ except e2b.InvalidArgumentException:
124
+ return FileDownloadResponse(path=path, content=None, error="invalid_path")
125
+ except PermissionError:
126
+ return FileDownloadResponse(
127
+ path=path,
128
+ content=None,
129
+ error="permission_denied",
130
+ )
131
+
132
+ def _write_file(self, path: str, content: bytes) -> FileUploadResponse:
133
+ if not path.startswith("/"):
134
+ return FileUploadResponse(path=path, error="invalid_path")
135
+
136
+ error: str | None = None
137
+ try:
138
+ info = self._sandbox.files.get_info(path)
139
+ if info.type == e2b.FileType.DIR:
140
+ error = "is_directory"
141
+ except e2b.FileNotFoundException:
142
+ pass
143
+ except e2b.InvalidArgumentException:
144
+ error = "invalid_path"
145
+ except PermissionError:
146
+ error = "permission_denied"
147
+
148
+ if error is None:
149
+ try:
150
+ self._sandbox.files.write(path, content)
151
+ except e2b.FileNotFoundException:
152
+ error = "file_not_found"
153
+ except e2b.InvalidArgumentException:
154
+ error = "invalid_path"
155
+ except PermissionError:
156
+ error = "permission_denied"
157
+
158
+ return FileUploadResponse(path=path, error=error)
159
+
160
+ def download_files(self, paths: list[str]) -> list[FileDownloadResponse]:
161
+ """Download files from the sandbox.
162
+
163
+ Args:
164
+ paths: Absolute sandbox file paths to download.
165
+
166
+ Returns:
167
+ Download responses in the same order as `paths`.
168
+ """
169
+ return [self._read_file(path) for path in paths]
170
+
171
+ def upload_files(self, files: list[tuple[str, bytes]]) -> list[FileUploadResponse]:
172
+ """Upload files into the sandbox.
173
+
174
+ Args:
175
+ files: `(path, content)` pairs to write.
176
+
177
+ Returns:
178
+ Upload responses in the same order as `files`.
179
+ """
180
+ return [self._write_file(path, content) for path, content in files]
@@ -0,0 +1,95 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "langchain-e2b"
7
+ description = "E2B sandbox integration for Deep Agents"
8
+ license = { text = "MIT" }
9
+ readme = "README.md"
10
+
11
+ classifiers = [
12
+ "Intended Audience :: Developers",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.11",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Programming Language :: Python :: 3.13",
18
+ "Programming Language :: Python :: 3.14",
19
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
20
+ ]
21
+
22
+ version = "0.0.1"
23
+ requires-python = ">=3.11,<4.0"
24
+ dependencies = [
25
+ "deepagents>=0.6.0,<0.7.0",
26
+ "e2b>=2.25.1,<3.0.0",
27
+ ]
28
+
29
+ [tool.hatch.build.targets.wheel]
30
+ packages = ["langchain_e2b"]
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/e2b-dev/langchain-e2b"
34
+ Repository = "https://github.com/e2b-dev/langchain-e2b"
35
+ Documentation = "https://github.com/e2b-dev/langchain-e2b#readme"
36
+ Issues = "https://github.com/e2b-dev/langchain-e2b/issues"
37
+
38
+ [dependency-groups]
39
+ test = [
40
+ "pytest>=7.3.0,<10.0.0",
41
+ "pytest-cov",
42
+ "pytest-socket",
43
+ "pytest-xdist",
44
+ "pytest-timeout>=2.3.1,<3.0.0",
45
+ "pytest-asyncio>=1.3.0",
46
+ "ruff>=0.13.1,<0.16.0",
47
+ "ty>=0.0.1,<1.0.0",
48
+ "langchain-tests>=1.1.6",
49
+ ]
50
+
51
+ [tool.uv]
52
+ constraint-dependencies = ["urllib3>=2.6.3"]
53
+
54
+ [tool.ty.environment]
55
+ python-version = "3.11"
56
+
57
+ [tool.ty.rules]
58
+ # https://docs.astral.sh/ty/rules/
59
+ division-by-zero = "error"
60
+
61
+ [tool.ruff.format]
62
+ docstring-code-format = true
63
+
64
+ [tool.ruff.lint]
65
+ select = ["ALL"]
66
+ ignore = [
67
+ "COM812", # Messes with the formatter
68
+ "ISC001", # Messes with the formatter
69
+ "ANN401", # Dynamically typed expressions (typing.Any) are disallowed — too strict for generic wrappers
70
+ ]
71
+ extend-safe-fixes = ["PLR6201"]
72
+
73
+ [tool.ruff.lint.pydocstyle]
74
+ convention = "google"
75
+ ignore-var-parameters = true # ignore missing documentation for *args and **kwargs parameters
76
+
77
+ [tool.ruff.lint.flake8-tidy-imports]
78
+ ban-relative-imports = "all"
79
+
80
+ [tool.coverage.run]
81
+ omit = ["tests/*"]
82
+
83
+ [tool.pytest.ini_options]
84
+ addopts = "--strict-markers --strict-config --durations=5"
85
+ testpaths = ["tests"]
86
+ markers = [
87
+ "requires: mark tests as requiring a specific library",
88
+ "compile: mark placeholder test used to compile integration tests without running them",
89
+ "scheduled: mark tests to run in scheduled testing",
90
+ ]
91
+ asyncio_mode = "auto"
92
+ filterwarnings = []
93
+
94
+ [tool.ruff.lint.extend-per-file-ignores]
95
+ "tests/**/*.py" = ["D", "S101"]
@@ -0,0 +1 @@
1
+ """Tests for `langchain-e2b`."""
@@ -0,0 +1 @@
1
+ """Integration tests for `langchain-e2b`."""