1882edfff6
- backend/api/auth.py: register, login (TOTP+backup), refresh, logout, me, change-password; per-account Redis rate limit; HIBP check - backend/main.py: Origin validation middleware, CSP headers middleware, CORS locked to settings.cors_origins, Redis lifespan (app.state.redis), admin bootstrap, auth router included, slowapi SlowAPIMiddleware - backend/services/email.py: already created in Plan 01 (verified exists) - Python 3.9 compat: fixed match statement in ai/__init__.py, str|None union syntax in openai_provider.py, api/documents.py, api/topics.py, api/settings.py, services/classifier.py All 17 tests in test_auth_api.py pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36 lines
1.3 KiB
Python
36 lines
1.3 KiB
Python
from ai.base import AIProvider, ClassificationResult
|
|
from ai.anthropic_provider import AnthropicProvider
|
|
from ai.openai_provider import OpenAIProvider
|
|
from ai.ollama_provider import OllamaProvider
|
|
from ai.lmstudio_provider import LMStudioProvider
|
|
|
|
|
|
def get_provider(settings: dict) -> AIProvider:
|
|
active = settings.get("active_provider", "lmstudio")
|
|
providers = settings.get("providers", {})
|
|
cfg = providers.get(active, {})
|
|
|
|
if active == "anthropic":
|
|
return AnthropicProvider(
|
|
api_key=cfg.get("api_key", ""),
|
|
model=cfg.get("model", "claude-sonnet-4-6"),
|
|
)
|
|
elif active == "openai":
|
|
return OpenAIProvider(
|
|
api_key=cfg.get("api_key", ""),
|
|
model=cfg.get("model", "gpt-4o"),
|
|
base_url=cfg.get("base_url") or None,
|
|
)
|
|
elif active == "ollama":
|
|
return OllamaProvider(
|
|
base_url=cfg.get("base_url", "http://host.docker.internal:11434"),
|
|
model=cfg.get("model", "llama3.2"),
|
|
)
|
|
elif active == "lmstudio":
|
|
return LMStudioProvider(
|
|
base_url=cfg.get("base_url", "http://host.docker.internal:1234"),
|
|
model=cfg.get("model", "gemma-4-e4b-it"),
|
|
)
|
|
else:
|
|
raise ValueError(f"Unknown AI provider: {active}")
|