Skip to content

feat(app): persistent results and multi-slot cache in the Streamlit app - #61

Merged
kjs11 merged 4 commits into
masterfrom
feat/streamlit-reactive-cache
Nov 1, 2026
Merged

kjs11 merged 4 commits into
masterfrom
feat/streamlit-reactive-cache

Conversation

@wenh06

@wenh06 wenh06 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Streamlit app already supported enter-to-search and sidebar changes re-triggering the lookup (via the confirmed_doi flag pattern from 047bd24), but AppTest-based behavioral testing surfaced four real gaps, all fixed here:

  1. Results were not persisted — the rendered output only lived in the script run that triggered the lookup, so a plain script re-run (e.g. a websocket reconnect) made the result vanish.
  2. Clearing the input left layout artifacts — the divider rendering depended on the same transient flag.
  3. Format switches always re-queried — toggling bibtex → text → bibtex on the same identifier hit the network twice, although the original result was already in the session.
  4. The cache was a single slot — only the last lookup was remembered.

Changes (streamlit_app.py, no package code touched)

  • do_lookup() is now a pure session-state writer: it stores a last_render descriptor (success / error / redirect) in st.session_state, and rendering happens unconditionally from that state afterwards. Results survive re-runs; empty input cleanly clears the result.
  • The history cache is keyed by (identifier, arxiv2doi, format) (multi-slot). Cached bibtex entries are re-rendered locally via _to_bib_item when alignment / capitalize_title change — zero network calls.
  • Redirect parsing references BibLookup.__REDIRECT_FLAG__ and the "visit: " marker in one place.

Support matrix (follow-up to the 3.9 CI failure this PR hit)

Python 3.9 has been EOL since 2025-10 and 3.10 since 2026-10, and the current dependency ecosystem (streamlit ≥ 1.66, pandas 3.x, numpy 2.3) already requires ≥ 3.11 — the 3.9 CI job was resolving a stale streamlit without streamlit.testing.v1. This PR raises the floor:

  • requires-python = ">=3.11"; classifiers drop 3.9/3.10
  • pytest matrix: ["3.11", "3.12", "3.13", "3.14"] — 3.14 was already claimed in the classifiers but never tested; now it is
  • users on older interpreters automatically resolve the last compatible release from PyPI

Tests

New test/test_streamlit_app.py (8 tests) uses the official Streamlit AppTest framework with BibLookup.__call__ stubbed (no network):

  • enter triggers exactly one lookup; button not needed
  • alignment / capitalize changes re-render from cache with zero new calls
  • bibtex → text → bibtex round trip costs exactly one call; the return leg is served from cache
  • result persists across a plain re-run; clearing the input clears the render
  • redirect, lookup-error, and exception paths render the expected states

Full suite: 104 passed (96 + 8 new) locally; the AppTests run in CI (the dev extra already includes streamlit).

- keep the rendered result in st.session_state["last_render"] instead of
  writing widgets inside the lookup callback: results now survive plain
  script re-runs (e.g. websocket reconnects), and clearing the input
  cleanly removes the result
- cache lookups per (identifier, arxiv2doi, format) instead of a single
  slot: switching between formats of the same identifier no longer
  re-queries the network, and cached bibtex entries are re-rendered
  locally when alignment / capitalize_title change
- do_lookup() is now a pure session-state writer and rendering happens
  unconditionally from the stored state; the confirm-flag dance with
  the divider is gone
- add AppTest-based regression tests (test/test_streamlit_app.py) covering
  enter-to-search, sidebar re-renders without network, format round trips,
  persistence across re-runs, and the redirect / error / exception paths
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-29T02:33:15.444784Z
We couldn’t complete this review. Comment @codex review to try again.
f4cffb7 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.61%. Comparing base (60364af) to head (02f0993).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master      #61   +/-   ##
=======================================
  Coverage   98.61%   98.61%           
=======================================
  Files          13       13           
  Lines        1944     1944           
=======================================
  Hits         1917     1917           
  Misses         27       27           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Older streamlit releases (resolved on Python 3.9 in CI) ship
streamlit.testing without the v1 submodule; name the full module in
importorskip so collection skips cleanly instead of erroring.
- Python 3.9 (EOL 2025-10) and 3.10 (EOL 2026-10) are dropped from
  requires-python, the classifiers, and the pytest matrix; the current
  dependency ecosystem (streamlit >= 1.66, pandas 3.x, numpy 2.3) already
  requires >= 3.11, so 3.9/3.10 users only ever got a stale dependency set
- add Python 3.14 to the pytest matrix (it was already claimed in the
  classifiers but never tested)
- keep the streamlit app tests skippable on interpreters whose resolved
  streamlit lacks streamlit.testing.v1
@kjs11
kjs11 added this pull request to the merge queue Nov 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 1, 2026
@kjs11
kjs11 added this pull request to the merge queue Nov 1, 2026
Merged via the queue into master with commit 0b654a4 Nov 1, 2026
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants