# How config.py Loads and Parses the .env File in Claude Video

> Discover how claude-video's config.py loads and parses the .env file. Learn about its custom UTF-8 parser, comment filtering, and key-value extraction for seamless configuration.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: how-to-guide
- Published: 2026-07-12

---

**[`config.py`](https://github.com/bradautomates/claude-video/blob/main/config.py) implements a custom UTF-8 parser that reads `~/.config/watch/.env`, filters comments and blank lines, extracts key-value pairs with support for quoted values and inline comments, and returns a dictionary consumed by `get_config()`.**

The `bradautomates/claude-video` repository contains a lightweight configuration system that does not rely on external libraries like `python-dotenv`. Instead, the [`skills/watch/scripts/config.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/config.py) module provides a self-contained implementation for loading and parsing the `.env` file. This approach gives the project precise control over encoding, comment handling, and value validation.

## Locating the Configuration File

The parser targets a fixed path defined by the `CONFIG_FILE` constant. By default, this resolves to `~/.config/watch/.env`. The `read_env_file()` function (lines 17‑45) attempts to open this location using UTF-8 encoding. If the file does not exist or lacks read permissions, the function gracefully returns an empty dictionary rather than raising an exception.

## The read_env_file() Parsing Algorithm

The core parsing logic in `read_env_file()` processes the file line-by-line through a multi-stage pipeline.

### File Reading and Error Handling

The function opens the configuration file in text mode with UTF-8 encoding. It reads all lines into memory and initializes an empty dictionary to store results. If any **IOError** occurs during file access, the function immediately returns the empty dictionary, ensuring the application can fall back to environment variables or defaults.

### Line Filtering and Validation

Each raw line undergoes initial sanitization. The parser strips surrounding whitespace and applies three exclusion rules:
- Blank lines (empty after stripping)
- Lines beginning with `#` (comment lines)
- Lines lacking an `=` character

This filtering occurs at line 29 of [`config.py`](https://github.com/bradautomates/claude-video/blob/main/config.py), ensuring only potential key-value pairs proceed to extraction.

### Key-Value Extraction

For valid lines, the parser splits the string at the first `=` character using Python's `partition()` method (line 31). This prevents truncation of values that contain `=` characters. Both the key and value components receive additional whitespace stripping to handle inconsistent indentation or spacing around the delimiter.

### Handling Quoted Values and Inline Comments

The parser implements distinct logic for quoted versus unquoted values.

**Quoted values:** If a value starts and ends with matching single or double quotes, the parser strips these delimiters (lines 33‑35). This preserves internal spaces and `#` characters, allowing complex values like API keys or paths containing hash symbols.

**Unquoted values:** For unquoted strings, the parser removes inline comments. It iterates through characters and identifies `#` symbols preceded by whitespace (space or tab). Upon finding this pattern, it truncates the value at that position and strips trailing whitespace (lines 36‑43). This ensures a line like `WATCH_DETAIL=balanced  # note` resolves to `"balanced"` rather than including the comment text.

## Environment Variable Override with get_config()

The `get_config()` function (lines 48‑62) provides a higher-level configuration interface. It first calls `read_env_file()` to obtain file-based values, then overlays any actual environment variables present in the process. This hierarchy ensures that shell-exported variables take precedence over file settings.

After merging sources, the function validates the `WATCH_DETAIL` value against an allowed set of options defined in the `DETAILS` constant. If the resolved value is invalid or missing, the system falls back to the default `"balanced"` setting (lines 56‑58). The function returns a dictionary containing the final detail level and the absolute path to the configuration file.

## Practical Usage Examples

Reading the configuration directly from the `.env` file:

```python
from skills.watch.scripts.config import read_env_file

env = read_env_file()
print(env)  # → {'WATCH_DETAIL': 'balanced', ...}

```

Getting the resolved configuration where environment variables override file settings:

```python
import os
from skills.watch.scripts.config import get_config

os.environ["WATCH_DETAIL"] = "efficient"  # overrides .env value

cfg = get_config()
print(cfg["detail"])        # → "efficient"

print(cfg["config_file"])  # → "/home/you/.config/watch/.env"

```

Using the validated detail level to determine frame processing limits:

```python
from skills.watch.scripts.config import frame_cap, get_config

detail = get_config()["detail"]
max_frames = frame_cap(detail)  # 50 for "efficient", 100 for "balanced", None for others

```

## Summary

- **[`config.py`](https://github.com/bradautomates/claude-video/blob/main/config.py)** uses a custom parser in `read_env_file()` (lines 17‑45) to read `~/.config/watch/.env` with UTF-8 encoding.
- The parser ignores blank lines, comment lines starting with `#`, and lines without `=`.
- It splits keys and values at the first `=` using `partition()`, strips whitespace, and handles quoted values by removing matching delimiters.
- Inline comments are removed from unquoted values only when preceded by whitespace.
- **`get_config()`** (lines 48‑62) merges file values with environment variables, validates against allowed `DETAILS`, and defaults to `"balanced"`.
- The system is self-contained and does not require external dependency libraries like `python-dotenv`.

## Frequently Asked Questions

### Where does config.py look for the .env file?

According to the `bradautomates/claude-video` source code, [`config.py`](https://github.com/bradautomates/claude-video/blob/main/config.py) defines a `CONFIG_FILE` constant pointing to `~/.config/watch/.env`. The `read_env_file()` function specifically targets this path when attempting to load configuration values.

### How does config.py handle missing or unreadable .env files?

If the file at `~/.config/watch/.env` does not exist or cannot be opened due to permission errors, `read_env_file()` returns an empty dictionary. This allows `get_config()` to proceed using only environment variables or default values without raising runtime exceptions.

### Can environment variables override .env file settings?

Yes. The `get_config()` function explicitly overlays environment variables on top of values read from the `.env` file. If a variable like `WATCH_DETAIL` exists in both the file and the process environment, the environment variable takes precedence.

### How are inline comments parsed in unquoted values?

For unquoted values, [`config.py`](https://github.com/bradautomates/claude-video/blob/main/config.py) removes inline comments by scanning for `#` characters preceded by whitespace (space or tab). When found, the parser truncates the value at that position and strips trailing whitespace. This behavior differs from quoted values, where the parser preserves the entire string including `#` characters.