# How API Keys Are Managed in CreativeMath Configuration: A Complete Guide

> Learn how CreativeMath manages API keys in its config.json file. Discover centralized storage and runtime loading for secure LLM credential management.

- Repository: [Junyi Ye/creativemath](https://github.com/junyiye/creativemath)
- Tags: how-to-guide
- Published: 2026-03-05

---

**CreativeMath stores all LLM API credentials in a centralized [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) file with placeholder values, loading them at runtime via the `load_config()` function in [`src/config.py`](https://github.com/junyiye/creativemath/blob/main/src/config.py) to initialize provider-specific clients.**

The `junyiye/creativemath` repository implements a straightforward, file-based approach to API key management that prioritizes transparency and ease of configuration. Understanding how API keys are managed in CreativeMath configuration is essential for securely connecting to external language model providers like OpenAI, Anthropic, Google Gemini, and DeepSeek.

## Centralized API Key Storage in config.json

All credentials reside in the repository root within [[`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json)](https://github.com/junyiye/creativemath/blob/main/config.json). This file declares an **`api_keys`** object containing placeholder strings for each supported provider:

```json
{
  "api_keys": {
    "ANTHROPIC_API_KEY": "YOUR_ANTHROPIC_API_KEY",
    "DEEPSEEK_API_KEY": "YOUR_DEEPSEEK_API_KEY",
    "GEMINI_API_KEY": "YOUR_GEMINI_API_KEY",
    "OPENAI_API_KEY": "YOUR_OPENAI_API_KEY"
  }
}

```

The placeholder format (`YOUR_XXX_API_KEY`) provides explicit visual cues that these values must be replaced with actual credentials before running experiments.

## Loading Configuration with load_config

The [[`src/config.py`](https://github.com/junyiye/creativemath/blob/main/src/config.py)](https://github.com/junyiye/creativemath/blob/main/src/config.py) module handles file I/O through the **`load_config`** function. This utility reads [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) once at import time and returns a Python dictionary:

```python
import json

def load_config():
    file_path = "config.json"
    with open(file_path, "r") as file:
        return json.load(file)

config = load_config()

```

By executing `config = load_config()` at the module level, CreativeMath ensures the configuration dictionary — including the nested `api_keys` mapping — is immediately available to all downstream modules without repeated disk access.

## Provider-Specific API Client Initialization

The [[`src/models/api_models.py`](https://github.com/junyiye/creativemath/blob/main/src/models/api_models.py)](https://github.com/junyiye/creativemath/blob/main/src/models/api_models.py) file consumes these credentials through the **`load_api_model`** function. This implementation extracts the appropriate key from `config["api_keys"]` and injects it into the corresponding provider's SDK:

```python
from src.config import config

def load_api_model(model_name):
    api_keys = config["api_keys"]
    
    if model_name in ["claude-3-opus", "claude-3-5-sonnet"]:
        client = Anthropic(api_key=api_keys["ANTHROPIC_API_KEY"])
    elif model_name == "deepseek-v2":
        client = OpenAI(api_key=api_keys["DEEPSEEK_API_KEY"], base_url="https://api.deepseek.com")
    elif model_name == "gemini-1.5-pro":
        genai.configure(api_key=api_keys["GEMINI_API_KEY"])
        client = genai.GenerativeModel(model_name)
    elif model_name in ["gpt-4", "gpt-4o", "gpt-4o-mini"]:
        client = OpenAI(api_key=api_keys["OPENAI_API_KEY"])
    
    return client

```

Each branch handles the specific authentication mechanism required by the provider's Python library, whether passing `api_key` to the constructor or calling a global configuration method.

## Security Best Practices and Placeholder Design

CreativeMath employs a **security-by-convention** approach rather than environment variable injection. The repository's `.gitignore` file excludes `.env` files, encouraging users to store real credentials locally and manually transfer them into [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) before execution.

This design offers several advantages for managing API keys in CreativeMath configuration:

- **Explicit visibility**: Placeholder strings make it immediately obvious which providers require credentials
- **Single source of truth**: All keys reside in one JSON structure, eliminating scattered environment variable references
- **Version control safety**: The placeholder-only [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) can be safely committed to git, while actual secrets remain uncommitted

## Practical Usage Examples

### Debugging Available Keys

To verify that CreativeMath has loaded your credentials correctly, import the config dictionary and inspect the `api_keys` mapping:

```python
from src.config import config

def show_keys():
    for name, key in config["api_keys"].items():
        masked = key[:4] + "..." + key[-4:] if len(key) > 8 else "NOT_SET"
        print(f"{name}: {masked}")

if __name__ == "__main__":
    show_keys()

```

### Running OpenAI GPT-4

Initialize the client using the shared configuration, then generate a response:

```python
from src.models.api_models import load_api_model, generate_api_response

# Initialize client (reads OPENAI_API_KEY from config.json)

client = load_api_model("gpt-4")

messages = [
    {"role": "system", "content": "You are a helpful math tutor."},
    {"role": "user", "content": "Explain the concept of a derivative."}
]

response = generate_api_response("gpt-4", client, messages)
print(response)

```

### Switching to Anthropic Claude

The same configuration object supplies credentials for Anthropic models without additional setup:

```python

# Switch to Claude (reads ANTHROPIC_API_KEY from config.json)

client = load_api_model("claude-3-opus")
response = generate_api_response("claude-3-opus", client, messages)
print(response)

```

## Summary

- CreativeMath stores all LLM credentials in a centralized **[`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json)** file using placeholder values for four providers: Anthropic, DeepSeek, Google Gemini, and OpenAI.
- The **`load_config()`** function in [`src/config.py`](https://github.com/junyiye/creativemath/blob/main/src/config.py) reads this JSON once at import time, making the `api_keys` dictionary available application-wide.
- Provider-specific clients in [`src/models/api_models.py`](https://github.com/junyiye/creativemath/blob/main/src/models/api_models.py) extract their respective keys from this shared configuration object during initialization.
- The placeholder-based design prevents accidental secret commits while maintaining explicit visibility into which external services require authentication.

## Frequently Asked Questions

### Where are API keys stored in CreativeMath?

API keys are stored in the [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) file at the repository root. This JSON file contains an `api_keys` object with placeholder strings for each supported LLM provider, including Anthropic, DeepSeek, Google Gemini, and OpenAI.

### How does CreativeMath load API configuration?

CreativeMath loads the configuration through the `load_config()` function defined in [`src/config.py`](https://github.com/junyiye/creativemath/blob/main/src/config.py). This function reads [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) and returns a Python dictionary. The configuration is loaded once when the module is imported, making the `api_keys` mapping immediately available to all model clients.

### Is it safe to commit API keys to the CreativeMath repository?

No, you should never commit real API keys to the repository. The [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) file distributed with CreativeMath contains placeholder values like `YOUR_OPENAI_API_KEY` specifically to prevent accidental commits. The repository's `.gitignore` file excludes `.env` files, encouraging users to store actual credentials locally and manually copy them into [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json) only for local execution.

### Which LLM providers does CreativeMath support for API key configuration?

CreativeMath supports four major LLM providers through its centralized configuration: **Anthropic** (Claude models), **DeepSeek** (DeepSeek-V2), **Google** (Gemini 1.5 Pro), and **OpenAI** (GPT-4, GPT-4o, and GPT-4o-mini). Each provider has a dedicated key entry in the `api_keys` object within [`config.json`](https://github.com/junyiye/creativemath/blob/main/config.json).