diff --git a/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py b/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py index f21d9fe4b8ef..ca55e07388cc 100644 --- a/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py +++ b/python/packages/autogen-ext/src/autogen_ext/code_executors/local/__init__.py @@ -30,6 +30,14 @@ __all__ = ("LocalCommandLineCodeExecutor",) +logger = logging.getLogger(__name__) + +LOCAL_COMMAND_LINE_CODE_EXECUTOR_WARNING = ( + "Using LocalCommandLineCodeExecutor may execute code on the local machine which can be unsafe. " + "For security, it is recommended to use DockerCommandLineCodeExecutor instead. " + "To install Docker, visit: https://docs.docker.com/get-docker/" +) + A = ParamSpec("A") @@ -160,13 +168,8 @@ def __init__( virtual_env_context: Optional[SimpleNamespace] = None, ): # Issue warning about using LocalCommandLineCodeExecutor - warnings.warn( - "Using LocalCommandLineCodeExecutor may execute code on the local machine which can be unsafe. " - "For security, it is recommended to use DockerCommandLineCodeExecutor instead. " - "To install Docker, visit: https://docs.docker.com/get-docker/", - UserWarning, - stacklevel=2, - ) + logger.warning(LOCAL_COMMAND_LINE_CODE_EXECUTOR_WARNING) + warnings.warn(LOCAL_COMMAND_LINE_CODE_EXECUTOR_WARNING, UserWarning, stacklevel=2) if timeout < 1: raise ValueError("Timeout must be greater than or equal to 1.") diff --git a/python/packages/autogen-ext/tests/code_executors/test_commandline_code_executor.py b/python/packages/autogen-ext/tests/code_executors/test_commandline_code_executor.py index 6ba30da76f15..57915da6ac86 100644 --- a/python/packages/autogen-ext/tests/code_executors/test_commandline_code_executor.py +++ b/python/packages/autogen-ext/tests/code_executors/test_commandline_code_executor.py @@ -2,6 +2,7 @@ # Credit to original authors import asyncio +import logging import os import platform import shutil @@ -10,6 +11,7 @@ import tempfile import types import venv +import warnings from pathlib import Path from typing import AsyncGenerator, TypeAlias from unittest.mock import patch @@ -212,6 +214,20 @@ async def test_local_commandline_code_executor_restart() -> None: await executor.restart() +def test_local_commandline_code_executor_security_warning_is_logged_when_warnings_are_suppressed( + caplog: pytest.LogCaptureFixture, +) -> None: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + with caplog.at_level(logging.WARNING, logger="autogen_ext.code_executors.local"): + LocalCommandLineCodeExecutor() + + assert any( + "Using LocalCommandLineCodeExecutor may execute code on the local machine" in record.message + for record in caplog.records + ) + + @pytest.mark.asyncio @pytest.mark.parametrize("executor_and_temp_dir", ["local"], indirect=True) async def test_invalid_relative_path(executor_and_temp_dir: ExecutorFixture) -> None: