added web service

This commit is contained in:
2026-09-02 12:48:03 +03:00
parent 84b7eceb9f
commit 02c43072c4
60 changed files with 6148 additions and 22 deletions
View File
+30
View File
@@ -0,0 +1,30 @@
from fastapi import Depends, HTTPException, Security, status
from fastapi.security import APIKeyHeader, HTTPAuthorizationCredentials, HTTPBearer
from app.core.config import get_settings
_bearer = HTTPBearer(auto_error=False)
_api_key = APIKeyHeader(name="X-API-Token", auto_error=False)
def require_token(
bearer: HTTPAuthorizationCredentials | None = Security(_bearer),
api_key: str | None = Security(_api_key),
) -> None:
settings = get_settings()
expected = settings.api_token
if not expected:
return
token = None
if bearer and bearer.credentials:
token = bearer.credentials
elif api_key:
token = api_key
if token != expected:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or missing API token",
)
AuthDep = Depends(require_token)
+33
View File
@@ -0,0 +1,33 @@
from functools import lru_cache
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
database_url: str = "postgresql+psycopg://gost:gost@localhost:5432/gost"
api_token: str = "changeme"
data_dir: str = "./data"
font_path: str = str(Path(__file__).resolve().parents[2] / "fonts" / "GOST_A.TTF")
openrouter_base_url: str = "https://openrouter.ai/api/v1"
openrouter_api_key: str = ""
openrouter_model: str = "deepseek/deepseek-chat"
# SOCKS5 proxy for OpenRouter, e.g. socks5://user:pass@host:1080
openrouter_proxy: str = ""
llm_max_context_rows: int = 80
cors_origins: str = "*"
@property
def cors_origin_list(self) -> list[str]:
if self.cors_origins.strip() == "*":
return ["*"]
return [o.strip() for o in self.cors_origins.split(",") if o.strip()]
@lru_cache
def get_settings() -> Settings:
return Settings()
+23
View File
@@ -0,0 +1,23 @@
from collections.abc import Generator
from sqlalchemy import create_engine
from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
from app.core.config import get_settings
class Base(DeclarativeBase):
pass
settings = get_settings()
engine = create_engine(settings.database_url, pool_pre_ping=True)
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)
def get_db() -> Generator[Session, None, None]:
db = SessionLocal()
try:
yield db
finally:
db.close()