Skip to content

Dotenv API Reference

Auto-generated API documentation for the dotenv module.

dotenv

.env file parser and loader — zero dependencies, stdlib only, Python 3.10+.

Part of zerodep: https://github.com/Oaklight/zerodep Copyright (c) 2026 Peng Ding. MIT License.

Drop-in replacement for python-dotenv core functionality.

Example::

load_dotenv()                       # load .env into os.environ
values = dotenv_values(".env")       # parse without modifying environ
path = find_dotenv()                 # search up for .env file

find_dotenv(filename='.env', raise_error_if_not_found=False, usecwd=False)

Walk up from the calling file's directory (or cwd) to find filename.

Parameters:

Name Type Description Default
filename str

Name of the file to search for.

'.env'
raise_error_if_not_found bool

Raise IOError if the file is not found.

False
usecwd bool

Start from the current working directory instead of the calling file's directory.

False

Returns:

Type Description
str

Absolute path to the found file, or empty string if not found.

Source code in dotenv/dotenv.py
def find_dotenv(
    filename: str = ".env",
    raise_error_if_not_found: bool = False,
    usecwd: bool = False,
) -> str:
    """Walk up from the calling file's directory (or cwd) to find *filename*.

    Args:
        filename: Name of the file to search for.
        raise_error_if_not_found: Raise IOError if the file is not found.
        usecwd: Start from the current working directory instead of the
            calling file's directory.

    Returns:
        Absolute path to the found file, or empty string if not found.
    """
    if usecwd:
        start = Path.cwd()
    else:
        frame = inspect.currentframe()
        caller = frame.f_back if frame is not None else None
        if caller is not None and caller.f_globals.get("__file__"):
            start = Path(caller.f_globals["__file__"]).resolve().parent
        else:
            start = Path.cwd()

    current = start
    while True:
        candidate = current / filename
        if candidate.is_file():
            return str(candidate)
        parent = current.parent
        if parent == current:
            break
        current = parent

    if raise_error_if_not_found:
        raise IOError(f"File {filename!r} not found starting from {start}")
    return ""

get_key(dotenv_path, key_to_get, encoding='utf-8')

Get a single value from a .env file.

Parameters:

Name Type Description Default
dotenv_path str | PathLike[str]

Path to the .env file.

required
key_to_get str

The key to retrieve.

required
encoding str

File encoding.

'utf-8'

Returns:

Type Description
str | None

The value for the key, or None if not found.

Source code in dotenv/dotenv.py
def get_key(
    dotenv_path: str | os.PathLike[str],
    key_to_get: str,
    encoding: str = "utf-8",
) -> str | None:
    """Get a single value from a .env file.

    Args:
        dotenv_path: Path to the .env file.
        key_to_get: The key to retrieve.
        encoding: File encoding.

    Returns:
        The value for the key, or None if not found.
    """
    values = dotenv_values(dotenv_path, encoding=encoding)
    return values.get(key_to_get)

set_key(dotenv_path, key_to_set, value_to_set, quote_mode='always', export=False, encoding='utf-8')

Set a key=value pair in a .env file, creating it if needed.

Parameters:

Name Type Description Default
dotenv_path str | PathLike[str]

Path to the .env file.

required
key_to_set str

The key to set.

required
value_to_set str

The value to set.

required
quote_mode str

Quoting strategy: "always", "auto", or "never".

'always'
export bool

Whether to prefix with export.

False
encoding str

File encoding.

'utf-8'

Returns:

Type Description
tuple[bool, str, str]

Tuple of (success, key, value).

Source code in dotenv/dotenv.py
def set_key(
    dotenv_path: str | os.PathLike[str],
    key_to_set: str,
    value_to_set: str,
    quote_mode: str = "always",
    export: bool = False,
    encoding: str = "utf-8",
) -> tuple[bool, str, str]:
    """Set a key=value pair in a .env file, creating it if needed.

    Args:
        dotenv_path: Path to the .env file.
        key_to_set: The key to set.
        value_to_set: The value to set.
        quote_mode: Quoting strategy: "always", "auto", or "never".
        export: Whether to prefix with ``export``.
        encoding: File encoding.

    Returns:
        Tuple of (success, key, value).
    """
    path = Path(dotenv_path)

    if quote_mode == "always":
        value_out = f'"{value_to_set}"'
    elif quote_mode == "never":
        value_out = value_to_set
    else:
        # auto: quote if value contains spaces or special chars
        if re.search(r"[\s#\"']", value_to_set):
            value_out = f'"{value_to_set}"'
        else:
            value_out = value_to_set

    export_prefix = "export " if export else ""
    new_line = f"{export_prefix}{key_to_set}={value_out}\n"

    if path.is_file():
        lines = path.read_text(encoding=encoding).splitlines(keepends=True)
        replaced = False
        for idx, line in enumerate(lines):
            m = re.match(
                r"\A\s*(?:export\s+)?(" + re.escape(key_to_set) + r")\s*=",
                line,
            )
            if m:
                lines[idx] = new_line
                replaced = True
                break
        if not replaced:
            if lines and not lines[-1].endswith("\n"):
                lines[-1] += "\n"
            lines.append(new_line)
        path.write_text("".join(lines), encoding=encoding)
    else:
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(new_line, encoding=encoding)

    return True, key_to_set, value_to_set

unset_key(dotenv_path, key_to_unset, quote_mode='always', encoding='utf-8')

Remove a key from a .env file.

Parameters:

Name Type Description Default
dotenv_path str | PathLike[str]

Path to the .env file.

required
key_to_unset str

The key to remove.

required
quote_mode str

Unused, kept for API compatibility.

'always'
encoding str

File encoding.

'utf-8'

Returns:

Type Description
tuple[bool, str]

Tuple of (success, key).

Source code in dotenv/dotenv.py
def unset_key(
    dotenv_path: str | os.PathLike[str],
    key_to_unset: str,
    quote_mode: str = "always",
    encoding: str = "utf-8",
) -> tuple[bool, str]:
    """Remove a key from a .env file.

    Args:
        dotenv_path: Path to the .env file.
        key_to_unset: The key to remove.
        quote_mode: Unused, kept for API compatibility.
        encoding: File encoding.

    Returns:
        Tuple of (success, key).
    """
    path = Path(dotenv_path)
    if not path.is_file():
        return True, key_to_unset

    lines = path.read_text(encoding=encoding).splitlines(keepends=True)
    new_lines = []
    for line in lines:
        m = re.match(
            r"\A\s*(?:export\s+)?(" + re.escape(key_to_unset) + r")\s*=",
            line,
        )
        if m:
            continue
        new_lines.append(line)

    path.write_text("".join(new_lines), encoding=encoding)
    return True, key_to_unset

dotenv_values(dotenv_path=None, stream=None, verbose=False, interpolate=True, override=False, encoding='utf-8')

Parse a .env file and return a dict without modifying os.environ.

Parameters:

Name Type Description Default
dotenv_path str | PathLike[str] | None

Path to the .env file. If None, uses find_dotenv().

None
stream IO[str] | None

A text stream to read from (overrides dotenv_path).

None
verbose bool

Print a warning when the file is missing.

False
interpolate bool

Expand $VAR and ${VAR} references.

True
override bool

Unused for dotenv_values (kept for API compatibility).

False
encoding str

File encoding.

'utf-8'

Returns:

Type Description
dict[str, str | None]

Dictionary mapping variable names to their values.

Source code in dotenv/dotenv.py
def dotenv_values(
    dotenv_path: str | os.PathLike[str] | None = None,
    stream: IO[str] | None = None,
    verbose: bool = False,
    interpolate: bool = True,
    override: bool = False,
    encoding: str = "utf-8",
) -> dict[str, str | None]:
    """Parse a .env file and return a dict without modifying ``os.environ``.

    Args:
        dotenv_path: Path to the .env file. If None, uses ``find_dotenv()``.
        stream: A text stream to read from (overrides *dotenv_path*).
        verbose: Print a warning when the file is missing.
        interpolate: Expand ``$VAR`` and ``${VAR}`` references.
        override: Unused for dotenv_values (kept for API compatibility).
        encoding: File encoding.

    Returns:
        Dictionary mapping variable names to their values.
    """
    if stream is not None:
        return dict(_parse_stream(stream, interpolate=interpolate))

    path = _resolve_dotenv_path(dotenv_path, verbose)
    if path is None:
        return {}

    with open(path, encoding=encoding) as f:
        return dict(_parse_stream(f, interpolate=interpolate))

load_dotenv(dotenv_path=None, stream=None, verbose=False, interpolate=True, override=False, encoding='utf-8')

Read a .env file and set os.environ.

Parameters:

Name Type Description Default
dotenv_path str | PathLike[str] | None

Path to the .env file. If None, uses find_dotenv().

None
stream IO[str] | None

A text stream to read from (overrides dotenv_path).

None
verbose bool

Print a warning when the file is missing.

False
interpolate bool

Expand $VAR and ${VAR} references.

True
override bool

If True, overwrite existing environment variables.

False
encoding str

File encoding.

'utf-8'

Returns:

Type Description
bool

True if a file was found and loaded.

Source code in dotenv/dotenv.py
def load_dotenv(
    dotenv_path: str | os.PathLike[str] | None = None,
    stream: IO[str] | None = None,
    verbose: bool = False,
    interpolate: bool = True,
    override: bool = False,
    encoding: str = "utf-8",
) -> bool:
    """Read a .env file and set ``os.environ``.

    Args:
        dotenv_path: Path to the .env file. If None, uses ``find_dotenv()``.
        stream: A text stream to read from (overrides *dotenv_path*).
        verbose: Print a warning when the file is missing.
        interpolate: Expand ``$VAR`` and ``${VAR}`` references.
        override: If True, overwrite existing environment variables.
        encoding: File encoding.

    Returns:
        True if a file was found and loaded.
    """
    if stream is not None:
        _apply_to_environ(_parse_stream(stream, interpolate=interpolate), override)
        return True

    path = _resolve_dotenv_path(dotenv_path, verbose)
    if path is None:
        return False

    with open(path, encoding=encoding) as f:
        _apply_to_environ(_parse_stream(f, interpolate=interpolate), override)
    return True