ModuleNotFoundError: No module named 'distutils'

Hi!

When trying to execute “crewai run” I receive the following error:
ModuleNotFoundError: No module named ‘distutils’

I’ve tried different Python version (10, 11, 12, 13…) but keep receiving the same error message.
I’ve installed ‘setuptools’ as I understood this could help, confirmed it is installed:
python3.11 -c "from distutils.util import strtobool; print(strtobool('yes'))"

but still receiving the same error message:
ModuleNotFoundError: No module named ‘distutils’

Anyone has run into this issue or has any idea of how to fix it? Tried ChatGPT but still nothing :sweat_smile:

Thank you.

Encountered the same issue; looks like distutils is deprecated from python 3.11 onwards. This is the workaround I’ve employed, which builds the distutils/strtobool functionality directly into your project eliminating any dependency:

Within your project directory, edit the following file:

~/.venv/lib/python3.12/site-packages/crewai_tools/tools/file_writer_tool/file_writer_tool.py

Overwrite the contents of file_writer_tool.py with:

import os
# from distutils.util import strtobool
# from setuptools._distutils.util import strtobool
def strtobool(val: str) -> bool:
    """Convert a string representation of truth to true (1) or false (0).

    True values are 'y', 'yes', 't', 'true', 'on', and '1';
    False values are 'n', 'no', 'f', 'false', 'off', and '0'.
    Raises ValueError if 'val' is anything else.
    """
    val = val.lower()
    if val in ("y", "yes", "t", "true", "on", "1"):
        return True
    elif val in ("n", "no", "f", "false", "off", "0"):
        return False
    else:
        raise ValueError(f"Invalid truth value: {val}")
from typing import Any, Optional, Type

from crewai.tools import BaseTool
from pydantic import BaseModel


class FileWriterToolInput(BaseModel):
    filename: str
    directory: Optional[str] = "./"
    overwrite: str = "False"
    content: str


class FileWriterTool(BaseTool):
    name: str = "File Writer Tool"
    description: str = "A tool to write content to a specified file. Accepts filename, content, and optionally a directory path and overwrite flag as input."
    args_schema: Type[BaseModel] = FileWriterToolInput

    def _run(self, **kwargs: Any) -> str:
        try:
            # Create the directory if it doesn't exist
            if kwargs.get("directory") and not os.path.exists(kwargs["directory"]):
                os.makedirs(kwargs["directory"])

            # Construct the full path
            filepath = os.path.join(kwargs.get("directory") or "", kwargs["filename"])

            # Convert overwrite to boolean
            kwargs["overwrite"] = bool(strtobool(kwargs["overwrite"]))

            # Check if file exists and overwrite is not allowed
            if os.path.exists(filepath) and not kwargs["overwrite"]:
                return f"File {filepath} already exists and overwrite option was not passed."

            # Write content to the file
            mode = "w" if kwargs["overwrite"] else "x"
            with open(filepath, mode) as file:
                file.write(kwargs["content"])
            return f"Content successfully written to {filepath}"
        except FileExistsError:
            return (
                f"File {filepath} already exists and overwrite option was not passed."
            )
        except KeyError as e:
            return f"An error occurred while accessing key: {str(e)}"
        except Exception as e:
            return f"An error occurred while writing to the file: {str(e)}"

Run crewai run again and you should be good to go. If you’re using OpenAI, make sure you have billing turned on for your API usage and a payment method added (this is independent of ChatGPT billing).

2 Likes

Thanks this helped resolved the issue

1 Like