Add semantic-index service, deployment assets, and tests

This commit is contained in:
Jason Thistlethwaite
2026-05-04 09:50:03 -04:00
parent faad70872b
commit b305544f63
42 changed files with 5059 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
from __future__ import annotations
import os
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, Optional
@dataclass(frozen=True)
class Settings:
openai_api_key: Optional[str]
qdrant_url: str
qdrant_api_key: Optional[str]
qdrant_collection: str
redmine_url: str
redmine_api_key: Optional[str]
redmine_project_identifier: Optional[str]
sample_limit: int
bind_host: str
bind_port: int
service_api_key: Optional[str]
refresh_state_path: Path
def load_dotenv(path: str | Path = ".env") -> Dict[str, str]:
values: Dict[str, str] = {}
dotenv = Path(path)
if not dotenv.exists():
return values
for raw_line in dotenv.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
values[key.strip()] = value.strip().strip('"').strip("'")
return values
def resolve_dotenv_path(dotenv_path: str | Path = ".env") -> Path:
primary = Path(dotenv_path)
if primary.exists():
return primary
package_env = primary.parent / "semantic_index" / ".env"
if package_env.exists():
return package_env
return primary
def load_settings(dotenv_path: str | Path = ".env") -> Settings:
env = {**load_dotenv(resolve_dotenv_path(dotenv_path)), **os.environ}
return Settings(
openai_api_key=env.get("OPENAI_API_KEY"),
qdrant_url=env.get("QDRANT_URL", "http://localhost:6333"),
qdrant_api_key=env.get("QDRANT_API_KEY"),
qdrant_collection=env.get("QDRANT_COLLECTION", "redmine_semantic_sample"),
redmine_url=env.get("REDMINE_URL", "http://localhost"),
redmine_api_key=env.get("REDMINE_API_KEY"),
redmine_project_identifier=env.get("REDMINE_PROJECT_IDENTIFIER"),
sample_limit=int(env.get("REDMINE_SAMPLE_LIMIT", "500")),
bind_host=env.get("SEMANTIC_INDEX_HOST", "127.0.0.1"),
bind_port=int(env.get("SEMANTIC_INDEX_PORT", "8787")),
service_api_key=env.get("SEMANTIC_INDEX_API_KEY"),
refresh_state_path=Path(env.get("SEMANTIC_INDEX_REFRESH_STATE_PATH", ".cache/semantic_index/refresh_state.json")),
)