fix: validate API keys at provider init to prevent 403 'authorization missing'

When NVIDIA_NIM_API_KEY or OPENROUTER_API_KEY is empty or not set,
the proxy forwarded requests without a valid Authorization header,
causing providers to return 403 with 'Header of type authorization
was missing'.

Now fail fast with HTTP 503 and a clear message telling users to add
the key to .env, with links to obtain keys.

Fixes #29

Co-authored-by: Ali Khokhar <alishahryar2@gmail.com>
This commit is contained in:
Cursor Agent 2026-02-17 07:33:56 +00:00
parent 7300156925
commit e9beb28897
2 changed files with 68 additions and 0 deletions

View file

@ -2,6 +2,7 @@
from typing import Optional
from fastapi import HTTPException
from loguru import logger
from config.settings import Settings, get_settings as _get_settings, NVIDIA_NIM_BASE_URL
@ -24,6 +25,17 @@ def get_provider() -> BaseProvider:
settings = get_settings()
if settings.provider_type == "nvidia_nim":
if (
not settings.nvidia_nim_api_key
or not settings.nvidia_nim_api_key.strip()
):
raise HTTPException(
status_code=503,
detail=(
"NVIDIA_NIM_API_KEY is not set. Add it to your .env file. "
"Get a key at https://build.nvidia.com/settings/api-keys"
),
)
from providers.nvidia_nim import NvidiaNimProvider
config = ProviderConfig(
@ -38,6 +50,17 @@ def get_provider() -> BaseProvider:
_provider = NvidiaNimProvider(config, nim_settings=settings.nim)
logger.info("Provider initialized: %s", settings.provider_type)
elif settings.provider_type == "open_router":
if (
not settings.open_router_api_key
or not settings.open_router_api_key.strip()
):
raise HTTPException(
status_code=503,
detail=(
"OPENROUTER_API_KEY is not set. Add it to your .env file. "
"Get a key at https://openrouter.ai/keys"
),
)
from providers.open_router import OpenRouterProvider
config = ProviderConfig(

View file

@ -1,4 +1,5 @@
import pytest
from fastapi import HTTPException
from unittest.mock import AsyncMock, MagicMock, patch
from api.dependencies import get_provider, get_settings, cleanup_provider
from providers.lmstudio import LMStudioProvider
@ -143,6 +144,50 @@ async def test_get_provider_passes_http_timeouts_from_settings():
assert timeout.connect == 5.0
@pytest.mark.asyncio
async def test_get_provider_nvidia_nim_missing_api_key():
"""NVIDIA NIM with empty API key raises HTTPException 503."""
with patch("api.dependencies.get_settings") as mock_settings:
mock_settings.return_value = _make_mock_settings(nvidia_nim_api_key="")
with pytest.raises(HTTPException) as exc_info:
get_provider()
assert exc_info.value.status_code == 503
assert "NVIDIA_NIM_API_KEY" in exc_info.value.detail
assert "build.nvidia.com" in exc_info.value.detail
@pytest.mark.asyncio
async def test_get_provider_nvidia_nim_whitespace_only_api_key():
"""NVIDIA NIM with whitespace-only API key raises HTTPException 503."""
with patch("api.dependencies.get_settings") as mock_settings:
mock_settings.return_value = _make_mock_settings(nvidia_nim_api_key=" ")
with pytest.raises(HTTPException) as exc_info:
get_provider()
assert exc_info.value.status_code == 503
assert "NVIDIA_NIM_API_KEY" in exc_info.value.detail
@pytest.mark.asyncio
async def test_get_provider_open_router_missing_api_key():
"""OpenRouter with empty API key raises HTTPException 503."""
with patch("api.dependencies.get_settings") as mock_settings:
mock_settings.return_value = _make_mock_settings(
provider_type="open_router",
open_router_api_key="",
)
with pytest.raises(HTTPException) as exc_info:
get_provider()
assert exc_info.value.status_code == 503
assert "OPENROUTER_API_KEY" in exc_info.value.detail
assert "openrouter.ai" in exc_info.value.detail
@pytest.mark.asyncio
async def test_get_provider_unknown_type():
"""Test that unknown provider_type raises ValueError."""