drowzeys's picture
Upload folder using huggingface_hub
676f5d4 verified
Raw
History Blame Contribute Delete
3.37 kB
from __future__ import annotations
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
ROOT = Path(__file__).resolve().parent.parent
CATEGORIES = (
"groceries",
"dining",
"transport",
"household",
"health",
"entertainment",
"utilities",
"office",
"travel",
"other",
)
DOC_KINDS = ("receipt", "invoice", "document")
ACCEPTED_SUFFIXES = {
".jpg",
".jpeg",
".png",
".webp",
".heic",
".heif",
".tif",
".tiff",
".pdf",
".txt",
}
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_prefix="RECEIPT_",
env_file=str(ROOT / ".env"),
env_file_encoding="utf-8",
extra="ignore",
)
root_dir: Path = ROOT
data_dir: Path = ROOT / "data"
inbox_dir: Path = ROOT / "inbox"
processing_dir: Path = ROOT / "processing"
processed_dir: Path = ROOT / "processed"
failed_dir: Path = ROOT / "failed"
exports_dir: Path = ROOT / "exports"
idle_seconds: float = 30.0
# Gemma 4 12B Unified is the default omni brain (vision extract + embed).
# It does not fit on the Lamp (6 GB). Point these URLs at the GPU box.
llm_backend: str = "gemma"
llm_base_url: str = "http://127.0.0.1:8080/v1"
llm_model: str = "google/gemma-4-12B-it"
llm_api_key: str = "local"
llm_accepts_images: bool = True
llm_max_tokens: int = 8192
llm_timeout_s: float = 180.0
# auto: Studio API if up, else vLLM, else Hermes custom_providers.
# direct: RECEIPT_LLM_BASE_URL. hermes: Hermes-discovered Gemma. studio: POST /api/inbox.
llm_route: str = "auto"
studio_url: str = ""
gpu_host: str = ""
hermes_base_url: str = ""
hermes_model: str = "google/gemma-4-12B-it"
hermes_config_path: Path = Path.home() / ".hermes" / "config.yaml"
embed_backend: str = "omni"
embed_base_url: str = ""
embed_model: str = "google/gemma-4-12B-it"
embed_dim: int = 3840
embed_api_key: str = "local"
embed_timeout_s: float = 120.0
embed_prefix: bool = True
ocr_backend: str = "none"
ocr_base_url: str = "http://127.0.0.1:11434/v1"
ocr_model: str = ""
ocr_api_key: str = "local"
camera_url: str = "http://127.0.0.1:5001"
snapshot_width: int = 1280
snapshot_quality: int = 85
sku_auto: float = 0.88
sku_review: float = 0.72
vendor_auto: float = 0.82
vendor_review: float = 0.65
ui_host: str = "127.0.0.1"
ui_port: int = 7860
ui_share_lan: bool = False
jpeg_max_edge: int = 2048
def model_post_init(self, _context: object) -> None:
if not self.embed_base_url:
object.__setattr__(self, "embed_base_url", self.llm_base_url)
if not self.embed_model:
object.__setattr__(self, "embed_model", self.llm_model)
@property
def db_path(self) -> Path:
return self.data_dir / "receipts.db"
def ensure_dirs(self) -> None:
for path in (
self.data_dir,
self.inbox_dir,
self.processing_dir,
self.processed_dir,
self.failed_dir,
self.exports_dir,
):
path.mkdir(parents=True, exist_ok=True)
def load_settings(**overrides: object) -> Settings:
settings = Settings(**overrides)
settings.ensure_dirs()
return settings