Skip to main content

Live API Testing Guide for Generators

This guide explains how to test generators with real provider APIs (Replicate, Fal.ai, OpenAI, etc.) rather than mocked responses.

Overview​

Boards includes two types of generator tests:

  1. Unit tests (test_<generator>.py) - Use mocks, run by default, fast and free
  2. Live API tests (test_<generator>_live.py) - Call real APIs, opt-in only, consume credits

Live API tests are never run by default. They must be explicitly invoked and require valid API keys.

When to Run Live API Tests​

Run live API tests when:

  • ✅ You've modified a generator implementation
  • ✅ You've updated a provider SDK dependency
  • ✅ You want to verify real API connectivity
  • ✅ You're debugging unexpected behavior in production
  • ✅ Before releasing a new generator to production

Don't run live tests:

  • ❌ During regular development (use unit tests instead)
  • ❌ In pre-commit hooks
  • ❌ As part of make test or make test-backend
  • ❌ In CI/CD pipelines (unless explicitly configured)

Setting Up API Keys​

Live tests require provider API keys. There are two ways to configure them:

Option 1: Via Environment Variables (Direct)​

# Replicate
export REPLICATE_API_TOKEN="r8_..."

# Fal.ai
export FAL_KEY="..."

# OpenAI
export OPENAI_API_KEY="sk-..."
# Single key
export BOARDS_GENERATOR_API_KEYS='{"REPLICATE_API_TOKEN": "r8_..."}'

# Multiple keys (JSON format)
export BOARDS_GENERATOR_API_KEYS='{
"REPLICATE_API_TOKEN": "r8_...",
"FAL_KEY": "...",
"OPENAI_API_KEY": "sk-..."
}'

Or add to your .env file:

BOARDS_GENERATOR_API_KEYS={"REPLICATE_API_TOKEN": "r8_..."}

The Boards config system will automatically sync these keys to os.environ for third-party SDKs.

Running Live API Tests​

Run a Single Generator's Live Test​

This is the most common workflow when developing generators:

# After modifying flux_pro.py
export REPLICATE_API_TOKEN="r8_..."
pytest tests/generators/implementations/test_flux_pro_live.py -v

Example output:

tests/generators/implementations/test_flux_pro_live.py::TestFluxProGeneratorLive::test_generate_basic PASSED
tests/generators/implementations/test_flux_pro_live.py::TestFluxProGeneratorLive::test_generate_with_aspect_ratio PASSED

If the API key is missing, tests will be skipped:

tests/generators/implementations/test_flux_pro_live.py::TestFluxProGeneratorLive::test_generate_basic SKIPPED (REPLICATE_API_TOKEN not set)

Run All Live Tests for One Provider​

# All Replicate generators
export REPLICATE_API_TOKEN="r8_..."
pytest -m live_replicate -v

# All Fal generators
export FAL_KEY="..."
pytest -m live_fal -v

# All OpenAI generators
export OPENAI_API_KEY="sk-..."
pytest -m live_openai -v

Run All Live API Tests (Rarely Used)​

# Requires ALL provider API keys to be set
export REPLICATE_API_TOKEN="r8_..."
export FAL_KEY="..."
export OPENAI_API_KEY="sk-..."

pytest -m live_api -v

⚠️ Warning: This will consume credits across all providers!

Run With Extra Verbosity​

# Show detailed output including print statements and logs
pytest tests/generators/implementations/test_flux_pro_live.py -v -s

# Show full error tracebacks
pytest tests/generators/implementations/test_flux_pro_live.py -v --tb=long

Cost Management​

Live API tests consume real provider credits. Follow these practices:

1. Cost Logging​

All live tests log estimated costs before running:

@pytest.mark.asyncio
async def test_generate_basic(self, cost_logger):
cost_logger("replicate-flux-pro", 0.055)
# Test implementation...

Look for log output like:

WARNING live_api_test_cost generator=replicate-flux-pro estimated_cost_usd=0.055

2. Minimal Inputs​

Tests use minimal/cheap parameters:

# ✅ Good - Simple prompt, small size
inputs = FluxProInput(
prompt="A simple red circle",
aspect_ratio="1:1",
)

# ❌ Bad - Complex prompt, large size, multiple images
inputs = FluxProInput(
prompt="Ultra detailed 8K photorealistic...",
aspect_ratio="21:9",
num_images=10,
)

3. Approximate Costs (as of 2024)​

ProviderGeneratorEstimated Cost
Replicateflux-pro$0.055/image
Fal.ainano-banana$0.05/image
Fal.ainano-banana-edit$0.05/image
OpenAIdalle3$0.04-$0.08/image
OpenAIwhisper$0.006/minute

Running a full test suite for one generator typically costs $0.10 - $0.30.

Verifying Tests Are Excluded​

Live tests are automatically excluded by default thanks to pytest.ini configuration:

# All of these commands exclude live tests by default:
make test-backend
cd packages/backend && uv run pytest
cd packages/backend && uv run pytest tests/

You should see output like:

337/350 tests collected (13 deselected)

The 13 deselected tests are the live API tests.

Check pytest markers to see which tests would run:

# List all live API tests (without running them)
pytest --collect-only -m live_api

# Verify default behavior excludes live tests
pytest --collect-only -q | tail -1
# Should show: "337/350 tests collected (13 deselected)"

Troubleshooting​

Tests Are Skipped​

Problem: All tests show SKIPPED status

Cause: API key not found

Solution:

# Verify API key is set
echo $REPLICATE_API_TOKEN

# If empty, export it
export REPLICATE_API_TOKEN="r8_..."

# Or check Boards config
python -c "from boards.config import settings; print(settings.generator_api_keys)"

API Errors​

Problem: Test fails with authentication error

Solutions:

  1. Verify API key is valid (not expired/revoked)
  2. Check API key has correct permissions
  3. Verify provider account has sufficient credits

Example error:

ValueError: API configuration invalid. Missing REPLICATE_API_TOKEN

Unexpected Costs​

Problem: Tests consumed more credits than expected

Prevention:

  1. Always read the test file first to understand what it does
  2. Check cost logger output before tests run
  3. Use single generator tests, not pytest -m live_api
  4. Start with one test function: pytest test_flux_pro_live.py::TestFluxProGeneratorLive::test_estimate_cost

Adding Live Tests for New Generators​

When creating a new generator, follow these steps:

1. Create the Live Test File​

# Template: test_<generator>_live.py
touch tests/generators/implementations/test_my_generator_live.py

2. Use This Template​

"""
Live API tests for MyGenerator.

To run: pytest tests/generators/implementations/test_my_generator_live.py -v
"""
import pytest
from boards.config import initialize_generator_api_keys
from boards.generators.implementations.provider.type.my_generator import (
MyGeneratorInput,
MyGenerator,
)

pytestmark = [pytest.mark.live_api, pytest.mark.live_<provider>]


class TestMyGeneratorLive:
"""Live API tests for MyGenerator."""

def setup_method(self):
"""Set up generator and sync API keys."""
self.generator = MyGenerator()
initialize_generator_api_keys()

@pytest.mark.asyncio
async def test_generate_basic(
self, skip_if_no_<provider>_key, dummy_context, cost_logger
):
"""Test basic generation with minimal parameters."""
# Log cost
estimated_cost = await self.generator.estimate_cost(
MyGeneratorInput(prompt="test")
)
cost_logger(self.generator.name, estimated_cost)

# Minimal input to reduce cost
inputs = MyGeneratorInput(prompt="Simple test")

# Execute
result = await self.generator.generate(inputs, dummy_context)

# Verify
assert result.outputs is not None
assert len(result.outputs) > 0
assert result.outputs[0].storage_url is not None

3. Add Provider-Specific Skip Fixture (If New Provider)​

If adding a new provider (not Replicate/Fal/OpenAI), add to conftest.py:

@pytest.fixture
def skip_if_no_my_provider_key():
"""Skip test if MY_PROVIDER_API_KEY is not available."""
if not check_api_key("MY_PROVIDER_API_KEY"):
pytest.skip("MY_PROVIDER_API_KEY not set, skipping live API test")

4. Add Pytest Marker (If New Provider)​

Update pytest.ini:

markers =
...
live_my_provider: marks tests that call MyProvider API (subset of live_api)

5. Test Your Live Test​

# Without API key - should skip
pytest tests/generators/implementations/test_my_generator_live.py -v

# With API key - should run
export MY_PROVIDER_API_KEY="..."
pytest tests/generators/implementations/test_my_generator_live.py -v

Best Practices​

DO:​

  • ✅ Run live tests individually after modifying a generator
  • ✅ Use minimal inputs to reduce costs
  • ✅ Log estimated costs before running tests
  • ✅ Keep live tests simple and focused
  • ✅ Verify tests are skipped when API keys are missing
  • ✅ Document expected costs in test docstrings

DON'T:​

  • ❌ Run pytest -m live_api unless you mean it
  • ❌ Add live tests to CI without explicit approval
  • ❌ Use live tests for load/performance testing
  • ❌ Test with expensive parameters (high quality, large sizes, etc.)
  • ❌ Create hundreds of test cases for one generator
  • ❌ Commit API keys to the repository

Continuous Integration (Optional)​

If you want to run live tests in CI (not recommended for most projects):

GitHub Actions Example​

name: Live API Tests (Manual)

on:
workflow_dispatch: # Manual trigger only

jobs:
live-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
cd packages/backend
pip install uv
uv sync
- name: Run Replicate live tests
env:
REPLICATE_API_TOKEN: ${{ secrets.REPLICATE_API_TOKEN }}
run: |
cd packages/backend
uv run pytest -m live_replicate --tb=short

Important: Only run on:

  • Manual workflow dispatch
  • Scheduled (e.g., nightly) runs
  • Release branches

Never run live tests on every PR or commit.

Summary​

  • Live API tests verify real connectivity to provider APIs
  • They are opt-in only and never run by default
  • Set up API keys via environment variables or Boards config
  • Run individual tests after modifying generators: pytest test_flux_pro_live.py -v
  • Monitor costs using cost logger output
  • Use minimal inputs to reduce expenses
  • Follow the template when adding tests for new generators