# How Environment Variables Are Used for API Keys in MoneyPrinterV2: A Complete Guide to GEMINI_API_KEY Configuration

> Learn how MoneyPrinterV2 uses environment variables for API keys like GEMINI_API_KEY. Configure your API key securely and efficiently with this complete guide.

- Repository: [FujiwaraChoki/MoneyPrinterV2](https://github.com/FujiwaraChoki/MoneyPrinterV2)
- Tags: how-to-guide
- Published: 2026-03-20

---

**MoneyPrinterV2 implements a dual-source configuration system that checks [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) first and falls back to the `GEMINI_API_KEY` environment variable when the API key is missing or empty.**

The open-source MoneyPrinterV2 repository by FujiwaraChoki manages sensitive credentials like the Gemini (Nanobanana2) API key through a flexible fallback mechanism. This approach allows developers to keep secrets out of version control while maintaining convenience for local development and CI/CD pipelines.

## The Dual-Source Configuration Pattern

MoneyPrinterV2 stores non-sensitive configuration in **[`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json)** at the repository root. However, for security-critical values like API keys, the application implements a priority-based lookup system:

1. **Primary Source**: The `nanobanana2_api_key` field in [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json)
2. **Fallback Source**: The `GEMINI_API_KEY` environment variable

This pattern ensures that if the JSON configuration is empty or omitted, the application can still retrieve the credential from the shell environment.

## How GEMINI_API_KEY Fallback Works in src/config.py

The core logic resides in **[`src/config.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/src/config.py)** within the `get_nanobanana2_api_key()` function (lines 115-124). This helper reads the local configuration file and implements the environment variable fallback:

```python

# From src/config.py

import json
import os

def get_nanobanana2_api_key():
    with open("config.json", "r") as f:
        config = json.load(f)
    
    # Priority: config.json value, then GEMINI_API_KEY env var

    configured = config.get("nanobanana2_api_key", "")
    return configured or os.environ.get("GEMINI_API_KEY", "")

```

**Key implementation details:**
- The function uses `os.environ.get()` to safely retrieve the environment variable without raising a `KeyError` if unset
- The `or` operator ensures that an empty string in [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) (falsy) triggers the fallback
- If neither source provides a value, the function returns an empty string

## Validation and Preflight Checks

Before the main application executes, **[`scripts/preflight_local.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/scripts/preflight_local.py)** performs sanity checks to ensure the API key is available from either source (lines 85-95):

```python

# From scripts/preflight_local.py

import json
import os
import sys

def validate_api_key():
    with open("config.json") as f:
        cfg = json.load(f)
    
    api_key = cfg.get("nanobanana2_api_key", "") or os.environ.get("GEMINI_API_KEY", "")
    
    if not api_key:
        print("ERROR: Gemini API key not found in config.json or GEMINI_API_KEY environment variable")
        sys.exit(1)
    
    return api_key

```

This validation step prevents runtime failures by ensuring the credential exists before any expensive operations begin.

## Consuming the API Key in Provider Classes

Individual service providers retrieve the key through the configuration helper. For example, **[`src/classes/YouTube.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/src/classes/YouTube.py)** uses the function to access Gemini capabilities for video title generation (lines 331-334):

```python

# From src/classes/YouTube.py

from src.config import get_nanobanana2_api_key

class YouTube:
    def generate_title(self, description):
        api_key = get_nanobanana2_api_key()
        # Use api_key with Gemini client...

```

This pattern ensures consistent credential management across all modules that interact with the Gemini API.

## Configuration Precedence and Security Best Practices

Understanding the precedence rules helps prevent configuration conflicts:

**Precedence Order (highest to lowest):**
1. **[`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json)** value (if non-empty)
2. **`GEMINI_API_KEY`** environment variable
3. Empty string (application handles as missing)

**Security recommendations:**
- **Never commit [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json)** with real API keys to version control
- **Use `.env.example`** (provided in the repository root) as a template for required environment variables
- **Set `GEMINI_API_KEY` in CI/CD pipelines** via secret management tools rather than storing in repository files
- **Keep [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) for non-sensitive settings** like `verbose` or `headless` mode

**Example environment setup:**

```bash

# Export for current session

export GEMINI_API_KEY="your-actual-api-key-here"

# Or add to .env file (if using python-dotenv)

echo "GEMINI_API_KEY=your-actual-api-key-here" >> .env

```

## Summary

- MoneyPrinterV2 uses a **dual-source configuration** system where [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) takes precedence over environment variables
- The **`GEMINI_API_KEY`** environment variable serves as a fallback when `nanobanana2_api_key` is empty in [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json)
- **Implementation** resides in [`src/config.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/src/config.py) within the `get_nanobanana2_api_key()` function
- **Validation** occurs in [`scripts/preflight_local.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/scripts/preflight_local.py) to ensure the key exists before runtime
- **Consumers** like [`src/classes/YouTube.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/src/classes/YouTube.py) retrieve the key through the centralized configuration helper

## Frequently Asked Questions

### What happens if both config.json and GEMINI_API_KEY are set?

If the `nanobanana2_api_key` field in [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) contains a non-empty string, that value takes precedence and the `GEMINI_API_KEY` environment variable is ignored. Only when the JSON value is empty or missing does the system check the environment variable.

### Is it safe to commit config.json with an empty nanobanana2_api_key field?

Yes, committing [`config.json`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/config.json) with an empty `nanobanana2_api_key` value (or placeholder text) is safe and recommended. This allows the repository to contain the configuration structure without exposing secrets, while the actual API key can be injected via the `GEMINI_API_KEY` environment variable during runtime.

### How do I set GEMINI_API_KEY for development on Windows?

On Windows Command Prompt, use `set GEMINI_API_KEY=your-key-here` for the current session, or use `setx GEMINI_API_KEY "your-key-here"` to persist it across sessions. On Windows PowerShell, use `$env:GEMINI_API_KEY="your-key-here"`. For permanent configuration, set the variable through System Properties > Environment Variables.

### Does MoneyPrinterV2 support .env files for loading environment variables?

The repository includes a `.env.example` file suggesting support for environment variables, but the core configuration system in [`src/config.py`](https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/main/src/config.py) uses `os.environ.get()` directly. To use `.env` files, you would need to load them manually using a library like `python-dotenv` before importing the configuration module, or export the variables in your shell before running the application.