Spaces:
Running
Running
|
Download docs/ui/react-workspace.md from gauravmeena0708/epfo-circulars: direct link, hf CLI and curl.
- Browser
- Download file 12.4 kB
-
https://huggingface.co/spaces/gauravmeena0708/epfo-circulars/resolve/main/docs/ui/react-workspace.md
- Command line
-
hf download hf://spaces/gauravmeena0708/epfo-circulars/docs/ui/react-workspace.md
-
curl -L -o react-workspace.md https://huggingface.co/spaces/gauravmeena0708/epfo-circulars/resolve/main/docs/ui/react-workspace.md
12.4 kB
| # React workspace decision and implementation | |
| Use React + Vite and FastAPI together in one Hugging Face Docker Space. The | |
| institutional interface uses navy `#173650`, teal `#217b7c`, restrained gold | |
| `#b58c45`, serif headings and fine rules. It identifies itself as an independent | |
| research tool and does not use an official seal. | |
| The [Docker Spaces documentation](https://huggingface.co/docs/hub/spaces-sdks-docker) | |
| and [configuration reference](https://huggingface.co/docs/hub/spaces-config-reference) | |
| confirm that an existing Space can use `sdk: docker`, a root Dockerfile and port | |
| 7860. A static React Space would need another service for Python retrieval and | |
| private inference credentials. One Docker Space keeps these on the same origin. | |
| ## Completed migration | |
| | Area | Implementation | | |
| | --- | --- | | |
| | Research | Existing policy router and FAISS/BM25/RRF/reranking pipeline, date cutoff, policy selector, English/Hindi streaming answers | | |
| | Sources | Numbered citations, selectable excerpts, page provenance, original PDF panel (fetched from the official URL and hash-checked), original-source links | | |
| | Policies by division | Sidebar page "Policies by division": division groups, searchable policy-topic tables with a status filter (status shown only where a circular says it), and links into the curated collections. Served by `/api/divisions` from `policy_data/division_catalog.json` | | |
| | Policy library timeline | Each curated history shows its first-to-latest issue span on a shared 2006-2026 bar and can be ordered latest first, earliest first or A to Z. Below them, any rule topic from the division catalog that is not yet a curated history is placed on the same timeline and opens the division page (none remain: every rule row links to a verified history) | | |
| | Policy collection | Live index count, eleven registered histories, dated timelines, scoped relationships, missing-source and commencement limitations | | |
| | PDF assistant | Native extraction, lazy Tesseract OCR in English/Hindi, physical-page markers, file questions, formal office noting, text/Word/original downloads | | |
| | CSV assistant | Schema, null counts, summary statistics, first 100 rows, exact-term search, category distributions, file-grounded questions and notes | | |
| | PDF utilities | Merge/reorder, extract, split, rotate, lossless compression, images to PDF, PDF to images, searchable OCR | | |
| | Word parity | Research report with sources and evidence cutoff, extracted document/profile, conversation transcript, OCR Word output | | |
| | Settings | Optional personal HF token in browser memory; shared server token remains the default | | |
| | Deployment | Root Dockerfile builds React, installs CPU Torch and lean Python dependencies, Tesseract English/Hindi, serves FastAPI as UID 1000 on 7860 | | |
| OCR downloads a ZIP containing a searchable PDF, Word document and UTF-8 text. | |
| Searchable PDF generation uses Tesseract's PDF renderer so the text layer retains | |
| word positions. Compression is lossless and may not reduce an already optimised | |
| file. Upload processing and PDF utilities do not call the language model. | |
| The existing GPT-OSS model/provider settings and bounded-prompt/HTTP-413 retry | |
| remain in `answer_generator.py`. No source PDFs, policy histories or vector indexes | |
| were changed by the interface migration. The corpus remains 75,110 passages and | |
| eleven curated histories. The histories are incomplete evidence inventories; | |
| issue-date filtering does not certify which law applies. Standard hybrid search | |
| explicitly states that it does not apply the history cutoff. | |
| ## Sessions and limits | |
| - Each browser load gets an unpredictable 128-bit session ID held in memory and | |
| sent in a header. Uploaded files, chats and research packets require that ID. | |
| Another session cannot read, delete, generate from or export those objects. | |
| No third-party cookies are needed inside the Hugging Face iframe. | |
| - Files expire after 30 minutes. A background task removes expired uploads every | |
| minute; reads also reject expired objects. Restarting the Space clears all | |
| uploaded files and conversations. Download anything needed for a record. | |
| - At most 24 uploads and 256 MB of accounted upload memory are retained in one | |
| process. PDF/CSV extraction and PDF operations allow two concurrent jobs. | |
| - PDF uploads: 50 MB / 100 pages. CSV: 25 MB input / 64 MB expanded dataframe. | |
| Utilities: 20 files, 50 MB each, 100 MB per request, 250 pages per file / 300 | |
| combined, 50 pages for rendering and 30 for OCR. Rendered-page area is bounded. | |
| - Research packets expire after 15 minutes, with at most 50 in memory. The shared | |
| inference limiter is reused. The deployment deliberately uses one worker so | |
| these limits and session stores apply consistently. | |
| - `HF_TOKEN` belongs in Space secrets. Optional personal tokens are sent in request | |
| headers over HTTPS and are never stored in uploads, exports or browser storage. | |
| Refreshing clears the personal token. A browser session is a temporary workspace, | |
| not an authenticated account or durable record store. | |
| - CPU embedding/reranker models load lazily. The catalogue and curated bank-KYC | |
| evidence work without those models or an inference token. Model download and | |
| loading can make the first hybrid search slower. | |
| ## Local use | |
| ```bash | |
| # Development: install CPU Torch first if it is not already available. | |
| python -m pip install torch==2.10.0 --index-url https://download.pytorch.org/whl/cpu | |
| python -m pip install -r requirements-react.txt | |
| python -m uvicorn web_api.app:app --host 0.0.0.0 --port 7861 | |
| npm --prefix frontend ci | |
| npm --prefix frontend run dev -- --port 5174 | |
| ``` | |
| The Vite proxy sends `/api` to `127.0.0.1:7861`. Local PDF OCR also requires system | |
| Tesseract with English/Hindi language data. The Docker image installs these. | |
| ```bash | |
| # Production-equivalent build and serving | |
| docker build -t epfo-workspace . | |
| docker run --rm -p 7860:7860 --env-file .env epfo-workspace | |
| ``` | |
| The root recipe and `deploy/react/Dockerfile` are identical. The latter is kept as | |
| a named migration recipe; update both if runtime dependencies or serving change. | |
| `requirements.txt` and `app.py` retain the original Streamlit app for local use. | |
| ## Verification on 29 October 2026 | |
| - The React production build passes with a checked-in lockfile. Vite emits benign | |
| client-directive warnings for lucide-react; this app does not use server components. | |
| - 60 tests pass across `test_web_api.py`, `test_web_workspace.py`, and the existing | |
| document/data/PDF/Word helper suites. Tests use real PDF and DOCX bytes and real | |
| Tesseract OCR. Model streaming tests use a fake model, not paid inference. | |
| - API tests cover live registry/index metadata, cutoffs, supersession and missing | |
| originals, archive path allowlisting, source numbering, session isolation, | |
| custom-token handling, expiry, CSV search/counts, all eight PDF operations, | |
| OCR text positions, research/Word/transcript exports and invalid inputs. | |
| - Chromium checks against the local API cover research, all eleven library cards, | |
| history, actual bank-KYC retrieval, PDF inspection, CSV upload/search/distribution, | |
| Word downloads, document extraction, merged PDF page count, session-token storage | |
| and mobile navigation at 390 px. No JavaScript errors or horizontal overflow. | |
| - The production Docker image builds and runs as UID 1000. Its catalogue reports | |
| 75,110 passages and eleven policies. Curated evidence, CSV upload, Word report and | |
| actual hybrid retrieval work inside the container. A cold hybrid query took | |
| about 40 seconds, including model loading/downloads. | |
| - These checks verify migration behavior; they are not a legal-accuracy benchmark | |
| or an LLM-answer quality evaluation. | |
| Screenshots in `screenshots/` show research, evidence, history, assistant and PDF | |
| utilities on desktop and mobile. | |
| ## Deployment and rollback | |
| GitHub Actions `.github/workflows/sync_to_hf.yaml` checks out LFS objects and uploads | |
| the repository to `gauravmeena0708/epfo-circulars`. README metadata selects Docker; | |
| the root Dockerfile builds and serves React. Keep `HF_TOKEN` as an existing Space | |
| secret. No token belongs in the Docker build or frontend bundle. | |
| After syncing, check the Space runtime is RUNNING with SDK docker, `/api/health` | |
| returns ok, `/api/catalog` shows the expected corpus/policies, and the main page | |
| loads React assets. Then test a dated bank-KYC query, archived source, Word report, | |
| CSV and PDF operation. Generation can be checked with the configured server token. | |
| For rollback, restore the README YAML to `sdk: streamlit`, | |
| `sdk_version: "1.45.1"`, `app_file: app.py`, remove `app_port`, and push through the | |
| same workflow. The original Streamlit code and dependency file remain available. | |
| Original policy PDFs are no longer stored in Git or in the Docker image. Each | |
| curated document keeps its public `source_url` and the SHA-256 of the original in | |
| `sources/*.json`. The first time a reader opens an original, the API downloads it from | |
| that URL, accepts it only if it is a PDF with the recorded hash, and caches it on the | |
| server's temporary disk (`EPFO_PDF_CACHE` overrides the location). If the official | |
| site is unreachable from the server, or the file has changed, the viewer link | |
| redirects to the official URL instead of showing an unverified copy. | |
| `python scripts/verify_policy_pdfs.py` re-checks that every recorded original can | |
| still be reproduced from its public URL (all 63 were byte-identical on 2 Nov 2026). | |
| ## Staff-policy extension | |
| Delegation of powers and EPFO employee benefits bring the collection count to 11. | |
| Their Matter controls work in research and Circular history; automatic detection | |
| can retain multiple named matters. Source-scoped fallback excludes unrelated | |
| matters and future issue dates. Invalid matter IDs fail explicitly. | |
| Twenty-one additional issuer-hosted PDFs supply 74 mapped pages and 226 passages. | |
| The aligned dense/SQLite/BM25 corpus now has 75,110 passages. Staged verification | |
| found zero changes to the original 75,110 passages. Medical originals and the | |
| reported 2026 publicity revision remain labelled unverified. Both October 2024 | |
| briefcase tables were checked against their scans, with raw OCR retained. | |
| 133 relevant Python checks pass, along with the frontend Markdown checks and the | |
| production build. The new development datasets each contain six source/page/date | |
| cases; these do not measure generated legal-answer accuracy. | |
| ## Runtime artifact storage | |
| The October 2026 staff-index upload reached the Space repository's 1 GB storage | |
| limit. The running Docker image now obtains its three aligned index files | |
| from immutable public GitHub LFS URLs using `deploy/runtime-assets.json`. Each file | |
| must match its recorded byte size and SHA-256 before it enters the image. Downloads | |
| happen in a separate Docker build stage so unchanged data can use the build cache. | |
| No credential is sent to GitHub for these public files. | |
| The GitHub sync excludes index binaries from new Space commits and pins the | |
| Hub upload client. Before upload it refreshes the manifest against the checked-out | |
| LFS bytes, advancing its source commit only when data changed. Normal GitHub commits | |
| and pushes therefore still publish updated policy data automatically. The Space | |
| keeps its existing history; this change does not squash or delete old revisions. | |
| For a local data change, commit the assets and run | |
| `python scripts/fetch_runtime_assets.py --record-commit <full-commit-sha>` before a | |
| local Docker build. CI refreshes the manifest automatically for the pushed commit. | |
| Builds need access to public GitHub LFS; a failed download or hash check fails the | |
| build and does not start an image with a mismatched corpus. | |
| ## Automatic research scope | |
| Policy research defaults to automatic policy and matter matching. Manual collection | |
| and matter selectors are collapsed under **Refine search scope**. Date and answer | |
| language remain visible. Results identify the detected policy/matters or explicitly | |
| state when the full collection was searched. A manual scope remains visible above | |
| the question with **Use automatic** to reset it. Example questions use automatic | |
| routing so they do not leave later questions pinned to a different policy. | |
| Circular history and library selectors remain visible for deliberate browsing. | |
| Browser checks cover an actual automatically routed bank-KYC question, an optional | |
| newspaper override, reset to automatic, and narrow-screen layout. | |