Self-hosted academic publication tracker. Track Google Scholar profiles, discover new papers automatically, resolve open-access PDFs, and stay on top of the literature you care about.
Find a file
Justin Visser 72bc046215 refactor: extract helpers from remaining long functions
- Extract _start_manual_run and _spawn_background_execution from run_manual route
- Extract _upsert_page_publications to deduplicate pagination loop
- Extract _classify_attempt from fetch_and_parse_with_retry
- Extract _log_alert_threshold_warnings from complete_run_for_user
- Functions 3f-3j accepted as kwargs-exception (body ≤50 lines excluding signatures)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:21:49 +01:00
.github chore: add MIT license and Buy Me a Coffee funding link 2026-02-27 11:25:13 +01:00
alembic ci: add ruff linting and mypy type checking 2026-02-26 22:11:41 +01:00
app refactor: extract helpers from remaining long functions 2026-02-27 16:21:49 +01:00
docs docs: rewrite README with project hook, feature table, and screenshot placeholders 2026-02-27 10:45:19 +01:00
frontend commit 2026-02-27 15:22:12 +01:00
scripts Initial release prep 2026-02-27 10:46:05 +01:00
tests refactor: fix naming, remove duplicate code from decomposition 2026-02-27 16:07:24 +01:00
.dockerignore streamlined 2026-02-17 21:59:41 +01:00
.env.example decompose application.py into enrichment, scholar processing, run completion 2026-02-27 14:19:39 +01:00
.gitignore chore: remove stale build artifacts, fix gitignore, use npm ci in CI 2026-02-26 21:24:59 +01:00
.python-version First product 2026-02-17 14:51:25 +01:00
agents.md docs(agents): expand testing section with ruff, mypy, and frontend gates 2026-02-27 11:06:38 +01:00
alembic.ini First product 2026-02-17 14:51:25 +01:00
DECOMPOSITION_SLICES.md refactor: extract helpers from oversized router and scheduler files 2026-02-27 15:41:23 +01:00
docker-compose.dev.yml test 2026-02-17 20:24:12 +01:00
docker-compose.yml arden scrape safety telemetry and polish run state UX 2026-02-19 21:59:36 +01:00
Dockerfile test 2026-02-17 20:24:12 +01:00
LICENSE chore: add MIT license and Buy Me a Coffee funding link 2026-02-27 11:25:13 +01:00
MODERNIZATION_PLAN.md Initial release prep 2026-02-27 10:46:05 +01:00
pyproject.toml ci: adopt python-semantic-release, fix hardcoded version strings 2026-02-27 00:07:25 +01:00
README.md docs: add CodeQL, release, Python version, and license badges to README 2026-02-27 11:10:56 +01:00
uv.lock updated uv 2026-02-27 11:41:19 +01:00

Scholarr

Scholarr

Self-hosted academic publication tracker.

Track Google Scholar profiles, discover new papers automatically, resolve open-access PDFs, and stay on top of the literature you care about.

CI CodeQL Release Docker Pulls Python License Docs


Publications dashboard

Why Scholarr?

Most researchers track new papers by manually checking Google Scholar, setting up email alerts, or juggling RSS feeds. Scholarr replaces all of that with a single self-hosted service:

  • Add scholars once -- by profile URL, Scholar ID, or name search
  • Publications appear automatically -- a background scheduler scrapes profiles on a configurable interval
  • Open-access PDFs are resolved for you -- Unpaywall and arXiv are queried automatically when a DOI is found
  • Everything is deduplicated -- publications are global records; no duplicates across scholars
  • Your data stays yours -- fully self-hosted, export/import your entire library at any time

Features

Automated Ingestion Background scheduler with configurable intervals, continuation queue, and multi-page pagination
Identifier Resolution Cross-references arXiv, Crossref, and OpenAlex to gather DOIs, arXiv IDs, PMIDs
PDF Discovery Resolves open-access PDFs via Unpaywall API and arXiv, with automatic retry queue
Scrape Safety Rate limiting, cooldowns, and backoff strategies that prevent IP bans -- these are safety floors, not optional
Multi-User Session-based auth, admin user management, user-scoped scholar tracking
Theming 7 color presets with light/dark mode, tokenized component system
Import / Export Portable scholar data with full publication and read-state preservation
Single Container FastAPI backend + Vue 3 frontend ship as one Docker image

Quick Start

# 1. Clone and configure
git clone https://github.com/JustinZeus/scholarr.git
cd scholarr
cp .env.example .env

# 2. Set required secrets in .env
#    POSTGRES_PASSWORD=<secure-password>
#    SESSION_SECRET_KEY=<random-32-char-string>

# 3. Start
docker compose up -d

# 4. Open http://localhost:8000

To bootstrap an admin account on first run, add to .env:

BOOTSTRAP_ADMIN_ON_START=1
BOOTSTRAP_ADMIN_EMAIL=admin@example.com
BOOTSTRAP_ADMIN_PASSWORD=<secure-password>

How It Works

graph LR
    UI[Vue 3 Dashboard] <-->|REST + SSE| API[FastAPI]
    API --> Scheduler[Scheduler]
    Scheduler -->|Scrape HTML| Scholar[Google Scholar]
    Scholar -->|Parse & Deduplicate| DB[(PostgreSQL)]
    Scholar -.->|Identify| Ext[arXiv / Crossref / OpenAlex]
    Ext --> DB
    DB -->|DOIs| PDF[PDF Resolution]
    PDF -->|Unpaywall / arXiv| DB
    API <--> DB

Tech Stack

Layer Technology
Backend Python 3.12, FastAPI, SQLAlchemy 2.0 (async), Alembic
Frontend TypeScript, Vue 3, Vite, Tailwind CSS
Database PostgreSQL 15
Infrastructure Multi-stage Docker, Docker Compose

Documentation

Full documentation: justinzeus.github.io/scholarr

Section Covers
User Guide Installation, configuration, all environment variables
Developer Guide Architecture, local dev, contributing, testing
Operations Deployment, database runbook, scrape safety
API Reference Envelope spec, all endpoints, DTO contracts

Contributing

Scholarr uses conventional commits and semantic versioning. See the contributing guide for PR process and code standards.

# Dev environment
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build

# Run tests (always in containers)
docker compose -f docker-compose.yml -f docker-compose.dev.yml run --rm app \
  python -m pytest

License

See LICENSE for details.