mirror of
https://github.com/arc53/DocsGPT.git
synced 2026-01-20 05:50:58 +00:00
Manage apikeys in settings
1. More pydantic management of api keys. 2. Clean up of variable declarations from docker compose files, used to block .env imports. Now should be managed ether by settings.py defaults or .env
This commit is contained in:
@@ -6,19 +6,6 @@ from typing import Dict, List, Optional
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _is_valid_api_key(key: Optional[str]) -> bool:
|
||||
"""
|
||||
Check if an API key is valid (not None, not empty, not string 'None').
|
||||
Handles Pydantic loading 'None' from .env as string "None".
|
||||
"""
|
||||
if key is None:
|
||||
return False
|
||||
if not isinstance(key, str):
|
||||
return False
|
||||
key_stripped = key.strip().lower()
|
||||
return key_stripped != "" and key_stripped != "none"
|
||||
|
||||
|
||||
class ModelProvider(str, Enum):
|
||||
OPENAI = "openai"
|
||||
AZURE_OPENAI = "azure_openai"
|
||||
@@ -101,29 +88,29 @@ class ModelRegistry:
|
||||
if not settings.OPENAI_BASE_URL:
|
||||
self._add_docsgpt_models(settings)
|
||||
if (
|
||||
_is_valid_api_key(settings.OPENAI_API_KEY)
|
||||
or (settings.LLM_PROVIDER == "openai" and _is_valid_api_key(settings.API_KEY))
|
||||
settings.OPENAI_API_KEY
|
||||
or (settings.LLM_PROVIDER == "openai" and settings.API_KEY)
|
||||
or settings.OPENAI_BASE_URL
|
||||
):
|
||||
self._add_openai_models(settings)
|
||||
if settings.OPENAI_API_BASE or (
|
||||
settings.LLM_PROVIDER == "azure_openai" and _is_valid_api_key(settings.API_KEY)
|
||||
settings.LLM_PROVIDER == "azure_openai" and settings.API_KEY
|
||||
):
|
||||
self._add_azure_openai_models(settings)
|
||||
if _is_valid_api_key(settings.ANTHROPIC_API_KEY) or (
|
||||
settings.LLM_PROVIDER == "anthropic" and _is_valid_api_key(settings.API_KEY)
|
||||
if settings.ANTHROPIC_API_KEY or (
|
||||
settings.LLM_PROVIDER == "anthropic" and settings.API_KEY
|
||||
):
|
||||
self._add_anthropic_models(settings)
|
||||
if _is_valid_api_key(settings.GOOGLE_API_KEY) or (
|
||||
settings.LLM_PROVIDER == "google" and _is_valid_api_key(settings.API_KEY)
|
||||
if settings.GOOGLE_API_KEY or (
|
||||
settings.LLM_PROVIDER == "google" and settings.API_KEY
|
||||
):
|
||||
self._add_google_models(settings)
|
||||
if _is_valid_api_key(settings.GROQ_API_KEY) or (
|
||||
settings.LLM_PROVIDER == "groq" and _is_valid_api_key(settings.API_KEY)
|
||||
if settings.GROQ_API_KEY or (
|
||||
settings.LLM_PROVIDER == "groq" and settings.API_KEY
|
||||
):
|
||||
self._add_groq_models(settings)
|
||||
if _is_valid_api_key(settings.HUGGINGFACE_API_KEY) or (
|
||||
settings.LLM_PROVIDER == "huggingface" and _is_valid_api_key(settings.API_KEY)
|
||||
if settings.HUGGINGFACE_API_KEY or (
|
||||
settings.LLM_PROVIDER == "huggingface" and settings.API_KEY
|
||||
):
|
||||
self._add_huggingface_models(settings)
|
||||
# Default model selection
|
||||
@@ -140,7 +127,7 @@ class ModelRegistry:
|
||||
self.default_model_id = settings.LLM_NAME
|
||||
|
||||
if not self.default_model_id:
|
||||
if settings.LLM_PROVIDER and _is_valid_api_key(settings.API_KEY):
|
||||
if settings.LLM_PROVIDER and settings.API_KEY:
|
||||
for model_id, model in self.models.items():
|
||||
if model.provider.value == settings.LLM_PROVIDER:
|
||||
self.default_model_id = model_id
|
||||
@@ -178,7 +165,7 @@ class ModelRegistry:
|
||||
)
|
||||
else:
|
||||
# Standard OpenAI API usage - add standard models if API key is valid
|
||||
if _is_valid_api_key(settings.OPENAI_API_KEY):
|
||||
if settings.OPENAI_API_KEY:
|
||||
for model in OPENAI_MODELS:
|
||||
self.models[model.id] = model
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from application.core.model_settings import ModelRegistry, _is_valid_api_key
|
||||
from application.core.model_settings import ModelRegistry
|
||||
|
||||
|
||||
def get_api_key_for_provider(provider: str) -> Optional[str]:
|
||||
@@ -19,11 +19,9 @@ def get_api_key_for_provider(provider: str) -> Optional[str]:
|
||||
}
|
||||
|
||||
provider_key = provider_key_map.get(provider)
|
||||
if provider_key and _is_valid_api_key(provider_key):
|
||||
if provider_key:
|
||||
return provider_key
|
||||
if _is_valid_api_key(settings.API_KEY):
|
||||
return settings.API_KEY
|
||||
return None
|
||||
return settings.API_KEY
|
||||
|
||||
|
||||
def get_all_available_models() -> Dict[str, Dict[str, Any]]:
|
||||
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
current_dir = os.path.dirname(
|
||||
@@ -158,6 +159,36 @@ class Settings(BaseSettings):
|
||||
COMPRESSION_PROMPT_VERSION: str = "v1.0" # Track prompt iterations
|
||||
COMPRESSION_MAX_HISTORY_POINTS: int = 3 # Keep only last N compression points to prevent DB bloat
|
||||
|
||||
@field_validator(
|
||||
"API_KEY",
|
||||
"OPENAI_API_KEY",
|
||||
"ANTHROPIC_API_KEY",
|
||||
"GOOGLE_API_KEY",
|
||||
"GROQ_API_KEY",
|
||||
"HUGGINGFACE_API_KEY",
|
||||
"EMBEDDINGS_KEY",
|
||||
"FALLBACK_LLM_API_KEY",
|
||||
"QDRANT_API_KEY",
|
||||
"ELEVENLABS_API_KEY",
|
||||
"INTERNAL_KEY",
|
||||
mode="before",
|
||||
)
|
||||
@classmethod
|
||||
def normalize_api_key(cls, v: Optional[str]) -> Optional[str]:
|
||||
"""
|
||||
Normalize API keys: convert 'None', 'none', empty strings,
|
||||
and whitespace-only strings to actual None.
|
||||
Handles Pydantic loading 'None' from .env as string "None".
|
||||
"""
|
||||
if v is None:
|
||||
return None
|
||||
if not isinstance(v, str):
|
||||
return v
|
||||
stripped = v.strip()
|
||||
if stripped == "" or stripped.lower() == "none":
|
||||
return None
|
||||
return stripped
|
||||
|
||||
|
||||
# Project root is one level above application/
|
||||
path = Path(__file__).parent.parent.parent.absolute()
|
||||
|
||||
@@ -11,17 +11,13 @@ services:
|
||||
|
||||
backend:
|
||||
build: ../application
|
||||
env_file:
|
||||
- ../.env
|
||||
environment:
|
||||
- API_KEY=$OPENAI_API_KEY
|
||||
- EMBEDDINGS_KEY=$OPENAI_API_KEY
|
||||
# Override URLs to use docker service names
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- CELERY_RESULT_BACKEND=redis://redis:6379/1
|
||||
- MONGO_URI=mongodb://mongo:27017/docsgpt
|
||||
- OPENAI_API_KEY=$OPENAI_API_KEY
|
||||
- OPENAI_API_BASE=$OPENAI_API_BASE
|
||||
- OPENAI_API_VERSION=$OPENAI_API_VERSION
|
||||
- AZURE_DEPLOYMENT_NAME=$AZURE_DEPLOYMENT_NAME
|
||||
- AZURE_EMBEDDINGS_DEPLOYMENT_NAME=$AZURE_EMBEDDINGS_DEPLOYMENT_NAME
|
||||
ports:
|
||||
- "7091:7091"
|
||||
volumes:
|
||||
@@ -35,18 +31,14 @@ services:
|
||||
worker:
|
||||
build: ../application
|
||||
command: celery -A application.app.celery worker -l INFO
|
||||
env_file:
|
||||
- ../.env
|
||||
environment:
|
||||
- API_KEY=$OPENAI_API_KEY
|
||||
- EMBEDDINGS_KEY=$OPENAI_API_KEY
|
||||
# Override URLs to use docker service names
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- CELERY_RESULT_BACKEND=redis://redis:6379/1
|
||||
- MONGO_URI=mongodb://mongo:27017/docsgpt
|
||||
- API_URL=http://backend:7091
|
||||
- OPENAI_API_KEY=$OPENAI_API_KEY
|
||||
- OPENAI_API_BASE=$OPENAI_API_BASE
|
||||
- OPENAI_API_VERSION=$OPENAI_API_VERSION
|
||||
- AZURE_DEPLOYMENT_NAME=$AZURE_DEPLOYMENT_NAME
|
||||
- AZURE_EMBEDDINGS_DEPLOYMENT_NAME=$AZURE_EMBEDDINGS_DEPLOYMENT_NAME
|
||||
depends_on:
|
||||
- redis
|
||||
- mongo
|
||||
|
||||
@@ -19,17 +19,11 @@ services:
|
||||
env_file:
|
||||
- ../.env
|
||||
environment:
|
||||
- API_KEY=$API_KEY
|
||||
- EMBEDDINGS_KEY=$EMBEDDINGS_KEY
|
||||
- EMBEDDINGS_BASE_URL=$EMBEDDINGS_BASE_URL
|
||||
- LLM_PROVIDER=$LLM_PROVIDER
|
||||
- LLM_NAME=$LLM_NAME
|
||||
# Override URLs to use docker service names
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- CELERY_RESULT_BACKEND=redis://redis:6379/1
|
||||
- MONGO_URI=mongodb://mongo:27017/docsgpt
|
||||
- CACHE_REDIS_URL=redis://redis:6379/2
|
||||
- OPENAI_BASE_URL=$OPENAI_BASE_URL
|
||||
- INTERNAL_KEY=$INTERNAL_KEY
|
||||
ports:
|
||||
- "7091:7091"
|
||||
volumes:
|
||||
@@ -47,17 +41,12 @@ services:
|
||||
env_file:
|
||||
- ../.env
|
||||
environment:
|
||||
- API_KEY=$API_KEY
|
||||
- EMBEDDINGS_KEY=$EMBEDDINGS_KEY
|
||||
- EMBEDDINGS_BASE_URL=$EMBEDDINGS_BASE_URL
|
||||
- LLM_PROVIDER=$LLM_PROVIDER
|
||||
- LLM_NAME=$LLM_NAME
|
||||
# Override URLs to use docker service names
|
||||
- CELERY_BROKER_URL=redis://redis:6379/0
|
||||
- CELERY_RESULT_BACKEND=redis://redis:6379/1
|
||||
- MONGO_URI=mongodb://mongo:27017/docsgpt
|
||||
- API_URL=http://backend:7091
|
||||
- CACHE_REDIS_URL=redis://redis:6379/2
|
||||
- INTERNAL_KEY=$INTERNAL_KEY
|
||||
volumes:
|
||||
- ../application/indexes:/app/indexes
|
||||
- ../application/inputs:/app/inputs
|
||||
|
||||
Reference in New Issue
Block a user