DEV Community

Arti Singh
Arti Singh

Posted on

Building an Offline-First AI Side Hustle with Ollama & Streamlit

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

I built Invoice & Receipt Sorter, a lightweight, offline-first desktop application designed for freelancers and small business owners to parse and organize their receipts and financial documents automatically.
​Instead of sending sensitive financial data to cloud-based APIs, the application processes everything 100% locally on the user's machine.
​Key Features:
​Privacy-First Data Extraction: Processes invoices and receipts completely offline without sending data to external servers.
​Structured Data Output: Extracts vendor names, dates, line items, and total amounts directly into structured JSON and CSV formats.
​Zero API Cost: Runs entirely on local hardware, eliminating recurring subscription or per-token usage fees.
​Simple & Intuitive UI: Built with Streamlit for a clean drag-and-drop workflow.

Demo

{
"vendor_name": "Acme Supplies",
"date": "2026-10-12",
"invoice_number": "INV-8921",
"total_amount": 45.50,
"currency": "USD"
}

Code

import streamlit as st
import ollama
from PIL import Image
import json

Page Configuration

st.set_page_config(
page_title="Local Invoice & Receipt Sorter",
page_icon="🧾",
layout="centered"
)

st.title("🧾 Local Invoice & Receipt Sorter")
st.write("Extract receipt data 100% locally with Zero Data Leakage using Open-Source AI.")

File Uploader

uploaded_file = st.file_uploader("Upload Receipt / Invoice Image", type=["jpg", "jpeg", "png"])

if uploaded_file is not None:
# Display uploaded image
image = Image.open(uploaded_file)
st.image(image, caption="Uploaded Invoice", use_container_width=True)

# Save temporary file for Ollama
temp_path = "temp_receipt.png"
image.save(temp_path)

if st.button("Extract Data Locally 🚀"):
with st.spinner("Processing locally with Ollama (llama3.2-vision)..."):
try:
# Call local Ollama model
response = ollama.chat(
model="llama3.2-vision",
messages=[{
"role": "user",
"content": (
"Analyze this receipt image and extract the following details in raw JSON format only: "
"vendor_name, date, invoice_number, total_amount, currency. "
"Do not include markdown or extra text."
),
"images": [temp_path]
}]
)

        # Show Output
        st.subheader("Extracted Details (JSON)")
        st.code(response['message']['content'], language="json")
        st.success("Successfully processed locally!")

    except Exception as e:
        st.error(f"Error processing image: {e}")
        st.info("Make sure Ollama is running locally (`ollama serve`) and `llama3.2-vision` is installed.")
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode




How I Built It

​Building Invoice & Receipt Sorter required combining a local LLM framework with a user-friendly frontend interface. Here is the step-by-step breakdown of how I built it:
​1. Setting Up the Local Inference Engine
​Instead of relying on cloud APIs, I used Ollama to run open-weight models locally on my machine. I chose llama3.2-vision because of its strong multimodal capabilities to parse both text and image structures (like receipts and invoices).

​To set up the model locally, I ran

Why Does Open Innovation Matter?

Building this project with open-source tools and open-weight models highlights why open innovation is crucial for building real-world AI applications:

​1. 100% Data Privacy & Security
​Financial documents like invoices and receipts contain sensitive vendor, personal, and payment data. Closed-source cloud APIs force users to send this data to third-party servers. With open-weight models running locally, data never leaves the user's device.

​2. Zero Marginal Cost & High Feasibility
​Paid APIs charge per token or image request, making micro-tools or small side hustles financially unviable. Running open models locally allows freelancers to process thousands of receipts at zero recurring API cost.

​3. No Vendor Lock-in & Full Control
​When you depend on a closed API, you are vulnerable to sudden price hikes, rate limits, or model deprecations. Open innovation gives developers full freedom to:

​Fine-tune models for niche receipt formats.

​Swap weights (e.g., switch from llama3.2-vision to Qwen-VL or Phi-3).

​Run the app completely offline without an internet connection.

My Agent Session

My First User

Prize Categories

Individual

Top comments (1)

Collapse
 
arti_singh_ae93fe70db4d00 profile image
Arti Singh •

Building this offline-first receipt sorter showed me how far open-weight models have come. It solves a real-world problem for freelancers and small businesses by prioritizing privacy and eliminating recurring subscription costs.