PaperMate / backend /config.py
ntphuc149's picture
refactor: remove Resend email service — login required, no email needed
f19919a
Raw
History Blame
3.05 kB
from typing import Literal
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
# LLM
llm_provider: Literal["anthropic", "openai", "gemini", "openrouter"] = "anthropic"
llm_model: str = "claude-sonnet-4-6"
# API Keys
anthropic_api_key: str = ""
openai_api_key: str = ""
gemini_api_key: str = ""
openrouter_api_key: str = ""
# LandingAI ADE
landingai_api_key: str = ""
# PDF Parser: "landingai" | "docling"
# "docling" uses a self-hosted Kaggle server discovered via ntfy.sh
pdf_parser: Literal["landingai", "docling"] = "landingai"
# Minimum extracted markdown length to consider a parse successful. Below this
# the pipeline fails fast instead of generating a review from empty text.
min_parsed_markdown_chars: int = 100
# ntfy.sh topic used to discover the Docling server URL from Kaggle
ntfy_topic: str = "papermate_pdf2md"
# Tavily
tavily_api_key: str = ""
# Tavily has no per-call credit API, so cost is computed locally:
# cost_usd = successful_searches * tavily_credits_per_search * tavily_price_per_credit
# Basic search = 1 credit; pricing snapshot $0.008/credit.
tavily_price_per_credit: float = 0.008
tavily_credits_per_search: int = 1
# App
app_base_url: str = "http://localhost:8000"
max_file_size_mb: int = 10
jobs_dir: str = "data/jobs"
logs_dir: str = "data/logs"
# Supabase
supabase_url: str = ""
supabase_service_role_key: str = ""
supabase_anon_key: str = "" # public key for the frontend (login)
supabase_jwt_secret: str = "" # only needed for local HS256 verify (unused by default)
supabase_storage_bucket: str = "paper-review-artifacts"
# Auth / RBAC
# Comma-separated emails auto-promoted to admin on first login (also seed via SQL).
admin_emails: str = ""
# When False, anonymous submit (email + access_key) keeps working as before.
auth_required_for_submit: bool = False
# Quota (per logged-in user, per calendar month). null/0 = unlimited.
default_monthly_review_limit: int = 0
default_monthly_cost_limit_usd: float = 0.0
# Dashboard cost alert: flag a day whose total cost exceeds this (USD). 0 = off.
cost_alert_daily_usd: float = 0.0
# Manual pricing snapshots, USD per 1M tokens. These default to zero so
# missing prices never block review generation.
openai_input_price_per_1m: float | None = None
openai_output_price_per_1m: float | None = None
anthropic_input_price_per_1m: float | None = None
anthropic_output_price_per_1m: float | None = None
gemini_input_price_per_1m: float | None = None
gemini_output_price_per_1m: float | None = None
openrouter_input_price_per_1m: float | None = None
openrouter_output_price_per_1m: float | None = None
class Config:
env_file = ".env"
env_file_encoding = "utf-8"
extra = "ignore" # ignore unrelated env vars (e.g. HF_TOKEN, DOCLING_HF_SPACE)
settings = Settings()