This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
PaperPilot is an invoice and expense assistant for freelancers, consultants, and small agencies.
Anyone who works for themselves ends up with a folder of PDF invoices and a dreaded tax season. Someone has to type every vendor, date, and total into a spreadsheet, spot the invoice that was uploaded twice, and remember who hasn't paid. In India there's an extra layer: GSTIN numbers and CGST, SGST, and IGST splits that generic tools handle poorly.
With PaperPilot you upload a digital PDF invoice and the app:
- Extracts the vendor, invoice number, dates, subtotal, GST amounts, and total
- Checks the numbers instead of trusting the AI blindly
- Lets you review and fix anything before saving
- Catches duplicate invoices before they are saved
- Flags overdue invoices from their due dates
- Matches a bank statement CSV to mark invoices as paid
- Exports everything to CSV, with search and filters
Demo
Code
๐งพ PaperPilot: Invoice & Expense Assistant
PaperPilot reads PDF invoices with Gemma, an open-weight AI model, checks the results and organises everything into searchable records and CSV exports Built for freelancers, consultants, and small agencies.
Features
- Upload digital PDF invoices (scanned or image files are not supported)
- Gemma extracts vendor, dates, subtotal, tax and total
- India GST support: GSTIN, CGST / SGST / IGST, HSN / SAC codes
- Duplicate invoice detection
- Overdue payment flags based on due date
- Bank statement matching: upload a CSV and mark paid invoices automatically
- Safety checks: totals that do not add up, bad GSTINs, or amounts missing from the document are flagged for review
- Search, filter, and CSV export
Why an open model?
- Open weights: Gemma's weights are public, so the same model can later be self-hosted by anyone who needs full control.
- Low cost: hosted Gemma is inexpensive to call, which suits aโฆ
How I Built It
The open model is Gemma. I use Gemma, Google's open-weight model, called through the Gemini API with a standard API key.
Pipeline:
- Read: PyMuPDF pulls the text out of a digital PDF.
- Redact: a small module blanks out emails, phone numbers, PAN, Aadhaar, and bank account numbers before anything is sent to the model. The GSTIN is kept, since it's a business number the app needs.
- Extract: Gemma returns the invoice fields as JSON. I prompt for a strict set of keys and parse the reply defensively (stripping code fences, converting numbers) because models don't always follow instructions perfectly.
- Validate: this is the part I care about most. Small models can misread numbers, so the app flags a subtotal plus tax that doesn't equal the total, a total that doesn't appear anywhere in the document, an invalid GSTIN, and unequal CGST and SGST. The AI suggests, the code checks, and the human confirms.
- Store and use: records go in SQLite. Duplicate detection, overdue flags, and bank matching are plain Python, not AI. I deliberately kept AI to the one task it's good at, which is reading messy layouts.
Stack: Python, Streamlit, PyMuPDF, SQLite, pandas, and Gemma via the Gemini API.
Why Does Open Innovation Matter?
- No lock-in. The model is a single setting. Swapping to another Gemma model is one line, and the rest of the app doesn't change.
- A path to full control. Because Gemma's weights are public, a business that doesn't want any data leaving its network can self-host the same model later. A closed model offers no such option, since you can only rent it.
Prize Categories
- Best Use of Render
- Best Use of Gemma




Top comments (0)