Skip to content

Repository files navigation

CiteScan

Scholar Citation Integrity Detector

Python 3.11+ Streamlit License: MIT Live demo Tests

Try it live → (no install needed - runs on a shared free OpenAlex quota, see Deploying your own copy if you hit a quota limit or want to run it yourself)

A tool for students preparing to reach out to or apply with a potential PhD advisor: enter a scholar's name (or search by field + institution), and CiteScan pulls public citation data from OpenAlex to compute a set of explainable metrics and a report with linked evidence — helping you judge whether an impressive citation count has something fishy behind it, instead of handing you an opaque "trust score."

Every result is a lead you should verify yourself, not proof of academic misconduct. Niche sub-fields naturally have higher mutual-citation rates, and OpenAlex's coverage isn't as complete as Google Scholar's. Always weigh results against the specific field and the evidence detail before drawing conclusions.

Report screenshot for a fictional scholar

Screenshot uses a fabricated scholar and dataset — no real person's report is shown here.

What it detects

Dimension What it does
Self- / external-citation rate A "deep external rate" that also strips out citations from flagged citation-ring partners, showing how much of the citation count genuinely comes from independent third parties
Suspected citation rings Detects implausibly high bidirectional mutual citation using a configuration-model null hypothesis, counted by distinct papers involved rather than raw citation count — so a paper that's genuinely influential and widely cited isn't mistaken for a reciprocal-citation deal
Suspected guest authorship Detects paper-count inflation via co-authorship rather than citation exchange — an unusual author-position pattern (almost never first or last author), or an implausibly high share of the scholar's total output with no single position dominating (unlike a typical student or a typical senior collaborator); reciprocity for any one collaborator can be verified on demand
Venue quality CCF recommended-venue tier (CS/EE fields) plus a median venue impact factor (cross-discipline, excluding venues with no data)
Publication velocity vs. quality Papers per year and average external citations per paper, to spot "high volume, low quality" patterns
Rule-based interpretation summary An automatically generated bilingual (EN/中文) summary built from all of the above, against transparent, documented thresholds, with the actual number behind every judgment

The number of papers analyzed is adjustable (5–500); if that's fewer than the scholar's total output, CiteScan draws a reproducible random sample instead of just taking the first N returned by the API. The UI supports switching between Chinese and English.

What you get

Searching a scholar and generating a report produces a single page with:

  • A rule-based interpretation summary at the top - one line per metric, colored by severity, each naming the actual number and the documented threshold behind the judgment (not a hidden score).
  • Metric cards for every dimension in the table above (self-citation rate, h-index vs. net h-index, Gini concentration, papers/year, venue quality, etc.), each with a ? help tooltip explaining the formula and its caveats.
  • A per-paper table (title, year, venue, CCF tier, venue impact factor, raw vs. estimated external citations) you can sort and inspect directly.
  • A suspected citation rings section - empty/green if none found, otherwise one entry per flagged partner with the specific paper pairs and years behind the flag.
  • A suspected guest authorship section - same idea, with a per-candidate breakdown (position counts, year range, venues, institution) and an on-demand "verify reciprocity" button.
  • Export buttons for the full report as JSON (structured data, for archiving or your own processing) or a standalone HTML document (readable/shareable without this app running).

The Methodology & disclaimer page (in the sidebar nav) documents every metric's exact formula, data source, and known limitations, plus how the ring-detection and guest-authorship algorithms work.

Quick start

# 1. Create a virtual environment and install dependencies
python -m venv .venv
.venv/Scripts/python.exe -m pip install -r requirements.txt   # Windows
# source .venv/bin/activate && pip install -r requirements.txt  # macOS/Linux

# 2. (Optional, strongly recommended) get a free OpenAlex API key at
#    openalex.org/settings/api to raise your daily request quota (~10x more
#    than the no-key tier), and set it in .env
cp .env.example .env   # then edit .env and fill in OPENALEX_API_KEY (and OPENALEX_MAILTO)

# 3. Launch
PYTHONPATH=src .venv/Scripts/python.exe -m streamlit run src/citescan/app.py

Open http://localhost:8501 in your browser and search for a scholar by name, or by field + institution, from the sidebar.

The CCF recommended-venue list ships pre-built in the repo (data/ccf/ccf_list.json), so there's nothing to generate before first run. To refresh it later: .venv/Scripts/python.exe scripts/build_ccf_list.py.

Running tests

PYTHONPATH=src .venv/Scripts/python.exe -m pytest tests/ -v

Deploying your own copy

The repo is set up to deploy directly to Streamlit Community Cloud (free) from this GitHub repo:

  1. Sign in at share.streamlit.io with GitHub and pick this repo.
  2. Set the main file path to streamlit_app.py (a thin shim at the repo root - Streamlit Cloud has no equivalent to the local PYTHONPATH=src launch flag, so this puts src/ on the path itself before running the real app).
  3. Under Advanced settings → Secrets, optionally add a server-side default API key:
    OPENALEX_API_KEY = "your-api-key"
    OPENALEX_MAILTO = "your-email@example.com"

OpenAlex's rate limit is a daily quota tied to an API key (or caller IP if none is given) - shared across every visitor to the deployed app unless they enter their own key. To keep a public deployment from having its shared quota drained by one heavy user, the app has two mitigations: a visitor can optionally paste their own free OpenAlex API key into the sidebar's "Use your own OpenAlex API key" expander, which routes just their requests onto their own quota (the response cache itself is still shared across everyone, regardless of whose key fetched it); and the default "papers to analyze" is kept modest (config.DEFAULT_PAPERS_TO_ANALYZE) so a first-time visitor's one click doesn't burn a disproportionate share of the shared quota. See datasources/cache.py for the per-key throttling and fail-fast quota-exhaustion handling behind this.

Data sources

  • OpenAlex — the primary data source: free, no registration, fully legal (unlike scraping Google Scholar, which violates its terms of service), with a complete citation graph. This is the core data behind self-citation rate, external-citation rate, and citation-ring detection.
  • Semantic Scholar — a supplementary source used only for the "influential citations" metric; its unauthenticated rate limit is strict, so only a scholar's most-cited papers are checked.
  • CCF recommended-venue list — from WenyanLiu/CCFrank4dblp (MIT licensed), covering CS/EE fields only; scripts/build_ccf_list.py fetches and caches it to data/ccf/ccf_list.json. Venue-name mismatches can be manually mapped in data/ccf/venue_overrides.json.
  • OpenAlex venue statistics (2-year mean citedness) — used to compute a cross-discipline "median venue impact factor," filling the gap left by the CCF list's CS-only coverage.

Project structure

streamlit_app.py               # Entry point for Streamlit Community Cloud (see "Deploying" above)
src/citescan/
  config.py                    # Paths, rate limits, detection thresholds - global config
  app.py                       # Streamlit UI
  i18n.py                      # Chinese / English UI text
  export.py                    # Report export to JSON / HTML
  datasources/
    cache.py                   # Disk-cached HTTP client with per-host throttling, adaptive
                                # backoff, and fail-fast quota-exhaustion detection
    openalex.py                # OpenAlex API client (authors/works/citations/topics/institutions)
    semantic_scholar.py        # Semantic Scholar client (influential citations)
    venue_tier.py               # Venue name -> CCF tier matching (exact/abbreviation/fuzzy)
  analysis/
    models.py                  # Shared data structures (ScholarData / PaperCitations)
    self_citation.py           # Self-/external-/coauthor-citation rates
    impact_metrics.py          # Gini concentration, net h-index
    velocity.py                # Publication velocity vs. citation quality
    journal_quality.py         # Venue impact factor enrichment
    influential_citations.py   # Semantic Scholar influential-citation enrichment
    ring_detection.py          # Citation-ring detection
    coauthorship.py            # Guest-authorship detection
    interpretation.py          # Rule-based interpretation summary
    report.py                  # Top-level pipeline tying all of the above together
scripts/
  build_ccf_list.py            # Fetch/refresh the CCF recommended-venue list
tests/
  test_ring_detection.py       # Citation-ring detection algorithm
  test_coauthorship.py         # Guest-authorship detection algorithm
  test_self_citation.py        # Self-/external-/deep-external-citation rate math
  test_interpretation.py       # Interpretation-summary threshold tiers
  test_journal_quality.py      # Venue impact factor enrichment, incl. failure isolation
  test_report.py               # Top-level pipeline, incl. per-paper failure isolation
  test_cache.py                # Identity-aware caching/throttling, secret redaction

Contributing

Issues and PRs are welcome - see CONTRIBUTING.md. See CHANGELOG.md for release history.

Known limitations

  • Citation-ring detection currently only identifies anomalous mutual citation between pairs, not groups of 3+; the "expected" citation count is normalized within the observed candidate pool, a relative comparison rather than an absolute benchmark against the whole literature.
  • Guest-authorship detection assumes author order reflects contribution (first author did the work, last author led it), which doesn't hold in fields that list authors alphabetically by convention (much of math, theoretical CS, economics). OpenAlex has no faculty-rank field, so "is this the scholar's own student" is only approximated via whether the institution matches and whether one author position dominates.
  • The CCF list only covers CS/EE fields; other disciplines showing "not in the CCF list" is expected and doesn't indicate low venue quality.
  • Data completeness depends on OpenAlex's coverage, which is less complete than Google Scholar's (especially older literature and some Chinese-language venues); OpenAlex also enforces a daily request quota, so heavy usage may require waiting for it to reset.

See the in-app "Methodology & disclaimer" page for the full metric definitions and limitations.

License

MIT

About

Scholar Citation Integrity Detector — explainable OpenAlex-based metrics to help PhD applicants vet potential advisors' citation quality

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages