FinAssist Copilot is a assistant that helps analysts browse financial PDFs, extract text or images, and query an AI copilot that understands the uploaded content. The repository bundles both the interactive front-end experience and the supporting Python services responsible for OCR, PDF processing, and image understanding.
- Document sidebar with instant navigation across bundled or user-provided PDFs.
- Real PDF rendering via PDF.js with smooth scrolling and selectable text layers.
- Embedded conversational assistant that can answer finance-focused questions about the active document.
- Vision pipeline capable of describing charts, tables, and general images detected in each PDF.
- Responsive Surseoir design system with 3D cards, subtle motion, and consistent typography.
- Frontend: static assets in
static/combining HTML, Tailwind CSS (via CDN), vanilla JavaScript, and PDF.js. - Backend: Flask application in
app.pywith supporting utilities underutils/for OCR, PDF parsing, and image analysis. - Vision services:
utils/vision.pyorchestrates OpenRouter calls, caching, and error handling for chart/table understanding. - Persistence: IndexedDB helper (
static/src/js/idb.js) keeps uploaded PDFs available offline. - Tests:
backend/tests/test_vision.pyandbackend/tests/test_vision_api.pyvalidate the computer-vision workflow and API surface.
Detailed explanations for each module live inside the documentation/ directory. Start with documentation/README.md for the table of contents.
# Option A: open the static page directly
open static/index.html
# Option B: run a lightweight server
python -m http.server 8000 -d static
# or
npx http-server staticNavigate to http://localhost:8000 after the server starts.
pip install -r backend/requirements.txt
cp .env.example .env # fill in OPENROUTER_API_KEY before running
python backend/app.py
# or
FLASK_APP=backend.app flask run --host=0.0.0.0 --port=5002- Place the files under
static/. - Update the document list in
static/src/js/app.js. - Reload the page to refresh the sidebar.
FinAssist/
├── backend/
│ ├── app.py # Flask entry point
│ ├── wsgi.py # Gunicorn entry point
│ ├── requirements.txt # Backend dependencies
│ ├── runtime.txt # Runtime pin for PaaS targets
│ ├── utils/ # OCR, PDF, and vision helpers
│ ├── tests/ # Backend test suite
│ └── vision_cache.json # Vision cache store
├── documentation/ # Technical documentation set
├── static/
│ ├── index.html # Main interface
│ └── src/
│ ├── css/
│ │ └── app.css
│ └── js/
│ ├── app.js
│ ├── idb.js
│ └── landing.js
├── Procfile # Gunicorn command (root for PaaS)
├── Dockerfile # Container build (targets backend/)
├── requirements.txt # Proxy to backend/requirements.txt
├── runtime.txt # Python runtime pin for PaaS
├── .python-version # Pyenv pin for local dev
├── README.md
└── LICENSE
- Frontend: HTML5, Tailwind CSS (CDN), vanilla JavaScript, PDF.js rendering.
- Backend: Python 3.12, Flask, gunicorn (for deployment), python-dotenv.
- Document Processing: PyPDF2 for text extraction, pytesseract + Pillow for OCR, OpenCV + NumPy for chart/table heuristics.
- AI Integration: OpenRouter-hosted models for language and vision reasoning with caching handled by
vision_cache.json. - Storage: Browser-side IndexedDB for offline PDFs; optional backend persistence via Flask extensions.
For deeper dives into each layer—OCR, PDF extraction, IndexedDB storage, CSS system, deployment, and the production roadmap—refer to the dedicated files inside documentation/.
- Duplicate
.env.exampleto.envand set the variables:OPENROUTER_API_KEY: API key used for LLM and vision requests (never commit the real key).FLASK_ENV:developmentby default; set toproductionin hosted environments.PORT: Listening port for the Flask server (defaults to5002).MAX_TOKENS_PER_REQUEST(optional): override the tiny demo rate limit enforced by/ask.RATE_LIMIT_CONTACT(optional): email displayed in the UI when the rate limit triggers.MAX_REQUESTS_PER_WINDOW(optional): number of/askcalls allowed perREQUEST_WINDOW_SECONDS.REQUEST_WINDOW_SECONDS(optional): duration of the sliding window for request rate limiting.
- Ensure
.envremains untracked (already covered by.gitignore) before publishing the repository publicly. - Rotate and revoke any keys that have been previously shared to avoid accidental exposure.
- PDFs do not render: confirm the files exist under
static/, the HTTP server has access, and the browser console does not show PDF.js errors. - Chat panel remains inactive: ensure
static/src/js/app.jsis loaded and the Flask API (when used) returns a 200 response. - Vision requests time out: review
vision_cache.json, check network access to OpenRouter, and verify theOPENROUTER_API_KEYvalue.
FinAssist Copilot is distributed under the Creative Commons Attribution-NonCommercial 4.0 International license. You may reuse and adapt the project for non-commercial work as long as you credit the FinAssist Team and link back to this repository. For commercial licensing or redistribution that removes the FinAssist branding, contact ismail.moudden1@gmail.com.
